|
Post by jcopernic on Jun 23, 2022 20:06:55 GMT 1
Hello everyone, Is there a library for complex numbers in gfa? Thank you!
|
|
|
Post by dragonjim on Jun 23, 2022 22:55:43 GMT 1
Not a helpful reply but, not to my knowledge.
There is certainly no keyword/function that I can find that handles complex or imaginary numbers.
|
|
|
Post by (X) on Jun 24, 2022 0:18:19 GMT 1
What functions were you looking for?
|
|
|
Post by (X) on Jun 24, 2022 0:42:48 GMT 1
from: www.vbforums.com/showthread.php?789035-VB6-Module-with-advanced-mathematical-functions-for-real-and-complex-numbers
Public Type Complex R As Double I As Double End Type
Public Type Matrix Col As Long ' Number of columns Row As Long ' Number of rows D() As Double End Type
Public Const PI = 3.14159265358979 Public Const E = 2.71828182845905
Private Const PI2 = PI / 2
'+=================== '| Complex numbers '+===================
' // R = 1, I = 0 Public Function cxOne() As Complex cxOne.R = 1 End Function
' // R = 0, I = 1 Public Function cxImgOne() As Complex cxOne.I = 1 End Function
' // R = 0, I = 0 Public Function cxZero() As Complex End Function
' // Creating a new complex number Public Function cxNew(ByVal Real As Double, ByVal Imaginary As Double) As Complex cxNew.R = Real: cxNew.I = Imaginary End Function
' // Creating a new complex number by polar coordinates Public Function cxPolar(ByVal Magnitude As Double, ByVal Phase As Double) As Complex cxPolar.R = Magnitude * Cos(Phase): cxPolar.I = Magnitude * Sin(Phase) End Function
' // Return the additive inverse of a specified complex number Public Function cxNeg(Op As Complex) As Complex cxNeg.R = -Op.R: cxNeg.I = -Op.I End Function
' // Return the inverse value of a complex number Public Function cxInv(Op As Complex) As Complex Dim Ab2 As Double Ab2 = Op.R * Op.R + Op.I * Op.I cxInv.R = Op.R / Ab2: cxInv.I = -Op.I / Ab2 End Function
' // Addition of two complex numbers Public Function cxAdd(Op1 As Complex, Op2 As Complex) As Complex cxAdd.R = Op1.R + Op2.R cxAdd.I = Op1.I + Op2.I End Function
' // Subtraction of two complex numbers Public Function cxSub(Op1 As Complex, Op2 As Complex) As Complex cxSub.R = Op1.R - Op2.R cxSub.I = Op1.I - Op2.I End Function
' // Multiplication of two complex numbers Public Function cxMul(Op1 As Complex, Op2 As Complex) As Complex cxMul.R = Op1.R * Op2.R - Op1.I * Op2.I cxMul.I = Op1.R * Op2.I + Op1.I * Op2.R End Function
' // Division of two complex numbers Public Function cxDiv(Op1 As Complex, Op2 As Complex) As Complex Dim R2 As Double, i2 As Double R2 = Op2.R * Op2.R: i2 = Op2.I * Op2.I cxDiv.R = (Op1.R * Op2.R + Op1.I * Op2.I) / (R2 + i2) cxDiv.I = (Op1.I * Op2.R - Op1.R * Op2.I) / (R2 + i2) End Function
' // Exponentiation of a complex number Public Function cxDgr(Op As Complex, ByVal Degree As Long) As Complex Dim Md As Double, Ar As Double Md = cxMod(Op): Ar = cxArg(Op): Md = Md ^ Degree: Ar = Ar * Degree cxDgr.R = Md * Cos(Ar): cxDgr.I = Md * Sin(Ar) End Function
' // The square root of a complex number Public Function cxSqr(Op As Complex) As Complex Dim M As Double, A As Double M = Sqr(cxMod(Op)): A = cxArg(Op) / 2 cxSqr.R = M * Cos(A): cxSqr.I = M * Sin(A) End Function
' // Module of a complex number Public Function cxMod(Op As Complex) As Double Dim R2 As Double, i2 As Double R2 = Op.R * Op.R: i2 = Op.I * Op.I cxMod = Sqr(R2 + i2) End Function
' // Phase of a complex number Public Function cxPhase(Op As Complex) As Double cxPhase = Atan2(Op.I, Op.R) End Function
' // Argument of a complex number (equal phase) Public Function cxArg(Op As Complex) As Double If Op.I = 0 Then If Op.R >= 0 Then cxArg = 0 Else cxArg = PI ElseIf Op.R = 0 Then If Op.I >= 0 Then cxArg = PI2 Else cxArg = -PI2 Else If Op.R > 0 Then cxArg = Atn(Op.I / Op.R) ElseIf Op.R < 0 And Op.I > 0 Then cxArg = PI + Atn(Op.I / Op.R) ElseIf Op.R < 0 And Op.I < 0 Then cxArg = -PI + Atn(Op.I / Op.R) End If End If End Function
' // Returns the number e, raised to power by complex number Public Function cxExp(Op As Complex) As Complex cxExp.R = Exp(Op.R) * Cos(Op.I): cxExp.I = Exp(Op.R) * Sin(Op.I) End Function
' // Addition real number and complex number Public Function cxAddReal(Op1 As Complex, ByVal Op2 As Double) As Complex cxAddReal.R = Op1.R + Op2 cxAddReal.I = Op1.I End Function
' // Subtraction from complex number a real number Public Function cxSubReal(Op1 As Complex, ByVal Op2 As Double) As Complex cxSubReal.R = Op1.R - Op2 cxSubReal.I = Op1.I End Function
' // Subtraction from real number a complex number Public Function cxRealSub(ByVal Op1 As Double, Op2 As Complex) As Complex cxRealSub.R = Op1 - Op2.R cxRealSub.I = -Op2.I End Function
' // Multiplication complex number on a real number Public Function cxMulReal(Op1 As Complex, ByVal Op2 As Double) As Complex cxMulReal.R = Op1.R * Op2 cxMulReal.I = Op1.I * Op2 End Function
' // Division a complex number on a real number Public Function cxDivReal(Op1 As Complex, ByVal Op2 As Double) As Complex Dim R2 As Double R2 = Op2 * Op2 cxDivReal.R = (Op1.R * Op2) / R2 cxDivReal.I = (Op1.I * Op2) / R2 End Function
' // Division a real number on a complex number Public Function cxRealDiv(ByVal Op1 As Double, Op2 As Complex) As Complex Dim R2 As Double, i2 As Double R2 = Op2.R * Op2.R: i2 = Op2.I * Op2.I cxRealDiv.R = (Op1 * Op2.R) / (R2 + i2) cxRealDiv.I = (-Op1 * Op2.I) / (R2 + i2) End Function
' // Addition of a complex number and imaginary part Public Function cxAddImg(Op1 As Complex, ByVal Op2 As Double) As Complex cxAddImg.R = Op1.R cxAddImg.I = Op1.I + Op2 End Function
' // Subtraction from a complex number a imaginary part Public Function cxSubImg(ByVal Op1 As Complex, Op2 As Double) As Complex cxSubImg.R = Op1.R cxSubImg.I = Op1.I - Op2 End Function
' // Subtraction from imaginary part a complex number Public Function cxImgSub(ByVal Op1 As Double, Op2 As Complex) As Complex cxImgSub.R = -Op2.R cxImgSub.I = Op1 - Op2.I End Function
' // Multiplication complex number on a imaginary part Public Function cxMulImg(Op1 As Complex, ByVal Op2 As Double) As Complex cxMulImg.R = -Op1.I * Op2 cxMulImg.I = Op1.R * Op2 End Function
' // Division a complex number on a imaginary part Public Function cxDivImg(Op1 As Complex, ByVal Op2 As Double) As Complex Dim i2 As Double i2 = Op2 * Op2 cxDivImg.R = (Op1.I * Op2) / i2 cxDivImg.I = (-Op1.R * Op2) / i2 End Function
' // Division imaginary part on a complex number Public Function cxImgDiv(ByVal Op1 As Double, Op2 As Complex) As Complex Dim R2 As Double, i2 As Double R2 = Op2.R * Op2.R: i2 = Op2.I * Op2.I cxImgDiv.R = (Op1 * Op2.I) / (R2 + i2) cxImgDiv.I = (Op1 * Op2.R) / (R2 + i2) End Function
' // Return true if complex number is equal Public Function cxEq(Op1 As Complex, Op2 As Complex, _ Optional NumDigitsAfterDecimal As Long = -1) As Boolean If NumDigitsAfterDecimal = -1 Then If Op1.R = Op2.R And Op1.I = Op2.I Then cxEq = True Else If Round(Op1.R, NumDigitsAfterDecimal) = Round(Op2.R, NumDigitsAfterDecimal) And _ Round(Op1.I, NumDigitsAfterDecimal) = Round(Op2.I, NumDigitsAfterDecimal) Then cxEq = True End If End Function
' // Return absolute value of a complex number Public Function cxAbs(Op As Complex) As Double If Op.I = 0 Then cxAbs = 0 ElseIf Op.R > Op.I Then cxAbs = Sqr(1 + (Op.I * Op.I) / (Op.R * Op.R)) ElseIf Op.R <= Op.I Then cxAbs = Sqr(1 + (Op.R * Op.R) / (Op.I * Op.I)) End If End Function
' // Return complex conjugate of complex number Public Function cxConj(Op As Complex) As Complex cxConj.R = Op.R cxConj.I = -Op.I End Function
' // The natural logarithm of a complex number Public Function cxLog(Op As Complex) As Complex Dim M As Double, A As Double M = cxMod(Op): A = cxArg(Op) cxLog.R = Log(M): cxLog.I = A End Function
' // The logarithm of a complex number by base X Public Function cxLogX(Op As Complex, ByVal Base As Double) As Complex Dim M As Double, A As Double, Nc As Complex M = cxMod(Op): A = cxArg(Op): Nc.R = Log(Base) cxLogX.R = Log(M): cxLogX.I = A cxLogX = cxDiv(cxLogX, Nc) End Function
' // Sine of a complex number Public Function cxSin(Op As Complex) As Complex cxSin.R = Sin(Op.R) * Cosh(Op.I): cxSin.I = Cos(Op.R) * Sinh(Op.I) End Function ' // Cosine of a complex number Public Function cxCos(Op As Complex) As Complex cxCos.R = Cos(Op.R) * Cosh(Op.I): cxCos.I = -Sin(Op.R) * Sinh(Op.I) End Function
' // Tangent of a complex number Public Function cxTan(Op As Complex) As Complex Dim C2 As Double, S2 As Double C2 = Cos(Op.R): C2 = C2 * C2: S2 = Sinh(Op.I): S2 = S2 * S2 cxTan.R = (Sin(Op.R) * Cos(Op.R)) / (C2 + S2) cxTan.I = (Sinh(Op.I) * Cosh(Op.I)) / (C2 + S2) End Function
' // Cotangent of a complex number Public Function cxCtg(Op As Complex) As Complex Dim C2 As Double, S2 As Double C2 = Sin(Op.R): C2 = C2 * C2: S2 = Sinh(Op.I): S2 = S2 * S2 cxCtg.R = (Sin(Op.R) * Cos(Op.R)) / (C2 + S2) cxCtg.I = -(Sinh(Op.I) * Cosh(Op.I)) / (C2 + S2) End Function
' // Secant of a complex number Public Function cxSec(Op As Complex) As Complex Dim C2 As Double, S2 As Double C2 = Cos(Op.R): C2 = C2 * C2: S2 = Sinh(Op.I): S2 = S2 * S2 cxSec.R = (Cos(Op.R) * Cosh(Op.I)) / (C2 + S2) cxSec.I = -(Sin(Op.R) * Sinh(Op.I)) / (C2 + S2) End Function
' // Cosecant of a complex number Public Function cxCsc(Op As Complex) As Complex Dim C2 As Double, S2 As Double C2 = Sin(Op.R): C2 = C2 * C2: S2 = Sinh(Op.I): S2 = S2 * S2 cxCsc.R = (Sin(Op.R) * Cosh(Op.I)) / (C2 + S2) cxCsc.I = (Cos(Op.R) * Sinh(Op.I)) / (C2 + S2) End Function
' // Arcsine of a complex number Public Function cxAsin(Op As Complex) As Complex cxAsin = cxMulImg(cxLog(cxAdd(cxMulImg(Op, 1), cxSqr(cxRealSub(1, cxMul(Op, Op))))), -1) End Function
' // Arccosine of a complex number Public Function cxAcos(Op As Complex) As Complex cxAcos = cxAddReal(cxMulImg(cxLog(cxAdd(cxMulImg(Op, 1), cxSqr(cxRealSub(1, cxMul(Op, Op))))), 1), PI2) End Function
' // Arctangent of a complex number Public Function cxAtan(Op As Complex) As Complex Dim Iz As Complex Iz = cxMulImg(Op, 1) cxAtan = cxMulImg(cxSub(cxLog(cxRealSub(1, Iz)), cxLog(cxAddReal(Iz, 1))), 0.5) End Function
' // Arccotangent of a complex number Public Function cxActg(Op As Complex) As Complex cxActg = cxMulImg(cxSub(cxLog(cxDiv(cxSubImg(Op, 1), Op)), cxLog(cxDiv(cxAddImg(Op, 1), Op))), 0.5) End Function
' // Arcsecant of a complex number Public Function cxAsec(Op As Complex) As Complex cxAsec = cxAcos(cxDgr(Op, -1)) End Function
' // Arccosecant of a complex number Public Function cxAcsc(Op As Complex) As Complex cxAcsc = cxAsin(cxDgr(Op, -1)) End Function
' // Hyperbolic sine of a complex number Public Function cxSinh(Op As Complex) As Complex cxSinh = cxMulImg(cxSin(cxMulImg(Op, 1)), -1) End Function
' // Hyperbolic cosine of a complex number Public Function cxCosh(Op As Complex) As Complex cxCosh = cxCos(cxMulImg(Op, 1)) End Function
' // Hyperbolic tangent of a complex number Public Function cxTanh(Op As Complex) As Complex cxTanh = cxMulImg(cxTan(cxMulImg(Op, 1)), -1) End Function
' // Hyperbolic cotangent of a complex number Public Function cxCtgh(Op As Complex) As Complex cxCtgh = cxRealDiv(1, cxTanh(Op)) End Function
' // Hyperbolic secant of a complex number Public Function cxSech(Op As Complex) As Complex cxSech = cxRealDiv(1, cxCosh(Op)) End Function
' // Hyperbolic cosecant of a complex number Public Function cxCsch(Op As Complex) As Complex cxCsch = cxRealDiv(1, cxSinh(Op)) End Function
' // Hyperbolic arcsine of a complex number Public Function cxAsinh(Op As Complex) As Complex cxAsinh = cxLog(cxAdd(Op, cxSqr(cxAddReal(cxMul(Op, Op), 1)))) End Function
' // Hyperbolic arccosine of a complex number Public Function cxAcosh(Op As Complex) As Complex cxAcosh = cxLog(cxAdd(Op, cxMul(cxSqr(cxAddReal(Op, 1)), cxSqr(cxSubReal(Op, 1))))) End Function
' // Hyperbolic arctangent of a complex number Public Function cxAtanh(Op As Complex) As Complex cxAtanh = cxMulReal(cxLog(cxDiv(cxAddReal(Op, 1), cxRealSub(1, Op))), 0.5) End Function
' // Hyperbolic arccotangent of a complex number Public Function cxActgh(Op As Complex) As Complex cxActgh = cxMulReal(cxLog(cxDiv(cxAddReal(Op, 1), cxSubReal(Op, 1))), 0.5) End Function
' // Hyperbolic arcsecant of a complex number Public Function cxAsech(Op As Complex) As Complex Dim Z As Complex Z = cxRealDiv(1, Op) cxAsech = cxLog(cxAdd(Z, cxSqr(cxAddReal(cxMul(Z, Z), 1)))) End Function
' // Hyperbolic arccosecant of a complex number Public Function cxAcsch(Op As Complex) As Complex Dim Z As Complex Z = cxRealDiv(1, Op) cxAcsch = cxLog(cxAdd(Z, cxMul(cxSqr(cxAddReal(Z, 1)), cxSqr(cxSubReal(Z, 1))))) End Function
|
|
|
Post by jcopernic on Jun 24, 2022 18:24:43 GMT 1
All basic arithmetic functions, plus trigonometric functions.
|
|
|
Post by dragonjim on Jun 25, 2022 12:12:51 GMT 1
Attached here ( Complex Numbers.G32 (16.3 KB) - updated) is the GFABASIC version of the above listing ready to create a LG32 library. I have not had time to test it so, if you have any problems with it, let me know.
|
|
|
Post by (X) on Jun 25, 2022 15:10:01 GMT 1
I tried creating a cx2str() function to ouptut a string representation of the complex number.
' // Convert a complex number to a string Function cx2str(ByRef cx As Complex) As String $Export Function cx2str " cx(<Real>, i<Imaginary>)" cx2str = "( " & Trim(cx.R) & " + i" & Trim(cx.I) & " )" EndFunc Things got a bit wonky at multiplying cxZero by cxOne and sqrt of cxOne...
|
|
|
Post by (X) on Jun 25, 2022 15:53:48 GMT 1
After explicitly setting R and I values in cxOne, cxImgOne and cxZero...
' // R = 1, I = 0 Function cxOne() As Complex $Export Function cxOne " R = 1, I = 0" cxOne.R = 1 cxOne.I = 0 End Function
' // R = 0, I = 1 Function cxImgOne() As Complex $Export Function cxImgOne " R = 0, I = 1" cxImgOne.R = 0 cxImgOne.I = 1 End Function
' // R = 0, I = 0 Function cxZero() As Complex $Export Function cxZero " R = 0, I = 0" cxZero.R = 0 cxZero.I = 0 End Function
The results seem better...
|
|
|
Post by (X) on Jun 25, 2022 16:15:09 GMT 1
The Complex Numbers Lib and Demo so far...
You'll need to compile* the Library file: Lib_Complex_Number.G32 to Lib_Complex_Number.LG32, and put it either in the same directory as the demo or eventually in the same place as all your other lib files.
* To quickly compile: (Ctrl-E + "Init LG32 Name"+ "OK")
/!\ I removed Lib_Complex_Numbers.G32 because there is another comparable library checkout dragonjim's post.
|
|
|
Post by (X) on Jun 25, 2022 18:31:42 GMT 1
I refined the cx2str() function to express cases of +1i and -1i as: "+i" and "-i" and values below 1e-16 are rounded to 0, (This only affects the output string not the values themselves.)
/!\ I removed Lib_Complex_Numbers.G32 because there is another comparable library checkout dragonjim's post.
|
|
|
Post by (X) on Jun 25, 2022 19:45:12 GMT 1
Depending on taste, you can use this version of cx2str() function to eliminate spaces in the output...
' // Convert a complex number to a string Function cx2str(ByRef cx As Complex) As String $Export Function cx2str " cx(<Real>, <Imaginary>i)" If (Abs(cx.R) < 1e-16) cx.R = 0 If (Abs(cx.I) < 1e-16) cx.I = 0 Dim i$ If Sgn(cx.I) => 0 If (cx.I == 1) i$ = "" Else i$ = Trim(cx.I) EndIf cx2str = "(" & Trim(cx.R) & "+" & i$ & "i)" Else If (cx.I == -1) i$ = "" Else i$ = Trim(Abs(cx.I)) EndIf cx2str = "(" & Trim(cx.R) & "-" & i$ & "i)" EndIf EndFunc
|
|
|
Post by (X) on Jun 25, 2022 19:59:15 GMT 1
All basic arithmetic functions, plus trigonometric functions. You've got me curious. Why / "for what project" are you planning to use complex numbers?
|
|
|
Post by jcopernic on Jun 25, 2022 20:07:14 GMT 1
I use complex numbers for digital signal processing Thank you all for your help and your answers.
|
|
|
Post by dragonjim on Jun 25, 2022 23:12:25 GMT 1
Hi,
The problems with CosH, SinH and TanH have been fixed in the latest UpdateRT library so should work as long as this library is referenced.
|
|
|
Post by (X) on Jun 26, 2022 3:49:13 GMT 1
Hi, The problems with CosH, SinH and TanH have been fixed in the latest UpdateRT library so should work as long as this library is referenced.
You are right! I modified the Lib_Complex_Numbers.G32 coding to use GFA's hyperbolic trig functions (CosH(), SinH() etc) and it works. I had forgotten to include the UpdateRT in the main code and that's exactly why I got an error when trying to use GFA's hyperbolic trig functions in the library.
I am checking consistency of results and found that for the Secant function: cxSec() there is a difference compared to a website calculator as to the sign of the imaginary component. I will look into this.
|
|
|
Post by (X) on Jun 26, 2022 3:57:01 GMT 1
The secant function is the inverse of the cosine function.
Taking the cxInv() of cxCos() to calculate cxSec() matches the online calculator results.
It would seem the original cxSec() is off by a sign, in the 5th line of code, there is a - sign that should be removed.
' // Secant of a complex number Function cxSec(ByRef Op As Complex) As Complex $Export Function cxSec " Secant of a complex number" Local C2# = Cos(Op.R) ^ 2 Local S2# = SinH(Op.I) ^ 2 cxSec.R = Cos(Op.R) * CosH(Op.I) / (C2 + S2) cxSec.I = -Sin(Op.R) * SinH(Op.I) / (C2 + S2) End Function
The 5th line of code should be changed to read:
' // Secant of a complex number Function cxSec(ByRef Op As Complex) As Complex $Export Function cxSec " Secant of a complex number" Local C2# = Cos(Op.R) ^ 2 Local S2# = SinH(Op.I) ^ 2 cxSec.R = Cos(Op.R) * CosH(Op.I) / (C2 + S2) cxSec.I = Sin(Op.R) * SinH(Op.I) / (C2 + S2) End Function
When you work through the cxCos() and cxInv() functions, to produce the cxSec() result, it becomes clear what the sign of Sin(Op.R) in cxSec()'s 5th line should be.
' // Return the inverse value of a complex number Function cxInv(ByRef Op As Complex) As Complex $Export Function cxInv " Return the inverse value of a complex number" Local Ab2 As Double Ab2 = Op.R * Op.R + Op.I * Op.I cxInv.R = Op.R / Ab2 : cxInv.I = -Op.I / Ab2 End Function
' // Cosine of a complex number Function cxCos(ByRef Op As Complex) As Complex $Export Function cxCos " Cosine of a complex number" cxCos.R = +Cos(Op.R) * CosH(Op.I) cxCos.I = -Sin(Op.R) * SinH(Op.I) End Function
|
|
|
Post by (X) on Jun 26, 2022 12:54:13 GMT 1
So as not to create confusion I will remove the attachments posted here: Lib_Complex_Numbers.G23 in deference to dragonjim's library / include resource. I believe he will create a new post in the Library section.
Please download that version and give feedback.
There is nothing stopping anyone from developing their own version of any library, in this case, I'd rather not create confusion as to which is the latest version.
(X)
|
|
|
Post by dragonjim on Jun 27, 2022 22:22:07 GMT 1
Hi, Here is the final alpha-tested version (mainly by (X)) of the Complex Numbers Library. The base file: Complex Numbers v0.23a 220722.g32 (20.67 KB) (Updated 22nd July 2022) The compiled library: ComplexNumbers.lg32 (13.3 KB) (Updated 22nd July 2022) Below is a very short piece of code with which to test the library: $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx
$Library "ComplexNumbers.lg32"
Local cx1 As Complex = cxNew(1, 1) Local cx2 As Complex = cxNew(2, 1) Trace cx2str2(cxAdd(cx1, cx2)) Trace cx2str2(cxMul(cx1, cx2)) Trace cx2str2(cxSub(cx1, cx2)) Trace cx2str2(cxDiv(cx1, cx2)) Debug.Show Note: Make sure that the ComplexNumbers.lg32 file is in the same folder as the code you are running. As noted above, the library has been reasonably thoroughly alpha-tested; however, errors in the code may still exist. If you find one, please post your finding to this forum post. As (X) commented, this library will be added to the main GFABASIC32 download, although this will not be until August or September. Until then, this post/thread will serve as the home for this library.
|
|
|
Post by (X) on Jun 30, 2022 13:50:34 GMT 1
It would seem the result of the cxCsc() is also off by a sign in the imaginary component.
For: cx1 = (1+i)
The following result should be the same because the Csc (cosecant) is the inverse of the Sin() function.
The result from: www.hackmath.net/en/calculator/complex-numberfor: csc(1+i) is...
The code from: Complex Numbers v0.2a 220627g32.g32, for the cxCsc() function is:
Function cxCsc(ByRef Op As Complex) As Complex $Export Function cxCsc "(ByRef Op As Complex) As Complex"#10"Cosecant of a complex number" Dim C2 As Double, S2 As Double C2 = Sin(Op.R) : C2 = C2 * C2 : S2 = SinH(Op.I) : S2 = S2 * S2 cxCsc.R = (Sin(Op.R) * CosH(Op.I)) / (C2 + S2) cxCsc.I = (Cos(Op.R) * SinH(Op.I)) / (C2 + S2) End Function
Changing the 6th line to: cxCsc.I = -(Cos(Op.R) * SinH(Op.I)) / (C2 + S2) seems to fix the problem.
|
|
|
Post by dragonjim on Jun 30, 2022 16:46:16 GMT 1
That makes a lot of sense, considering that the Secant function was also incorrect. Thanks for testing that.
The updated library and compiled library files are in the post two above this one....
...and updated again (1st July 2022)
|
|
|
Post by jcopernic on Jul 20, 2022 17:11:20 GMT 1
Hi, The cxDgr function has a problem with negative numbers, when both the real and imaginary parts are negative. This generates an error. A small example of code :
Dim z1 As Complex = cxNew(-2, 4) Dim z2 As Complex = cxNew(1, -3) Dim z3 As Complex = cxNew(-6, -5)
Trace cx2str2(cxDgr(z1, 2)) ' result = -12 -16i Trace cx2str2(cxDgr(z2, 2)) ' result = -8 -6i Trace cx2str2(cxDgr(z3, 2)) ' Access-Violation Exception : 0xc0000005 ;"The result should be = 11 +60i"
|
|
|
Post by (X) on Jul 20, 2022 21:51:11 GMT 1
Seems like cxArg() is a good candidate for substituting Atan2...
Though which parameter should be x and y should be adjusted from GFA's Help file. Although GFA has documented: Atan2(x, y) the results correspond to Atan2(y, x).
I have notified the GFA help file editor at: gfahelpfile@outlook.com. You are encouraged to advise GFA of any help file issues in this way.
A quick search for a standard Atan2() parameter configuration...
Here is the original code (commented) with the Atan2() substitution...
Function cxArg(ByRef Op As Complex) As Double Naked $Export Function cxArg "(ByRef Op As Complex) As Double"#10"Argument of a complex number (equal phase)" °If Op.I = 0 Then °If Op.R >= 0 Then cxArg = 0 Else cxArg = PI °ElseIf Op.R = 0 Then °If Op.I >= 0 Then cxArg = PI2 Else cxArg = -PI2 °Else °If Op.R > 0 Then °cxArg = Atn(Op.I / Op.R) °ElseIf Op.R < 0 And Op.I > 0 Then °cxArg = PI + Atn(Op.I / Op.R) °ElseIf Op.R < 0 And Op.I < 0 Then °cxArg = -PI + Atn(Op.I / Op.R) °End If °End If cxArg = Atan2(Op.i, Op.R) End Function
From GFA Help:
The code for the above results...
Trace Deg(Atan2(+1, +1)) Trace Deg(Atan2(-1, +1)) Trace Deg(Atan2(+1, -1)) Trace Deg(Atan2(-1, -1)) Trace Deg(Atan2(+1, +0)) Trace Deg(Atan2(-1, +0)) Trace Deg(Atan2(+0, +0)) Trace Deg(Atan2(+0, +1)) Trace Deg(Atan2(+0, -1))
|
|
|
Post by (X) on Jul 20, 2022 22:53:47 GMT 1
This seems to be ok now. It is up to dragonjim to adjust the lib if I am correct. $Library "gfawinx" $Library "UpdateRT" UpdateRuntime ' Patches GfaWin23.Ocx $Library "Complex Numbers v0.22a 220701"
Dim z1 As Complex = cxNew(-2, 4) Dim z2 As Complex = cxNew(1, -3) Dim z3 As Complex = cxNew(-6, -5)
Trace cx2str2(cxDgr(z1, 2)) ' result = -12 -16i Trace cx2str2(cxDgr(z2, 2)) ' result = -8 -6i Trace cx2str2(cxDgr(z3, 2)) ' The result should be = 11 +60i
'''''''''''''''''''''''''''''''''''''''''''''''''' ' The mod to cxArg() seems to return the expected ' result. ' 'TRACE:(1):cx2str2(cxDgr(z1, 2)) = (-12-16i) 'TRACE:(2):cx2str2(cxDgr(z2, 2)) = (-8-6i) 'TRACE:(3):cx2str2(cxDgr(z3, 2)) = (11+60i)
This new code for cxArg() seems to correct the previous error.
Function cxArg(ByRef Op As Complex) As Double Naked $Export Function cxArg "(ByRef Op As Complex) As Double"#10"Argument of a complex number (equal phase)" cxArg = Atan2(Op.i, Op.R) End Function
Atan2() is an improved Atan() function since it automatically returns the correct angle for + | - values and 0 for both x and y.
|
|
|
Post by jcopernic on Jul 21, 2022 16:18:06 GMT 1
Thank you very much X.
|
|
|
Post by (X) on Jul 22, 2022 12:18:57 GMT 1
Thank you for your input. This is what I like best about this forum. The sharing of knowledge.
|
|
|
Post by dragonjim on Jul 22, 2022 13:20:30 GMT 1
The library and code have been updated with this new amendment: The base file: Complex Numbers v0.23a 220722.g32 (20.67 KB) (Updated 22nd July 2022) The compiled library: ComplexNumbers.lg32 (13.3 KB) (Updated 22nd July 2022) The other links have also been updated...
|
|
|
Post by (X) on Jul 23, 2022 9:10:15 GMT 1
The library and code have been updated with this new amendment: The base file: View Attachment (Updated 22nd July 2022) The compiled library: View Attachment (Updated 22nd July 2022) The other links have also been updated... Thanks. This all checks out AFAIK.
|
|
|
Post by (X) on Jul 28, 2022 12:34:33 GMT 1
Hi dragonjim,
To produce a comma separated output string for a complex number:
Suggested code ammendment...
' // Convert a complex number to a string Function cx2str(ByRef cx As Complex) As String Naked $Export Function cx2str "(ByRef cx As Complex) As String"#10"Convert a complex number to a string in comma-separated format: (<Real>, <Imaginary>)" cx2str = "(" & Trim(cx.R) & ", " & Trim(cx.I) & ")" EndFunc
Debug output...
|
|
|
Post by (X) on Jul 28, 2022 12:52:13 GMT 1
Hi dragonjim,
This is a suggestion to improve the cx2str2() functions to include a set of parenthesis in the case of the Real component being zero or the Imaginanry component is zero or both...
' // Convert a complex number to a string Function cx2str2(ByRef cx As Complex) As String Naked $Export Function cx2str2 "(ByRef cx As Complex) As String"#10"Convert a complex number to a string in standard format: (<Real>[+/-]<Imaginary>i)" If (Abs(cx.R) < 1e-16) cx.R = 0 If (Abs(cx.I) < 1e-16) cx.I = 0 Dim i$ If (cx.R == 0) And (cx.I == 0) cx2str2 = "(" & Trim(cx.R) & ")" ElseIf (cx.R == 0) cx2str2 = "(" & Trim(cx.I) & "i)" ElseIf (cx.I == 0) cx2str2 = "(" & Trim(cx.R) & ")" ElseIf (Sgn(cx.I) => 0) If (cx.I == 1) i$ = "" Else i$ = Trim(cx.I) EndIf cx2str2 = "(" & Trim(cx.R) & "+" & i$ & "i)" Else If (cx.I == -1) i$ = "" Else i$ = Trim(Abs(cx.I)) EndIf cx2str2 = "(" & Trim(cx.R) & "-" & i$ & "i)" EndIf Clr i$ EndFunc
Sample code...
Dim z1 As Complex = cxNew(-2, 4) Dim z2 As Complex = cxNew(1, -3) Dim z3 As Complex = cxNew(-6, -5) Dim z4 As Complex = cxNew(0, -5) Dim z5 As Complex = cxNew(5, 0) Dim z6 As Complex = cxNew(0, 0)
Debug "Using cx2str() (Comma separated)" Trace cx2str(cxDgr(z1, 2)) ' result = -12 -16i Trace cx2str(cxDgr(z2, 2)) ' result = -8 -6i Trace cx2str(cxDgr(z3, 2)) ' The result should be = 11 +60i Trace cx2str(z4) Trace cx2str(z5) Trace cx2str(z6) Debug Debug "Using cx2str2() (i notation)" Trace cx2str2(cxDgr(z1, 2)) ' result = -12 -16i Trace cx2str2(cxDgr(z2, 2)) ' result = -8 -6i Trace cx2str2(cxDgr(z3, 2)) ' The result should be = 11 +60i Trace cx2str2(z4) Trace cx2str2(z5) Trace cx2str2(z6) Debug results...
|
|