| 1: | | (declare (fixnum)) |
| 2: | | |
| 3: | | (define volume-map |
| 4: | | '((4 skip) |
| 5: | | (23 inactive) |
| 6: | | (16 active) |
| 7: | | (16 inactive) |
| 8: | | (16 active) |
| 9: | | (16 inactive) |
| 10: | | (16 active) |
| 11: | | (16 inactive) |
| 12: | | (16 active) |
| 13: | | (21 inactive))) |
| 14: | | |
| 15: | | (define (create-volume-indices types) |
| 16: | | (let loop ((volume-map volume-map) |
| 17: | | (next-index 0) |
| 18: | | (result '())) |
| 19: | | (if (null? volume-map) |
| 20: | | (list->vector (reverse result)) |
| 21: | | (let* ((volume-number-and-type (car volume-map)) |
| 22: | | (volume-type (cadr volume-number-and-type)) |
| 23: | | (volume-number (car volume-number-and-type))) |
| 24: | | (if (memq volume-type types) |
| 25: | | (do ((i next-index (+ i 1)) |
| 26: | | (j 0 (+ j 1)) |
| 27: | | (result result (cons i result))) |
| 28: | | ((= j volume-number) (loop (cdr volume-map) |
| 29: | | i |
| 30: | | result))) |
| 31: | | (loop (cdr volume-map) |
| 32: | | (+ next-index volume-number) |
| 33: | | result)))))) |
| 34: | | |
| 35: | | (define active-volume-indices (create-volume-indices '(active))) |
| 36: | | (define inactive-volume-indices (create-volume-indices '(inactive))) |
| 37: | | |
| 38: | | (define (get-volumes-from-indices data volume-indices) |
| 39: | | (let ((domain (Fixed-array-domain data)) |
| 40: | | (indexer (Fixed-array-indexer data))) |
| 41: | | (call-with-values |
| 42: | | (lambda () (Interval-curry domain 1)) |
| 43: | | (lambda (left-interval right-interval) |
| 44: | | (build-Array (build-Interval '#(0) |
| 45: | | (vector (vector-length volume-indices))) |
| 46: | | (lambda (i) |
| 47: | | (Fixed-array-share! data |
| 48: | | right-interval |
| 49: | | (lambda (j k l) |
| 50: | 0% | (values (vector-ref volume-indices i) j k l))))))))) |
| 51: | | |
| 52: | | (define (make-covariance a00 a01 a10 a11) |
| 53: | | (let ((body (f64vector a00 a01 a10 a11))) |
| 54: | | (lambda (i j) |
| 55: | | (f64vector-ref body (+ (* 2 i) j))))) |
| 56: | | |
| 57: | | (define (add-covariance S1 S2) |
| 58: | | (declare (flonum)) |
| 59: | | (make-covariance (+ (S1 0 0) (S2 0 0)) |
| 60: | | (+ (S1 0 1) (S2 0 1)) |
| 61: | | (+ (S1 1 0) (S2 1 0)) |
| 62: | | (+ (S1 1 1) (S2 1 1)))) |
| 63: | | |
| 64: | | (define (scale-covariance a S) |
| 65: | | (declare (flonum)) |
| 66: | | (make-covariance (* a (S 0 0)) |
| 67: | | (* a (S 0 1)) |
| 68: | | (* a (S 1 0)) |
| 69: | | (* a (S 1 1)))) |
| 70: | | |
| 71: | | (define (complex-compute-volume-moments active-or-inactive-data) |
| 72: | | (let ((result (Array-map generic-array-manipulators |
| 73: | | (lambda (v) |
| 74: | | (f64vector 0. 0. 0. 0. 0.)) |
| 75: | | ((Array-accessor active-or-inactive-data) 0)))) |
| 76: | | (Array-for-each (lambda (volume) |
| 77: | | (Array-for-each (lambda (value result) |
| 78: | | (let ((real (Complex-real value)) |
| 79: | | (imag (Complex-imag value))) |
| 80: | | (f64vector-set! result 0 (FLOAT (+ (f64vector-ref result 0) real))) |
| 81: | | (f64vector-set! result 1 (FLOAT (+ (f64vector-ref result 1) imag))) |
| 82: | | (f64vector-set! result 2 (FLOAT (+ (f64vector-ref result 2) (* real real)))) |
| 83: | | (f64vector-set! result 3 (FLOAT (+ (f64vector-ref result 3) (* imag imag)))) |
| 84: | | (f64vector-set! result 4 (FLOAT (+ (f64vector-ref result 4) (* real imag)))))) |
| 85: | | volume result)) |
| 86: | | active-or-inactive-data) |
| 87: | | result)) |
| 88: | | |
| 89: | | (define (complex-calculate-means-and-covariance moments number-of-volumes) |
| 90: | | (declare (flonum)) |
| 91: | | (let ((real (f64vector-ref moments 0)) |
| 92: | | (imag (f64vector-ref moments 1)) |
| 93: | | (real*real (f64vector-ref moments 2)) |
| 94: | | (imag*imag (f64vector-ref moments 3)) |
| 95: | | (real*imag (f64vector-ref moments 4)) |
| 96: | | (imag*real (f64vector-ref moments 4))) ;;; just for symmetry |
| 97: | | (let ((real-mean (/ real number-of-volumes)) |
| 98: | | (imag-mean (/ imag number-of-volumes))) |
| 99: | | (let ((covariance (make-covariance (/ (- real*real (* number-of-volumes real-mean real-mean)) (- number-of-volumes 1.0)) |
| 100: | | (/ (- real*imag (* number-of-volumes real-mean imag-mean)) (- number-of-volumes 1.0)) |
| 101: | | (/ (- imag*real (* number-of-volumes imag-mean real-mean)) (- number-of-volumes 1.0)) |
| 102: | | (/ (- imag*imag (* number-of-volumes imag-mean imag-mean)) (- number-of-volumes 1.0))))) |
| 103: | | (values real-mean imag-mean covariance))))) |
| 104: | | |
| 105: | | (define (complex-compute-active-regions data) |
| 106: | | (let ((active-moments (complex-compute-volume-moments (get-volumes-from-indices data active-volume-indices))) |
| 107: | | (inactive-moments (complex-compute-volume-moments (get-volumes-from-indices data inactive-volume-indices))) |
| 108: | | (number-of-active-volumes (exact->inexact (vector-length active-volume-indices))) |
| 109: | | (number-of-inactive-volumes (exact->inexact (vector-length inactive-volume-indices)))) |
| 110: | | (Array-map generic-array-manipulators |
| 111: | | (lambda (active inactive) |
| 112: | | (declare (flonum)) |
| 113: | | (let-values (((real-mean-active imag-mean-active active-covariance) (complex-calculate-means-and-covariance active number-of-active-volumes)) |
| 114: | | ((real-mean-inactive imag-mean-inactive inactive-covariance) (complex-calculate-means-and-covariance inactive number-of-inactive-volumes))) |
| 115: | | (let ((real-difference (- real-mean-active real-mean-inactive)) |
| 116: | | (imag-difference (- imag-mean-active imag-mean-inactive)) |
| 117: | | (S (scale-covariance (/ (+ number-of-active-volumes number-of-inactive-volumes -2.0)) |
| 118: | | (add-covariance (scale-covariance (- number-of-active-volumes 1.0) active-covariance) |
| 119: | | (scale-covariance (- number-of-inactive-volumes 1.0) inactive-covariance))))) |
| 120: | | (let ((determinant (- (* (S 0 0) (S 1 1)) |
| 121: | | (* (S 0 1) (S 1 0))))) |
| 122: | | (let ((S-inverse (scale-covariance (/ determinant) (make-covariance (S 1 1) (- (S 1 0)) |
| 123: | | (- (S 0 1)) (S 0 0))))) |
| 124: | | (let ((T^2 (* (/ (* number-of-active-volumes number-of-inactive-volumes) |
| 125: | | (+ number-of-active-volumes number-of-inactive-volumes)) |
| 126: | | (+ (* real-difference real-difference (S-inverse 0 0)) |
| 127: | | (* real-difference imag-difference (S-inverse 0 1)) |
| 128: | | (* imag-difference real-difference (S-inverse 1 0)) |
| 129: | | (* imag-difference imag-difference (S-inverse 1 1)))))) |
| 130: | | (> (* (/ (+ number-of-active-volumes number-of-inactive-volumes -3.0) |
| 131: | | (* (+ number-of-active-volumes number-of-inactive-volumes -2.0) 2.0)) |
| 132: | | T^2) |
| 133: | | 7.24 ;; 99.9% |
| 134: | | ;; 4.75 99% |
| 135: | | ;; 3.06 95% |
| 136: | | ))))))) |
| 137: | | active-moments |
| 138: | | inactive-moments))) |
| 139: | | |
| 140: | | (define (real-compute-volume-moments active-or-inactive-data) |
| 141: | | (let ((result (Array-map generic-array-manipulators |
| 142: | | (lambda (v) |
| 143: | .02% | (f64vector 0. 0.)) |
| 144: | | ((Array-accessor active-or-inactive-data) 0)))) |
| 145: | | (Array-for-each (lambda (volume) |
| 146: | 0% | (Array-for-each (lambda (value result) |
| 147: | 2.35% | (f64vector-set! result 0 (FLOAT (+ (f64vector-ref result 0) value))) |
| 148: | 2.46% | (f64vector-set! result 1 (FLOAT (+ (f64vector-ref result 1) (* value value))))) |
| 149: | | volume result)) |
| 150: | | active-or-inactive-data) |
| 151: | | result)) |
| 152: | | |
| 153: | | (define (real-calculate-mean-and-covariance moments number-of-volumes) |
| 154: | | (declare (flonum)) |
| 155: | .02% | (let ((real (f64vector-ref moments 0)) |
| 156: | .01% | (real*real (f64vector-ref moments 1))) |
| 157: | .02% | (let ((real-mean (/ real number-of-volumes))) |
| 158: | .03% | (let ((covariance (/ (- real*real (* number-of-volumes real-mean real-mean)) (- number-of-volumes 1.0)))) |
| 159: | .02% | (values real-mean covariance))))) |
| 160: | | |
| 161: | | (define (real-compute-active-regions data) |
| 162: | | (let ((active-moments (real-compute-volume-moments (get-volumes-from-indices data active-volume-indices))) |
| 163: | | (inactive-moments (real-compute-volume-moments (get-volumes-from-indices data inactive-volume-indices))) |
| 164: | | (number-of-active-volumes (exact->inexact (vector-length active-volume-indices))) |
| 165: | | (number-of-inactive-volumes (exact->inexact (vector-length inactive-volume-indices)))) |
| 166: | | (Array-map generic-array-manipulators |
| 167: | | (lambda (active inactive) |
| 168: | | (declare (flonum)) |
| 169: | .12% | (let-values (((mean-active active-covariance) (real-calculate-mean-and-covariance active number-of-active-volumes)) |
| 170: | | ((mean-inactive inactive-covariance) (real-calculate-mean-and-covariance inactive number-of-inactive-volumes))) |
| 171: | | (let ((difference (- mean-active mean-inactive)) |
| 172: | | (S (* (/ (+ number-of-active-volumes number-of-inactive-volumes -2.0)) |
| 173: | | (+ (* (- number-of-active-volumes 1.0) active-covariance) |
| 174: | | (* (- number-of-inactive-volumes 1.0) inactive-covariance))))) |
| 175: | | (let ((T^2 (* (/ (* number-of-active-volumes number-of-inactive-volumes) |
| 176: | | (+ number-of-active-volumes number-of-inactive-volumes)) |
| 177: | | (* difference difference (/ S))))) |
| 178: | | (> (* (/ (+ number-of-active-volumes number-of-inactive-volumes -2.0) |
| 179: | | (+ number-of-active-volumes number-of-inactive-volumes -2.0)) |
| 180: | | T^2) |
| 181: | | 11.26 ;; 99.9% |
| 182: | | ;; 6.81 99% |
| 183: | | ;; 3.90 95% |
| 184: | | ))))) |
| 185: | | active-moments |
| 186: | | inactive-moments))) |
| 187: | | |
| 188: | | (declare (generic)) |