This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,18 @@
USING: combinators kernel math math.functions prettyprint ;
C{ 1 2 } C{ 0.9 -2.78 } {
[ + . ] ! addition
[ - . ] ! subtraction
[ * . ] ! multiplication
[ / . ] ! division
[ ^ . ] ! power
} 2cleave
C{ 1 2 } {
[ neg . ] ! negation
[ 1 swap / . ] ! multiplicative inverse
[ conjugate . ] ! complex conjugate
[ sin . ] ! sine
[ log . ] ! natural logarithm
[ sqrt . ] ! square root
} cleave

View file

@ -0,0 +1,19 @@
# GAP knows gaussian integers, gaussian rationals (i.e. Q[i]), and cyclotomic fields. Here are some examples.
# E(n) is an nth primitive root of 1
i := Sqrt(-1);
# E(4)
(3 + 2*i)*(5 - 7*i);
# 29-11*E(4)
1/i;
# -E(4)
Sqrt(-3);
# E(3)-E(3)^2
i in GaussianIntegers;
# true
i/2 in GaussianIntegers;
# false
i/2 in GaussianRationals;
# true
Sqrt(-3) in Cyclotomics;
# true

View file

@ -0,0 +1,94 @@
class Complex {
final Number real, imag
static final Complex I = [0,1] as Complex
Complex(Number real) { this(real, 0) }
Complex(real, imag) { this.real = real; this.imag = imag }
Complex plus (Complex c) { [real + c.real, imag + c.imag] as Complex }
Complex plus (Number n) { [real + n, imag] as Complex }
Complex minus (Complex c) { [real - c.real, imag - c.imag] as Complex }
Complex minus (Number n) { [real - n, imag] as Complex }
Complex multiply (Complex c) { [real*c.real - imag*c.imag , imag*c.real + real*c.imag] as Complex }
Complex multiply (Number n) { [real*n , imag*n] as Complex }
Complex div (Complex c) { this * c.recip() }
Complex div (Number n) { this * (1/n) }
Complex negative () { [-real, -imag] as Complex }
/** the complex conjugate of this complex number.
* Overloads the bitwise complement (~) operator. */
Complex bitwiseNegate () { [real, -imag] as Complex }
/** the magnitude of this complex number. */
// could also use Math.sqrt( (this * (~this)).real )
Number abs () { Math.sqrt( real*real + imag*imag ) }
/** the complex reciprocal of this complex number. */
Complex recip() { (~this) / ((this * (~this)).real) }
/** derived angle θ (theta) for polar form.
* Normalized to 0 &#x2264; &#x03B8; < 2&#x03C0;. */
Number getTheta() {
def theta = Math.atan2(imag,real)
theta = theta < 0 ? theta + 2 * Math.PI : theta
}
/** derived magnitude &#x03C1; (rho) for polar form. */
Number getRho() { this.abs() }
/** Runs Euler's polar-to-Cartesian complex conversion,
* converting [&#x03C1;, &#x03B8;] inputs into a [real, imag]-based complex number */
static Complex fromPolar(Number rho, Number theta) {
[rho * Math.cos(theta), rho * Math.sin(theta)] as Complex
}
/** Creates new complex with same magnitude &#x03C1;, but different angle &#x03B8; */
Complex withTheta(Number theta) { fromPolar(this.rho, theta) }
/** Creates new complex with same angle &#x03B8;, but different magnitude &#x03C1; */
Complex withRho(Number rho) { fromPolar(rho, this.theta) }
static Complex exp(Complex c) { fromPolar(Math.exp(c.real), c.imag) }
static Complex log(Complex c) { [Math.log(c.rho), c.theta] as Complex }
Complex power(Complex c) {
this == 0 && c != 0 \
? [0] as Complex \
: c == 1 \
? this \
: exp( log(this) * c )
}
Complex power(Number n) { this ** ([n, 0] as Complex) }
boolean equals(other) {
other != null && (other instanceof Complex \
? [real, imag] == [other.real, other.imag] \
: other instanceof Number && [real, imag] == [other, 0])
}
int hashCode() { [real, imag].hashCode() }
String toString() {
def realPart = "${real}"
def imagPart = imag.abs() == 1 ? "i" : "${imag.abs()}i"
real == 0 && imag == 0 \
? "0" \
: real == 0 \
? (imag > 0 ? '' : "-") + imagPart \
: imag == 0 \
? realPart \
: realPart + (imag > 0 ? " + " : " - ") + imagPart
}
}

View file

@ -0,0 +1,36 @@
def tol = 0.000000001 // tolerance: acceptable "wrongness" to account for rounding error
println 'Demo 1: functionality as requested'
def a = [5,3] as Complex
println 'a == ' + a
def b = [0.5,6] as Complex
println 'b == ' + b
println "a + b == (${a}) + (${b}) == " + (a + b)
println "a * b == (${a}) * (${b}) == " + (a * b)
assert a + (-a) == 0
println "-a == -(${a}) == " + (-a)
assert (a * a.recip() - 1).abs() < tol
println "1/a == (${a}).recip() == " + (a.recip())
println()
println 'Demo 2: other functionality not requested, but important for completeness'
println "a - b == (${a}) - (${b}) == " + (a - b)
println "a / b == (${a}) / (${b}) == " + (a / b)
println "a ** b == (${a}) ** (${b}) == " + (a ** b)
println 'a.real == ' + a.real
println 'a.imag == ' + a.imag
println 'a.rho == ' + a.rho
println 'a.theta == ' + a.theta
println '|a| == ' + a.abs()
println 'a_bar == ' + ~a
def rho = 10
def piOverTheta = 3
def theta = Math.PI / piOverTheta
def fromPolar1 = Complex.fromPolar(rho, theta) // direct polar-to-cartesian conversion
def fromPolar2 = Complex.exp(Complex.I * theta) * rho // Euler's equation
println "rho*cos(theta) + rho*i*sin(theta) == ${rho}*cos(pi/${piOverTheta}) + ${rho}*i*sin(pi/${piOverTheta}) == " + fromPolar1
println "rho * exp(i * theta) == ${rho} * exp(i * pi/${piOverTheta}) == " + fromPolar2
assert (fromPolar1 - fromPolar2).abs() < tol
println()

View file

@ -0,0 +1,10 @@
x=complex(1,1)
y=complex(!pi,1.2)
print,x+y
( 4.14159, 2.20000)
print,x*y
( 1.94159, 4.34159)
print,-x
( -1.00000, -1.00000)
print,1/x
( 0.500000, -0.500000)

View file

@ -0,0 +1,22 @@
procedure main()
SetupComplex()
a := complex(1,2)
b := complex(3,4)
c := complex(&pi,1.5)
d := complex(1)
e := complex(,1)
every v := !"abcde" do write(v," := ",cpxstr(variable(v)))
write("a+b := ", cpxstr(cpxadd(a,b)))
write("a-b := ", cpxstr(cpxsub(a,b)))
write("a*b := ", cpxstr(cpxmul(a,b)))
write("a/b := ", cpxstr(cpxdiv(a,b)))
write("neg(a) := ", cpxstr(cpxneg(a)))
write("inv(a) := ", cpxstr(cpxinv(a)))
write("conj(a) := ", cpxstr(cpxconj(a)))
write("abs(a) := ", cpxabs(a))
write("neg(1) := ", cpxstr(cpxneg(1)))
end

View file

@ -0,0 +1,27 @@
link complex # for complex number support
procedure SetupComplex() #: used to setup safe complex
COMPLEX() # replace complex record constructor
SetupComplex := 1 # never call here again
return
end
procedure COMPLEX(rpart,ipart) #: new safe record constructor and coercion
initial complex :=: COMPLEX # get in front of record constructor
return if /ipart & (type(rpart) == "complex")
then rpart # already complex
else COMPLEX( real(\rpart | 0.0), real(\ipart|0) ) # create a new complex number
end
procedure cpxneg(z) #: negate z
z := complex(z) # coerce
return complex( -z.rpart, -z.ipart)
end
procedure cpxinv(z) #: inverse of z
local denom
z := complex(z) # coerce
denom := z.rpart ^ 2 + z.ipart ^ 2
return complex(z.rpart / denom, z.ipart / denom)
end

View file

@ -0,0 +1,10 @@
x=: 1j1
y=: 3.14159j1.2
x+y
4.14159j2.2
x*y
1.94159j4.34159
%x
0.5j_0.5
-x
_1j_1

View file

@ -0,0 +1,51 @@
mainwin 50 10
print " Adding"
call cprint cadd$( complex$( 1, 1), complex$( 3.14159265, 1.2))
print " Multiplying"
call cprint cmulti$( complex$( 1, 1), complex$( 3.14159265, 1.2))
print " Inverting"
call cprint cinv$( complex$( 1, 1))
print " Negating"
call cprint cneg$( complex$( 1, 1))
end
sub cprint cx$
print "( "; word$( cx$, 1); " + i *"; word$( cx$, 2); ")"
end sub
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 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 cneg$( a$)
ar = val( word$( a$ , 1 ) )
ai = val( word$( a$ , 2 ) )
cneg$ =complex$( 0 -ar, 0 -ai)
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

View file

@ -0,0 +1,2 @@
x := 1+I;
y := Pi+I*1.2;

View file

@ -0,0 +1,4 @@
x*y;
==> (1 + I) (Pi + 1.2 I)
simplify(x*y);
==> 1.941592654 + 4.341592654 I

View file

@ -0,0 +1,4 @@
x+y;
x*y;
-x;
1/x;

View file

@ -0,0 +1,11 @@
x=1+2I
y=3+4I
x+y => 4 + 6 I
x-y => -2 - 2 I
y x => -5 + 10 I
y/x => 11/5 - (2 I)/5
x^3 => -11 - 2 I
y^4 => -527 - 336 I
x^y => (1 + 2 I)^(3 + 4 I)
N[x^y] => 0.12901 + 0.0339241 I

View file

@ -0,0 +1,9 @@
Exp Log
Sin Cos Tan Csc Sec Cot
ArcSin ArcCos ArcTan ArcCsc ArcSec ArcCot
Sinh Cosh Tanh Csch Sech Coth
ArcSinh ArcCosh ArcTanh ArcCsch ArcSech ArcCoth
Sinc
Haversine InverseHaversine
Factorial Gamma PolyGamma LogGamma
Erf BarnesG Hyperfactorial Zeta ProductLog RamanujanTauL

View file

@ -0,0 +1,44 @@
z1: 5 + 2 * %i;
2*%i+5
z2: 3 - 7 * %i;
3-7*%i
carg(z1);
atan(2/5)
cabs(z1);
sqrt(29)
rectform(z1 * z2);
29-29*%i
polarform(z1);
sqrt(29)*%e^(%i*atan(2/5))
conjugate(z1);
5-2*%i
z1 + z2;
8-5*%i
z1 - z2;
9*%i+2
z1 * z2;
(3-7*%i)*(2*%i+5)
z1 * z2, rectform;
29-29*%i
z1 / z2;
(2*%i+5)/(3-7*%i)
z1 / z2, rectform;
(41*%i)/58+1/58
realpart(z1);
5
imagpart(z1);
2

View file

@ -0,0 +1,66 @@
MODULE complex;
IMPORT InOut;
TYPE Complex = RECORD R, Im : REAL END;
VAR z : ARRAY [0..3] OF Complex;
PROCEDURE ShowComplex (str : ARRAY OF CHAR; p : Complex);
BEGIN
InOut.WriteString (str); InOut.WriteString (" = ");
InOut.WriteReal (p.R, 6, 2);
IF p.Im >= 0.0 THEN InOut.WriteString (" + ") ELSE InOut.WriteString (" - ") END;
InOut.WriteReal (ABS (p.Im), 6, 2); InOut.WriteString (" i ");
InOut.WriteLn; InOut.WriteBf
END ShowComplex;
PROCEDURE AddComplex (x1, x2 : Complex; VAR x3 : Complex);
BEGIN
x3.R := x1.R + x2.R;
x3.Im := x1.Im + x2.Im
END AddComplex;
PROCEDURE SubComplex (x1, x2 : Complex; VAR x3 : Complex);
BEGIN
x3.R := x1.R - x2.R;
x3.Im := x1.Im - x2.Im
END SubComplex;
PROCEDURE MulComplex (x1, x2 : Complex; VAR x3 : Complex);
BEGIN
x3.R := x1.R * x2.R - x1.Im * x2.Im;
x3.Im := x1.R * x2.Im + x1.Im * x2.R
END MulComplex;
PROCEDURE InvComplex (x1 : Complex; VAR x2 : Complex);
BEGIN
x2.R := x1.R / (x1.R * x1.R + x1.Im * x1.Im);
x2.Im := -1.0 * x1.Im / (x1.R * x1.R + x1.Im * x1.Im)
END InvComplex;
PROCEDURE NegComplex (x1 : Complex; VAR x2 : Complex);
BEGIN
x2.R := - x1.R; x2.Im := - x1.Im
END NegComplex;
BEGIN
InOut.WriteString ("Enter two complex numbers : ");
InOut.WriteBf;
InOut.ReadReal (z[0].R); InOut.ReadReal (z[0].Im);
InOut.ReadReal (z[1].R); InOut.ReadReal (z[1].Im);
ShowComplex ("z1", z[0]); ShowComplex ("z2", z[1]);
InOut.WriteLn;
AddComplex (z[0], z[1], z[2]); ShowComplex ("z1 + z2", z[2]);
SubComplex (z[0], z[1], z[2]); ShowComplex ("z1 - z2", z[2]);
MulComplex (z[0], z[1], z[2]); ShowComplex ("z1 * z2", z[2]);
InvComplex (z[0], z[2]); ShowComplex ("1 / z1", z[2]);
NegComplex (z[0], z[2]); ShowComplex (" - z1", z[2]);
InOut.WriteLn
END complex.