more function can of course be added.
complex.bi
Code: Select all
'
' FILE: Complex.cpp
' AUTHOR: Rob Tillaart
' VERSION: 0.1.09
' PURPOSE: library for Complex math for Arduino
' URL: http:'arduino.cc/playground/Main/ComplexMath
'
' Released to the public domain
'
' translated to FreeBASIC by srvaldez 2017 sep 18
Type complex
As Double re, im
Declare Constructor()
Declare Constructor(Byval re As Double)
Declare Constructor(Byval re As Double, Byval im As Double)
Declare Operator Let ( Byval rhs As Long )
Declare Operator Let ( Byval rhs As Longint )
Declare Operator Let ( Byval rhs As Integer )
Declare Operator Let ( Byval rhs As Double )
Declare Operator Let ( Byref rhs As complex )
Declare Operator Let ( Byref rhs As String )
Declare Operator Cast ( ) As String
End Type
Const pi =3.141592653589793
Const pi2=6.283185307179586
''' uncomment if you wish
'''Dim Shared As Const Complex i = complex(0,1)
Constructor complex()
this.re=Cdbl(0)
this.im=Cdbl(0)
End Constructor
Constructor complex(Byval re As Double)
this.re=re
this.im=Cdbl(0)
End Constructor
Constructor complex(Byval re As Double, Byval im As Double)
this.re=re
this.im=im
End Constructor
Operator complex.let( Byval rhs As Long )
this.re=Cdbl(rhs)
this.im=Cdbl(0)
End Operator
Operator complex.let( Byval rhs As Longint )
this.re=Cdbl(rhs)
this.im=Cdbl(0)
End Operator
Operator complex.let( Byval rhs As Integer )
this.re=Cdbl(rhs)
this.im=Cdbl(0)
End Operator
Operator complex.let( Byval rhs As Double )
this.re=rhs
this.im=Cdbl(0)
End Operator
Operator complex.let( Byref rhs As complex )
this.re=rhs.re
this.im=rhs.im
End Operator
Operator complex.let (Byref s As String)
Dim As String b, a=Ucase(Ltrim(Rtrim(s)))
Dim As Long c, i, k, l=Len(a), Sgn1=1, sgn2=1
If Right(a,1)<>"I" Then
Print "not a valid complex number"
this.re=0 : this.im=0
Exit Operator
End If
if a="I" or a="+I" then
this.re=0
this.im=1
exit operator
elseif a="-I" then
this.re=0
this.im=-1
exit operator
end if
i=l-2
While i>=0 Andalso a[i]=32
i-=1
Wend
b=chr(a[i])
If b<>"*" Then
if b="+" or b="-" then
if b="-" then this.im=-1 else this.im=1
i+=1
else
Print "not a valid complex number"
this.re=0 : this.im=0
Exit Operator
end if
End If
a=Rtrim(Left(a,i))
If Left(a,1)="-" Then
Sgn1=-1
a=Mid(a,2)
End If
l=Len(a)
c=Instr(a,"E")
k=Instr(c+1,a,Any "+-")
If k=c+1 Then
k=Instr(k+1,a,Any "+-")
End If
If Chr(a[k-1])="-" Then
sgn2=-1
End If
this.re=Sgn1*Val(Left(a,k-1))
if this.im=0 then this.im=sgn2*Val(Mid(a,k+1))
End Operator
Operator complex.cast ( ) As String
Dim As String c=" "
If (this.re)<0 Then c = ""
c += Str(this.re)
if this.im=1 then
c+=" + i"
elseif this.im=-1 then
c+=" - i"
elseif this.im<0 Then
c+=" - "+Str(Abs(this.im))+"*i"
Elseif this.im>0 Then
c+=" + "+Str(this.im)+"*i"
End If
Operator = c
End Operator
#Macro hypot(x,y)
(Sqr(((x)*(x))+((y)*(y))))
#Endmacro
#Define modulus hypot
#Macro phase(x,y)
(Atan2(y,x))
#Endmacro
Function reciprocal(Byval x As complex) As complex
Dim As Double f = 1.0/(x.re*x.re + x.im*x.im)
Dim As Double r = x.re*f
Dim As Double i = -x.im*f
Return Complex(r,i)
End Function
Function cabs(Byval x As complex) As complex
Return Complex(Sqr(x.re*x.re+x.im*x.im),0)
End Function
Operator + (Byval lhs As complex, rhs As complex) As complex
Return Complex(lhs.re + rhs.re, lhs.im + rhs.im)
End Operator
Operator + (Byval lhs As complex, rhs As Double) As complex
Return Complex(lhs.re + rhs, lhs.im)
End Operator
Operator + (Byval lhs As Double, rhs As complex) As complex
Return Complex(lhs + rhs.re, rhs.im)
End Operator
Operator - (rhs As complex) As complex 'negate
Return Complex(-rhs.re, -rhs.im)
End Operator
Operator - (Byval lhs As complex, rhs As complex) As complex
Return Complex(lhs.re - rhs.re, lhs.im - rhs.im)
End Operator
Operator - (Byval lhs As complex, rhs As Double) As complex
Return Complex(lhs.re - rhs, lhs.im)
End Operator
Operator - (Byval lhs As Double, rhs As complex) As complex
Return Complex(lhs - rhs.re, -rhs.im)
End Operator
Operator * (Byval lhs As complex, rhs As complex) As complex
Dim As Double re = lhs.re * rhs.re - lhs.im * rhs.im
Dim As Double im = lhs.re * rhs.im + lhs.im * rhs.re
Return Complex(re, im)
End Operator
Operator * (Byval lhs As complex, rhs As Double) As complex
Dim As Double re = lhs.re * rhs
Dim As Double im = lhs.im * rhs
Return Complex(re, im)
End Operator
Operator * (Byval lhs As Double, rhs As complex) As complex
Dim As Double re = lhs * rhs.re
Dim As Double im = lhs * rhs.im
Return Complex(re, im)
End Operator
Operator / (Byval lhs As complex, rhs As complex) As complex
Dim As Double f = 1.0/(rhs.re*rhs.re + rhs.im*rhs.im)
Dim As Double re = (lhs.re * rhs.re + lhs.im * rhs.im) * f
Dim As Double im = (lhs.im * rhs.re - lhs.re * rhs.im) * f
Return Complex(re, im)
End Operator
Operator / (Byval lhs As complex, rhs As Double) As complex
Dim As Double f = 1.0/(rhs*rhs)
Dim As Double re = (lhs.re * rhs) * f
Dim As Double im = (lhs.im * rhs) * f
Return Complex(re, im)
End Operator
Operator / (Byval lhs As double, rhs As complex) As complex
Dim As Double f = 1.0/(rhs.re*rhs.re + rhs.im*rhs.im)
Dim As Double re = (lhs * rhs.re) * f
Dim As Double im = (-lhs * rhs.im) * f
Return Complex(re, im)
End Operator
Function csquare(Byval x As complex) As complex
Dim As Double re = x.re * x.re - x.im * x.im
Dim As Double im = 2 * x.re * x.im
Return Complex(re, im)
End Function
Function csqr(Byval x As complex) As complex
Dim As Double m = hypot(x.re,x.im)
Dim As Double re = Sqr(0.5 * (m+x.re))
Dim As Double im = Sqr(0.5 * (m-x.re))
If x.im < 0 Then im = -im
Return Complex(re, im)
End Function
Function cexp(Byval x As complex) As complex
Dim As Double e = Exp(x.re)
Return Complex(e * Cos(x.im), e * Sin(x.im))
End Function
Function clog(Byval x As complex) As complex
Dim As Double m = modulus(x.re, x.im)
Dim As Double p = phase(x.re, x.im)
If p > pi Then p -= pi2
Return Complex(Log(m), p)
End Function
Function cpow(Byval x As complex, Byval c As Const Complex) As complex
Dim As Complex t = clog(x)
t = t * c
Return cexp(t)
End Function
Function clogn(Byval x As complex, Byval c As Const Complex) As complex
Return clog(x)/clog(c)
End Function
Function clog10(Byval x As complex) As complex
Return clogn(x, 10)
End Function
Function sinh(Byval x As Double) As Double
Dim As Double y=Exp(x)
Return (y-1.0/y)*0.5
End Function
Function cosh(Byval x As Double) As Double
Dim As Double y=Exp(x)
Return (y+1.0/y)*0.5
End Function
Function tanh(Byval x As Double) As Double
Dim As Double y=Exp(x)
Return (y-1.0/y)/(y+1.0/y)
End Function
Function csin(Byval x As complex) As complex
Dim As Double s = Sin(x.re)
Dim As Double c = Sqr(1.0-s*s)
Return Complex(s * cosh(x.im), c * sinh(x.im))
End Function
Function ccos(Byval x As complex) As complex
Dim As Double s = Sin(x.re)
Dim As Double c = Sqr(1.0-s*s)
Return Complex(c * cosh(x.im), -s * sinh(x.im))
End Function
Function ctan(Byval x As complex) As complex
'/* faster but 350 bytes longer!!
Dim As Double s = Sin(x.re)
Dim As Double c = Cos(x.re)
Dim As Double sh = sinh(x.im)
Dim As Double ch = cosh(x.im)
'' return Complex(s*ch, c*sh) / Complex(c*ch, -s*sh)
Dim As Double r0 = s*ch
Dim As Double i0 = c*sh
Dim As Double cre = c*ch
Dim As Double cim = -s*sh
Dim As Double f = 1.0/(cre*cre + cim*cim)
Dim As Double r = r0 * cre + i0 * cim
Dim As Double i = r0 * cim - i0 * cre
Return Complex(r * f, -i * f)
'''return c_sin() / c_cos();
End Function
Dim Shared As Const Complex one = 1
Function gonioHelper1(Byval x As complex, Byval mode As Const Byte) As complex
Dim As Complex c = csqr(one - csquare(x))
If mode = 0 Then
c = c + x * Complex(0,-1)
Else
c = x + c * Complex(0,-1)
End If
c = clog(c) * Complex(0,1)
Return c
End Function
Function casin(Byval x As complex) As complex
Return gonioHelper1(x, 0)
End Function
Function cacos(Byval x As complex) As complex
Return gonioHelper1(x, 1)
End Function
Function catan(Byval x As complex) As complex
Return (Complex(0,-1) * clog(Complex(x.re, x.im - 1)/Complex(-x.re, -x.im - 1))) * 0.5
End Function
Function ccsc(Byval x As complex) As complex
Return one / csin(x)
End Function
Function csec(Byval x As complex) As complex
Return one / ccos(x)
End Function
Function ccot(Byval x As complex) As complex
Return one / ctan(x)
End Function
Function cacsc(Byval x As complex) As complex
Return one / casin(x)
End Function
Function casec(Byval x As complex) As complex
Return one / cacos(x)
End Function
Function cacot(Byval x As complex) As complex
Return one / catan(x)
End Function
'HYPERBOLICUS I
function csinh(Byval x As complex) as complex
dim as complex y=cexp(x)
return (y-reciprocal(y))*0.5
end function
function ccosh(Byval x As complex) as complex
dim as complex y=cexp(x)
return (y+reciprocal(y))*0.5
end function
function ctanh(Byval x As complex) as complex
return csinh(x) / ccosh(x)
end function
function gonioHelper2(Byval x As complex, byval mode as const byte) as complex
dim as Complex c = csquare(x)
if mode = 0 then
c = c+1
else
c = c-1
end if
c = clog(x + csqr(c))
return c
end function
function casinh(Byval x As complex) as complex
return gonioHelper2(x,0)
end function
function cacosh(Byval x As complex) as complex
return clog(x+csqr(x-one)*csqr(x+one))
'return gonioHelper2(x,1)
end function
function catanh(Byval x As complex) as complex
dim as Complex c = clog(x + one)
c = c - clog(-(x - one))
return c * 0.5
end function
'HYPERBOLICUS II
function ccsch(Byval x As complex) as complex
return one / csinh(x)
end function
function csech(Byval x As complex) as complex
return one / ccosh(x)
end function
function ccoth(Byval x As complex) as complex
return one / ctanh(x)
end function
function cacsch(Byval x As complex) as complex
return casinh(one/x)
end function
function casech(Byval x As complex) as complex
return cacosh(one/x)
end function
function cacoth(Byval x As complex) as complex
return catanh(one/x)
end function
test-complex.bas
Code: Select all
#include "complex.bi"
Dim As complex x=complex(2,5),y=complex(3,7),z
Dim As Double r=1
z=x-y
Print "z = ";x;" - ";y;" = ";z
z=ctan(z)
z=catan(z)
Print "catan(ctan(";z;")) = ";z
Print "assignment from string"
z="-1e+10 + 1e-100 * i "
Print "z = ";Chr(34)+"-1e+10 + 1e-100 * i "+Chr(34);" = ";z
z="+100 - 0.0000001 * i"
Print "z = ";Chr(34)+"+100 - 0.0000001 * i"+Chr(34);" = ";z
Print "passing a double value to a complex function"
Print "dim r as double = 1 : print catan(r) -> ";catan(r)