Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,4 +1,5 @@
A '''[[wp:Complex number|complex number]]''' is a number which can be written as "<math>a + b \times i</math>" (sometimes shown as "<math>b + a \times i</math>") where a and b are real numbers and [[wp:Imaginary_unit|<math>i</math> is the square root of -1]]. Typically, complex numbers are represented as a pair of real numbers called the "imaginary part" and "real part", where the imaginary part is the number to be multiplied by <math>i</math>.
A '''[[wp:Complex number|complex number]]''' is a number which can be written as "<math>a + b \times i</math>" (sometimes shown as "<math>b + a \times i</math>") where a and b are real numbers and [[wp:Imaginary_unit|<math>i</math> is the square root of -1]].
Typically, complex numbers are represented as a pair of real numbers called the "imaginary part" and "real part", where the imaginary part is the number to be multiplied by <math>i</math>.
* Show addition, multiplication, negation, and inversion of complex numbers in separate functions. (Subtraction and division operations can be made with pairs of these operations.) Print the results for each operation tested.
* ''Optional:'' Show complex conjugation. By definition, the [[wp:complex conjugate|complex conjugate]] of <math>a + bi</math> is <math>a - bi</math>.

View file

@ -0,0 +1,28 @@
(add=a b.!arg:(?a,?b)&!a+!b)
& ( multiply
= a b.!arg:(?a,?b)&1+!a*!b+-1
)
& (negate=.1+-1*!arg+-1)
& ( conjugate
= a b
. !arg:i&-i
| !arg:-i&i
| !arg:?a_?b&(conjugate$!a)_(conjugate$!b)
| !arg
)
& ( invert
= conjugated
. conjugate$!arg:?conjugated
& multiply$(!arg,!conjugated)^-1*!conjugated
)
& out$("(a+i*b)+(a+i*b) =" add$(a+i*b,a+i*b))
& out$("(a+i*b)+(a+-i*b) =" add$(a+i*b,a+-i*b))
& out$("(a+i*b)*(a+i*b) =" multiply$(a+i*b,a+i*b))
& out$("(a+i*b)*(a+-i*b) =" multiply$(a+i*b,a+-i*b))
& out$("-1*(a+i*b) =" negate$(a+i*b))
& out$("-1*(a+-i*b) =" negate$(a+-i*b))
& out$("sin$x = " sin$x)
& out$("conjugate sin$x =" conjugate$(sin$x))
& out
$ ("sin$x minus conjugate sin$x =" sin$x+negate$(conjugate$(sin$x)))
& done;

View file

@ -0,0 +1,37 @@
(ns rosettacode.arithmetic.cmplx
(:require [clojure.algo.generic.arithmetic :as ga])
(:import [java.lang Number]))
(defrecord Complex [^Number r ^Number i]
Object
(toString [{:keys [r i]}]
(apply str
(cond
(zero? r) [(if (= i 1) "" i) "i"]
(zero? i) [r]
:else [r (if (neg? i) "-" "+") i "i"]))))
(defmethod ga/+ [Complex Complex]
[x y] (map->Complex (merge-with + x y)))
(defmethod ga/+ [Complex Number] ; reals become y + 0i
[{:keys [r i]} y] (->Complex (+ r y) i))
(defmethod ga/- Complex
[x] (->> x vals (map -) (apply ->Complex)))
(defmethod ga/* [Complex Complex]
[x y] (map->Complex (merge-with * x y)))
(defmethod ga/* [Complex Number]
[{:keys [r i]} y] (->Complex (* r y) (* i y)))
(ga/defmethod* ga / Complex
[x] (->> x vals (map /) (apply ->Complex)))
(defn conj [^Complex {:keys [r i]}]
(->Complex r (- i)))
(defn inv [^Complex {:keys [r i]}]
(let [m (+ (* r r) (* i i))]
(->Complex (/ r m) (- (/ i m)))))

View file

@ -0,0 +1,60 @@
# create an immutable Complex type
class Complex
constructor: (@r=0, @i=0) ->
@magnitude = @r*@r + @i*@i
plus: (c2) ->
new Complex(
@r + c2.r,
@i + c2.i
)
times: (c2) ->
new Complex(
@r*c2.r - @i*c2.i,
@r*c2.i + @i*c2.r
)
negation: ->
new Complex(
-1 * @r,
-1 * @i
)
inverse: ->
throw Error "no inverse" if @magnitude is 0
new Complex(
@r / @magnitude,
-1 * @i / @magnitude
)
toString: ->
return "#{@r}" if @i == 0
return "#{@i}i" if @r == 0
if @i > 0
"#{@r} + #{@i}i"
else
"#{@r} - #{-1 * @i}i"
# test
do ->
a = new Complex(5, 3)
b = new Complex(4, -3)
sum = a.plus b
console.log "(#{a}) + (#{b}) = #{sum}"
product = a.times b
console.log "(#{a}) * (#{b}) = #{product}"
negation = b.negation()
console.log "-1 * (#{b}) = #{negation}"
diff = a.plus negation
console.log "(#{a}) - (#{b}) = #{diff}"
inverse = b.inverse()
console.log "1 / (#{b}) = #{inverse}"
quotient = product.times inverse
console.log "(#{product}) / (#{b}) = #{quotient}"

View file

@ -1,62 +1,68 @@
class Complex {
final Number real, imag
static final Complex I = [0,1] as Complex
static final Complex i = [0,1] as Complex
Complex(Number real) { this(real, 0) }
Complex(Number r, Number i = 0) { (real, imag) = [r, i] }
Complex(real, imag) { this.real = real; this.imag = imag }
Complex(Map that) { (real, imag) = [that.real ?: 0, that.imag ?: 0] }
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. */
/** 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 ) }
// could also use Math.sqrt( (this * (~this)).real )
Number getAbs() { Math.sqrt( real*real + imag*imag ) }
/** the magnitude of this complex number. */
Number abs() { this.abs }
/** the complex reciprocal of this complex number. */
Complex recip() { (~this) / ((this * (~this)).real) }
/** the reciprocal of this complex number. */
Complex getRecip() { (~this) / (ρ**2) }
/** the reciprocal of this complex number. */
Complex recip() { this.recip }
/** derived angle &#x03B8; (theta) for polar form.
* Normalized to 0 &#x2264; &#x03B8; < 2&#x03C0;. */
/** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
Number getTheta() {
def theta = Math.atan2(imag,real)
theta = theta < 0 ? theta + 2 * Math.PI : theta
def θ = Math.atan2(imag,real)
θ = θ < 0 ? θ + 2 * Math.PI : θ
}
/** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
Number getΘ() { this.theta } // this is greek uppercase theta
/** derived magnitude &#x03C1; (rho) for polar form. */
Number getRho() { this.abs() }
/** derived polar magnitude ρ (rho) for polar form. */
Number getRho() { this.abs }
/** derived polar magnitude ρ (rho) for polar form. */
Number getΡ() { this.abs } // this is greek uppercase rho, not roman P
/** 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
* converting [ρ, θ] inputs into a [real, imag]-based complex number */
static Complex fromPolar(Number ρ, Number θ) {
[ρ * Math.cos(θ), ρ * Math.sin(θ)] 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 magnitude ρ, but different angle θ */
Complex withTheta(Number θ) { fromPolar(this.rho, θ) }
/** Creates new complex with same magnitude ρ, but different angle θ */
Complex withΘ(Number θ) { fromPolar(this.rho, θ) }
/** Creates new complex with same angle &#x03B8;, but different magnitude &#x03C1; */
Complex withRho(Number rho) { fromPolar(rho, this.theta) }
/** Creates new complex with same angle θ, but different magnitude ρ */
Complex withRho(Number ρ) { fromPolar(ρ, this.θ) }
/** Creates new complex with same angle θ, but different magnitude ρ */
Complex withΡ(Number ρ) { fromPolar(ρ, this.θ) } // this is greek uppercase rho, not roman P
static Complex exp(Complex c) { fromPolar(Math.exp(c.real), c.imag) }
@ -72,10 +78,10 @@ class Complex {
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])
boolean equals(that) {
that != null && (that instanceof Complex \
? [this.real, this.imag] == [that.real, that.imag] \
: that instanceof Number && [this.real, this.imag] == [that, 0])
}
int hashCode() { [real, imag].hashCode() }

View file

@ -1,36 +1,17 @@
def tol = 0.000000001 // tolerance: acceptable "wrongness" to account for rounding error
import org.codehaus.groovy.runtime.DefaultGroovyMethods
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
class ComplexCategory {
static Complex getI (Number a) { [0, a] as Complex }
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()
static Complex plus (Number a, Complex b) { b + a }
static Complex minus (Number a, Complex b) { -b + a }
static Complex multiply (Number a, Complex b) { b * a }
static Complex div (Number a, Complex b) { ([a] as Complex) / b }
static Complex power (Number a, Complex b) { ([a] as Complex) ** b }
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()
static <T> T asType (Number a, Class<T> type) {
type == Complex \
? [a] as Complex
: DefaultGroovyMethods.asType(a, type)
}
}

View file

@ -0,0 +1,63 @@
import static Complex.*
Number.metaClass.mixin ComplexCategory
def ε = 0.000000001 // tolerance (epsilon): acceptable "wrongness" to account for rounding error
println 'Demo 1: functionality as requested'
def a = [5,3] as Complex
def a1 = [real:5, imag:3] as Complex
def a2 = 5 + 3.i
def a3 = 5 + 3*i
assert a == a1 && a == a2 && a == a3
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 < ε
println "1/a == (${a}).recip == " + (a.recip)
println "a * 1/a == " + (a * a.recip)
println()
println 'Demo 2: other functionality not requested, but important for completeness'
def c = 10
def d = 10 as Complex
assert d instanceof Complex && c instanceof Number && d == c
assert a + c == c + a
println "a + 10 == 10 + a == " + (c + a)
assert c - a == -(a - c)
println "10 - a == -(a - 10) == " + (c - a)
println "a - b == (${a}) - (${b}) == " + (a - b)
assert c * a == a * c
println "10 * a == a * 10 == " + (c * a)
assert (c / a - (a / c).recip).abs < ε
println "10 / a == 1 / (a / 10) == " + (c / a)
println "a / b == (${a}) / (${b}) == " + (a / b)
assert (a ** 2 - a * a).abs < ε
println "a ** 2 == a * a == " + (a ** 2)
println "0.9 ** b == " + (0.9 ** b)
println "a ** b == (${a}) ** (${b}) == " + (a ** b)
println 'a.real == ' + a.real
println 'a.imag == ' + a.imag
println '|a| == ' + a.abs
println 'a.rho == ' + a.rho
println 'a.ρ == ' + a.ρ
println 'a.theta == ' + a.theta
println 'a.θ == ' + a.θ
println '~a (conjugate) == ' + ~a
def ρ = 10
def π = Math.PI
def n = 3
def θ = π / n
def fromPolar1 = fromPolar(ρ, θ) // direct polar-to-cartesian conversion
def fromPolar2 = exp(θ.i) * ρ // Euler's equation
println "ρ*cos(θ) + i*ρ*sin(θ) == ${ρ}*cos(π/${n}) + i*${ρ}*sin(π/${n})"
println " == 10*0.5 + i*10*√(3/4) == " + fromPolar1
println "ρ*exp(i*θ) == ${ρ}*exp(i*π/${n}) == " + fromPolar2
assert (fromPolar1 - fromPolar2).abs < ε

View file

@ -0,0 +1,14 @@
import Data.Complex
main = do
let a = 1.0 :+ 2.0 -- complex number 1+2i
let b = 4 -- complex number 4+0i
-- 'b' is inferred to be complex because it's used in
-- arithmetic with 'a' below.
putStrLn $ "Add: " ++ show (a + b)
putStrLn $ "Subtract: " ++ show (a - b)
putStrLn $ "Multiply: " ++ show (a * b)
putStrLn $ "Divide: " ++ show (a / b)
putStrLn $ "Negate: " ++ show (-a)
putStrLn $ "Inverse: " ++ show (recip a)
putStrLn $ "Conjugate:" ++ show (conjugate a)

View file

@ -1,25 +1,23 @@
/*REXX program to show how to support math functions for complex numbers*/
x = '(5,3i)' /*this little piggy uses "I" (or "i") ···*/
y = '( .5, 6j)' /*this little piggy uses "J" (or "j") ···*/
x = '(5,3i)' /*this little piggy uses "I" (or "i") ... */
y = '( .5, 6j)' /*this little piggy uses "J" (or "j") ... */
sum = Cadd(x,y); say ' addition: ' x " + " y ' = ' sum
dif = Csub(x,y); say ' subtration: ' x " + " y ' = ' dif
prod = Cmul(x,y); say 'multiplication: ' x " * " y ' = ' prod
quot = Cdiv(x,y); say ' division: ' x " ÷ " y ' = ' quot
inv = Cinv(x); say ' inverse: ' x " = " inv
cnjX = Ccnj(x); say ' conjugate of: ' x " = " cnjX
negX = Cneg(x); say ' negation of: ' x " = " negX
sum = Cadd(x,y) ; say ' addition: ' x " + " y ' = ' sum
dif = Csub(x,y) ; say ' subtraction: ' x " + " y ' = ' dif
prod = Cmul(x,y) ; say 'multiplication: ' x " * " y ' = ' prod
quot = Cdiv(x,y) ; say ' division: ' x " ÷ " y ' = ' quot
inv = Cinv(x) ; say ' inverse: ' x " = " inv
cnjX = Ccnj(x) ; say ' conjugate of: ' x " = " cnjX
negX = Cneg(x) ; say ' negation of: ' x " = " negX
exit /*stick a fork in it, we're done.*/
/*─────────────────────────────────────one─liners───────────────────────*/
Ccnj: procedure;arg a ',' b,c ',' d;call Cg;r1=a;r2=-b;return Cr()
Cadd: procedure;arg a ',' b,c ',' d;call Cg;r1=a+c;r2=b+d;return Cr()
Csub: procedure;arg a ',' b,c ',' d;call Cg;r1=a-c;r2=b-d;return Cr()
Cmul: procedure;arg a ',' b,c ',' d;call Cg;r1=a*c-b*d; r2=b*c+a*d;return Cr()
Cdiv: procedure;arg a ',' b,c ',' d;call Cg;_=c*c+d*d;r1=(a*c+b*d)/_;r2=(b*c-a*d)/_;return Cr()
Cg: a=Cdej(a); b=Cdej(b); c=Cdej(c); d=Cdej(d); return
Cr: _='['r1; if r2\=0 then _=_','r2"j"; return _']'
Cdej: return word(translate(arg(1),,'{[(JI)]}') 0,1)
Cneg: return Cmul(arg(1),-1)
Cinv: return Cdiv(1,arg(1))
/*─────────────────────────────────────one─liners──────────────────────────────────────────────*/
Ccnj: procedure; arg a ',' b,c ',' d; call Cg; r1=a; r2=-b; return Cr()
Cadd: procedure; arg a ',' b,c ',' d; call Cg; r1=a+c; r2=b+d; return Cr()
Csub: procedure; arg a ',' b,c ',' d; call Cg; r1=a-c; r2=b-d; return Cr()
Cmul: procedure; arg a ',' b,c ',' d; call Cg; r1=a*c-b*d; r2=b*c+a*d; return Cr()
Cdiv: procedure; arg a ',' b,c ',' d; call Cg;_=c*c+d*d;r1=(a*c+b*d)/_;r2=(b*c-a*d)/_;return Cr()
Cdej: return word(translate(arg(1), , '{[(JI)]}') 0, 1)
Cg: a=Cdej(a); b=Cdej(b); c=Cdej(c); d=Cdej(d); return
Cinv: return Cdiv(1, arg(1))
Cneg: return Cmul(arg(1), -1)
Cr: _='['r1; if r2\=0 then _=_','r2"j"; return _']'

View file

@ -0,0 +1,75 @@
typeset -T Complex_t=(
float real=0
float imag=0
function to_s {
print -- "${_.real} + ${_.imag} i"
}
function dup {
nameref other=$1
_=( real=${other.real} imag=${other.imag} )
}
function add {
typeset varname
for varname; do
nameref other=$varname
(( _.real += other.real ))
(( _.imag += other.imag ))
done
}
function negate {
(( _.real *= -1 ))
(( _.imag *= -1 ))
}
function conjugate {
(( _.imag *= -1 ))
}
function multiply {
typeset varname
for varname; do
nameref other=$varname
float a=${_.real} b=${_.imag} c=${other.real} d=${other.imag}
(( _.real = a*c - b*d ))
(( _.imag = b*c + a*d ))
done
}
function inverse {
if (( _.real == 0 && _.imag == 0 )); then
print -u2 "division by zero"
return 1
fi
float denom=$(( _.real*_.real + _.imag*_.imag ))
(( _.real = _.real / denom ))
(( _.imag = -1 * _.imag / denom ))
}
)
Complex_t a=(real=1 imag=1)
a.to_s # 1 + 1 i
Complex_t b=(real=3.14159 imag=1.2)
b.to_s # 3.14159 + 1.2 i
Complex_t c
c.add a b
c.to_s # 4.14159 + 2.2 i
c.negate
c.to_s # -4.14159 + -2.2 i
c.conjugate
c.to_s # -4.14159 + 2.2 i
c.dup a
c.multiply b
c.to_s # 1.94159 + 4.34159 i
Complex_t d=(real=2 imag=1)
d.inverse
d.to_s # 0.4 + -0.2 i