srfi-25.scm (42123B)
1 ;;;; srfi-25.scm - Jussi Piitulainen's array library 2 3 4 (define array:array-tag (list 'array)) 5 6 (define (array:make vec ind shp) (vector array:array-tag vec ind shp)) 7 (define (array:array? x) (and (vector? x) (eq? (vector-ref x 0) array:array-tag))) 8 (define (array:vector a) (vector-ref a 1)) 9 (define (array:index a) (vector-ref a 2)) 10 (define (array:shape a) (vector-ref a 3)) 11 12 13 ;;; array 14 ;;; 1997 - 2001 Jussi Piitulainen 15 16 17 ;;; --- Intro --- 18 19 ;;; This interface to arrays is based on Alan Bawden's array.scm of 20 ;;; 1993 (earlier version in the Internet Repository and another 21 ;;; version in SLIB). This is a complete rewrite, to be consistent 22 ;;; with the rest of Scheme and to make arrays independent of lists. 23 24 ;;; Some modifications are due to discussion in srfi-25 mailing list. 25 26 ;;; (array? obj) 27 ;;; (make-array shape [obj]) changed arguments 28 ;;; (shape bound ...) new 29 ;;; (array shape obj ...) new 30 ;;; (array-rank array) changed name back 31 ;;; (array-start array dimension) new 32 ;;; (array-end array dimension) new 33 ;;; (array-ref array k ...) 34 ;;; (array-ref array index) new variant 35 ;;; (array-set! array k ... obj) changed argument order 36 ;;; (array-set! array index obj) new variant 37 ;;; (share-array array shape proc) changed arguments 38 39 ;;; All other variables in this file have names in "array:". 40 41 ;;; Should there be a way to make arrays with initial values mapped 42 ;;; from indices? Sure. The current "initial object" is lame. 43 ;;; 44 ;;; Removed (array-shape array) from here. There is a new version 45 ;;; in arlib though. 46 47 ;;; --- Representation type dependencies --- 48 49 ;;; The mapping from array indices to the index to the underlying vector 50 ;;; is whatever array:optimize returns. The file "opt" provides three 51 ;;; representations: 52 ;;; 53 ;;; mbda) mapping is a procedure that allows an optional argument 54 ;;; tter) mapping is two procedures that takes exactly the indices 55 ;;; ctor) mapping is a vector of a constant term and coefficients 56 ;;; 57 ;;; Choose one in "opt" to make the optimizer. Then choose the matching 58 ;;; implementation of array-ref and array-set!. 59 ;;; 60 ;;; These should be made macros to inline them. Or have a good compiler 61 ;;; and plant the package as a module. 62 63 ;;; 1. Pick an optimizer. 64 ;;; 2. Pick matching index representation. 65 ;;; 3. Pick a record implementation; as-procedure is generic; syntax inlines. 66 ;;; 3. This file is otherwise portable. 67 68 ;;; --- Portable R5RS (R4RS and multiple values) --- 69 70 ;;; (array? obj) 71 ;;; returns #t if `obj' is an array and #t or #f otherwise. 72 73 (define (array? obj) 74 (array:array? obj)) 75 76 (define-syntax check-array 77 (syntax-rules () 78 ((_ x loc) 79 (let ((var x)) 80 (or (##core#check (array:array? var)) 81 (##sys#signal-hook #:type-error loc (##core#immutable '"bad argument type - not an array") var) ) ) ) ) ) 82 83 ;;; (make-array shape) 84 ;;; (make-array shape obj) 85 ;;; makes array of `shape' with each cell containing `obj' initially. 86 87 (define (make-array shape . rest) 88 (or (##core#check (array:good-shape? shape)) 89 (##sys#signal-hook #:type-error 'make-array "bad argument type - not a valid shape" shape)) 90 (apply array:make-array shape rest)) 91 92 (define (array:make-array shape . rest) 93 (let ((size (array:size shape))) 94 (array:make 95 (if (pair? rest) 96 (apply (lambda (o) (make-vector size o)) rest) 97 (make-vector size)) 98 (if (= size 0) 99 (array:optimize-empty 100 (vector-ref (array:shape shape) 1)) 101 (array:optimize 102 (array:make-index shape) 103 (vector-ref (array:shape shape) 1))) 104 (array:shape->vector shape)))) 105 106 ;;; (shape bound ...) 107 ;;; makes a shape. Bounds must be an even number of exact, pairwise 108 ;;; non-decreasing integers. Note that any such array can be a shape. 109 110 (define (shape . bounds) 111 (let ((v (list->vector bounds))) 112 (or (##core#check (even? (vector-length v))) 113 (##sys#error 'shape "uneven number of bounds" bounds) ) 114 (let ((shp (array:make 115 v 116 (if (pair? bounds) 117 (array:shape-index) 118 (array:empty-shape-index)) 119 (vector 0 (quotient (vector-length v) 2) 120 0 2)))) 121 (or (##core#check (array:good-shape? shp)) 122 (##sys#signal-hook #:type-error 'shape "bounds are not pairwise non-decreasing exact integers" bounds) ) 123 shp))) 124 125 ;;; (array shape obj ...) 126 ;;; is analogous to `vector'. 127 128 (define (array shape . elts) 129 (or (##core#check (array:good-shape? shape)) 130 (##sys#signal-hook #:type-error 'array "bad argument type - not a valid shape" shape) ) 131 (let ((size (array:size shape))) 132 (let ((vector (list->vector elts))) 133 (or (##core#check (= (vector-length vector) size)) 134 (##sys#error 'array "bad number of elements" shape elts) ) 135 (array:make 136 vector 137 (if (= size 0) 138 (array:optimize-empty 139 (vector-ref (array:shape shape) 1)) 140 (array:optimize 141 (array:make-index shape) 142 (vector-ref (array:shape shape) 1))) 143 (array:shape->vector shape))))) 144 145 ;;; (array-rank array) 146 ;;; returns the number of dimensions of `array'. 147 148 (define (array-rank array) 149 (check-array array 'array-rank) 150 (quotient (vector-length (array:shape array)) 2)) 151 152 ;;; (array-start array k) 153 ;;; returns the lower bound index of array along dimension k. This is 154 ;;; the least valid index along that dimension if the dimension is not 155 ;;; empty. 156 157 (define (array-start array d) 158 (check-array array 'array-start) 159 (vector-ref (array:shape array) (+ d d))) 160 161 ;;; (array-end array k) 162 ;;; returns the upper bound index of array along dimension k. This is 163 ;;; not a valid index. If the dimension is empty, this is the same as 164 ;;; the lower bound along it. 165 166 (define (array-end array d) 167 (check-array array 'array-end) 168 (vector-ref (array:shape array) (+ d d 1))) 169 170 ;;; (share-array array shape proc) 171 ;;; makes an array that shares elements of `array' at shape `shape'. 172 ;;; The arguments to `proc' are indices of the result. The values of 173 ;;; `proc' are indices of `array'. 174 175 ;;; Todo: in the error message, should recognise the mapping and show it. 176 177 (define (share-array array subshape f) 178 (check-array array 'share-array) 179 (or (##core#check (array:good-shape? subshape)) 180 (##sys#signal-hook #:type-error 'share-array "not a shape" subshape) ) 181 (let ((subsize (array:size subshape))) 182 (or (##core#check (array:good-share? subshape subsize f (array:shape array))) 183 (##sys#error 'share-array "subshape does not map into supershape" subshape shape) ) 184 (let ((g (array:index array))) 185 (array:make 186 (array:vector array) 187 (if (= subsize 0) 188 (array:optimize-empty 189 (vector-ref (array:shape subshape) 1)) 190 (array:optimize 191 (lambda ks 192 (call-with-values 193 (lambda () (apply f ks)) 194 (lambda ks (array:vector-index g ks)))) 195 (vector-ref (array:shape subshape) 1))) 196 (array:shape->vector subshape))))) 197 198 ;;; --- Hrmph --- 199 200 ;;; (array:share/index! ...) 201 ;;; reuses a user supplied index object when recognising the 202 ;;; mapping. The mind balks at the very nasty side effect that 203 ;;; exposes the implementation. So this is not in the spec. 204 ;;; But letting index objects in at all creates a pressure 205 ;;; to go the whole hog. Arf. 206 207 ;;; Use array:optimize-empty for an empty array to get a 208 ;;; clearly invalid vector index. 209 210 ;;; Surely it's perverse to use an actor for index here? But 211 ;;; the possibility is provided for completeness. 212 213 (define (array:share/index! array subshape proc index) 214 (array:make 215 (array:vector array) 216 (if (= (array:size subshape) 0) 217 (array:optimize-empty 218 (quotient (vector-length (array:shape array)) 2)) 219 ((if (vector? index) 220 array:optimize/vector 221 array:optimize/actor) 222 (lambda (subindex) 223 (let ((superindex (proc subindex))) 224 (if (vector? superindex) 225 (array:index/vector 226 (quotient (vector-length (array:shape array)) 2) 227 (array:index array) 228 superindex) 229 (array:index/array 230 (quotient (vector-length (array:shape array)) 2) 231 (array:index array) 232 (array:vector superindex) 233 (array:index superindex))))) 234 index)) 235 (array:shape->vector subshape))) 236 237 (define (array:optimize/vector f v) 238 (let ((r (vector-length v))) 239 (do ((k 0 (+ k 1))) 240 ((= k r)) 241 (vector-set! v k 0)) 242 (let ((n0 (f v)) 243 (cs (make-vector (+ r 1))) 244 (apply (array:applier-to-vector (+ r 1)))) 245 (vector-set! cs 0 n0) 246 (let wok ((k 0)) 247 (if (< k r) 248 (let ((k1 (+ k 1))) 249 (vector-set! v k 1) 250 (let ((nk (- (f v) n0))) 251 (vector-set! v k 0) 252 (vector-set! cs k1 nk) 253 (wok k1))))) 254 (apply (array:maker r) cs)))) 255 256 (define (array:optimize/actor f a) 257 (let ((r (array-end a 0)) 258 (v (array:vector a)) 259 (i (array:index a))) 260 (do ((k 0 (+ k 1))) 261 ((= k r)) 262 (vector-set! v (array:actor-index i k) 0)) 263 (let ((n0 (f a)) 264 (cs (make-vector (+ r 1))) 265 (apply (array:applier-to-vector (+ r 1)))) 266 (vector-set! cs 0 n0) 267 (let wok ((k 0)) 268 (if (< k r) 269 (let ((k1 (+ k 1)) 270 (t (array:actor-index i k))) 271 (vector-set! v t 1) 272 (let ((nk (- (f a) n0))) 273 (vector-set! v t 0) 274 (vector-set! cs k1 nk) 275 (wok k1))))) 276 (apply (array:maker r) cs)))) 277 278 ;;; --- Internals --- 279 280 (define (array:shape->vector shape) 281 (let ((idx (array:index shape)) 282 (shv (array:vector shape)) 283 (rnk (vector-ref (array:shape shape) 1))) 284 (let ((vec (make-vector (* rnk 2)))) 285 (do ((k 0 (+ k 1))) 286 ((= k rnk) 287 vec) 288 (vector-set! vec (+ k k) 289 (vector-ref shv (array:shape-vector-index idx k 0))) 290 (vector-set! vec (+ k k 1) 291 (vector-ref shv (array:shape-vector-index idx k 1))))))) 292 293 ;;; (array:size shape) 294 ;;; returns the number of elements in arrays of shape `shape'. 295 296 (define (array:size shape) 297 (let ((idx (array:index shape)) 298 (shv (array:vector shape)) 299 (rnk (vector-ref (array:shape shape) 1))) 300 (do ((k 0 (+ k 1)) 301 (s 1 (* s 302 (- (vector-ref shv (array:shape-vector-index idx k 1)) 303 (vector-ref shv (array:shape-vector-index idx k 0)))))) 304 ((= k rnk) s)))) 305 306 ;;; (array:make-index shape) 307 ;;; returns an index function for arrays of shape `shape'. This is a 308 ;;; runtime composition of several variable arity procedures, to be 309 ;;; passed to array:optimize for recognition as an affine function of 310 ;;; as many variables as there are dimensions in arrays of this shape. 311 312 (define (array:make-index shape) 313 (let ((idx (array:index shape)) 314 (shv (array:vector shape)) 315 (rnk (vector-ref (array:shape shape) 1))) 316 (do ((f (lambda () 0) 317 (lambda (k . ks) 318 (+ (* s (- k (vector-ref 319 shv 320 (array:shape-vector-index idx (- j 1) 0)))) 321 (apply f ks)))) 322 (s 1 (* s (- (vector-ref 323 shv 324 (array:shape-vector-index idx (- j 1) 1)) 325 (vector-ref 326 shv 327 (array:shape-vector-index idx (- j 1) 0))))) 328 (j rnk (- j 1))) 329 ((= j 0) 330 f)))) 331 332 333 ;;; --- Error checking --- 334 335 ;;; (array:good-shape? shape) 336 ;;; returns true if `shape' is an array of the right shape and its 337 ;;; elements are exact integers that pairwise bound intervals `[lo..hi)´. 338 339 (define (array:good-shape? shape) 340 (and (array:array? shape) 341 (let ((u (array:shape shape)) 342 (v (array:vector shape)) 343 (x (array:index shape))) 344 (and (= (vector-length u) 4) 345 (= (vector-ref u 0) 0) 346 (= (vector-ref u 2) 0) 347 (= (vector-ref u 3) 2)) 348 (let ((p (vector-ref u 1))) 349 (do ((k 0 (+ k 1)) 350 (true #t (let ((lo (vector-ref 351 v 352 (array:shape-vector-index x k 0))) 353 (hi (vector-ref 354 v 355 (array:shape-vector-index x k 1)))) 356 (and true 357 (integer? lo) 358 (exact? lo) 359 (integer? hi) 360 (exact? hi) 361 (<= lo hi))))) 362 ((= k p) true)))))) 363 364 ;;; (array:good-share? subv subsize mapping superv) 365 ;;; returns true if the extreme indices in the subshape vector map 366 ;;; into the bounds in the supershape vector. 367 368 ;;; If some interval in `subv' is empty, then `subv' is empty and its 369 ;;; image under `f' is empty and it is trivially alright. One must 370 ;;; not call `f', though. 371 372 (define (array:good-share? subshape subsize f super) 373 (or (zero? subsize) 374 (letrec 375 ((sub (array:vector subshape)) 376 (dex (array:index subshape)) 377 (ck (lambda (k ks) 378 (if (zero? k) 379 (call-with-values 380 (lambda () (apply f ks)) 381 (lambda qs (array:good-indices? qs super))) 382 (and (ck (- k 1) 383 (cons (vector-ref 384 sub 385 (array:shape-vector-index 386 dex 387 (- k 1) 388 0)) 389 ks)) 390 (ck (- k 1) 391 (cons (- (vector-ref 392 sub 393 (array:shape-vector-index 394 dex 395 (- k 1) 396 1)) 397 1) 398 ks))))))) 399 (let ((rnk (vector-ref (array:shape subshape) 1))) 400 (or (array:unchecked-share-depth? rnk) 401 (ck rnk '())))))) 402 403 ;;; Check good-share on 10 dimensions at most. The trouble is, 404 ;;; the cost of this check is exponential in the number of dimensions. 405 406 (define (array:unchecked-share-depth? rank) 407 (if (> rank 10) 408 (begin 409 (display `(warning: unchecked depth in share: 410 ,rank subdimensions)) 411 (newline) 412 #t) 413 #f)) 414 415 ;;; (array:check-indices caller indices shape-vector) 416 ;;; (array:check-indices.o caller indices shape-vector) 417 ;;; (array:check-index-vector caller index-vector shape-vector) 418 ;;; return if the index is in bounds, else signal error. 419 ;;; 420 ;;; Shape-vector is the internal representation, with 421 ;;; b and e for dimension k at 2k and 2k + 1. 422 423 (define (array:check-indices who ks shv) 424 (or (array:good-indices? ks shv) 425 (##sys#signal-hook #:bounds-error (array:not-in who ks shv)))) 426 427 (define (array:check-indices.o who ks shv) 428 (or (array:good-indices.o? ks shv) 429 (##sys#signal-hook #:bounds-error (array:not-in who (reverse (cdr (reverse ks))) shv)))) 430 431 (define (array:check-index-vector who ks shv) 432 (or (array:good-index-vector? ks shv) 433 (##sys#signal-hook #:bounds-error (array:not-in who (vector->list ks) shv)))) 434 435 (define (array:check-index-actor who ks shv) 436 (let ((shape (array:shape ks))) 437 (or (and (= (vector-length shape) 2) 438 (= (vector-ref shape 0) 0)) 439 (##sys#signal-hook #:type-error "not an actor")) 440 (or (array:good-index-actor? 441 (vector-ref shape 1) 442 (array:vector ks) 443 (array:index ks) 444 shv) 445 (array:not-in who (do ((k (vector-ref shape 1) (- k 1)) 446 (m '() (cons (vector-ref 447 (array:vector ks) 448 (array:actor-index 449 (array:index ks) 450 (- k 1))) 451 m))) 452 ((= k 0) m)) 453 shv)))) 454 455 (define (array:good-indices? ks shv) 456 (let ((d2 (vector-length shv))) 457 (do ((kp ks (if (pair? kp) 458 (cdr kp))) 459 (k 0 (+ k 2)) 460 (true #t (and true (pair? kp) 461 (array:good-index? (car kp) shv k)))) 462 ((= k d2) 463 (and true (null? kp)))))) 464 465 (define (array:good-indices.o? ks.o shv) 466 (let ((d2 (vector-length shv))) 467 (do ((kp ks.o (if (pair? kp) 468 (cdr kp))) 469 (k 0 (+ k 2)) 470 (true #t (and true (pair? kp) 471 (array:good-index? (car kp) shv k)))) 472 ((= k d2) 473 (and true (pair? kp) (null? (cdr kp))))))) 474 475 (define (array:good-index-vector? ks shv) 476 (let ((r2 (vector-length shv))) 477 (and (= (* 2 (vector-length ks)) r2) 478 (do ((j 0 (+ j 1)) 479 (k 0 (+ k 2)) 480 (true #t (and true 481 (array:good-index? (vector-ref ks j) shv k)))) 482 ((= k r2) true))))) 483 484 (define (array:good-index-actor? r v i shv) 485 (and (= (* 2 r) (vector-length shv)) 486 (do ((j 0 (+ j 1)) 487 (k 0 (+ k 2)) 488 (true #t (and true 489 (array:good-index? (vector-ref 490 v 491 (array:actor-index i j)) 492 shv 493 k)))) 494 ((= j r) true)))) 495 496 ;;; (array:good-index? index shape-vector 2d) 497 ;;; returns true if index is within bounds for dimension 2d/2. 498 499 (define (array:good-index? w shv k) 500 (and (integer? w) 501 (exact? w) 502 (<= (vector-ref shv k) w) 503 (< w (vector-ref shv (+ k 1))))) 504 505 (define (array:not-in who ks shv) 506 (##sys#signal-hook #:bounds-error (string-append who ": index not in bounds") ks shv) ) 507 508 509 (begin 510 (define (array:coefficients f n0 vs vp) 511 (case vp 512 ((()) '()) 513 (else 514 (set-car! vp 1) 515 (let ((n (- (apply f vs) n0))) 516 (set-car! vp 0) 517 (cons n (array:coefficients f n0 vs (cdr vp))))))) 518 (define (array:vector-index x ks) 519 (do ((sum 0 (+ sum (* (vector-ref x k) (car ks)))) 520 (ks ks (cdr ks)) 521 (k 0 (+ k 1))) 522 ((null? ks) (+ sum (vector-ref x k))))) 523 (define (array:shape-index) '#(2 1 0)) 524 (define (array:empty-shape-index) '#(0 0 -1)) 525 (define (array:shape-vector-index x r k) 526 (+ 527 (* (vector-ref x 0) r) 528 (* (vector-ref x 1) k) 529 (vector-ref x 2))) 530 (define (array:actor-index x k) 531 (+ (* (vector-ref x 0) k) (vector-ref x 1))) 532 (define (array:0 n0) (vector n0)) 533 (define (array:1 n0 n1) (vector n1 n0)) 534 (define (array:2 n0 n1 n2) (vector n1 n2 n0)) 535 (define (array:3 n0 n1 n2 n3) (vector n1 n2 n3 n0)) 536 (define (array:n n0 n1 n2 n3 n4 . ns) 537 (apply vector n1 n2 n3 n4 (append ns (list n0)))) 538 (define (array:maker r) 539 (case r 540 ((0) array:0) 541 ((1) array:1) 542 ((2) array:2) 543 ((3) array:3) 544 (else array:n))) 545 (define array:indexer/vector 546 (let ((em 547 (vector 548 (lambda (x i) (+ (vector-ref x 0))) 549 (lambda (x i) 550 (+ 551 (* (vector-ref x 0) (vector-ref i 0)) 552 (vector-ref x 1))) 553 (lambda (x i) 554 (+ 555 (* (vector-ref x 0) (vector-ref i 0)) 556 (* (vector-ref x 1) (vector-ref i 1)) 557 (vector-ref x 2))) 558 (lambda (x i) 559 (+ 560 (* (vector-ref x 0) (vector-ref i 0)) 561 (* (vector-ref x 1) (vector-ref i 1)) 562 (* (vector-ref x 2) (vector-ref i 2)) 563 (vector-ref x 3))) 564 (lambda (x i) 565 (+ 566 (* (vector-ref x 0) (vector-ref i 0)) 567 (* (vector-ref x 1) (vector-ref i 1)) 568 (* (vector-ref x 2) (vector-ref i 2)) 569 (* (vector-ref x 3) (vector-ref i 3)) 570 (vector-ref x 4))) 571 (lambda (x i) 572 (+ 573 (* (vector-ref x 0) (vector-ref i 0)) 574 (* (vector-ref x 1) (vector-ref i 1)) 575 (* (vector-ref x 2) (vector-ref i 2)) 576 (* (vector-ref x 3) (vector-ref i 3)) 577 (* (vector-ref x 4) (vector-ref i 4)) 578 (vector-ref x 5))) 579 (lambda (x i) 580 (+ 581 (* (vector-ref x 0) (vector-ref i 0)) 582 (* (vector-ref x 1) (vector-ref i 1)) 583 (* (vector-ref x 2) (vector-ref i 2)) 584 (* (vector-ref x 3) (vector-ref i 3)) 585 (* (vector-ref x 4) (vector-ref i 4)) 586 (* (vector-ref x 5) (vector-ref i 5)) 587 (vector-ref x 6))) 588 (lambda (x i) 589 (+ 590 (* (vector-ref x 0) (vector-ref i 0)) 591 (* (vector-ref x 1) (vector-ref i 1)) 592 (* (vector-ref x 2) (vector-ref i 2)) 593 (* (vector-ref x 3) (vector-ref i 3)) 594 (* (vector-ref x 4) (vector-ref i 4)) 595 (* (vector-ref x 5) (vector-ref i 5)) 596 (* (vector-ref x 6) (vector-ref i 6)) 597 (vector-ref x 7))) 598 (lambda (x i) 599 (+ 600 (* (vector-ref x 0) (vector-ref i 0)) 601 (* (vector-ref x 1) (vector-ref i 1)) 602 (* (vector-ref x 2) (vector-ref i 2)) 603 (* (vector-ref x 3) (vector-ref i 3)) 604 (* (vector-ref x 4) (vector-ref i 4)) 605 (* (vector-ref x 5) (vector-ref i 5)) 606 (* (vector-ref x 6) (vector-ref i 6)) 607 (* (vector-ref x 7) (vector-ref i 7)) 608 (vector-ref x 8))) 609 (lambda (x i) 610 (+ 611 (* (vector-ref x 0) (vector-ref i 0)) 612 (* (vector-ref x 1) (vector-ref i 1)) 613 (* (vector-ref x 2) (vector-ref i 2)) 614 (* (vector-ref x 3) (vector-ref i 3)) 615 (* (vector-ref x 4) (vector-ref i 4)) 616 (* (vector-ref x 5) (vector-ref i 5)) 617 (* (vector-ref x 6) (vector-ref i 6)) 618 (* (vector-ref x 7) (vector-ref i 7)) 619 (* (vector-ref x 8) (vector-ref i 8)) 620 (vector-ref x 9))))) 621 (it 622 (lambda (w) 623 (lambda (x i) 624 (+ 625 (* (vector-ref x 0) (vector-ref i 0)) 626 (* (vector-ref x 1) (vector-ref i 1)) 627 (* (vector-ref x 2) (vector-ref i 2)) 628 (* (vector-ref x 3) (vector-ref i 3)) 629 (* (vector-ref x 4) (vector-ref i 4)) 630 (* (vector-ref x 5) (vector-ref i 5)) 631 (* (vector-ref x 6) (vector-ref i 6)) 632 (* (vector-ref x 7) (vector-ref i 7)) 633 (* (vector-ref x 8) (vector-ref i 8)) 634 (* (vector-ref x 9) (vector-ref i 9)) 635 (do ((xi 636 0 637 (+ 638 (* (vector-ref x u) (vector-ref i u)) 639 xi)) 640 (u (- w 1) (- u 1))) 641 ((< u 10) xi)) 642 (vector-ref x w)))))) 643 (lambda (r) (if (< r 10) (vector-ref em r) (it r))))) 644 (define array:indexer/array 645 (let ((em 646 (vector 647 (lambda (x v i) (+ (vector-ref x 0))) 648 (lambda (x v i) 649 (+ 650 (* 651 (vector-ref x 0) 652 (vector-ref v (array:actor-index i 0))) 653 (vector-ref x 1))) 654 (lambda (x v i) 655 (+ 656 (* 657 (vector-ref x 0) 658 (vector-ref v (array:actor-index i 0))) 659 (* 660 (vector-ref x 1) 661 (vector-ref v (array:actor-index i 1))) 662 (vector-ref x 2))) 663 (lambda (x v i) 664 (+ 665 (* 666 (vector-ref x 0) 667 (vector-ref v (array:actor-index i 0))) 668 (* 669 (vector-ref x 1) 670 (vector-ref v (array:actor-index i 1))) 671 (* 672 (vector-ref x 2) 673 (vector-ref v (array:actor-index i 2))) 674 (vector-ref x 3))) 675 (lambda (x v i) 676 (+ 677 (* 678 (vector-ref x 0) 679 (vector-ref v (array:actor-index i 0))) 680 (* 681 (vector-ref x 1) 682 (vector-ref v (array:actor-index i 1))) 683 (* 684 (vector-ref x 2) 685 (vector-ref v (array:actor-index i 2))) 686 (* 687 (vector-ref x 3) 688 (vector-ref v (array:actor-index i 3))) 689 (vector-ref x 4))) 690 (lambda (x v i) 691 (+ 692 (* 693 (vector-ref x 0) 694 (vector-ref v (array:actor-index i 0))) 695 (* 696 (vector-ref x 1) 697 (vector-ref v (array:actor-index i 1))) 698 (* 699 (vector-ref x 2) 700 (vector-ref v (array:actor-index i 2))) 701 (* 702 (vector-ref x 3) 703 (vector-ref v (array:actor-index i 3))) 704 (* 705 (vector-ref x 4) 706 (vector-ref v (array:actor-index i 4))) 707 (vector-ref x 5))) 708 (lambda (x v i) 709 (+ 710 (* 711 (vector-ref x 0) 712 (vector-ref v (array:actor-index i 0))) 713 (* 714 (vector-ref x 1) 715 (vector-ref v (array:actor-index i 1))) 716 (* 717 (vector-ref x 2) 718 (vector-ref v (array:actor-index i 2))) 719 (* 720 (vector-ref x 3) 721 (vector-ref v (array:actor-index i 3))) 722 (* 723 (vector-ref x 4) 724 (vector-ref v (array:actor-index i 4))) 725 (* 726 (vector-ref x 5) 727 (vector-ref v (array:actor-index i 5))) 728 (vector-ref x 6))) 729 (lambda (x v i) 730 (+ 731 (* 732 (vector-ref x 0) 733 (vector-ref v (array:actor-index i 0))) 734 (* 735 (vector-ref x 1) 736 (vector-ref v (array:actor-index i 1))) 737 (* 738 (vector-ref x 2) 739 (vector-ref v (array:actor-index i 2))) 740 (* 741 (vector-ref x 3) 742 (vector-ref v (array:actor-index i 3))) 743 (* 744 (vector-ref x 4) 745 (vector-ref v (array:actor-index i 4))) 746 (* 747 (vector-ref x 5) 748 (vector-ref v (array:actor-index i 5))) 749 (* 750 (vector-ref x 6) 751 (vector-ref v (array:actor-index i 6))) 752 (vector-ref x 7))) 753 (lambda (x v i) 754 (+ 755 (* 756 (vector-ref x 0) 757 (vector-ref v (array:actor-index i 0))) 758 (* 759 (vector-ref x 1) 760 (vector-ref v (array:actor-index i 1))) 761 (* 762 (vector-ref x 2) 763 (vector-ref v (array:actor-index i 2))) 764 (* 765 (vector-ref x 3) 766 (vector-ref v (array:actor-index i 3))) 767 (* 768 (vector-ref x 4) 769 (vector-ref v (array:actor-index i 4))) 770 (* 771 (vector-ref x 5) 772 (vector-ref v (array:actor-index i 5))) 773 (* 774 (vector-ref x 6) 775 (vector-ref v (array:actor-index i 6))) 776 (* 777 (vector-ref x 7) 778 (vector-ref v (array:actor-index i 7))) 779 (vector-ref x 8))) 780 (lambda (x v i) 781 (+ 782 (* 783 (vector-ref x 0) 784 (vector-ref v (array:actor-index i 0))) 785 (* 786 (vector-ref x 1) 787 (vector-ref v (array:actor-index i 1))) 788 (* 789 (vector-ref x 2) 790 (vector-ref v (array:actor-index i 2))) 791 (* 792 (vector-ref x 3) 793 (vector-ref v (array:actor-index i 3))) 794 (* 795 (vector-ref x 4) 796 (vector-ref v (array:actor-index i 4))) 797 (* 798 (vector-ref x 5) 799 (vector-ref v (array:actor-index i 5))) 800 (* 801 (vector-ref x 6) 802 (vector-ref v (array:actor-index i 6))) 803 (* 804 (vector-ref x 7) 805 (vector-ref v (array:actor-index i 7))) 806 (* 807 (vector-ref x 8) 808 (vector-ref v (array:actor-index i 8))) 809 (vector-ref x 9))))) 810 (it 811 (lambda (w) 812 (lambda (x v i) 813 (+ 814 (* 815 (vector-ref x 0) 816 (vector-ref v (array:actor-index i 0))) 817 (* 818 (vector-ref x 1) 819 (vector-ref v (array:actor-index i 1))) 820 (* 821 (vector-ref x 2) 822 (vector-ref v (array:actor-index i 2))) 823 (* 824 (vector-ref x 3) 825 (vector-ref v (array:actor-index i 3))) 826 (* 827 (vector-ref x 4) 828 (vector-ref v (array:actor-index i 4))) 829 (* 830 (vector-ref x 5) 831 (vector-ref v (array:actor-index i 5))) 832 (* 833 (vector-ref x 6) 834 (vector-ref v (array:actor-index i 6))) 835 (* 836 (vector-ref x 7) 837 (vector-ref v (array:actor-index i 7))) 838 (* 839 (vector-ref x 8) 840 (vector-ref v (array:actor-index i 8))) 841 (* 842 (vector-ref x 9) 843 (vector-ref v (array:actor-index i 9))) 844 (do ((xi 845 0 846 (+ 847 (* 848 (vector-ref x u) 849 (vector-ref 850 v 851 (array:actor-index i u))) 852 xi)) 853 (u (- w 1) (- u 1))) 854 ((< u 10) xi)) 855 (vector-ref x w)))))) 856 (lambda (r) (if (< r 10) (vector-ref em r) (it r))))) 857 (define array:applier-to-vector 858 (let ((em 859 (vector 860 (lambda (p v) (p)) 861 (lambda (p v) (p (vector-ref v 0))) 862 (lambda (p v) 863 (p (vector-ref v 0) (vector-ref v 1))) 864 (lambda (p v) 865 (p 866 (vector-ref v 0) 867 (vector-ref v 1) 868 (vector-ref v 2))) 869 (lambda (p v) 870 (p 871 (vector-ref v 0) 872 (vector-ref v 1) 873 (vector-ref v 2) 874 (vector-ref v 3))) 875 (lambda (p v) 876 (p 877 (vector-ref v 0) 878 (vector-ref v 1) 879 (vector-ref v 2) 880 (vector-ref v 3) 881 (vector-ref v 4))) 882 (lambda (p v) 883 (p 884 (vector-ref v 0) 885 (vector-ref v 1) 886 (vector-ref v 2) 887 (vector-ref v 3) 888 (vector-ref v 4) 889 (vector-ref v 5))) 890 (lambda (p v) 891 (p 892 (vector-ref v 0) 893 (vector-ref v 1) 894 (vector-ref v 2) 895 (vector-ref v 3) 896 (vector-ref v 4) 897 (vector-ref v 5) 898 (vector-ref v 6))) 899 (lambda (p v) 900 (p 901 (vector-ref v 0) 902 (vector-ref v 1) 903 (vector-ref v 2) 904 (vector-ref v 3) 905 (vector-ref v 4) 906 (vector-ref v 5) 907 (vector-ref v 6) 908 (vector-ref v 7))) 909 (lambda (p v) 910 (p 911 (vector-ref v 0) 912 (vector-ref v 1) 913 (vector-ref v 2) 914 (vector-ref v 3) 915 (vector-ref v 4) 916 (vector-ref v 5) 917 (vector-ref v 6) 918 (vector-ref v 7) 919 (vector-ref v 8))))) 920 (it 921 (lambda (r) 922 (lambda (p v) 923 (apply 924 p 925 (vector-ref v 0) 926 (vector-ref v 1) 927 (vector-ref v 2) 928 (vector-ref v 3) 929 (vector-ref v 4) 930 (vector-ref v 5) 931 (vector-ref v 6) 932 (vector-ref v 7) 933 (vector-ref v 8) 934 (vector-ref v 9) 935 (do ((k r (- k 1)) 936 (r 937 '() 938 (cons (vector-ref v (- k 1)) r))) 939 ((= k 10) r))))))) 940 (lambda (r) (if (< r 10) (vector-ref em r) (it r))))) 941 (define array:applier-to-actor 942 (let ((em 943 (vector 944 (lambda (p a) (p)) 945 (lambda (p a) (p (array-ref a 0))) 946 (lambda (p a) 947 (p (array-ref a 0) (array-ref a 1))) 948 (lambda (p a) 949 (p 950 (array-ref a 0) 951 (array-ref a 1) 952 (array-ref a 2))) 953 (lambda (p a) 954 (p 955 (array-ref a 0) 956 (array-ref a 1) 957 (array-ref a 2) 958 (array-ref a 3))) 959 (lambda (p a) 960 (p 961 (array-ref a 0) 962 (array-ref a 1) 963 (array-ref a 2) 964 (array-ref a 3) 965 (array-ref a 4))) 966 (lambda (p a) 967 (p 968 (array-ref a 0) 969 (array-ref a 1) 970 (array-ref a 2) 971 (array-ref a 3) 972 (array-ref a 4) 973 (array-ref a 5))) 974 (lambda (p a) 975 (p 976 (array-ref a 0) 977 (array-ref a 1) 978 (array-ref a 2) 979 (array-ref a 3) 980 (array-ref a 4) 981 (array-ref a 5) 982 (array-ref a 6))) 983 (lambda (p a) 984 (p 985 (array-ref a 0) 986 (array-ref a 1) 987 (array-ref a 2) 988 (array-ref a 3) 989 (array-ref a 4) 990 (array-ref a 5) 991 (array-ref a 6) 992 (array-ref a 7))) 993 (lambda (p a) 994 (p 995 (array-ref a 0) 996 (array-ref a 1) 997 (array-ref a 2) 998 (array-ref a 3) 999 (array-ref a 4) 1000 (array-ref a 5) 1001 (array-ref a 6) 1002 (array-ref a 7) 1003 (array-ref a 8))))) 1004 (it 1005 (lambda (r) 1006 (lambda (p a) 1007 (apply 1008 a 1009 (array-ref a 0) 1010 (array-ref a 1) 1011 (array-ref a 2) 1012 (array-ref a 3) 1013 (array-ref a 4) 1014 (array-ref a 5) 1015 (array-ref a 6) 1016 (array-ref a 7) 1017 (array-ref a 8) 1018 (array-ref a 9) 1019 (do ((k r (- k 1)) 1020 (r '() (cons (array-ref a (- k 1)) r))) 1021 ((= k 10) r))))))) 1022 (lambda (r) 1023 "These are high level, hiding implementation at call site." 1024 (if (< r 10) (vector-ref em r) (it r))))) 1025 (define array:applier-to-backing-vector 1026 (let ((em 1027 (vector 1028 (lambda (p ai av) (p)) 1029 (lambda (p ai av) 1030 (p (vector-ref av (array:actor-index ai 0)))) 1031 (lambda (p ai av) 1032 (p 1033 (vector-ref av (array:actor-index ai 0)) 1034 (vector-ref av (array:actor-index ai 1)))) 1035 (lambda (p ai av) 1036 (p 1037 (vector-ref av (array:actor-index ai 0)) 1038 (vector-ref av (array:actor-index ai 1)) 1039 (vector-ref av (array:actor-index ai 2)))) 1040 (lambda (p ai av) 1041 (p 1042 (vector-ref av (array:actor-index ai 0)) 1043 (vector-ref av (array:actor-index ai 1)) 1044 (vector-ref av (array:actor-index ai 2)) 1045 (vector-ref av (array:actor-index ai 3)))) 1046 (lambda (p ai av) 1047 (p 1048 (vector-ref av (array:actor-index ai 0)) 1049 (vector-ref av (array:actor-index ai 1)) 1050 (vector-ref av (array:actor-index ai 2)) 1051 (vector-ref av (array:actor-index ai 3)) 1052 (vector-ref av (array:actor-index ai 4)))) 1053 (lambda (p ai av) 1054 (p 1055 (vector-ref av (array:actor-index ai 0)) 1056 (vector-ref av (array:actor-index ai 1)) 1057 (vector-ref av (array:actor-index ai 2)) 1058 (vector-ref av (array:actor-index ai 3)) 1059 (vector-ref av (array:actor-index ai 4)) 1060 (vector-ref av (array:actor-index ai 5)))) 1061 (lambda (p ai av) 1062 (p 1063 (vector-ref av (array:actor-index ai 0)) 1064 (vector-ref av (array:actor-index ai 1)) 1065 (vector-ref av (array:actor-index ai 2)) 1066 (vector-ref av (array:actor-index ai 3)) 1067 (vector-ref av (array:actor-index ai 4)) 1068 (vector-ref av (array:actor-index ai 5)) 1069 (vector-ref av (array:actor-index ai 6)))) 1070 (lambda (p ai av) 1071 (p 1072 (vector-ref av (array:actor-index ai 0)) 1073 (vector-ref av (array:actor-index ai 1)) 1074 (vector-ref av (array:actor-index ai 2)) 1075 (vector-ref av (array:actor-index ai 3)) 1076 (vector-ref av (array:actor-index ai 4)) 1077 (vector-ref av (array:actor-index ai 5)) 1078 (vector-ref av (array:actor-index ai 6)) 1079 (vector-ref av (array:actor-index ai 7)))) 1080 (lambda (p ai av) 1081 (p 1082 (vector-ref av (array:actor-index ai 0)) 1083 (vector-ref av (array:actor-index ai 1)) 1084 (vector-ref av (array:actor-index ai 2)) 1085 (vector-ref av (array:actor-index ai 3)) 1086 (vector-ref av (array:actor-index ai 4)) 1087 (vector-ref av (array:actor-index ai 5)) 1088 (vector-ref av (array:actor-index ai 6)) 1089 (vector-ref av (array:actor-index ai 7)) 1090 (vector-ref av (array:actor-index ai 8)))))) 1091 (it 1092 (lambda (r) 1093 (lambda (p ai av) 1094 (apply 1095 p 1096 (vector-ref av (array:actor-index ai 0)) 1097 (vector-ref av (array:actor-index ai 1)) 1098 (vector-ref av (array:actor-index ai 2)) 1099 (vector-ref av (array:actor-index ai 3)) 1100 (vector-ref av (array:actor-index ai 4)) 1101 (vector-ref av (array:actor-index ai 5)) 1102 (vector-ref av (array:actor-index ai 6)) 1103 (vector-ref av (array:actor-index ai 7)) 1104 (vector-ref av (array:actor-index ai 8)) 1105 (vector-ref av (array:actor-index ai 9)) 1106 (do ((k r (- k 1)) 1107 (r 1108 '() 1109 (cons 1110 (vector-ref 1111 av 1112 (array:actor-index ai (- k 1))) 1113 r))) 1114 ((= k 10) r))))))) 1115 (lambda (r) 1116 "These are low level, exposing implementation at call site." 1117 (if (< r 10) (vector-ref em r) (it r))))) 1118 (define (array:index/vector r x v) 1119 ((array:indexer/vector r) x v)) 1120 (define (array:index/array r x av ai) 1121 ((array:indexer/array r) x av ai)) 1122 (define (array:apply-to-actor r p a) 1123 ((array:applier-to-actor r) p a)) 1124 (define (array:apply-to-vector r p v) 1125 ((array:applier-to-vector r) p v)) 1126 (define (array:optimize f r) 1127 (case r 1128 ((0) (let ((n0 (f))) (array:0 n0))) 1129 ((1) (let ((n0 (f 0))) (array:1 n0 (- (f 1) n0)))) 1130 ((2) 1131 (let ((n0 (f 0 0))) 1132 (array:2 n0 (- (f 1 0) n0) (- (f 0 1) n0)))) 1133 ((3) 1134 (let ((n0 (f 0 0 0))) 1135 (array:3 1136 n0 1137 (- (f 1 0 0) n0) 1138 (- (f 0 1 0) n0) 1139 (- (f 0 0 1) n0)))) 1140 (else 1141 (let ((v 1142 (do ((k 0 (+ k 1)) (v '() (cons 0 v))) 1143 ((= k r) v)))) 1144 (let ((n0 (apply f v))) 1145 (apply 1146 array:n 1147 n0 1148 (array:coefficients f n0 v v))))))) 1149 (define (array:optimize-empty r) 1150 (let ((x (make-vector (+ r 1) 0))) 1151 (vector-set! x r -1) 1152 x))) 1153 1154 1155 (define (array-ref a . xs) 1156 (or (##core#check (array:array? a)) 1157 (##sys#signal-hook #:type-error 'array-ref "not an array" a)) 1158 (let ((shape (array:shape a))) 1159 (##core#check 1160 (if (null? xs) 1161 (array:check-indices "array-ref" xs shape) 1162 (let ((x (car xs))) 1163 (if (vector? x) 1164 (array:check-index-vector "array-ref" x shape) 1165 (if (integer? x) 1166 (array:check-indices "array-ref" xs shape) 1167 (if (array:array? x) 1168 (array:check-index-actor "array-ref" x shape) 1169 (##sys#signal-hook #:type-error 'array-ref "not an index object" x))))))) 1170 (vector-ref 1171 (array:vector a) 1172 (if (null? xs) 1173 (vector-ref (array:index a) 0) 1174 (let ((x (car xs))) 1175 (if (vector? x) 1176 (array:index/vector 1177 (quotient (vector-length shape) 2) 1178 (array:index a) 1179 x) 1180 (if (integer? x) 1181 (array:vector-index (array:index a) xs) 1182 (if (##core#check (array:array? x)) 1183 (array:index/array 1184 (quotient (vector-length shape) 2) 1185 (array:index a) 1186 (array:vector x) 1187 (array:index x)) 1188 (##sys#signal-hook #:type-error 'array-ref "bad index object" x))))))))) 1189 1190 (define (array-set! a x . xs) 1191 (or (##core#check (array:array? a)) 1192 (##sys#signal-hook #:type-error 'array-set! "not an array" a)) 1193 (let ((shape (array:shape a))) 1194 (##core#check 1195 (if (null? xs) 1196 (array:check-indices "array-set!" '() shape) 1197 (if (vector? x) 1198 (array:check-index-vector "array-set!" x shape) 1199 (if (integer? x) 1200 (array:check-indices.o "array-set!" (cons x xs) shape) 1201 (if (array:array? x) 1202 (array:check-index-actor "array-set!" x shape) 1203 (##sys#signal-hook #:type-error 'array-set! "not an index object" x)))))) 1204 (if (null? xs) 1205 (vector-set! (array:vector a) (vector-ref (array:index a) 0) x) 1206 (if (vector? x) 1207 (vector-set! (array:vector a) 1208 (array:index/vector 1209 (quotient (vector-length shape) 2) 1210 (array:index a) 1211 x) 1212 (car xs)) 1213 (if (integer? x) 1214 (let ((v (array:vector a)) 1215 (i (array:index a)) 1216 (r (quotient (vector-length shape) 2))) 1217 (do ((sum (* (vector-ref i 0) x) 1218 (+ sum (* (vector-ref i k) (car ks)))) 1219 (ks xs (cdr ks)) 1220 (k 1 (+ k 1))) 1221 ((= k r) 1222 (vector-set! v (+ sum (vector-ref i k)) (car ks))))) 1223 (if (##core#check (array:array? x)) 1224 (vector-set! (array:vector a) 1225 (array:index/array 1226 (quotient (vector-length shape) 2) 1227 (array:index a) 1228 (array:vector x) 1229 (array:index x)) 1230 (car xs)) 1231 (##sys#signal-hook 1232 #:type-error 'array-set! 1233 "bad index object: " 1234 x))))))) 1235 1236 (define (array:make-locative a x weak?) 1237 (or (##core#check (array:array? a)) 1238 (##sys#signal-hook #:type-error 'array:make-locative "not an array")) 1239 (let ((shape (array:shape a))) 1240 (##core#check 1241 (if (vector? x) 1242 (array:check-index-vector "array:make-locative" x shape) 1243 (if (integer? x) 1244 (array:check-indices.o "array:make-locative" (list x) shape) 1245 (if (array:array? x) 1246 (array:check-index-actor "array:make-locative" x shape) 1247 (##sys#signal-hook #:type-error 'array:make-locative "not an index object" x))))) 1248 (if (vector? x) 1249 (##core#inline_allocate 1250 ("C_a_i_make_locative" 5) 1251 0 1252 (array:vector a) 1253 (array:index/vector 1254 (quotient (vector-length shape) 2) 1255 (array:index a) 1256 x) 1257 weak?) 1258 (if (##core#check (array:array? x)) 1259 (##core#inline_allocate 1260 ("C_a_i_make_locative" 5) 1261 0 1262 (array:vector a) 1263 (array:index/array 1264 (quotient (vector-length shape) 2) 1265 (array:index a) 1266 (array:vector x) 1267 (array:index x)) 1268 weak?) 1269 (##sys#signal-hook #:type-error 'array:make-locative "bad index object: " x)))))