ramap.test 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. ;;;; ramap.test --- test array mapping functions -*- scheme -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2004, 2005, 2006, 2009, 2013 Free Software Foundation, Inc.
  4. ;;;;
  5. ;;;; This library is free software; you can redistribute it and/or
  6. ;;;; modify it under the terms of the GNU Lesser General Public
  7. ;;;; License as published by the Free Software Foundation; either
  8. ;;;; version 3 of the License, or (at your option) any later version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free Software
  17. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. (define-module (test-suite test-ramap)
  19. #:use-module (test-suite lib))
  20. (define exception:shape-mismatch
  21. (cons 'misc-error ".*shape mismatch.*"))
  22. (define (array-row a i)
  23. (make-shared-array a (lambda (j) (list i j))
  24. (cadr (array-dimensions a))))
  25. (define (array-col a j)
  26. (make-shared-array a (lambda (i) (list i j))
  27. (car (array-dimensions a))))
  28. ;;;
  29. ;;; array-index-map!
  30. ;;;
  31. (with-test-prefix "array-index-map!"
  32. (pass-if "basic test"
  33. (let ((nlst '()))
  34. (array-index-map! (make-array #f '(1 1))
  35. (lambda (n)
  36. (set! nlst (cons n nlst))))
  37. (equal? nlst '(1))))
  38. (with-test-prefix "empty arrays"
  39. (pass-if "all axes empty"
  40. (array-index-map! (make-typed-array 'f64 0 0 0) (const 0))
  41. (array-index-map! (make-typed-array 'b #t 0 0) (const #t))
  42. (array-index-map! (make-typed-array #t 0 0 0) (const 0))
  43. #t)
  44. (pass-if "last axis empty"
  45. (array-index-map! (make-typed-array 'f64 0 2 0) (const 0))
  46. (array-index-map! (make-typed-array 'b #t 2 0) (const #t))
  47. (array-index-map! (make-typed-array #t 0 2 0) (const 0))
  48. #t)
  49. ; the 'f64 cases fail in 2.0.9 with out-of-range.
  50. (pass-if "axis empty, other than last"
  51. (array-index-map! (make-typed-array 'f64 0 0 2) (const 0))
  52. (array-index-map! (make-typed-array 'b #t 0 2) (const #t))
  53. (array-index-map! (make-typed-array #t 0 0 2) (const 0))
  54. #t))
  55. (pass-if "rank 2"
  56. (let ((a (make-array 0 2 2))
  57. (b (make-array 0 2 2)))
  58. (array-index-map! a (lambda (i j) i))
  59. (array-index-map! b (lambda (i j) j))
  60. (and (array-equal? a #2((0 0) (1 1)))
  61. (array-equal? b #2((0 1) (0 1)))))))
  62. ;;;
  63. ;;; array-copy!
  64. ;;;
  65. (with-test-prefix "array-copy!"
  66. (with-test-prefix "empty arrays"
  67. (pass-if "empty other than last, #t"
  68. (let* ((b (make-array 0 2 2))
  69. (c (make-shared-array b (lambda (i j) (list i j)) 0 2)))
  70. (array-copy! #2:0:2() c)
  71. (array-equal? #2:0:2() c)))
  72. (pass-if "empty other than last, 'f64"
  73. (let* ((b (make-typed-array 'f64 0 2 2))
  74. (c (make-shared-array b (lambda (i j) (list i j)) 0 2)))
  75. (array-copy! #2:0:2() c)
  76. (array-equal? #2f64:0:2() c)))
  77. ;; FIXME add empty, type 'b cases.
  78. )
  79. ;; note that it is the opposite of array-map!. This is, unfortunately,
  80. ;; documented in the manual.
  81. (pass-if "matching behavior I"
  82. (let ((a #(1 2))
  83. (b (make-array 0 3)))
  84. (array-copy! a b)
  85. (equal? b #(1 2 0))))
  86. (pass-if-exception "matching behavior II" exception:shape-mismatch
  87. (let ((a #(1 2 3))
  88. (b (make-array 0 2)))
  89. (array-copy! a b)
  90. (equal? b #(1 2))))
  91. ;; here both a & b are are unrollable down to the first axis, but the
  92. ;; size mismatch limits unrolling to the last axis only.
  93. (pass-if "matching behavior III"
  94. (let ((a #3(((1 2) (3 4)) ((5 6) (7 8))))
  95. (b (make-array 0 2 3 2)))
  96. (array-copy! a b)
  97. (array-equal? b #3(((1 2) (3 4) (0 0)) ((5 6) (7 8) (0 0))))))
  98. (pass-if "rank 0"
  99. (let ((a #0(99))
  100. (b (make-array 0)))
  101. (array-copy! a b)
  102. (equal? b #0(99))))
  103. (pass-if "rank 1"
  104. (let* ((a #2((1 2) (3 4)))
  105. (b (make-shared-array a (lambda (j) (list 1 j)) 2))
  106. (c (make-shared-array a (lambda (i) (list (- 1 i) 1)) 2))
  107. (d (make-array 0 2))
  108. (e (make-array 0 2)))
  109. (array-copy! b d)
  110. (array-copy! c e)
  111. (and (equal? d #(3 4))
  112. (equal? e #(4 2)))))
  113. (pass-if "rank 2"
  114. (let ((a #2((1 2) (3 4)))
  115. (b (make-array 0 2 2))
  116. (c (make-array 0 2 2))
  117. (d (make-array 0 2 2))
  118. (e (make-array 0 2 2)))
  119. (array-copy! a b)
  120. (array-copy! a (transpose-array c 1 0))
  121. (array-copy! (transpose-array a 1 0) d)
  122. (array-copy! (transpose-array a 1 0) (transpose-array e 1 0))
  123. (and (equal? a #2((1 2) (3 4)))
  124. (equal? b #2((1 2) (3 4)))
  125. (equal? c #2((1 3) (2 4)))
  126. (equal? d #2((1 3) (2 4)))
  127. (equal? e #2((1 2) (3 4))))))
  128. (pass-if "rank 2, discontinuous"
  129. (let ((A #2((0 1) (2 3) (4 5)))
  130. (B #2((10 11) (12 13) (14 15)))
  131. (C #2((20) (21) (22)))
  132. (X (make-array 0 3 5))
  133. (piece (lambda (X w s)
  134. (make-shared-array
  135. X (lambda (i j) (list i (+ j s))) 3 w))))
  136. (array-copy! A (piece X 2 0))
  137. (array-copy! B (piece X 2 2))
  138. (array-copy! C (piece X 1 4))
  139. (and (array-equal? X #2((0 1 10 11 20) (2 3 12 13 21) (4 5 14 15 22))))))
  140. (pass-if "null increments, not empty"
  141. (let ((a (make-array 0 2 2)))
  142. (array-copy! (make-shared-array #0(1) (lambda x '()) 2 2) a)
  143. (array-equal? #2((1 1) (1 1))))))
  144. ;;;
  145. ;;; array-map!
  146. ;;;
  147. (with-test-prefix "array-map!"
  148. (pass-if-exception "no args" exception:wrong-num-args
  149. (array-map!))
  150. (pass-if-exception "one arg" exception:wrong-num-args
  151. (array-map! (make-array #f 5)))
  152. (with-test-prefix "no sources"
  153. (pass-if "closure 0"
  154. (array-map! (make-array #f 5) (lambda () #f))
  155. #t)
  156. (pass-if-exception "closure 1" exception:wrong-num-args
  157. (array-map! (make-array #f 5) (lambda (x) #f)))
  158. (pass-if-exception "closure 2" exception:wrong-num-args
  159. (array-map! (make-array #f 5) (lambda (x y) #f)))
  160. (pass-if-exception "subr_1" exception:wrong-num-args
  161. (array-map! (make-array #f 5) length))
  162. (pass-if-exception "subr_2" exception:wrong-num-args
  163. (array-map! (make-array #f 5) logtest))
  164. (pass-if-exception "subr_2o" exception:wrong-num-args
  165. (array-map! (make-array #f 5) number->string))
  166. (pass-if-exception "dsubr" exception:wrong-num-args
  167. (array-map! (make-array #f 5) sqrt))
  168. (pass-if "rpsubr"
  169. (let ((a (make-array 'foo 5)))
  170. (array-map! a =)
  171. (equal? a (make-array #t 5))))
  172. (pass-if "asubr"
  173. (let ((a (make-array 'foo 5)))
  174. (array-map! a +)
  175. (equal? a (make-array 0 5))))
  176. ;; in Guile 1.6.4 and earlier this resulted in a segv
  177. (pass-if "noop"
  178. (array-map! (make-array #f 5) noop)
  179. #t))
  180. (with-test-prefix "one source"
  181. (pass-if-exception "closure 0" exception:wrong-num-args
  182. (array-map! (make-array #f 5) (lambda () #f)
  183. (make-array #f 5)))
  184. (pass-if "closure 1"
  185. (let ((a (make-array #f 5)))
  186. (array-map! a (lambda (x) 'foo) (make-array #f 5))
  187. (equal? a (make-array 'foo 5))))
  188. (pass-if-exception "closure 2" exception:wrong-num-args
  189. (array-map! (make-array #f 5) (lambda (x y) #f)
  190. (make-array #f 5)))
  191. (pass-if "subr_1"
  192. (let ((a (make-array #f 5)))
  193. (array-map! a length (make-array '(x y z) 5))
  194. (equal? a (make-array 3 5))))
  195. (pass-if-exception "subr_2" exception:wrong-num-args
  196. (array-map! (make-array #f 5) logtest
  197. (make-array 999 5)))
  198. (pass-if "subr_2o"
  199. (let ((a (make-array #f 5)))
  200. (array-map! a number->string (make-array 99 5))
  201. (equal? a (make-array "99" 5))))
  202. (pass-if "dsubr"
  203. (let ((a (make-array #f 5)))
  204. (array-map! a sqrt (make-array 16.0 5))
  205. (equal? a (make-array 4.0 5))))
  206. (pass-if "rpsubr"
  207. (let ((a (make-array 'foo 5)))
  208. (array-map! a = (make-array 0 5))
  209. (equal? a (make-array #t 5))))
  210. (pass-if "asubr"
  211. (let ((a (make-array 'foo 5)))
  212. (array-map! a - (make-array 99 5))
  213. (equal? a (make-array -99 5))))
  214. ;; in Guile 1.6.5 and 1.6.6 this was an error
  215. (pass-if "1+"
  216. (let ((a (make-array #f 5)))
  217. (array-map! a 1+ (make-array 123 5))
  218. (equal? a (make-array 124 5))))
  219. (pass-if "rank 0"
  220. (let ((a #0(99))
  221. (b (make-array 0)))
  222. (array-map! b values a)
  223. (equal? b #0(99))))
  224. (pass-if "rank 2, discontinuous"
  225. (let ((A #2((0 1) (2 3) (4 5)))
  226. (B #2((10 11) (12 13) (14 15)))
  227. (C #2((20) (21) (22)))
  228. (X (make-array 0 3 5))
  229. (piece (lambda (X w s)
  230. (make-shared-array
  231. X (lambda (i j) (list i (+ j s))) 3 w))))
  232. (array-map! (piece X 2 0) values A)
  233. (array-map! (piece X 2 2) values B)
  234. (array-map! (piece X 1 4) values C)
  235. (and (array-equal? X #2((0 1 10 11 20) (2 3 12 13 21) (4 5 14 15 22))))))
  236. (pass-if "null increments, not empty"
  237. (let ((a (make-array 0 2 2)))
  238. (array-map! a values (make-shared-array #0(1) (lambda x '()) 2 2))
  239. (array-equal? a #2((1 1) (1 1))))))
  240. (with-test-prefix "two sources"
  241. (pass-if-exception "closure 0" exception:wrong-num-args
  242. (array-map! (make-array #f 5) (lambda () #f)
  243. (make-array #f 5) (make-array #f 5)))
  244. (pass-if-exception "closure 1" exception:wrong-num-args
  245. (array-map! (make-array #f 5) (lambda (x) #f)
  246. (make-array #f 5) (make-array #f 5)))
  247. (pass-if "closure 2"
  248. (let ((a (make-array #f 5)))
  249. (array-map! a (lambda (x y) 'foo)
  250. (make-array #f 5) (make-array #f 5))
  251. (equal? a (make-array 'foo 5))))
  252. (pass-if-exception "subr_1" exception:wrong-num-args
  253. (array-map! (make-array #f 5) length
  254. (make-array #f 5) (make-array #f 5)))
  255. (pass-if "subr_2"
  256. (let ((a (make-array 'foo 5)))
  257. (array-map! a logtest
  258. (make-array 999 5) (make-array 999 5))
  259. (equal? a (make-array #t 5))))
  260. (pass-if "subr_2o"
  261. (let ((a (make-array #f 5)))
  262. (array-map! a number->string
  263. (make-array 32 5) (make-array 16 5))
  264. (equal? a (make-array "20" 5))))
  265. (pass-if-exception "dsubr" exception:wrong-num-args
  266. (let ((a (make-array #f 5)))
  267. (array-map! a sqrt
  268. (make-array 16.0 5) (make-array 16.0 5))
  269. (equal? a (make-array 4.0 5))))
  270. (pass-if "rpsubr"
  271. (let ((a (make-array 'foo 5)))
  272. (array-map! a = (make-array 99 5) (make-array 77 5))
  273. (equal? a (make-array #f 5))))
  274. (pass-if "asubr"
  275. (let ((a (make-array 'foo 5)))
  276. (array-map! a - (make-array 99 5) (make-array 11 5))
  277. (equal? a (make-array 88 5))))
  278. (pass-if "+"
  279. (let ((a (make-array #f 4)))
  280. (array-map! a + #(1 2 3 4) #(5 6 7 8))
  281. (equal? a #(6 8 10 12))))
  282. (pass-if "noncompact arrays 1"
  283. (let ((a #2((0 1) (2 3)))
  284. (c (make-array 0 2)))
  285. (begin
  286. (array-map! c + (array-row a 1) (array-row a 1))
  287. (array-equal? c #(4 6)))))
  288. (pass-if "noncompact arrays 2"
  289. (let ((a #2((0 1) (2 3)))
  290. (c (make-array 0 2)))
  291. (begin
  292. (array-map! c + (array-col a 1) (array-col a 1))
  293. (array-equal? c #(2 6)))))
  294. (pass-if "noncompact arrays 3"
  295. (let ((a #2((0 1) (2 3)))
  296. (c (make-array 0 2)))
  297. (begin
  298. (array-map! c + (array-col a 1) (array-row a 1))
  299. (array-equal? c #(3 6)))))
  300. (pass-if "noncompact arrays 4"
  301. (let ((a #2((0 1) (2 3)))
  302. (c (make-array 0 2)))
  303. (begin
  304. (array-map! c + (array-col a 1) (array-row a 1))
  305. (array-equal? c #(3 6)))))
  306. (pass-if "offset arrays 1"
  307. (let ((a #2@1@-3((0 1) (2 3)))
  308. (c (make-array 0 '(1 2) '(-3 -2))))
  309. (begin
  310. (array-map! c + a a)
  311. (array-equal? c #2@1@-3((0 2) (4 6)))))))
  312. ;; note that array-copy! has the opposite behavior.
  313. (pass-if-exception "matching behavior I" exception:shape-mismatch
  314. (let ((a #(1 2))
  315. (b (make-array 0 3)))
  316. (array-map! b values a)
  317. (equal? b #(1 2 0))))
  318. (pass-if "matching behavior II"
  319. (let ((a #(1 2 3))
  320. (b (make-array 0 2)))
  321. (array-map! b values a)
  322. (equal? b #(1 2))))
  323. ;; here both a & b are are unrollable down to the first axis, but the
  324. ;; size mismatch limits unrolling to the last axis only.
  325. (pass-if "matching behavior III"
  326. (let ((a #3(((1 2) (3 4) (5 6)) ((7 8) (9 10) (11 12))))
  327. (b (make-array 0 2 2 2)))
  328. (array-map! b values a)
  329. (array-equal? b #3(((1 2) (3 4)) ((7 8) (9 10)))))))
  330. ;;;
  331. ;;; array-for-each
  332. ;;;
  333. (with-test-prefix "array-for-each"
  334. (with-test-prefix "1 source"
  335. (pass-if-equal "rank 0"
  336. '(99)
  337. (let* ((a #0(99))
  338. (l '())
  339. (p (lambda (x) (set! l (cons x l)))))
  340. (array-for-each p a)
  341. l))
  342. (pass-if-equal "noncompact array"
  343. '(3 2 1 0)
  344. (let* ((a #2((0 1) (2 3)))
  345. (l '())
  346. (p (lambda (x) (set! l (cons x l)))))
  347. (array-for-each p a)
  348. l))
  349. (pass-if-equal "vector"
  350. '(3 2 1 0)
  351. (let* ((a #(0 1 2 3))
  352. (l '())
  353. (p (lambda (x) (set! l (cons x l)))))
  354. (array-for-each p a)
  355. l))
  356. (pass-if-equal "shared array"
  357. '(3 2 1 0)
  358. (let* ((a #2((0 1) (2 3)))
  359. (a' (make-shared-array a
  360. (lambda (x)
  361. (list (quotient x 4)
  362. (modulo x 4)))
  363. 4))
  364. (l '())
  365. (p (lambda (x) (set! l (cons x l)))))
  366. (array-for-each p a')
  367. l)))
  368. (with-test-prefix "3 sources"
  369. (pass-if-equal "noncompact arrays 1"
  370. '((3 3 3) (2 2 2))
  371. (let* ((a #2((0 1) (2 3)))
  372. (l '())
  373. (rec (lambda args (set! l (cons args l)))))
  374. (array-for-each rec (array-row a 1) (array-row a 1) (array-row a 1))
  375. l))
  376. (pass-if-equal "noncompact arrays 2"
  377. '((3 3 3) (2 2 1))
  378. (let* ((a #2((0 1) (2 3)))
  379. (l '())
  380. (rec (lambda args (set! l (cons args l)))))
  381. (array-for-each rec (array-row a 1) (array-row a 1) (array-col a 1))
  382. l))
  383. (pass-if-equal "noncompact arrays 3"
  384. '((3 3 3) (2 1 1))
  385. (let* ((a #2((0 1) (2 3)))
  386. (l '())
  387. (rec (lambda args (set! l (cons args l)))))
  388. (array-for-each rec (array-row a 1) (array-col a 1) (array-col a 1))
  389. l))
  390. (pass-if-equal "noncompact arrays 4"
  391. '((3 2 3) (1 0 2))
  392. (let* ((a #2((0 1) (2 3)))
  393. (l '())
  394. (rec (lambda args (set! l (cons args l)))))
  395. (array-for-each rec (array-col a 1) (array-col a 0) (array-row a 1))
  396. l)))
  397. (with-test-prefix "empty arrays"
  398. (pass-if "empty other than last, #t" ; fails in 2.0.9 with bad a.
  399. (let* ((a (list))
  400. (b (make-array 0 2 2))
  401. (c (make-shared-array b (lambda (i j) (list i j)) 0 2)))
  402. (array-for-each (lambda (c) (set! a (cons c a))) c)
  403. (equal? a '())))
  404. (pass-if "empty other than last, f64" ; fails in 2.0.9 with out of range.
  405. (let* ((a (list))
  406. (b (make-typed-array 'f64 0 2 2))
  407. (c (make-shared-array b (lambda (i j) (list i j)) 0 2)))
  408. (array-for-each (lambda (c) (set! a (cons c a))) c)
  409. (equal? a '())))
  410. ;; FIXME add type 'b cases.
  411. (pass-if-exception "empty arrays shape check" exception:shape-mismatch
  412. (let* ((a (list))
  413. (b (make-typed-array 'f64 0 0 2))
  414. (c (make-typed-array 'f64 0 2 0)))
  415. (array-for-each (lambda (b c) (set! a (cons* b c a))) b c)))))