|
309 | 309 | ((Matrix Real) (Matrix Real) -> Real) |
310 | 310 | ((Matrix Float-Complex) (Matrix Float-Complex) -> Float-Complex) |
311 | 311 | ((Matrix Number) (Matrix Number) -> Number))) |
312 | | -(define (matrix-cos-angle M N) |
313 | | - (/ (matrix-dot M N) (* (matrix-2norm M) (matrix-2norm N)))) |
314 | | - |
315 | | -(: matrix-angle (case-> ((Matrix Float-Complex) (Matrix Float-Complex) -> Float-Complex) |
| 312 | +(define matrix-cos-angle |
| 313 | + (let () |
| 314 | + (define (mag² [x : Number]) (if (real? x) (sqr x) (+ (sqr (real-part x)) (sqr (imag-part x))))) |
| 315 | + (define (inf=>1 [x : Real]) : Flonum (if (eq? x +inf.0) 1. (if (eq? x -inf.0) -1. 0.))) |
| 316 | + (: cinf=>1 (case-> (-> Real Flonum) |
| 317 | + (-> Float-Complex Float-Complex) |
| 318 | + (-> Number Number))) |
| 319 | + (define (cinf=>1 x) |
| 320 | + (if (real? x) |
| 321 | + (inf=>1 x) |
| 322 | + (make-flrectangular (inf=>1 (real-part x)) |
| 323 | + (inf=>1 (imag-part x))))) |
| 324 | + (: unit-bound (case-> (-> Flonum Flonum) |
| 325 | + (-> Real Real))) |
| 326 | + (define (unit-bound x) |
| 327 | + (if (flonum? x) |
| 328 | + (flmin (flmax -1. x) 1.) |
| 329 | + (min (max -1 x) 1))) |
| 330 | + (: inner (case-> ((Matrix Flonum) (Matrix Flonum) -> Flonum) |
| 331 | + ((Matrix Real) (Matrix Real) -> Real) |
| 332 | + ((Matrix Float-Complex) (Matrix Float-Complex) -> Float-Complex) |
| 333 | + ((Matrix Number) (Matrix Number) -> Number))) |
| 334 | + (define (inner A* B*) |
| 335 | + (define nA (sqrt (array-all-sum (inline-array-map mag² A*)))) |
| 336 | + (define nB (sqrt (array-all-sum (inline-array-map mag² B*)))) |
| 337 | + |
| 338 | + (define result (/ (matrix-dot A* B*) (* nA nB))) |
| 339 | + |
| 340 | + (if (real? result) |
| 341 | + (unit-bound result) |
| 342 | + (make-rectangular (unit-bound (real-part result)) |
| 343 | + (unit-bound (imag-part result))))) |
| 344 | + (λ (A B) |
| 345 | + (define mA (array-strict (inline-array-map nonstupid-magnitude A))) |
| 346 | + (define mB (array-strict (inline-array-map nonstupid-magnitude B))) |
| 347 | + (define mxA (array-all-max mA)) |
| 348 | + (define mxB (array-all-max mB)) |
| 349 | + |
| 350 | + (cond |
| 351 | + [(and (rational? mxA) (positive? mxA) |
| 352 | + (rational? mxB) (positive? mxB)) |
| 353 | + (define A* (inline-array-map (λ (x) (/ x mxA)) A)) |
| 354 | + (define B* (inline-array-map (λ (x) (/ x mxB)) B)) |
| 355 | + |
| 356 | + (inner A* B*)] |
| 357 | + [(or (nan? mxA) (nan? mxB) (= 0 mxA) (= 0 mxB)) |
| 358 | + (/ (matrix-dot A B) (* mxA mxB))] |
| 359 | + [else |
| 360 | + (define A* (if (rational? mxA) |
| 361 | + (inline-array-map (λ (x) (/ x mxA)) A) |
| 362 | + (array-strict (inline-array-map cinf=>1 A)))) |
| 363 | + (define B* (if (rational? mxB) |
| 364 | + (inline-array-map (λ (x) (/ x mxB)) B) |
| 365 | + (array-strict (inline-array-map cinf=>1 B)))) |
| 366 | + (inner A* B*)])))) |
| 367 | + |
| 368 | +(: matrix-angle (case-> ((Matrix Flonum) (Matrix Flonum) -> Flonum) |
| 369 | + ((Matrix Real) (Matrix Real) -> Real) |
| 370 | + ((Matrix Float-Complex) (Matrix Float-Complex) -> Float-Complex) |
316 | 371 | ((Matrix Number) (Matrix Number) -> Number))) |
317 | | -(define (matrix-angle M N) |
318 | | - (acos (matrix-cos-angle M N))) |
| 372 | +(define (matrix-angle A B) |
| 373 | + (define ca (matrix-cos-angle A B)) |
| 374 | + (cond |
| 375 | + [(flonum? ca) (flacos ca)] |
| 376 | + [(real? ca) |
| 377 | + (if (eq? ca 1) 0 (flacos (fl ca)))] |
| 378 | + [else (acos ca)])) |
319 | 379 |
|
320 | 380 | (: matrix-normalize |
321 | 381 | (All (A) (case-> ((Matrix Flonum) -> (Matrix Flonum)) |
|
0 commit comments