;;;; math-utils-vector-test.scm -*- Scheme -*- ;;;; Kon Lovett, Jul '23 (import test) (import (only (chicken format) format) (test-utils gloss)) ;;; (test-begin "Math Utils Vector") (import (math-utils vector)) ;;; (import (chicken string)) (import (chicken fixnum)) (import (chicken random)) (import (only vector-lib vector-unfold)) ;; ;https://en.wikipedia.org/wiki/Cosine_similarity (define (cosine-similarity/reference a b) (/ (dot-product a b) (* (absolute-magnitude a) (absolute-magnitude b))) ) #; (repeat-random (100) (let*-random ((len 1000) (a (vector-of real len)) (b (vector-of real len)) ) (test "\"fast\" cosine-similarity eqv cosine-similarity reference" (cosine-similarity/reference a b) (cosine-similarity a b)) ) ) (define (make-random-real-vector len #!optional (zeros? #f) (rnd pseudo-random-real)) (vector-unfold (lambda _ #;(i . seeds) (let loop ((trys 10)) (let ((n (rnd))) (if (or (not (zero? n)) zeros?) n (if (fx< trys 0) 1 (loop (fx- trys 1)))) ) ) ) len) ) ;; (test-group "cosine-similarity \"fast\" = reference w/ random length & real values" (let loop ((cnt (pseudo-random-integer 25))) (unless (fx= 0 cnt) (let* ((len (pseudo-random-integer 10000)) (a (make-random-real-vector len)) (b (make-random-real-vector len)) ) (test (conc "Length " len) (exact->inexact (cosine-similarity/reference a b)) (exact->inexact (cosine-similarity a b))) (loop (fx- cnt 1)) ) ) ) ) (test-group "operations" (test 10 (dot-product #(1 2 3) #(3 2 1))) (test-group "any X empty is 0" (test 0 (cross-product #() #())) (test 0 (cross-product #() #(3))) (test 0 (cross-product #(1) #())) ) (test 3 (cross-product #(1) #(3))) (test -4 (cross-product #(1 2) #(3 2))) (test #(-4 8 -4) (cross-product #(1 2 3) #(3 2 1))) ) (test-group "vector apply" (define (vector-mul . vs) (apply vector-apply * vs)) (define (vector-add . vs) (apply vector-apply + vs)) (define (vector-dif . vs) (apply vector-apply - vs)) (test #(4 4 4) (vector-add #(1 2 3) #(3 2 1))) (test #(3 4 3) (vector-mul #(1 2 3) #(3 2 1))) (test "cmp" #(-2 0 2) (vector-dif #(1 2 3) #(3 2 1))) ) (test-group "vector reduce" ;use of inf.0 as `seed' w/ max/min causes inexact result! ;(define (vector/max v) (vector-reduce max -inf.0 v)) ;(define (vector/min v) (vector-reduce min +inf.0 v)) (define (vector/max v) (vector-reduce max (vector-ref v 0) v 1)) (define (vector/min v) (vector-reduce min (vector-ref v 0) v 1)) (test 3 (vector/max #(1 2 3))) (test 1 (vector/min #(1 2 3))) ) (test-group "compare" (test "diff len" 1 (vector-compare #(1 2 3 4) #(3 2 1))) (test "<" -2 (vector-compare #(1 2 3) #(3 2 1))) (test "=" 0 (vector-compare #(3 2 1) #(3 2 1))) (test ">" 2 (vector-compare #(3 2 1) #(1 2 3))) (test "multi <" -5 (vector-compare #(-2 0 2) #(3 2 1) #(1 2 3))) (test "multi =" 0 (vector-compare #(1 2 3) #(1 2 3) #(1 2 3))) (test "multi >" 2 (vector-compare #(3 2 1) #(1 2 3) #(-2 0 2))) ) (test-group "softmax" (parameterize ((current-test-epsilon 0.001)) ;2 places precision of input (test 0.0 (vector-compare #(0.01 0.00 0.03 0.09 0.61 0.00 0.25) (softmax #(-0.8 -5.0 +0.5 +1.5 +3.4 -2.3 +2.5)))) (test 0.0 (vector-compare #(0.00 0.00 0.00 0.00 0.99 0.01 0.00) (softmax #(-0.8 -5.0 +0.5 +1.5 +8.5 -2.3 +2.5)))) ) ) (test-group "softmax w/ temp" (parameterize ((current-test-epsilon 0.001)) ;2 places precision of input (test "same when temp = 1" 0.0 (vector-compare #(0.01 0.00 0.03 0.09 0.61 0.00 0.25) (softmax* #(-0.8 -5.0 +0.5 +1.5 +3.4 -2.3 +2.5)))) ;(gloss (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 6.57)) (test "temp > 1" 0.0 (vector-compare #(0.19 0.04 0.14 0.10 0.34 0.05 0.14) (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 6.57))) ;(gloss (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 0.5)) (test "temp < 1" 0.0 (vector-compare #(0.0 0.0 0.0 0.0 0.99957 0.0 0.0) (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 0.5))) #; (gloss (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 0)) #; (test "temp = 0" 0.0 (vector-compare #(0.19 0.04 0.14 0.10 0.34 0.05 0.14) (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 0))) (test-error "temp = 0 (error for now)" (softmax* #(+6.0 -5.0 +4.0 +1.5 +9.9 -2.3 +4.0) 0)) ) ) ;;; (test-end "Math Utils Vector") (test-exit)