Skip to content

Commit a942dbd

Browse files
committed
hypercomplex-complex division
1 parent 0765050 commit a942dbd

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Ready
22

3-
* hypercomplex division
3+
* real-hypercomplex division
44
* complex, hypercomplex exp
55
* operations on rgb values
66
* operations on hypercomplex values

aiscm/hypercomplex.scm

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<hypercomplex<>>
2626
<hypercomplex<float>> <meta<hypercomplex<float>>> <hypercomplex<float<single>>> <meta<hypercomplex<float<single>>>>
2727
<hypercomplex<double>> <meta<hypercomplex<double>>> <hypercomplex<float<double>>> <meta<hypercomplex<float<double>>>>)
28-
#:re-export (real-part imag-part equal? + - abs conj))
28+
#:re-export (real-part imag-part equal? + - abs conj * /))
2929

3030

3131
(define-class <hypercomplex> ()
@@ -132,3 +132,33 @@
132132
(hypercomplex (* (real-part a) b) (* (imag-part a) b) (* (jmag-part a) b) (* (kmag-part a) b)))
133133
(define-method (* (a <scalar>) (b <hypercomplex<>>))
134134
(hypercomplex (* a (real-part b)) (* a (imag-part b)) (* a (jmag-part b)) (* a (kmag-part b))))
135+
136+
(define (hypercomplex-inverse a)
137+
(jit-let [(d1 (- (real-part a) (kmag-part a)))
138+
(d2 (+ (imag-part a) (jmag-part a)))
139+
(d3 (+ (real-part a) (kmag-part a)))
140+
(d4 (- (imag-part a) (jmag-part a)))
141+
(denom (* (+ (* d1 d1) (* d2 d2)) (+ (* d3 d3) (* d4 d4))))
142+
(squares (+ (* (real-part a) (real-part a))
143+
(* (imag-part a) (imag-part a))
144+
(* (jmag-part a) (jmag-part a))
145+
(* (kmag-part a) (kmag-part a))))
146+
(cross (- (* (real-part a) (kmag-part a)) (* (imag-part a) (jmag-part a))))
147+
(c1 (* (kmag-part a) cross))
148+
(c2 (* (jmag-part a) cross))
149+
(c3 (* (imag-part a) cross))
150+
(c4 (* (real-part a) cross))]
151+
(hypercomplex (/ (- (* (real-part a) squares) (+ c1 c1)) denom)
152+
(/ (- (- (* (imag-part a) squares)) (+ c2 c2)) denom)
153+
(/ (- (- (* (jmag-part a) squares)) (+ c3 c3)) denom)
154+
(/ (- (* (kmag-part a) squares) (+ c4 c4)) denom))))
155+
(define (complex-inverse a)
156+
(jit-let [(denom (+ (* (real-part a) (real-part a)) (* (imag-part a) (imag-part a))))]
157+
(complex (/ (real-part a) denom) (/ (- (imag-part a)) denom))))
158+
159+
(define-method (/ (a <hypercomplex<>>) (b <hypercomplex<>>))
160+
(jit-let [(inverse (hypercomplex-inverse b))] (* a inverse)))
161+
(define-method (/ (a <hypercomplex<>>) (b <complex<>>))
162+
(jit-let [(inverse (complex-inverse b))] (* a inverse)))
163+
(define-method (/ (a <complex<>>) (b <hypercomplex<>>))
164+
(jit-let [(inverse (hypercomplex-inverse b))] (* a inverse)))

etc/playground.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
(use-modules (srfi srfi-1) (oop goops) (aiscm core) (aiscm util) (aiscm hypercomplex))
22

3+
; // http://mathworld.wolfram.com/HypercomplexNumber.html
4+
35
(define (hypercomplex-inverse a)
46
(jit-let [(d1 (- (real-part a) (kmag-part a)))
57
(d2 (+ (imag-part a) (jmag-part a)))

tests/test_hypercomplex.scm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,23 @@
166166
(test-equal "multiply hypercomplex and real number"
167167
(make-hypercomplex 4.0 6.0 10.0 14.0) ((jit (list (hypercomplex <float>) <float>) *) (make-hypercomplex 2 3 5 7) 2)))
168168

169+
(test-group "hypercomplex division"
170+
(let [(f (jit (list (hypercomplex <float>) (hypercomplex <float>)) /))]
171+
(test-approximate "real part is one when dividing number by itself"
172+
1.0 (real-part (f (make-hypercomplex 2 3 5 7) (make-hypercomplex 2 3 5 7))) 0.001)
173+
(test-approximate "imaginary part is zero when dividing number by itself"
174+
0.0 (imag-part (f (make-hypercomplex 2 3 5 7) (make-hypercomplex 2 3 5 7))) 0.001)
175+
(test-approximate "jmaginary part is zero when dividing number by itself"
176+
0.0 (jmag-part (f (make-hypercomplex 2 3 5 7) (make-hypercomplex 2 3 5 7))) 0.001)
177+
(test-approximate "kmaginary part is zero when dividing number by itself"
178+
0.0 (kmag-part (f (make-hypercomplex 2 3 5 7) (make-hypercomplex 2 3 5 7))) 0.001))
179+
(let [(f (jit (list (hypercomplex <float>) (complex <float>)) /))]
180+
(test-approximate "real part is one for trivial hypercomplex-complex division"
181+
1.0 (real-part (f (make-hypercomplex 2 3 0 0) 2+3i)) 0.001))
182+
(let [(f (jit (list (complex <float>) (hypercomplex <float>)) /))]
183+
(test-approximate "real part is one for trivial complex-hypercomplex division"
184+
1.0 (real-part (f 2+3i (make-hypercomplex 2 3 0 0))) 0.001)))
185+
169186
(test-group "hypercomplex properties"
170187
(test-equal "hypercomplex absolute value"
171188
4.0 ((jit (list (hypercomplex <float>)) abs) (make-hypercomplex 2 2 -2 -2)))

0 commit comments

Comments
 (0)