Skip to content

Commit 2b1d2d9

Browse files
committed
Fix array-append for non-zero based intervals.
Closes #972.
1 parent a8939fe commit 2b1d2d9

File tree

3 files changed

+78
-52
lines changed

3 files changed

+78
-52
lines changed

lib/srfi/231/base.scm

+19-19
Original file line numberDiff line numberDiff line change
@@ -162,25 +162,25 @@
162162
(values ivc (vector-ref ivc 0)))))
163163

164164
(define (interval-fold-left f kons knil iv)
165-
(case (interval-dimension iv)
166-
((1)
167-
(let ((end (interval-upper-bound iv 0)))
168-
(do ((i (interval-lower-bound iv 0) (+ i 1))
169-
(acc knil (kons acc (f i))))
170-
((>= i end) acc))))
171-
((2)
172-
(let ((end0 (interval-upper-bound iv 0))
173-
(start1 (interval-lower-bound iv 1))
174-
(end1 (interval-upper-bound iv 1)))
175-
(do ((i (interval-lower-bound iv 0) (+ i 1))
176-
(acc knil
177-
(do ((j start1 (+ j 1))
178-
(acc acc (kons acc (f i j))))
179-
((>= j end1) acc))))
180-
((>= i end0) acc))))
181-
(else
182-
(if (interval-empty? iv)
183-
knil
165+
(if (interval-empty? iv)
166+
knil
167+
(case (interval-dimension iv)
168+
((1)
169+
(let ((end (interval-upper-bound iv 0)))
170+
(do ((i (interval-lower-bound iv 0) (+ i 1))
171+
(acc knil (kons acc (f i))))
172+
((>= i end) acc))))
173+
((2)
174+
(let ((end0 (interval-upper-bound iv 0))
175+
(start1 (interval-lower-bound iv 1))
176+
(end1 (interval-upper-bound iv 1)))
177+
(do ((i (interval-lower-bound iv 0) (+ i 1))
178+
(acc knil
179+
(do ((j start1 (+ j 1))
180+
(acc acc (kons acc (f i j))))
181+
((>= j end1) acc))))
182+
((>= i end0) acc))))
183+
(else
184184
(let ((ivc (interval-cursor iv)))
185185
(let lp ((acc knil))
186186
(let ((acc (kons acc (apply f (interval-cursor-get ivc)))))

lib/srfi/231/test.sld

+21-1
Original file line numberDiff line numberDiff line change
@@ -3255,7 +3255,7 @@
32553255
(make-array (make-interval '#(2 3)) list)))
32563256
)
32573257

3258-
(test-group "stack/block"
3258+
(test-group "stack/block/append"
32593259
(let* ((a
32603260
(make-array (make-interval '#(4 10)) list))
32613261
(a-column
@@ -3315,6 +3315,26 @@
33153315
(list (list*->array 2 '((12 13)))
33163316
(list*->array 2 '((14)))
33173317
(list*->array 2 '((15 16 17)))))))))
3318+
(test-assert
3319+
(array-append
3320+
1
3321+
(list
3322+
(list->array
3323+
(make-interval (quote #(1 -9 -1 3))
3324+
(quote #(5 -8 5 8)))
3325+
'(0 4 9 1 7 4 5 9 5 2 2 2 2 5 7 1 5 2 1 1 5 4 6 1 1 2 5 2 5 3 5 7 1 6 9 5 4 4 6 2 2 8 4 6 5 4 2 5 9 7 1 8 4 0 6 9 8 7 9 8 0 9 4 0 0 4 4 5 8 3 7 8 0 4 4 7 1 1 1 1 2 9 1 5 7 0 5 0 4 4 5 0 3 7 1 2 9 5 7 7 6 0 2 5 4 9 0 6 1 2 2 4 4 6 4 3 0 1 8 6))
3326+
(list->array
3327+
(make-interval (quote #(1 -8 -1 3))
3328+
(quote #(5 -6 5 8)))
3329+
'(3 1 9 0 4 3 7 4 6 2 9 9 4 7 2 4 4 4 7 4 6 9 5 3 4 3 6 8 1 4 2 3 0 6 5 9 1 4 0 9 7 9 0 5 7 5 4 1 0 6 4 6 5 1 4 4 6 2 3 3 3 5 0 5 8 3 8 1 3 1 2 6 5 5 2 6 5 3 3 3 4 5 9 7 9 7 4 1 9 8 7 8 4 9 5 3 0 0 1 9 8 9 8 4 7 3 9 3 5 0 9 7 4 6 8 4 3 0 7 7 7 0 9 7 3 2 7 6 9 2 0 1 0 1 1 9 7 7 1 9 7 0 9 9 0 0 7 6 5 2 9 2 9 4 9 3 7 6 1 8 9 4 4 4 5 7 2 4 6 0 3 0 7 4 3 6 3 0 3 2 2 4 4 0 1 9 3 9 8 5 7 3 9 8 9 2 4 1 8 4 4 5 6 9 3 7 2 8 2 9 0 4 6 6 7 4 2 2 3 1 7 0 8 4 8 7 6 4 3 9 2 7 1 1 9 0 1 8 3 1))
3330+
(list->array
3331+
(make-interval (quote #(1 -6 -1 3))
3332+
(quote #(5 -6 5 8)))
3333+
'())
3334+
(list->array
3335+
(make-interval (quote #(1 -6 -1 3))
3336+
(quote #(5 -5 5 8)))
3337+
'(3 1 6 2 8 0 8 1 2 6 7 2 9 4 6 5 2 4 5 4 5 2 6 6 0 6 4 2 1 3 4 6 9 6 7 2 4 8 4 3 5 5 8 0 6 4 6 3 7 6 3 4 1 6 2 3 1 9 1 0 3 1 5 0 3 5 8 1 8 0 2 3 1 5 0 4 9 5 3 2 0 7 6 5 5 9 4 8 5 3 2 5 1 4 8 4 5 7 4 6 1 5 8 2 0 1 5 0 8 3 0 4 6 1 7 1 7 1 6 9)))))
33183338
)
33193339

33203340
'(test-group "assign/product"

lib/srfi/231/transforms.scm

+38-32
Original file line numberDiff line numberDiff line change
@@ -452,20 +452,22 @@
452452
(apply list->array domain (vector->list vec) o))
453453

454454
(define (array-assign! destination source)
455-
(assert (and (mutable-array? destination) (array? source)
456-
(interval= (array-domain destination) (array-domain source))))
457-
(let ((getter (array-getter source))
458-
(setter (array-setter destination)))
459-
(interval-for-each
460-
(case (array-dimension destination)
461-
((1) (lambda (i) (setter (getter i) i)))
462-
((2) (lambda (i j) (setter (getter i j) i j)))
463-
((3) (lambda (i j k) (setter (getter i j k) i j k)))
464-
(else
465-
(lambda multi-index
466-
(apply setter (apply getter multi-index) multi-index))))
467-
(array-domain source))
468-
destination))
455+
(let ((dest-domain (array-domain destination))
456+
(source-domain (array-domain source)))
457+
(assert (and (mutable-array? destination) (array? source)
458+
(interval= dest-domain source-domain)))
459+
(let ((getter (array-getter source))
460+
(setter (array-setter destination)))
461+
(interval-for-each
462+
(case (array-dimension destination)
463+
((1) (lambda (i) (setter (getter i) i)))
464+
((2) (lambda (i j) (setter (getter i j) i j)))
465+
((3) (lambda (i j k) (setter (getter i j k) i j k)))
466+
(else
467+
(lambda multi-index
468+
(apply setter (apply getter multi-index) multi-index))))
469+
(array-domain source))
470+
destination)))
469471

470472
(define (reshape-without-copy array new-domain)
471473
(let* ((domain (array-domain array))
@@ -612,7 +614,8 @@
612614
(pair? arrays)
613615
(every array? arrays)
614616
(< -1 axis (array-dimension (car arrays)))))
615-
(let* ((a (car arrays))
617+
(let* ((arrays (remove array-empty? arrays))
618+
(a (car arrays))
616619
(a-domain (array-domain a))
617620
(storage (if (pair? o) (car o) generic-storage-class))
618621
(mutable? (if (and (pair? o) (pair? (cdr o)))
@@ -634,29 +637,32 @@
634637
(vector-ref c-hi axis)
635638
(cdr arrays)))
636639
(let* ((c-domain (make-interval c-lo c-hi))
637-
(c (make-specialized-array/default c-domain storage safe?))
638-
(b-trans (make-vector (array-dimension a) 0)))
640+
(c (make-specialized-array/default c-domain storage safe?)))
639641
(array-assign!
640642
(array-extract c (make-interval c-lo (interval-widths a-domain)))
641643
(array-translate a (vector-map - a-lo)))
642644
(let lp ((arrays (cdr arrays))
643645
(b-offset (- (interval-upper-bound a-domain axis)
644646
(interval-lower-bound a-domain axis))))
645-
(if (null? arrays)
646-
(if mutable? c (array-freeze! c))
647-
(let* ((b (car arrays))
648-
(b-domain (array-domain b))
649-
(b-offset2 (+ b-offset (interval-width b-domain axis)))
650-
(b-lo (make-vector (interval-dimension b-domain) 0))
651-
(b-hi (interval-widths b-domain)))
652-
(vector-set! b-lo axis b-offset)
653-
(vector-set! b-hi axis b-offset2)
654-
(vector-set! b-trans axis (- b-offset))
655-
(let ((view (array-translate
656-
(array-extract c (make-interval b-lo b-hi))
657-
b-trans)))
658-
(array-assign! view b)
659-
(lp (cdr arrays) b-offset2)))))))))
647+
(cond
648+
((null? arrays)
649+
(if mutable? c (array-freeze! c)))
650+
(else
651+
(let* ((b (car arrays))
652+
(b-domain (array-domain b))
653+
(b-offset2 (+ b-offset (interval-width b-domain axis)))
654+
(b-lo (make-vector (interval-dimension b-domain) 0))
655+
(b-hi (interval-widths b-domain)))
656+
(vector-set! b-lo axis b-offset)
657+
(vector-set! b-hi axis b-offset2)
658+
(let ((dest-view (array-extract c (make-interval b-lo b-hi)))
659+
(b-trans
660+
(vector-map - (interval-lower-bounds->vector b-domain))))
661+
(vector-set! b-trans axis (+ (vector-ref b-trans axis)
662+
b-offset))
663+
(array-assign! dest-view (array-translate b b-trans))
664+
(lp (cdr arrays) b-offset2))
665+
))))))))
660666

661667
(define array-append! array-append)
662668

0 commit comments

Comments
 (0)