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)) |