The documentation for Kernel-Numbers/Complex says that arcSin, arcCos and arcTan are missing. "sqrt" is also handy for implementing some of these.
Following are versions of these functions, plus a cut-and-paste set of manual tests from a Workspace. I'm new to Smalltalk, so there are certainly lots more parentheses than necessary, plus I'm sure lots of other style failures. There will also be lots of numerical and efficiency improvements possible. I hope the functions provide a start, though.
sqrt "complex square root: principal value taken as upper half-plane" | | imaginary = 0.0 ifTrue: [real >= 0.0 ifTrue: [^real sqrt] ifFalse: [^real negated sqrt * 1 i] ]. ^ (0.5 * (self ln)) exp.
arcSin "analytic continuation of inverse sine function" | | ^ ((self * 1 i) + (1 - (self squared)) sqrt) ln * (-1 i).
arcCos "inverse of cosine function extended to Complex" | | ^ (self + ((self squared - 1) sqrt)) ln * -1 i .
arcTan "inverse of tan on the complex domain" | iself | iself := 1 i * self. ^ 0.5 i * ((1.0 - iself) / (1.0 + iself)) ln.
Here are some simple tests, copied & pasted from Workspace:
Transcript clear. { 0 . 0 + 0i . 1 . 1 + 0 i . 3 + 4 i . 1.3 + 4 i . 1 i . -1 i .} do: [: z | Transcript show: 'z = '; show: z ; show: ' z sqrt ='; show: z sqrt ; show: ' z arcSin = '; show: z arcSin; show: ' z arcSin sin = '; show: z arcSin sin; show: ' z sin arcSin = '; show: z sin arcSin; show: ' z arcCos = '; show: z arcCos; show: ' z arcCos cos = '; show: z arcCos cos; show: ' z cos arcCos = '; show: z cos arcCos; show: String crlfcrlf].
And the results are:
z = 0 z sqrt =0.0 z arcSin = 0.0 z arcSin sin = 0.0 z sin arcSin = 0.0 z arcCos = 1.570796326794897 z arcCos cos = 1.224646799147353e-16 z cos arcCos = 0.0
z = 0 + 0 i z sqrt =0.0 z arcSin = 0.0 + 0.0 i z arcSin sin = 0.0 + 0.0 i z sin arcSin = 0.0 + 0.0 i z arcCos = 1.570796326794897 + 0.0 i z arcCos cos = 6.12323399573677e-17 + 0.0 i z cos arcCos = 0.0 + 0.0 i
z = 1 z sqrt =1.0 z arcSin = 1.570796326794897 z arcSin sin = 1.0 z sin arcSin = 1.0 z arcCos = 0.0 z arcCos cos = 1.0 z cos arcCos = 1.0
z = 1 + 0 i z sqrt =1.0 z arcSin = 1.570796326794897 + 0.0 i z arcSin sin = 1.0 - 6.12323399573677e-17 i z sin arcSin = 1.0 + 0.0 i z arcCos = 0.0 + 0.0 i z arcCos cos = 1.0 + 0.0 i z cos arcCos = 1.0 + 1.110223024625156e-16 i
z = 3 + 4 i z sqrt =2.0 + 1.0 i z arcSin = 0.633983865639184 + 2.305509031243485 i z arcSin sin = 3.000000000000056 + 4.00000000000001 i z sin arcSin = 0.1415926535897932 - 4.0 i z arcCos = 0.93681246115572 - 2.305509031243477 i z arcCos cos = 3.0 + 4.0 i z cos arcCos = 2.999999999999935 + 4.00000000000009 i
z = 1.3 + 4 i z sqrt =1.659208873072136 + 1.205393746657626 i z arcSin = 0.306199697879277 + 2.14098384538913 i z arcSin sin = 1.299999999999996 + 3.999999999999993 i z sin arcSin = 1.300000000000133 + 3.99999999999994 i z arcCos = 1.264596628915619 - 2.140983845389134 i z arcCos cos = 1.3 + 4.0 i z cos arcCos = -1.3 - 4.0 i
z = 0 + 1 i z sqrt =0.7071067811865475 + 0.7071067811865475 i z arcSin = 0.0 + 0.881373587019543 i z arcSin sin = 0.0 + 1.0 i z sin arcSin = 0.0 + 1.0 i z arcCos = 1.570796326794897 - 0.881373587019543 i z arcCos cos = 1.47827945580917e-16 + 1.0 i z cos arcCos = 0.0 - 1.0 i
z = 0 - 1 i z sqrt =0.7071067811865475 - 0.7071067811865475 i z arcSin = 0.0 - 0.881373587019543 i z arcSin sin = 0.0 - 1.0 i z sin arcSin = 0.0 - 1.0 i z arcCos = 1.570796326794897 + 0.881373587019543 i z arcCos cos = 2.536326566618168e-17 - 1.0 i z cos arcCos = 0.0 - 1.0 i
Note that these functions aren't one-to-one, so "z sin arcsin" isn't necessarily the identity. The real part can take jumps of multiples of Pi, signs can change, etcetera. For example, note: (3 + 4 i) sin arcSin -> 0.1415926535897932 - 4.0 i (3 + 4 i) sin arcSin sin arcSin -> 0.1415926535897932 - 4.0 i The first time through, "sin arcSin" jumps branches; after that it's the identity.
I may be missing something, but is there a specific reason why we do not implement complex numbers simply by extending Point ? it would make it easier to work with transformations on the complex plane where conversion between Point and Complex would happen all the time.
Stef
martin
why don't you send a cs and some tests to back up your implementation.
Stef
On 30 sept. 05, at 08:03, Martin Snelgrove wrote:
The documentation for Kernel-Numbers/Complex says that arcSin, arcCos and arcTan are missing. "sqrt" is also handy for implementing some of these.
Following are versions of these functions, plus a cut-and-paste set of manual tests from a Workspace. I'm new to Smalltalk, so there are certainly lots more parentheses than necessary, plus I'm sure lots of other style failures. There will also be lots of numerical and efficiency improvements possible. I hope the functions provide a start, though.
sqrt "complex square root: principal value taken as upper half-plane" | | imaginary = 0.0 ifTrue: [real >= 0.0 ifTrue: [^real sqrt] ifFalse: [^real negated sqrt * 1 i] ]. ^ (0.5 * (self ln)) exp.
arcSin "analytic continuation of inverse sine function" | | ^ ((self * 1 i) + (1 - (self squared)) sqrt) ln * (-1 i).
arcCos "inverse of cosine function extended to Complex" | | ^ (self + ((self squared - 1) sqrt)) ln * -1 i .
arcTan "inverse of tan on the complex domain" | iself | iself := 1 i * self. ^ 0.5 i * ((1.0 - iself) / (1.0 + iself)) ln.
Here are some simple tests, copied & pasted from Workspace:
Transcript clear. { 0 . 0 + 0i . 1 . 1 + 0 i . 3 + 4 i . 1.3 + 4 i . 1 i . -1 i .} do: [: z | Transcript show: 'z = '; show: z ; show: ' z sqrt ='; show: z sqrt ; show: ' z arcSin = '; show: z arcSin; show: ' z arcSin sin = '; show: z arcSin sin; show: ' z sin arcSin = '; show: z sin arcSin; show: ' z arcCos = '; show: z arcCos; show: ' z arcCos cos = '; show: z arcCos cos; show: ' z cos arcCos = '; show: z cos arcCos; show: String crlfcrlf].
And the results are:
z = 0 z sqrt =0.0 z arcSin = 0.0 z arcSin sin = 0.0 z sin arcSin = 0.0 z arcCos = 1.570796326794897 z arcCos cos = 1.224646799147353e-16 z cos arcCos = 0.0
z = 0 + 0 i z sqrt =0.0 z arcSin = 0.0 + 0.0 i z arcSin sin = 0.0 + 0.0 i z sin arcSin = 0.0 + 0.0 i z arcCos = 1.570796326794897 + 0.0 i z arcCos cos = 6.12323399573677e-17 + 0.0 i z cos arcCos = 0.0 + 0.0 i
z = 1 z sqrt =1.0 z arcSin = 1.570796326794897 z arcSin sin = 1.0 z sin arcSin = 1.0 z arcCos = 0.0 z arcCos cos = 1.0 z cos arcCos = 1.0
z = 1 + 0 i z sqrt =1.0 z arcSin = 1.570796326794897 + 0.0 i z arcSin sin = 1.0 - 6.12323399573677e-17 i z sin arcSin = 1.0 + 0.0 i z arcCos = 0.0 + 0.0 i z arcCos cos = 1.0 + 0.0 i z cos arcCos = 1.0 + 1.110223024625156e-16 i
z = 3 + 4 i z sqrt =2.0 + 1.0 i z arcSin = 0.633983865639184 + 2.305509031243485 i z arcSin sin = 3.000000000000056 + 4.00000000000001 i z sin arcSin = 0.1415926535897932 - 4.0 i z arcCos = 0.93681246115572 - 2.305509031243477 i z arcCos cos = 3.0
- 4.0 i z cos arcCos = 2.999999999999935 + 4.00000000000009 i
z = 1.3 + 4 i z sqrt =1.659208873072136 + 1.205393746657626 i z arcSin = 0.306199697879277 + 2.14098384538913 i z arcSin sin = 1.299999999999996 + 3.999999999999993 i z sin arcSin = 1.300000000000133 + 3.99999999999994 i z arcCos = 1.264596628915619 - 2.140983845389134 i z arcCos cos = 1.3 + 4.0 i z cos arcCos = -1.3 - 4.0 i
z = 0 + 1 i z sqrt =0.7071067811865475 + 0.7071067811865475 i z arcSin = 0.0 + 0.881373587019543 i z arcSin sin = 0.0 + 1.0 i z sin arcSin = 0.0 + 1.0 i z arcCos = 1.570796326794897 - 0.881373587019543 i z arcCos cos = 1.47827945580917e-16 + 1.0 i z cos arcCos = 0.0 - 1.0 i
z = 0 - 1 i z sqrt =0.7071067811865475 - 0.7071067811865475 i z arcSin = 0.0 - 0.881373587019543 i z arcSin sin = 0.0 - 1.0 i z sin arcSin = 0.0 - 1.0 i z arcCos = 1.570796326794897 + 0.881373587019543 i z arcCos cos = 2.536326566618168e-17 - 1.0 i z cos arcCos = 0.0 - 1.0 i
Note that these functions aren't one-to-one, so "z sin arcsin" isn't necessarily the identity. The real part can take jumps of multiples of Pi, signs can change, etcetera. For example, note: (3 + 4 i) sin arcSin -> 0.1415926535897932
- 4.0 i
(3 + 4 i) sin arcSin sin arcSin -> 0.1415926535897932 - 4.0 i The first time through, "sin arcSin" jumps branches; after that it's the identity.
squeak-dev@lists.squeakfoundation.org