;;; cfl.ms ;;; Copyright 1984-2017 Cisco Systems, Inc. ;;; ;;; Licensed under the Apache License, Version 2.0 (the "License"); ;;; you may not use this file except in compliance with the License. ;;; You may obtain a copy of the License at ;;; ;;; http://www.apache.org/licenses/LICENSE-2.0 ;;; ;;; Unless required by applicable law or agreed to in writing, software ;;; distributed under the License is distributed on an "AS IS" BASIS, ;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ;;; See the License for the specific language governing permissions and ;;; limitations under the License. (define *fuzz* 1e-14) (define ~= (lambda (x y) (or (= x y) (and (fl~= (inexact (real-part x)) (inexact (real-part y))) (fl~= (inexact (imag-part x)) (inexact (imag-part y))))))) (define fl~= (lambda (x y) (cond [(and (fl>= (flabs x) 2.0) (fl>= (flabs y) 2.0)) (fl~= (fl/ x 2.0) (fl/ y 2.0))] [(and (fl< 0.0 (flabs x) 1.0) (fl< 0.0 (flabs y) 1.0)) (fl~= (fl* x 2.0) (fl* y 2.0))] [else (let ([d (flabs (fl- x y))]) (or (fl<= d *fuzz*) (begin (printf "fl~~=: ~s~%" d) #f)))]))) (define cfl~= (lambda (x y) (and (fl~= (cfl-real-part x) (cfl-real-part y)) (fl~= (cfl-imag-part x) (cfl-imag-part y))))) (define zero 0.0) (define a 1.1) (define b +1.1i) (define c 1.1+1.1i) (define aa 1.21) (define ab +1.21i) (define ac 1.21+1.21i) (define bb -1.21) (define bc -1.21+1.21i) (define cc +2.42i) (mat cflonum? (not (cflonum? 3)) (not (cflonum? 18/2)) (not (cflonum? 1+0i)) (not (cflonum? 23084982309482034820348023423048230482304)) (not (cflonum? 203480234802384/23049821)) (not (cflonum? -3/4)) (not (cflonum? -1)) (not (cflonum? 0)) (not (cflonum? -12)) (cflonum? 3.5) (cflonum? 1.8e-10) (cflonum? -3e5) (cflonum? -1231.2344) (cflonum? 3+5.0i) (cflonum? 1.8e10@10) (cflonum? -3e5+1.0i) (cflonum? -1.0i) (cflonum? +1.0i) (not (cflonum? 'a)) (not (cflonum? "hi")) (not (cflonum? (cons 3 4))) (cflonum? a) (cflonum? b) (cflonum? c) ) (mat fl-make-rectangular (error? (fl-make-rectangular 3 'a)) (error? (fl-make-rectangular 'b 4)) (error? (fl-make-rectangular 3 -4)) (eqv? (fl-make-rectangular 3.0 -4.0) 3.0-4.0i) (eqv? (fl-make-rectangular a a) c) ) (mat cfl-real-part (error? (cfl-real-part 'a)) (error? (cfl-real-part 3/2)) (eqv? (cfl-real-part 3.2) 3.2) (eqv? (cfl-real-part -1.0+2.0i) -1.0) (eqv? (cfl-real-part a) a) (eqv? (cfl-real-part c) a) (eqv? (cfl-real-part b) zero) ) (mat cfl-imag-part (error? (cfl-imag-part 'a)) (error? (cfl-imag-part -3)) (eqv? (cfl-imag-part 3.2) zero) (eqv? (cfl-imag-part -1.0+2.0i) 2.0) (eqv? (cfl-imag-part a) zero) (eqv? (cfl-imag-part c) a) (eqv? (cfl-imag-part b) a) ) (mat cfl-conjugate (error? (cfl-conjugate 'a)) (eqv? (cfl-conjugate 3.2) 3.2) (eqv? (cfl-conjugate 3.2+2.0i) 3.2-2.0i) (eqv? (cfl-conjugate a) a) (eqv? (cfl-conjugate c) (+ a (- b))) (eqv? (cfl-conjugate b) -1.1i) ) (mat conjugate (error? (conjugate 'a)) (eqv? (conjugate 3.2) 3.2) (eqv? (conjugate 3.2+2.0i) 3.2-2.0i) ) (mat cfl-magnitude-squared (error? (cfl-magnitude-squared 'a)) (eqv? (cfl-magnitude-squared 3.2) (fl* 3.2 3.2)) (eqv? (cfl-magnitude-squared 3.5-2.0i) 16.25) (fl~= (cfl-magnitude-squared 3.5@2.0) 12.25) ) (mat magnitude-squared (error? (magnitude-squared 'a)) (eqv? (magnitude-squared 3.5) 12.25) (eqv? (magnitude-squared 3.5-2.0i) 16.25) (fl~= (magnitude-squared 3.5@2.0) 12.25) ) (mat cfl+ (error? (cfl+ 'a)) (error? (cfl+ 'a 3)) (error? (cfl+ 'a 3 4)) (eqv? (cfl+) zero) (eqv? (cfl+ a) a) (eqv? (cfl+ b) b) (eqv? (cfl+ c) c) (eqv? (cfl+ a b) c) (cfl~= (cfl+ a b c) (cfl+ a (cfl+ b c))) (cfl~= (cfl+ a b c a b c) (cfl+ (cfl+ a b c) (cfl+ a b c))) (cfl~= (cfl+ 1+2.0i 3.0) 4.0+2.0i) (cfl~= (cfl+ 1.0+2.2i -3.7+5.3i) -2.7+7.5i) (cfl~= (cfl+ 1.0+2.2i -3.7) -2.7+2.2i) (cfl~= (cfl+ 1.0 -3.7+5.3i) -2.7+5.3i) (cfl~= (cfl+ 1.0+2.2i +5.3i) 1.0+7.5i) (cfl~= (cfl+ +2.2i -3.7+5.3i) -3.7+7.5i) (cfl~= (cfl+ 26.0 2.0) 28.0) (test-cp0-expansion eqv? '(cfl+) zero) (test-cp0-expansion eqv? `(cfl+ ,a) a) (test-cp0-expansion eqv? `(cfl+ ,b) b) (test-cp0-expansion eqv? `(cfl+ ,c) c) (test-cp0-expansion eqv? `(cfl+ ,a ,b) c) (test-cp0-expansion cfl~= `(cfl+ ,a ,b ,c) (cfl+ a (cfl+ b c))) (test-cp0-expansion cfl~= `(cfl+ ,a ,b ,c ,a ,b ,c) (cfl+ (cfl+ a b c) (cfl+ a b c))) (test-cp0-expansion cfl~= '(cfl+ 1+2.0i 3.0) 4.0+2.0i) (test-cp0-expansion cfl~= '(cfl+ 1.0+2.2i -3.7+5.3i) -2.7+7.5i) (test-cp0-expansion cfl~= '(cfl+ 1.0+2.2i -3.7) -2.7+2.2i) (test-cp0-expansion cfl~= '(cfl+ 1.0 -3.7+5.3i) -2.7+5.3i) (test-cp0-expansion cfl~= '(cfl+ 1.0+2.2i +5.3i) 1.0+7.5i) (test-cp0-expansion cfl~= '(cfl+ +2.2i -3.7+5.3i) -3.7+7.5i) (test-cp0-expansion cfl~= '(cfl+ 26.0 2.0) 28.0) ) (mat cfl- (error? (cfl- 'a)) (error? (cfl- 'a 3)) (error? (cfl- 'a 3 4)) (error? (cfl-)) (eqv? (cfl- a) -1.1) (eqv? (cfl- b) -0.0-1.1i) (eqv? (cfl- c) -1.1-1.1i) (eqv? (cfl- a a) zero) (cfl~= (cfl- b b) zero) (cfl~= (cfl- c c) zero) (eqv? (cfl- c a) b) (cfl~= (cfl- c b) a) (cfl~= (cfl- a b c) (cfl- (cfl- a b) c)) (cfl~= (cfl- a b c a b c) (cfl- a (cfl+ b c a b c))) (cfl~= (cfl- 1+2.0i 3.0) -2.0+2.0i) (cfl~= (cfl- 1.0+2.2i -3.7+5.3i) 4.7-3.1i) (cfl~= (cfl- 1.0+2.2i -3.7) 4.7+2.2i) (cfl~= (cfl- 1.0 -3.7+5.3i) 4.7-5.3i) (cfl~= (cfl- 1.0+2.2i +5.3i) 1.0-3.1i) (cfl~= (cfl- +2.2i -3.7+5.3i) 3.7-3.1i) (cfl~= (cfl- 26.0 2.0) 24.0) (andmap (lambda (a) (andmap (lambda (b) (andmap (lambda (c) (eqv? (cfl- a b c) (cfl- (cfl- a b) c))) '(0.0 -0.0))) '(0.0 -0.0))) '(0.0 -0.0)) (let () (define-syntax ff (syntax-rules () [(_ k1 k2) (lambda (x) (eqv? (cfl- k1 x k2) (cfl- (cfl- k1 x) k2)))])) (andmap (lambda (p) (and (p +0.0) (p -0.0))) (list (ff +0.0 +0.0) (ff +0.0 -0.0) (ff -0.0 +0.0) (ff -0.0 -0.0)))) (error? (cfl- 3.0 5.4 'a)) (error? (cfl- 'a 3.0 5.4)) (error? (cfl- 3.0 'a 5.4)) (eqv? (cfl- 5.0 4.0 3.0 2.0) -4.0) (eqv? (cfl- 5.0 4.0 3.0 2.0 1.0 0.0 -1.0 -2.0) -2.0) (cfl~= (cfl- 1e30 1e30 7.0) -7.0) (test-cp0-expansion eqv? `(cfl- ,a) -1.1) (test-cp0-expansion eqv? `(cfl- ,b) -0.0-1.1i) (test-cp0-expansion eqv? `(cfl- ,c) -1.1-1.1i) (test-cp0-expansion eqv? `(cfl- ,a ,a) zero) (test-cp0-expansion cfl~= `(cfl- ,b ,b) zero) (test-cp0-expansion cfl~= `(cfl- ,c ,c) zero) (test-cp0-expansion eqv? `(cfl- ,c ,a) b) (test-cp0-expansion cfl~= `(cfl- ,c ,b) a) (test-cp0-expansion cfl~= `(cfl- ,a ,b ,c) (cfl- (cfl- a b) c)) (test-cp0-expansion cfl~= `(cfl- ,a ,b ,c ,a ,b ,c) (cfl- a (cfl+ b c a b c))) (test-cp0-expansion cfl~= '(cfl- 1+2.0i 3.0) -2.0+2.0i) (test-cp0-expansion cfl~= '(cfl- 1.0+2.2i -3.7+5.3i) 4.7-3.1i) (test-cp0-expansion cfl~= '(cfl- 1.0+2.2i -3.7) 4.7+2.2i) (test-cp0-expansion cfl~= '(cfl- 1.0 -3.7+5.3i) 4.7-5.3i) (test-cp0-expansion cfl~= '(cfl- 1.0+2.2i +5.3i) 1.0-3.1i) (test-cp0-expansion cfl~= '(cfl- +2.2i -3.7+5.3i) 3.7-3.1i) (test-cp0-expansion cfl~= '(cfl- 26.0 2.0) 24.0) (test-cp0-expansion eqv? '(cfl- 5.0 4.0 3.0 2.0) -4.0) (test-cp0-expansion eqv? '(cfl- 5.0 4.0 3.0 2.0 1.0 0.0 -1.0 -2.0) -2.0) (test-cp0-expansion cfl~= '(cfl- 1e30 1e30 7.0) -7.0) ) (mat cfl* (error? (cfl* 'a)) (error? (cfl* 'a 3)) (error? (cfl* 'a 3 4)) (eqv? (cfl*) 1.0) (eqv? (cfl* a) a) (eqv? (cfl* b) b) (eqv? (cfl* c) c) (eqv? (cfl* zero a) zero) (cfl~= (cfl* zero b) zero) (cfl~= (cfl* zero c) zero) (cfl~= (cfl* a a) aa) (cfl~= (cfl* a b) ab) (cfl~= (cfl* a c) ac) (cfl~= (cfl* b b) bb) (cfl~= (cfl* b c) bc) (cfl~= (cfl* c c) cc) (cfl~= (cfl* a b c) (cfl* a (cfl* b c))) (cfl~= (cfl* a b c a b c) (cfl* (cfl* a b c) (cfl* a b c))) (cfl~= (cfl* 1+2.0i 3.0) 3.0+6.0i) (cfl~= (cfl* 1.0+2.0i 3.0+4.0i) -5.0+10.0i) (cfl~= (cfl* 1.0+2.0i 3.0) 3.0+6.0i) (cfl~= (cfl* -2.0 3.0+4.0i) -6.0-8.0i) (cfl~= (cfl* 1.0+2.0i +4.0i) -8.0+4.0i) (cfl~= (cfl* +2.0i 3.0+4.0i) -8.0+6.0i) (cfl~= (cfl* 26.0 2.0) 52.0) (test-cp0-expansion eqv? '(cfl*) 1.0) (test-cp0-expansion eqv? `(cfl* ,a) a) (test-cp0-expansion eqv? `(cfl* ,b) b) (test-cp0-expansion eqv? `(cfl* ,c) c) (test-cp0-expansion eqv? `(cfl* ,zero ,a) zero) (test-cp0-expansion cfl~= `(cfl* ,zero ,b) zero) (test-cp0-expansion cfl~= `(cfl* ,zero ,c) zero) (test-cp0-expansion cfl~= `(cfl* ,a ,a) aa) (test-cp0-expansion cfl~= `(cfl* ,a ,b) ab) (test-cp0-expansion cfl~= `(cfl* ,a ,c) ac) (test-cp0-expansion cfl~= `(cfl* ,b ,b) bb) (test-cp0-expansion cfl~= `(cfl* ,b ,c) bc) (test-cp0-expansion cfl~= `(cfl* ,c ,c) cc) (test-cp0-expansion cfl~= `(cfl* ,a ,b ,c) (cfl* a (cfl* b c))) (test-cp0-expansion cfl~= `(cfl* ,a ,b ,c ,a ,b ,c) (cfl* (cfl* a b c) (cfl* a b c))) (test-cp0-expansion cfl~= '(cfl* 1+2.0i 3.0) 3.0+6.0i) (test-cp0-expansion cfl~= '(cfl* 1.0+2.0i 3.0+4.0i) -5.0+10.0i) (test-cp0-expansion cfl~= '(cfl* 1.0+2.0i 3.0) 3.0+6.0i) (test-cp0-expansion cfl~= '(cfl* -2.0 3.0+4.0i) -6.0-8.0i) (test-cp0-expansion cfl~= '(cfl* 1.0+2.0i +4.0i) -8.0+4.0i) (test-cp0-expansion cfl~= '(cfl* +2.0i 3.0+4.0i) -8.0+6.0i) (test-cp0-expansion cfl~= '(cfl* 26.0 2.0) 52.0) ) (mat cfl/ (error? (cfl/ 'a)) (error? (cfl/ 'a 3)) (error? (cfl/ 'a 3 4)) (error? (cfl/)) (fl~= (cfl/ a) (fl/ a)) (eqv? (cfl/ zero a) zero) (cfl~= (cfl/ zero b) zero) (cfl~= (cfl/ zero c) zero) (cfl~= (cfl/ a a) 1.0) (cfl~= (cfl/ b b) 1.0) (cfl~= (cfl/ c c) 1.0) (cfl~= (cfl/ aa a) a) (cfl~= (cfl/ ab b) a) (cfl~= (cfl/ ab a) b) (cfl~= (cfl/ ac c) a) (cfl~= (cfl/ ac a) c) (cfl~= (cfl/ bc c) b) (cfl~= (cfl/ bc b) c) (cfl~= (cfl/ cc c) c) (cfl~= (cfl/ a b c) (cfl/ (cfl/ a b) c)) (cfl~= (cfl/ a b c a b c) (cfl/ a (cfl* b c a b c))) (cfl~= (cfl/ 3+6.0i 3.0) 1.0+2.0i) (cfl~= (cfl/ -5.0+10.0i 1.0+2.0i) 3.0+4.0i) (cfl~= (cfl/ -6.0-8.0i -2.0) 3.0+4.0i) (cfl~= (cfl/ 26.0 3.0-2.0i) 6.0+4.0i) (cfl~= (cfl/ -8.0+6.0i +2.0i) 3.0+4.0i) (cfl~= (cfl/ +26.0i 3.0+2.0i) 4.0+6.0i) (cfl~= (cfl/ 26.0 2.0) 13.0) (andmap (lambda (a) (andmap (lambda (b) (andmap (lambda (c) (eqv? (cfl/ a b c) (cfl/ (cfl/ a b) c))) '(1e300 1e250))) '(1e300 1e250))) '(1e300 1e250)) (error? (cfl/ 3.0 5.4 'a)) (error? (cfl/ 'a 3.0 5.4)) (error? (cfl/ 3.0 'a 5.4)) (eqv? (cfl/ 16.0 2.0 -2.0 2.0) -2.0) (eqv? (cfl/ 16.0 2.0 -2.0 2.0 4.0 1.0 -1.0) 0.5) (test-cp0-expansion eqv? `(cfl/ ,zero ,a) zero) (test-cp0-expansion eqv? '(cfl/ 16.0 2.0 -2.0 2.0) -2.0) (test-cp0-expansion eqv? '(cfl/ 16.0 2.0 -2.0 2.0 4.0 1.0 -1.0) 0.5) (test-cp0-expansion cfl~= `(cfl/ ,zero ,b) zero) (test-cp0-expansion cfl~= `(cfl/ ,zero ,c) zero) (test-cp0-expansion cfl~= `(cfl/ ,a ,a) 1.0) (test-cp0-expansion cfl~= `(cfl/ ,b ,b) 1.0) (test-cp0-expansion cfl~= `(cfl/ ,c ,c) 1.0) (test-cp0-expansion cfl~= `(cfl/ ,aa ,a) a) (test-cp0-expansion cfl~= `(cfl/ ,ab ,b) a) (test-cp0-expansion cfl~= `(cfl/ ,ab ,a) b) (test-cp0-expansion cfl~= `(cfl/ ,ac ,c) a) (test-cp0-expansion cfl~= `(cfl/ ,ac ,a) c) (test-cp0-expansion cfl~= `(cfl/ ,bc ,c) b) (test-cp0-expansion cfl~= `(cfl/ ,bc ,b) c) (test-cp0-expansion cfl~= `(cfl/ ,cc ,c) c) (test-cp0-expansion cfl~= `(cfl/ ,a ,b ,c) (cfl/ (cfl/ a b) c)) (test-cp0-expansion cfl~= `(cfl/ ,a ,b ,c ,a ,b ,c) (cfl/ a (cfl* b c a b c))) (test-cp0-expansion cfl~= '(cfl/ 3+6.0i 3.0) 1.0+2.0i) (test-cp0-expansion cfl~= '(cfl/ -5.0+10.0i 1.0+2.0i) 3.0+4.0i) (test-cp0-expansion cfl~= '(cfl/ -6.0-8.0i -2.0) 3.0+4.0i) (test-cp0-expansion cfl~= '(cfl/ 26.0 3.0-2.0i) 6.0+4.0i) (test-cp0-expansion cfl~= '(cfl/ -8.0+6.0i +2.0i) 3.0+4.0i) (test-cp0-expansion cfl~= '(cfl/ +26.0i 3.0+2.0i) 4.0+6.0i) (test-cp0-expansion cfl~= '(cfl/ 26.0 2.0) 13.0) ) (mat cfl= (error? (cfl= 'a)) (error? (cfl= 'a 3)) (error? (cfl= 'a 3 4)) (error? (cfl=)) (cfl= a a) (cfl= b b) (cfl= c c) (cfl= (- c c) zero) (cfl= (+ a b) c) (not (cfl= a b)) (cfl= 1.1+1.1i c) (cfl= c 1.1+1.1i c) (not (cfl= c 1.1+1.1i c a)) (not (cfl= 3+6.0i 3.0)) (not (cfl= 3+6.0i +6.0i)) (cfl= 1.0+2.0i 1.0+2.0i) (cfl= 5.4 5.4) )