Complex+numbers+(a+library+&+demonstrations)

Complex numbers (a library & demonstrations)
From original post by tenochtitlanuk: > //Several of the group (myself, tsh & bluatigro especially) have found it useful to develop easy ways to handle complex numbers in a transparent way, where the real and imaginary parts are bound together by being part of a single string variable.//

code format="vbnet" ' '  Complex  function library and demo ' '  ComplexBluatigroJhf5.bas, '  posted by tenochtitlanuk, modified by tsh73 ' '  To-dos:- '      change to XOR plotting the vector so it can be erased. DONE   18/09/2010 '      add buttons to draw families of say ( 1, zero degrees) to ( 1, 360 degrees) '      add screen-print '      function complexFromStr$(a$) should work as Val: read from the start of string and stop on first invalid symbol '          For now, it starts from behind and looks for separator of Real and Imaginary parts '          (works the same for correct representation, but behaves differently for wrong ones)

'  Demos of usage in mainwin

mainwin 130 20

print print " I will first demonstrate some of the functions." print

print " Printing a complex constant with real & imag spec'd.", print "complex$( 0, -1)",, call cprint complex$( 0, -1)

'  print a complex number whose components are variables real =3: imag =4 print " Printing a complex variable.",, print "real =3: imag =4: complex$( real, imag)", call cprint complex$( real, imag)

'  print absolute value of a complex number print " Printing magnitude of a complex number.",, print "cabs( complex$( -3, 5))",, print cabs( complex$( -3, 5))

'  print direction of complex vector in Argand plane real =4: imag =4 print " Direction of a complex number vector.",, print "real =4: imag =4: atan2( imag, real)", print atan2( imag, real); " radians"

'  print inverse of a complex number print " Printing inverse of a complex number.",, print "cinv$( complex$( 4, -3))",, call cprint cinv$( complex$( 4, -3))

'  print sum of two complex numbers print " Printing sum of 2 complex numbers.",, print "cadd$( complex$( 3, 2), complex$( 0, 1))", call cprint cadd$(  complex$( 3, 2), complex$( 0, 1))

'  print difference of two complex numbers print " Printing difference of two complex numbers.", print "csub$( complex$( 3, 2), complex$( 0, 1))", call cprint csub$(  complex$( 3, 2), complex$( 0, 1))

'  print product of two complex numbers print " Printing product of two complex numbers.", print "cmulti$( complex$(3, 2), complex$(0, 1))", call cprint cmulti$( complex$( 3, 2), complex$( 0, 1))

'  print quotient of two complex numbers print " Printing quotient of two complex numbers.", print "cdiv$( complex$( 3, 2), complex$( 0, 1))", call cprint cdiv$(  complex$( 3, 2), complex$( 0, 1))

'  print square root of two complex numbers print " Printing square root of a complex number.", print "csqr$( complex$( 4, -4))",, call cprint csqr$(   complex$( 4, -4))

'  print e to a complex value print " Printing 'e' raised to a complex power.",, print "cexp$( complex$( 4, -4))",, call cprint cexp$(   complex$( 4, -4))

'  print natural log of a complex number print " Printing natural ln of a complex number.", print "cln$( complex$( 4, -4))",, call cprint cln$(    complex$( 4, -4))

print print " Now I'll open a graphic window demonstration."

timer 5000, [j] wait [j] timer 0

'  _____________________________________________ '   Demos of usage in graphic windows & boxes.

UpperLeftX  = 10 UpperLeftY  = 50 WindowWidth =870 WindowHeight =500

graphicbox #w.g1,   10,  10, 400, 400 textbox   #w.tb1,   20, 420, 200,  30

button    #w.b1, "Show Vector", [show],     LR, 510, 18 button    #w.b2, "Random",      [Generate], LR, 570, 18

statictext #w.st1 "", 440, 10, 420, 430

open "Complex library demos" for window as #w


 * 1) w "trapclose [quit]"

rndComplex$=complex$(int(11 *rnd( 1)) -5, int( 11 *rnd( 1)) -5)
 * 1) w.tb1 "!font courier 16 bold"
 * 1) w.tb1 formatCompl$(rndComplex$)


 * 1) w.st1 "!font arial 12"

for r =1 to 7 #w.g1 "circle "; r *40 next r
 * 1) w.g1 "color darkblue ; home ; down ; size 2"
 * 2) w.g1 "circle "; 4

for x =-5 to 5 #w.g1 "up ;  goto "; 199 +x *40; "   0" #w.g1 "down ; goto "; 199 +x *40; " 400" next x
 * 1) w.g1 "color cyan"

for y =-5 to 5 #w.g1 "up ;  goto   0 "; 199 -y *40 #w.g1 "down ; goto 400 "; 199 -y *40 next y
 * 1) w.g1 "color darkgray"

st$ ="" for j =1 to 24 read txt$ st$ =st$ +txt$ +chr$( 13) next j


 * 1) w.st1 st$

'  _____________________________________________
 * 1) w.g1 "up ; goto 400 200 ; size 4 ; color green ; size 4 ; down ; goto 204 200 ; up ; color red ; size 6 ; flush"

wait

[show] cEntered$=complexFromStr$(complex$) r =val( word$( cEntered$, 1)) i =val( word$( cEntered$, 2)) timer 1000, [jf] wait [jf] timer 0 wait
 * 1) w.tb1 "!contents? complex$"
 * 1) w.g1, "rule XOR"
 * 2) w.g1 "goto 198 199 ; down ; goto "; 198 +r *40; " "; 199 -i *40
 * 1) w.g1, "goto 198 199"

[Generate] rndComplex$=complex$(int(11 *rnd( 1)) -5, int( 11 *rnd( 1)) -5) wait
 * 1) w.tb1 formatCompl$(rndComplex$)

[quit] close #w

end

data "     You are looking at an 'Argand Diagram'." data "" data "The rectangular grid show x and y between +5 and -5." data "The circles show radii up to 7 from the center origin." data "" data "Complex numbers are entered as" data " Re+Imi or Re-Imi (there Im is number and final 'i' is letter)" data " You can enter just Re or Imi. No spaces inside please." data "" data "A valid entry could be        3+2i" data "        representing 3 right and 2 up," data "        or         -3-3i    ( 3 left, 3 down)" data "A random example will be showing in the text-box." data "Click the 'Show' button to see it as a vector," data "" data "The green line shows the positive, real direction." data "Angles are measured anti-clockwise from here." data "The red line which appears represents your complex no." data "" data "Click  for a new random vector." data "" data "NB You can alter it to your own vector in the stated format." data "Decimal values as well as integers are allowed." data "You can even use exponential form (1.2e3)."

'  _____________________________________________ '   **************** THE LIBRARY **************** '  _____________________________________________

sub cprintOld cx$ print "( "; word$( cx$, 1); " + i *"; word$( cx$, 2); ")" end sub

function formatCompl$(cx$) Re = val(word$( cx$, 1)) Im = val(word$( cx$, 2)) if Re=0 and Im=0 then formatCompl$ = "0": exit function Re$ = word$( cx$, 1) if Re =0 then Re$=""   'and no next "+" Im$=str$(Im)+"i" if Im =0 then Im$="" formatCompl$ = Re$+ iif$(Im>0 and Re<>0, "+", "")+ Im$ end function

sub cprint cx$ print formatCompl$(cx$) end sub

function iif$(test, valYes$, valNo$) iif$ = valNo$ if test then iif$ = valYes$ end function

function complexFromStr$(a$) a$=trim$(a$) if right$(a$,1)<>"i" then  'consider thing real Re=val(a$) complexFromStr$=complex$(Re,0) exit function end if   'else we probably have real and imaging parts 'they could be divided by + or -. Only trouble is to check for exponential form. 'Because it could quite legitimately look like this: "-12E-4-2e-4i" 'go from the back('cause we know Im part is definitely here) a$=left$(a$, len(a$)-1) expFound=0 divPos=0 for i = len(a$) to 1 step -1 c$=mid$(a$, i,1) if instr("+-",c$)=0 then 'do nothing else if expFound =0 then 'there was not exponent found before 'we should check if it's part of exponent: lookahead prevC$=mid$(a$, i-1,1) if instr("eE",prevC$)<>0 then 'indeed part of exponent 'do nothing else   'we just found divider. We will not bother more and assign all before divider to Re$ divPos = i: exit for end if           else 'found divider divPos = i: exit for end if       end if    next 'divide by divPos Re$=left$(a$,divPos-1) Im$=mid$(a$,divPos) print Re$, Im$ complexFromStr$=complex$(val(Re$),val(Im$)) end function

function atan2( y, x)   pi = acs(-1) if y =0 and x =0 then notice "atan2( 0,0) undefined": end if y >=0 and x <0 then at =atn( y /x) +pi: goto [j] if y <0 and x <0 then at =atn( y /x) -pi: goto [j] if y >0 and x =0 then at =    pi /2:      goto [j] if y <0 and x =0 then at = 0 -pi /2:      goto [j] if x >0          then at =atn( y /x) [j] atan2 =at end function

function complex$( a, bj ) ''complex number string-object constructor complex$ = str$( a ) ; " " ; str$( bj ) end function

function cadd$( a$, b$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) br = val( word$( b$, 1 ) ) bi = val( word$( b$, 2 ) ) cadd$ = complex$( ar + br, ai + bi ) end function

function csub$( a$, b$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) br = val( word$( b$, 1 ) ) bi = val( word$( b$, 2 ) ) csub$ = complex$( ar - br, ai - bi ) end function

function cmulti$( a$, b$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) br = val( word$( b$, 1 ) ) bi = val( word$( b$, 2 ) ) cmulti$ = complex$( ar * br - ai * bi _                  , ar * bi + ai * br ) end function

function cdiv$( a$, b$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) br = val( word$( b$, 1 ) ) bi = val( word$( b$, 2 ) ) cdiv$ = complex$((ar*br+ai*bi)/(br*br+bi*bi) _                 ,(br*ai-ar*bi)/(br*br+bi*bi)) end function

function cabs( a$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) cabs = sqr( ar ^ 2 + ai ^ 2 ) end function

function csqr$( a$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) ha = sqr((ar+cabs(a$))/2) hb = 2*sqr((ar+cabs(a$))/2) hb = ai / hb csqr$ = complex$( ha, hb ) end function

function cexp$( a$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) ha = exp( ar ) * cos( ai ) hb = exp( ar ) * sin( ai ) cexp$ = complex$( ha, hb ) end function

function cln$( a$ ) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) cln$ = complex$( log( cabs( a$) ) _     , atn( ai / ar ) ) end function

function cinv$( a$) ar = val( word$( a$, 1 ) ) ai = val( word$( a$, 2 ) ) D =ar^2 +ai^2 cinv$ =complex$( ar /D, 0 -ai /D ) end function

code