View Full Version : The flexibility and power of Thinbasic ;-)
Hi all,
Something I was missing in many languages (coming from Lisp where such things are trivial (Autodesk)).
Given the fact that the oxygen script is a string which can be changed by the program itself and that by its JIT nature it can be compiled anywhere/anytime (not compiled once) some sophisticated flows can be set up. It works somewhat as a compiled eval function.
Attached an example, very very simple - but the idea can be expanded limitless : Thinbasic changes the content of the oxygen script.
(such things are very important for AI programs and prototyping programs not only depending from parameters but also from methods).
-- to put it simple you can easily write programs that write/change/test programs ;-)
In this little program the METHOD textbox changes the operator -- it's a simple example that tests the criterium to exit the iteration loop, normally this is done by comparing the square of |z| with a certain limit , but other and faster methods may work too.
The nice thing is that this operator is injected inside the script and compiled .. no need for if ... then's etc... -- very simple (and expandable at infinity with whatever you need.
(if you try it - if using "-" minus lower the maximum of iterations a lot (around 10 or so) -- the program has to do a very lot of calculations - "division" at your own risk -- even slower, and some values may reach ?/0 resulting in a crash - there's no zero division test built in ).
I compared the speed with Freebasic (GAS - GNU compiler - any using the same method ) of which the makers say : "FreeBASIC has been rated close in speed with mainstream tools, such as GCC." - ... it's similar ...
best Rob (the operator is changed in the last sub JIT() ... simple comme bonjour )
ErosOlmi
18-10-2013, 23:19
Thanks a lot Rob, another great example, and quite fast.
ReneMiner
19-10-2013, 12:22
Beautiful, I like it :)
ErosOlmi
19-10-2013, 22:15
I applied some changes in order to be more flexible in changing Oxygen Source code before compiling.
Removed attached file: there was a bug
Thanks Rene, Eros !
.. first_hide ... last_hide : clever ;-)
I'll study your code , Eros - there're some new things inside to absorb ..
Yes, I had something similar in mind : str = static1 + dynamic (by textbox) + static2 + .. + .. etc .. using a fixed place and fixed length as I initially did, gives very limited possibilities - and invites mistakes.
thanks again, Rob
I'll work out something else -- I will "show" the program how to do some simple differentiations ...
ErosOlmi
19-10-2013, 23:48
Forget my previous version, there was a bug in replacing placeholders: a new string was needed otherwise only the first replace would work.
Attached a new version using TIMER.
Using a timer to show image instead of a FOR/NEXT will open a completely new way to handle the applications and can also allow user interactions while executing.
This method allows to add Start/Stop buttons. You can also drag the window while fractal is calculating
Have fun and thanks a lot for example Rob!
Let me know
Eros
ErosOlmi
20-10-2013, 16:11
I'm so fascinated by this example ... the mix of thinBasic and Oxygen and iys JIT (Just in Time) compiler that can open a new sort of realtime examples.
I've changed again example adding real time changing of parameter while fractal is executing.
Press Start than change some parameter.
Than press Stop and change again some parameter.
Wow, a great thanks to Rob that introduced this method.
ATTENTION
this example can be executed only using thinBasic 1.9.10.0 because I've introduced a new CANVAS function, Canvas_BitmapSet_ByRef, able to work with any memory areas instead of fixed strings.
Hi Eros,
Nice, some blues inside now (I mentioned I mixed the R and B channel between oxygen and TB).
This extra colour gives extra information - from a math viewpoint and is nice to see ;-)
I'll study them later (sitting on a Linux OS puter now, I only can read the scripts but not run them -- however I can run the exe's without problems when importing the needed Win dll's -- with no loss of speed, it is not an emulator ).
I will learn from the them -- did not used the ... timer ... yet, and many TB words are not known yet.
Good , made something special (I think).
First I gave Thinbasic some rules to do a derivative (very basic for the moment, but all the rules, trigs , hyperbolic functions etc ... can be programmed) ... the button D calculate the derivative of two terms - these are injected in the oxygen script , compiled and executed.
This time a shared array is used (much slower than a BMP), but it does not matter at all here.
I set up the Oxygen code in a separate Textbox - so one can control the "injection".
The make things somewhat nicer to see, a Canvas is attached ...
As said, I did not programmed the derivatives by formula -- the program arranged this itself -- you can hit (and inject/compile) till both or 0 .. you will get a message then ;-)
All this thanks to the flexible architecture of Thinbasic / oxygen etc ....
best Rob (program not tested on mistakes )
Checking the code and wondering why no parabola showed up on the canvas,
it seems oxygen gives p.e. pow(-2,2) = -4
I'm missing something ??
best,
Rob
ErosOlmi
20-10-2013, 21:17
I've asked to Charles Pegge, Oxygen author
http://www.oxygenbasic.org/forum/index.php?topic=876.0
Charles Pegge
20-10-2013, 22:16
Hi Rob,
There is a new Oxygen for thinBasic with a more intelligent pow() :)
I have not hooked into Eros new SVN network yet, but the new files are ready to include with future thinBasic releases.
http://www.thinbasic.com/community/showthread.php?t=12175
Hi Charles ,
Many thanks !!
pow(x,y) is much more difficult than it seems, of course ....
I attached a scr copy from what I got
best Rob
( with all respect for your excellent work ! )
ErosOlmi
20-10-2013, 22:37
Hi Charles,
sorry I missed your update.
I'm trying this version and it shows a message box titled "O2H" with message "lib\oxygen.dll"
I think it means that oxygen.dll was not found.
I suppose because you hard coded "\lib\" directory instead it should be loaded from the same directory where "thinBasic_Oxygen.dll" wrapper DLL is loaded from.
Do you think it can be changed?
Correct path is passed by thinCore.dll to thinBasic_Oxygen.dll in LoadLocalSymbols function as sPath param
Thanks a lot
Eros
Charles Pegge
20-10-2013, 23:58
Yes Eros, both DLLs need to be in lib
few more details here:
http://www.oxygenbasic.org/forum/index.php?topic=876.msg7437;topicseen#msg7437
ErosOlmi
21-10-2013, 06:54
For the way thinBasic has been built, that is not good Charles.
DLL must not have any paths hard coded, otherwise it would be a nightmare.
For example:
during development the modules is into a directory
when thinBasic is released to users, modules are into another directory
when a script is embedded into a bundled exe, modules are into another directory dynamically decided at run-time.
That's the reason why thinBasic pass to each thinBasic modules the path from which they have been loaded: in order to be aware of it and do the correct assumptions.
Do you think to have a chance to change current behave?
Otherwise the only way I have to make it working is that I will make another wrapper instead of your thinBasic_Oxygen.dll and dynamically load Oxygen.dll at run-time from the same directory of the wrapper.
Ciao
Eros
Charles Pegge
21-10-2013, 10:12
Hi Eros,
I have now recoded the module to use spath to locate oxygen at runtime, and bind to it within LoadLocalSymbols. So it should now work in any directory determined by thinBasic.
http://www.thinbasic.com/community/showthread.php?t=12175
ErosOlmi
21-10-2013, 20:55
Charles,
thanks a lot!!
It works great now.
I will release a new thinBasic version in few days.
Ciao
Eros
Thanks Charles, Eros .. it gives the correct positive value now.
Amazing program Eros, ! -- finally I ran it , very impressing those real-time inter-actions.
This all made me curious about that pow(x,y) function on several programming languages.
I noticed that when y is not an integer, both Thinbasic and the GFA compiler use the closest integer for y to get a real number result in case x < 0. (in case x is a negative number and y contains a fraction the result is a complex number )
In this case both Freebasic and the LISP give respec. QNAN and NAN -- something as "not an available number" iirc.
( .. mm , that NAN could be dangerous incase one gets 1.999999 that sould be 2 or so .... )
best Rob
Charles Pegge
22-10-2013, 14:26
Thanks Eros, There will probably be another update before your next release.
Rob, do you use deMoivre to resolve fractional powers into complex numbers?
Hi Charles,
pow(x,y)
I use the Euler notation -- (somewhat similar , de Moivre's Cis(x) <-> exp(i.x) )
Anyway, both give excellent visualization possibilities about the things happening.
I attached a little program.
On the canvas are represented the real (red if the number has a complex component - green if I(z)=0 ) and imaginary (blue) part - the green line is the axis where the imaginary part is 0 and real numbers are generated.
The problem is that we consider pow(x,y) as a function , which it isn't p.e. pow(x,0.5) has two solutions pow(4,0.5) = 2 and -2 ... , in fact much severe problems start when y is a transcendental number, iirc it only can be solved on Riemann surfaces ... (It's almost 40 yrs ago when I started studying higher mathematics :-(
I think , I should avoid pow(x,y) solutions where y contains a fraction and introduce the nth square root to compensate this. .. something as pow(x, 3/2) = sqrtn(pow(x,3) , 2 ) -- only with integers for both y's in pow() and sqrtn()
best
Rob
Charles Pegge
22-10-2013, 23:07
I think this function does the job, except for providing more than one solution:
/*
http://www.suitcaseofdreams.net/De_Moivre_formula.htm
*/
'Solving fractional powers of negative values using complex numbers
'OxygenBasic
type complex double x,y
function zpower(complex*z, double n)
====================================
'Using DeMoivre theorem
double radius,angle,scale
radius = hypot(z.x, z.y)
scale = radius^n
if z.x=0 then
angle=.5*pi 'equiv 90 degrees
if z.y<0 then angle=-angle
else
angle = atan(z.y, z.x)
end if
angle*=n
z.x = scale * cos(angle)
z.y = scale * sin(angle)
end function
'TEST
=====
complex n={-2.0 , 0.0}
zpower( n, 0.5)
print str(n.x,6) " , " str(n.y,6) "i"
Yes, seems correct ...
if you want to find the other roots , you have to add 2.k.pi.n into the Cis(x) k : integer 0... and 2.k.pi.n < 2pi
p.e pow(1, 1/4 )
roots are : 1*Cis(0/4 + 2kpi/4 ) Cis(x) = (cos(x)+i.sin(x))
k=0 Cis(0)=1
k=1 Cis(pi/2) = i
k=2 Cis(pi) = -1
k=3 Cis(3pi/2) = -i
best
Rob