Omnimaga
Calculator Community => Major Community Projects => The Axe Parser Project => Topic started by: jacobly on October 25, 2011, 07:18:09 pm
-
This axiom allows you to access the os variables and do floating point math with them!
Feel free to ask questions instead of trying to read and understand this entire post.
Did you ever want to store the value of the real/complex variable A into the real/complex variable B inside of an axe program? Now it is easier than ever!
:A→B
:#Axiom(CPLXMATH) .varA could be complex
:Select("varA")→Select("varB") .Select( is in the 2nd List Ops menu
:solve() .optional but suggested, frees used memory
But maybe you wanted to store A + B to C. Well that is almost as simple.
:A+B→C
:#Axiom(CPLXMATH) .varA or varB could be complex
:solve(ᵀ+,Select("varA"),Select("varB"))→Select("varC") .solve( is on the Math Math menu
:solve() .optional, but suggested - frees used memory
In general, solve(ᵀ<op>,<args>) applies <op> to <args>. <op> can be be almost anything from ^, dim( to inString(!
Note: even though Axe changes inString( to inData(, it still does its original function when used in this command. Also, don't close the ( in <op>!
Well that's cool, but can I use Lists you ask? Of course!
:L₁∗A→L₂
:#Axiom(CPLXMATH) .L₁ or L₂ could be complex lists
:solve(ᵀ∗,Select("L₁"),Select("varA"))→Select("L₂")
:solve() .optional but suggested, frees used memory
But I only wanted to used the 42nd number in L₁ you ask? Well, why not!
:L₁(42)‒A→L₂(42)
:#Axiom(CPLXMATH) ... see above
:solve(ᵀ‒,Select("L₁",42),Select("varA"))→Select("L₂",42)
:solve() ... see above
Notice how Select( loads or saves to a variable, and solve( applies an operation to loaded variables.
The above code doesn't work if L₁ is too small, you say? Well why don't we resize L₁.
:42→dim(L₁)
:#Axiom(CPLXMATH) ...you know
:dim("L₁",42) .notice the slight difference in syntax
Note that solve() is unnecessary because dim does not currently use any memory.
I'll bet you forgot about matricies, you say... Nope!
:{5,5}→dim([A])
:For(A,1,5)
:For(B,1,5)
:10A+B→[A](A,B)
:End
:End
:#Axiom(REALMATH) .only real numbers used AND no arbitrary variable access
:Buff(9)→GDB1 .a temp floating point - they are 9 bytes large
:dim("[A]",5,5)
:For(A,1,5) .remember, A and B are still Axe variables
:For(B,1,5)
:A∗10+B→float{GDB1} .load temp with A∗10+B converted to a floating point
:GDB1→Select("[A]",A,B) .see, I didn't forget matrix support
:solve() .especially important inside loops
:End
:End
Or, if you are familiar with the format of floating point numbers:
:#Axiom(REALMATH) .see above
:"[A]"→Str1
:[008100000000000000]→GDB1 .floating point zero, prepared for 2 digit numbers
:dim(Str1,5,5)
:For(A,1,5)
:For(B,1,5)
:A∗16+B→{GDB1+2} .A and B are between 0 and 10 exclusive, treat as bcd digits
:GDB1→Select(Str1,A,B)
:End
:solve() .delete temp memory at least moderately often (~100 bytes at this point!)
:End
Now for an example that actually does something useful.
:(-B+√(B²‒4AC))/(2A)→C
:(-B‒√(B²‒4AC))/(2A)→D
:#Axiom(CPLXMATH) .obviously
:Buff(9)→GDB2 .declare constants
:Buff(9)→GDB4
:2→float{GDB2} .initialize constants
:4→float{GDB4}
:solve(ᵀ/,solve(ᵀ+,solve(ᵀ-,Select("varB")),solve(ᵀ√(,solve(ᵀ‒,solve(ᵀ²,Select("varB")),solve(ᵀ∗,GDB4,solve(ᵀ∗,Select("varA"),Select("varB")))))),solve(ᵀ∗,GDB2,Select("varA")))→Select("varC")
:solve()
:solve(ᵀ/,solve(ᵀ‒,solve(ᵀ-,Select("varB")),solve(ᵀ√(,solve(ᵀ‒,solve(ᵀ²,Select("varB")),solve(ᵀ∗,GDB4,solve(ᵀ∗,Select("varA"),Select("varB")))))),solve(ᵀ∗,GDB2,Select("varA")))→Select("varC")
:solve()
JK, it doesn't have to be that unreadable. I just wanted to show what you could do if you really wanted to. (Yes, that means you can nest as much as you want, limited only by the amount of memory available.) A normal person might do something more like this:
:#Axiom(CPLXMATH) .obviously
:Buff(9)→GDB2 .declare constants
:Buff(9)→GDB4
:2→float{GDB2} .initialize constants
:4→float{GDB4}
:Select("varA")→A .yes you can do that
:Select("varB")→B
:Select("varC")→C
:solve(ᵀ√(,solve(ᵀ‒,solve(ᵀ²,B),solve(ᵀ∗,GDB4,solve(ᵀ∗,A,C))))→D
:solve(ᵀ-,B)→B .pre-calculate stuff
:solve(ᵀ∗,GDB2,A)→A
:solve(ᵀ/,solve(ᵀ+,B,D),A)→Select("varD")
:solve(ᵀ/,solve(ᵀ‒,B,D),A)→Select("varE")
:solve()
Let's return the result in Ans instead of D and E.
:(-B+{1,-1}√(B²+i²4AC))/(2A)
i²=-1, but it allows the result to be complex regardless of mode. Similarly, complex constants are used below, with no i component, in order to allow complex answers in any mode.
:#Axiom(CPLXMATH)
:[015D]"TEMP"→Str1LT .[015D] must be used instead of the ᴸ before a list in the current version of Axe
:[0C80200000000000000C8000000000000000]→GDB2 .still 2, but complex
:[0C80400000000000000C8000000000000000]→GDB4 .complex floating point 4
:Select("varA")→A
:Select("varB")→B
:Select("varC")→C
:solve(ᵀ√(,solve(ᵀ‒,solve(ᵀ²,B),solve(ᵀ∗,GDB4,solve(ᵀ∗,A,C))))→C .we don't need C anymore
:solve(ᵀ-,B)→B .pre-calculate stuff
:solve(ᵀ∗,GDB2,A)→A
:DelVar Str1LT .Delete ᴸTemp in case it already exists
:solve(ᵀ/,solve(ᵀ+,B,C),A)→Select(Str1LT,1)
:solve(ᵀ/,solve(ᵀ‒,B,C),A)→Select(Str1LT,2)
:Select(Str1LT)→Select("varAns") .yep, that's right
:DelVar Str1LT .no one needs ᴸTemp anymore
:solve() .we are done
Strange OP codes (used instead of ᵀ<token>)
ECE | ECF | ED0 | ED1 | ED2 | ED3 | ED4 | ED5 | ED6 | ED7 | ED8 | ED9 | EDA | EDB |
npv( | irr( | bal( | ∑Prn( | ∑Int | ➤Nom( | ➤Eff( | dbd( | lcm( | gcd( | randInt( | randBin( | sub( | stdDev( |
|
EDC | EDD | EDE | EDF | EE0 | EE1 | EE2 | EE3 | EE4 | EE5 | EE6 | EE7 | EE8 | EE9 |
variance( | inString( | normalcdf( | invNorm( | tcdf( | Χ²cdf( | Ϝcdf( | binompdf( | binomcdf( | poissonpdf( | poissoncdf( | geometpdf( | geometcdf( | normalpdf( |
|
EEA | EEB | EEC | EED | E89 | E8A | E8B | E8C | E8D | E8E | E8F | E90 | E91 | E92 | E93 |
tpdf( | Χ²pdf( | Ϝpdf( | randNorm( | conj( | real( | imag( | angle( | cumSum( | expr( | length( | ΔList( | ref( | rref( | Fill( |
Update 0.1: Tutorial added.
Update 0.2: Major bugfix.
Update 0.3: Select( is replaced with get(. Key: seq(
*Warning: Please do not use RealMath unless you are absolutely sure that your code will never see anything that could posibly be complex. (unless you want corrupted mem, etc.) However, use it if you can, since it is smaller and faster.
-
I personally haven't had a use for it yet, but good work :) Using T to grab operations is genius!
-
it looks awesome!
So Quad solver in Axe finally? :D
-
Oh, I have a suggestion. Not sure how this would work, but why not merge Select() with float{} somehow, seeing as the latter's already used natively by Axe? Again, I have no idea how that would work, but if it could work that'd be awesome. It would mean one fewer token used up by an Axiom.
yeong, oh dear D:
-
did we already had one?
-
According the the almighty Quigibo ;), that doesn't work yet.
Unfortunately, you cannot re-define current Axe tokens in Axioms which is why you're getting that error, you can only overwrite unused tokens.
EDIT:
Oh, and I originally did use solve( for everything instead of Select(. The code may have been slightly unreadable. D:
Besides, Select( takes a string and float{ takes a pointer...
-
Intriguing. Now, people really can write a CAS in Axe. ;)
Perhaps I should release the routine I made to convert a string to a real and store it in a real var, so it would make this even easier to use this library, as it doesn't require knowledge of the FP format.
-
Perhaps I should release the routine I made to convert a string to a real and store it in a real var, so it would make this even easier to use this library, as it doesn't require knowledge of the FP format.
This Axiom doesn't either, does it? ???
-
Perhaps I should release the routine I made to convert a string to a real and store it in a real var, so it would make this even easier to use this library, as it doesn't require knowledge of the FP format.
This Axiom doesn't either, does it? ???
If you want to create an FP number like -0.145 in the program, I believe you have to create it using hex.
I believe the Axiom only adds math functions, not creating or displaying non-integer FP numbers.
-
This is really awesome! Thanks for making this wonderful library. :D
-
/me checks the posting date
O.O
I was planning on asking for help with floating point in Axe tonight. Awesome timing.
-
That is.... AMAZING! O_O The impossible is now done! :D (Well, not impossible, just hard.)
I guess this is a good time to revive the Z80 CAS topic (http://ourl.ca/11451)? :D
Also, I agree with the above suggestions of making the numbers easy to parse - we should use relatively simple syntax to make it work.
Before a CAS could be made, the following needs to occur:
1) String -> FP number
2) FP number -> String
3) Display FP number on arbitrary display buffer at certain position (pref. #2)
4) ???
I might still have code to print FP numbers, but it's in BASIC and requires... FP functions? :P (Specifically, log, int(), fPart(), and iPart().) If you would like to use it, tell me and I'll try to dig it out of a calc backup that is in a dead HDD backup... :P
-
/me checks the posting date
O.O
I was planning on asking for help with floating point in Axe tonight. Awesome timing.
Maybe he learned how to make axioms elsewhere? Maybe he has another account?
-
Some assembly code can be whipped up to convert between string and FP, but I am not going to commit myself to that task XD
-
I have seen some AXE programmes using strings to export images or tilemaps. How is that possible?
-
Before a CAS could be made, the following needs to occur:
1) String -> FP number
2) FP number -> String
3) Display FP number on arbitrary display buffer at certain position (pref. #2)
4) ???
I have some WIP Axe code to create FP numbers from supplied ASCII strings and store them to OS vars. Currently, scientific notation support is non-existent and it only works for real numbers. I also have a WIP routine for converting FP numbers to ASCII strings for displaying, but only real numbers are supported and scientific notation support is currently iffy at best.
-
I have seen some AXE programmes using strings to export images or tilemaps. How is that possible?
You just have to manipulate the data correctly. Here's the basic premise:
Set up the string. This is done in a similar method to setting up a Picture, which I detailed here (http://ourl.ca/13565/254961).
Then loop through the data for the sprite and convert this. Each nibble (generally) contains one hex character (each byte contains two), so this must be converted to 0-9 or A-F. Switch the number to its ASCII equivalent, which is shown in this chart:
L0 equ 030h
L1 equ 031h
L2 equ 032h
L3 equ 033h
L4 equ 034h
L5 equ 035h
L6 equ 036h
L7 equ 037h
L8 equ 038h
L9 equ 039h
LcapA equ 041h
LcapB equ 042h
LcapC equ 043h
LcapD equ 044h
LcapE equ 045h
LcapF equ 046h
So yeah, that's the basic premise. I hope it helps. :)
-
Bug fix! (See first post)
Also, I started creating a tutorial, so I included that too.
-
Update. Changes:
solve() becomes solve()ʳ
solve(x) returns a pointer to the floating-point number represented by x.
Examples:
float{solve(Select("varA"))}➔A
float{solve(solve(ᵀ+,Select("varA"),Select("varB")))}➔C
-
Is it just me or do the code boxes only say "array"?
-
I think it depends on the browser. I am using Chrome and it works fine for me :/
-
@Taranok: Welcome here. And yea, I think it's a browser issue. Works fine in Firefox too.
-
I'm using firefox also... 10.0.2.
The boxes still say array.
-
I notice your aciom use Select() command, but it's the same tokens than Axe parser command, is there no conflict? ???
-
My savior! ;D
However...I don't see a way to display the numbers in FP format (complex or not), and I need that before I use this. :P
-
WARNING: untested code
I think the following code should do the trick::Text(X,Y)
:Asm(7DEFF74B)
-
WARNING: untested code
Test it, and I'll get back to you, thanks. I don't want a RAM clear again. :P
-
RAM clears are fun. :D/me uses zStart
-
Well, I wouldn't say "fun", but indeed, I use zStart and RAM Clears don't annoy me at all ;)
-
I often clear RAM myself since I use it actually.
-
WARNING: untested code
I think the following code should do the trick::Text(X,Y)
:Asm(7DEFF74B)
That work with complex?
-
CPLXMATH.8xv, for some reason is sending to my calc as a program file, despite it being a .8xv?
Edit: Also, how do you take a float pointed to by, say GDB1, and store it to an OS var A, pointed to by the Axe A? Is that just GDB1->A, or would it involve the Copy command?