Arithmetic/Complex: Difference between revisions

→‎{{header|Groovy}}: Fixes breakage that occurred between versions. Current as of Groovy 3.0
m (→‎{{header|Julia}}: fix syntax highlighting markup)
(→‎{{header|Groovy}}: Fixes breakage that occurred between versions. Current as of Groovy 3.0)
Line 2,221:
<lang groovy>class Complex {
final Number real, imag
 
static final Complex i = [0,1] as Complex
 
Complex(Number r, Number i = 0) { (real, imag) = [r, i] }
 
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. */
Complex bitwiseNegate () { [real, -imag] as Complex }
 
/** the magnitude of this complex number. */
// could also use Math.sqrt( (this * (~this)).real )
Line 2,250:
/** the magnitude of this complex number. */
Number abs() { this.abs }
 
/** the reciprocal of this complex number. */
Complex getRecip() { (~this) / (ρ**2) }
/** the reciprocal of this complex number. */
Complex recip() { this.recip }
 
/** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
Number getTheta() {
Line 2,263:
/** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
Number getΘ() { this.theta } // this is greek uppercase theta
 
/** 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 [ρ, θ] inputs into a [real, imag]-based complex number */
Line 2,274:
[ρ * Math.cos(θ), ρ * Math.sin(θ)] as Complex
}
 
/** 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 θ, 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) }
 
static Complex log(Complex c) { [Math.log(c.rho), c.theta] as Complex }
 
Complex power(Complex c) {
thisdef == 0 && czero != [0] as \Complex
(this == zero && c != ? [0] as Complexzero) \
? zero \
: c == 1 \
? this \
: exp( log(this) * c )
}
 
Complex power(Number n) { this ** ([n, 0] as Complex) }
 
boolean equals(that) {
that != null && (that instanceof Complex \
Line 2,304 ⟶ 2,305:
: that instanceof Number && [this.real, this.imag] == [that, 0])
}
 
int hashCode() { [real, imag].hashCode() }
 
String toString() {
def realPart = "${real}"
Line 2,322 ⟶ 2,323:
The following ''ComplexCategory'' class allows for modification of regular ''Number'' behavior when interacting with ''Complex''.
<lang groovy>import org.codehaus.groovy.runtime.DefaultGroovyMethods
 
class ComplexCategory {
static Complex getI (Number a) { [0, a] as Complex }
 
static Complex plus (Number a, Complex b) { b + a }
static Complex minus (Number a, Complex b) { -b + a }
Line 2,331 ⟶ 2,332:
static Complex div (Number a, Complex b) { ([a] as Complex) / b }
static Complex power (Number a, Complex b) { ([a] as Complex) ** b }
static <N extends Number,T> T asType (NumberN a, Class<T> type) {
type == Complex \
? [a as Number] as Complex
: DefaultGroovyMethods.asType(a, type)
}
Line 2,342 ⟶ 2,343:
Test Program (mixes the ComplexCategory methods into the Number class):
<lang groovy>import static Complex.*
 
Number.metaClass.mixin ComplexCategory
Integer.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
Line 2,356 ⟶ 2,358:
def b = [0.5,6] as Complex
println 'b == ' + b
 
println "a + b == (${a}) + (${b}) == " + (a + b)
println "a * b == (${a}) * (${b}) == " + (a * b)
Line 2,365 ⟶ 2,367:
println "a * 1/a == " + (a * a.recip)
println()
 
println 'Demo 2: other functionality not requested, but important for completeness'
def c = 10
Line 2,392 ⟶ 2,394:
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
Line 2,424 ⟶ 2,426:
a ** 2 == a * a == 16.000000000000004 + 30.000000000000007i
0.9 ** b == 0.7653514303676113 - 0.5605686291920475i
a ** b == (5 + 3i) ** (0.5 + 6i) == -0.013750112198456855013750112198456853 - 0.09332524760169053i09332524760169052i
a.real == 5
a.imag == 3
Anonymous user