test-ploy.scm 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. ; (c) Daniel Llorens - 2012-2013
  2. ; Tests for (ploy ploy).
  3. ; This library is free software; you can redistribute it and/or modify it under
  4. ; the terms of the GNU General Public License as published by the Free
  5. ; Software Foundation; either version 3 of the License, or (at your option) any
  6. ; later version.
  7. (import (srfi srfi-1) (srfi srfi-9) (srfi srfi-26) (ploy basic) (ploy ploy)
  8. (ploy test))
  9. (assert (= 99 (array-cell-ref #0(99))))
  10. (assert (= 99 (array-cell-ref #(99) 0)))
  11. (assert (= 99 (array-cell-ref (array-cell-ref #2((55 77) (77 99)) 1) 1)))
  12. (define a (array-copy #t #3(((0 1) (2 3)) ((4 5) (6 7)))))
  13. (array-cell-set! a #(12 13) 0 1)
  14. (T a #3(((0 1) (12 13)) ((4 5) (6 7))))
  15. (array-cell-set! a #2((10 11) (12 13)) 0)
  16. (T a #3(((10 11) (12 13)) ((4 5) (6 7))))
  17. (define (test-A A)
  18. (for-each
  19. (lambda (d)
  20. (let ((data (if (zero? d) '(()) (apply list-product (map iota (take ($ A) d))))))
  21. (for-each
  22. (lambda (i)
  23. (T (apply array-cell-ref A i) (apply array-cell-ref A i)))
  24. data)))
  25. (iota (+ 1 (rank A)))))
  26. (test-A (i. 2 3 2))
  27. (test-A (i. 2 3))
  28. (test-A (i. 2))
  29. (test-A (i.))
  30. ; @TODO benchmark this other version of i., maybe C.
  31. (define (i.* . args)
  32. (let* ((a (apply make-array *unspecified* args))
  33. (a1 (array-contents a))
  34. (z (tally a1)))
  35. (let loop ((i 0))
  36. (cond ((< i z) (array-set! a1 i i) (loop (1+ i)))
  37. (else a)))))
  38. ; ---------------------------------------------
  39. ; reshape (@TODO complete).
  40. ; ---------------------------------------------
  41. ; corner cases, allow placeholder to be zero.
  42. (T (reshape (i. 0 3) #t 2) #2:0:2())
  43. (T (reshape (i. 3 0) #t 2) #2:0:2())
  44. (T (reshape (i. 0 3) 2 #t) #2(() ()))
  45. (T (reshape (i. 3 0) 2 #t) #2(() ()))
  46. ; corner cases, flag error if placeholder can't be computed.
  47. (assert-fail (reshape (i. 3 2) 0 #t) "bad dim deduction with empty shape")
  48. (T-msg "bad size deduction from scalar" #(9) (reshape 9 #t))
  49. ; doc examples.
  50. (T (reshape (i. 2 3) 6) #(0 1 2 3 4 5))
  51. (T (reshape (i. 2 3) 5) #(0 1 2 3 4))
  52. (T (reshape (i. 2 3) 7) #(0 1 2 3 4 5 0))
  53. (T (reshape (i. 2 3) 3 2) #2((0 1) (2 3) (4 5)))
  54. (T (reshape (i. 2 3) 2 2 2) #3(((0 1) (2 3)) ((4 5) (0 1))))
  55. (T (reshape (i. 2 3) 4 2) #2((0 1) (2 3) (4 5) (0 1)))
  56. (T (reshape (i. 2 3) #t 2) #2((0 1) (2 3) (4 5)))
  57. (T (reshape (i. 2 3) 2 #t) #2((0 1 2) (3 4 5)))
  58. (T (reshape (i. 2 3) #t) #(0 1 2 3 4 5))
  59. (T (reshape (i. 2 3) 0 3) #2:0:3())
  60. (T (reshape (i. 2 3) 0) #())
  61. (T (reshape (i. 2 3) 0 0 0) #3())
  62. (assert-fail (reshape (i. 2 3) 0 #t))
  63. (assert-fail (reshape (i. 2 3) 4 #t))
  64. (T (reshape (i. 2 3)) 0)
  65. ; ---------------------------------------------
  66. ; simpler ply. Match frames at each nesting level, no types. Lots of copying,
  67. ; testing only. @TODO This approach could work for nested (ragged) vectors.
  68. ; ---------------------------------------------
  69. (define (match-frame* A f r)
  70. (cond ((= (length f) (- (rank A) r))
  71. A)
  72. ((not (array? A))
  73. (match-frame* (make-array A) f r))
  74. (else
  75. (apply make-shared-array A
  76. (lambda i (append (take i (- (rank A) r)) (take-right i r)))
  77. (append f (take-right ($ A) r))))))
  78. (define (prefix-frame* A r)
  79. "Frame common to all arrays A with cell ranks r"
  80. (fold (lambda (A r f)
  81. (let ((fA (drop-right! ($ A) r)))
  82. (let loop ((s f) (sA fA))
  83. (cond ((null? sA) f)
  84. ((null? s) fA)
  85. ((= (car s) (car sA)) (loop (cdr s) (cdr sA)))
  86. (else (error "shape clash" A r))))))
  87. '() A r))
  88. (define (ply* op . a)
  89. (let ((op (if (verb? op) op (verb op))))
  90. (let ((ro (apply verb-actual-ri op (map rank a)))
  91. (sop (if (verb-final? op)
  92. (verb-op op)
  93. (lambda a (apply ply* (verb-op op) a)))))
  94. (let ((f (prefix-frame* a ro)))
  95. (if (null? f)
  96. (apply sop a)
  97. (let ((a (map (cut match-frame* <> f <>) a ro)))
  98. (collapse-array
  99. #t
  100. (let ((o (apply make-array *unspecified* f)))
  101. (apply array-map/frame! o f sop a)
  102. o))))))))
  103. ; prefix-frame*, match-frame*
  104. (define x 3)
  105. (define A #(1 2 3))
  106. (define B #2((1 2) (1 2) (1 2)))
  107. (define f00 (prefix-frame* (list A B) (list 0 0)))
  108. (define f01 (prefix-frame* (list A B) (list 0 1)))
  109. (define f10 (prefix-frame* (list A B) (list 1 0)))
  110. (define f11 (prefix-frame* (list A B) (list 1 1)))
  111. (define f00_ (prefix-frame* (list B A) (list 0 0)))
  112. (define f01_ (prefix-frame* (list B A) (list 1 0)))
  113. (define f10_ (prefix-frame* (list B A) (list 0 1)))
  114. (define f11_ (prefix-frame* (list B A) (list 1 1)))
  115. (assert (equal? f00 f00_ '(3 2)))
  116. (assert (equal? f01 f01_ '(3)))
  117. (assert (equal? f10 f10_ '(3 2)))
  118. (assert (equal? f11 f11_ '(3)))
  119. (T (match-frame* A f00 0) #2((1 1) (2 2) (3 3)))
  120. (T (match-frame* B f00 0) #2((1 2) (1 2) (1 2)))
  121. (T (match-frame* A f01 0) #(1 2 3))
  122. (T (match-frame* B f01 1) #2((1 2) (1 2) (1 2)))
  123. (T (match-frame* A f10 1) #3(((1 2 3) (1 2 3)) ((1 2 3) (1 2 3)) ((1 2 3) (1 2 3))))
  124. (T (match-frame* B f10 0) #2((1 2) (1 2) (1 2)))
  125. (T (match-frame* A f11 1) #2((1 2 3) (1 2 3) (1 2 3)))
  126. (T (match-frame* B f11 1) #2((1 2) (1 2) (1 2)))
  127. (T '(2) (prefix-frame* '(#2((0 0) (0 0)) #(0 0)) '(1 1)))
  128. (T 9 (match-frame* 9 '() 0))
  129. (define x 3)
  130. (define A #(1 2 3))
  131. (define B #2((1 2 3) (1 2 3) (1 2 3)))
  132. (T (ply - A B) (ply* - A B) #2((0 -1 -2) (1 0 -1) (2 1 0)))
  133. (T (ply - B A) (ply* - B A) #2((0 1 2) (-1 0 1) (-2 -1 0)))
  134. (T (ply - x A) (ply* - x A) #(2 1 0))
  135. (T (ply - x B) (ply* - x B) #2((2 1 0) (2 1 0) (2 1 0)))
  136. (T (ply - A x) (ply* - A x) #(-2 -1 0))
  137. (T (ply - B x) (ply* - B x) #2((-2 -1 0) (-2 -1 0) (-2 -1 0)))
  138. ; rank 0 inner op, deduced...
  139. (T (ply + #(10 20) #2((1 2 3) (1 2 3)))
  140. #2((11 12 13) (21 22 23)))
  141. ; a case that requires rank>2 loop.
  142. ; (10 20) + (2 2 2 $ 1 + i. 8)
  143. (T (ply + #(10 20) (reshape #(1 2 3 4 5 6 7 8) 2 2 2))
  144. #3(((11 12) (13 14)) ((25 26) (27 28))))
  145. ; rank 0 inner op, explicit.
  146. (T (ply (verb + '() 0 0) #(10 20) #2((1 2 3) (1 2 3)))
  147. #2((11 12 13) (21 22 23)))
  148. ; specifying output rank.
  149. (T (ply (verb + '() 0 0) #(10 20) #2((1 2 3) (1 2 3)))
  150. #2((11 12 13) (21 22 23)))
  151. ; rank 0 with wrapped ranks.
  152. ; (10 * 1 + i.2) (+"0 0) (2 3 $ 1 2 3 1 2 3)
  153. (T (ply (w/rank + 0 0) #(10 20) #2((1 2 3) (1 2 3)))
  154. #2((11 12 13) (21 22 23)))
  155. ; (10 * 1 + i.3) (+"1 1) (2 3 $ 1 2 3 1 2 3)
  156. (T (ply (w/rank + 1 1) #(10 20 30) #2((1 2 3) (1 2 3)))
  157. #2((11 22 33) (11 22 33)))
  158. ; (10 * 1 + i.3) (+"1 0) (2 3 $ 1 2 3 5 6 7)
  159. (T (ply (w/rank + 1 0) #(10 20 30) #2((1 2 3) (5 6 7)))
  160. #3(((11 21 31) (12 22 32) (13 23 33)) ((15 25 35) (16 26 36) (17 27 37))))
  161. ; (10 * 1 + i.2) (+"1 2) (2 3 $ 1 2 3 5 6 7)
  162. (T (ply (w/rank + 1 2) #(10 20) #2((1 2 3) (5 6 7)))
  163. #2((11 12 13) (25 26 27)))
  164. ; rank 0 with nested ranks.
  165. ; 100 200 300 +"0"0 _ (1 2 3 4) NB. From Rich2006 ch. 6
  166. (T (ply (w/rank (w/rank + 0 0) 0 '_) #(100 200 300) #(1 2 3 4))
  167. #2((101 102 103 104) (201 202 203 204) (301 302 303 304)))
  168. ; 100 200 +"0"_ 0 (1 2 3) NB. From Rich2006 ch. 6
  169. (T (ply (w/rank (w/rank + 0 0) '_ 0) #(100 200) #(1 2 3))
  170. #2((101 201) (102 202) (103 203)))
  171. (define (_sqr a) (* a a))
  172. (define _sqrm
  173. (verb (lambda (a)
  174. (array-fold (lambda (a c) (+ c (_sqr (real-part a)) (_sqr (imag-part a))))
  175. 0. a))
  176. #f 1))
  177. (define _sqrmd
  178. (verb (lambda (a b)
  179. (array-fold (lambda (a b c)
  180. (let ((a (- a b)))
  181. (+ c (_sqr (real-part a)) (_sqr (imag-part a)))))
  182. 0. a b))
  183. #f 1 1))
  184. ; rank 1 inner op.
  185. (T-eps 0. (ply _sqrm #2((1 1 1) (2 2 2))) #(3. 12.))
  186. (T (ply (verb tally '() 1) #2((1 1 1) (2 2 2))) #(3 3))
  187. ; specifying output rank, so collapse-rank can be elided.
  188. (T (ply (verb from (lambda (x y) '(3)) -1 0)
  189. (array-copy 's32 (i. 3 3 3))
  190. #(2 0 1))
  191. ; alternative: output-shape will be called with the shapes of the cells.
  192. (ply (verb from (lambda (x y) (cdr x)) -1 0)
  193. (array-copy 's32 (i. 3 3 3))
  194. #(2 0 1))
  195. #2s32((6 7 8) (9 10 11) (21 22 23)))
  196. ; @TODO since the output is pile'd, any output rank is ok. However, this should somehow be known in advance to preallocate the result array.
  197. (T (ply (verb (cut sort <> <) #f 1) #2((4 2 1) (1 3 2)))
  198. #2((1 2 4) (1 2 3)))
  199. (define _cross (verb (lambda (a b)
  200. (let ((a (cut array-ref a <>))
  201. (b (cut array-ref b <>)))
  202. (vector (- (* (a 1) (b 2)) (* (a 2) (b 1)))
  203. (- (* (a 2) (b 0)) (* (a 0) (b 2)))
  204. (- (* (a 0) (b 1)) (* (a 1) (b 0))))))
  205. #f 1 1))
  206. ; rank 1 with rank extension.
  207. (T (ply _cross #2((1 0 0) (0 1 0)) #2((0 1 0) (0 0 1)))
  208. #2((0 0 1) (1 0 0)))
  209. (T (ply _cross #(1 0 0) #(0 0 1))
  210. #(0 -1 0))
  211. (T (ply _cross #2((1 0 0) (0 1 0)) #(0 0 1))
  212. #2((0 -1 0) (1 0 0)))
  213. (T (ply _cross #(0 0 1) #2((1 0 0) (0 1 0)))
  214. #2((0 1 0) (-1 0 0)))
  215. ; rank 1 with wrapped rank.
  216. (T (ply (w/rank _cross 2 1) #2((1 0 0) (0 1 0)) #(0 0 1))
  217. #2((0 -1 0) (1 0 0)))
  218. (T (ply _cross #3(((1 0 0) (0 1 0)) ((2 0 0) (0 2 0))) #(0 0 1))
  219. #3(((0 -1 0) (1 0 0)) ((0 -2 0) (2 0 0))))
  220. (T (ply _cross #3(((1 0 0) (0 1 0)) ((2 0 0) (0 2 0))) #2((0 0 1) (0 0 2)))
  221. #3(((0 -1 0) (1 0 0)) ((0 -4 0) (4 0 0))))
  222. (T (ply (w/rank _cross 2 2) #3(((1 0 0) (0 1 0)) ((2 0 0) (0 2 0))) #2((0 0 1) (0 0 2)))
  223. #3(((0 -1 0) (2 0 0)) ((0 -2 0) (4 0 0))))
  224. (T (ply (w/rank _cross 3 2) #3(((1 0 0) (0 1 0)) ((2 0 0) (0 2 0))) #2((0 0 1) (0 0 2)))
  225. #3(((0 -1 0) (1 0 0)) ((0 -4 0) (4 0 0))))
  226. ; rank 2.
  227. (define (_invert a)
  228. (let* ((a (cut array-ref a <> <>))
  229. (D (- (* (a 0 0) (a 1 1)) (* (a 0 1) (a 1 0)))))
  230. (reshape `#(,(a 1 1) ,(- (a 0 1)) ,(- (a 1 0)) ,(a 0 0)) 2 2)))
  231. (T-eps 0.0
  232. (ply (verb _invert values 2) #3(((1 0) (0 1)) ((1 1) (0 1))))
  233. #3(((1.0 0.0) (0.0 1.0)) ((1.0 -1.0) (0.0 1.0))))
  234. ; mixed ranks inner op (in J( { b. 0 -> 1 0 _ )
  235. ; (2 2 $ 3 2 0 1) { 1 2 3 4
  236. (T (ply (verb from #f 1 0) #(1 2 3 4) #2((3 2) (0 1)))
  237. #2((4 3) (1 2)))
  238. ; 0 1 1 0 { (2 2 $ 3 2 0 1)
  239. (T (ply (verb from #f 2 0) #2((3 2) (0 1)) #(0 1 1 0))
  240. #2((3 2) (0 1) (0 1) (3 2)))
  241. ; 0 1 1 0 ({"1 2) (2 2 $ 3 2 0 1)
  242. (T (ply (w/rank (verb from #f 2 0) 2 1) #2((3 2) (0 1)) #(0 1 1 0))
  243. #2((3 2) (0 1) (0 1) (3 2)))
  244. ; (2 2 $ 0 1 1 0) { (2 2 $ 3 2 0 1)
  245. (T (ply (verb from #f 2 0) #2((3 2) (0 1)) #2((0 1) (1 0)))
  246. #3(((3 2) (0 1)) ((0 1) (3 2))))
  247. ; (2 2 $ 0 1 1 0) ({"1 2) (2 2 $ 3 2 0 1)
  248. (T (ply (w/rank (verb from #f 2 0) 2 1) #2((3 2) (0 1)) #2((0 1) (1 0)))
  249. #3(((3 2) (0 1)) ((0 1) (3 2))))
  250. ; (2 2 $ 0 1 1 0) ({"2 1) (2 2 $ 3 2 0 1)
  251. (T (ply (w/rank (verb from #f '_ 0) 1 2) #2((3 2) (0 1)) #2((0 1) (1 0)))
  252. #3(((3 2) (2 3)) ((0 1) (1 0))))
  253. ; (i. 3 4) +"1"2 i. 2 3 4
  254. (T (ply (w/rank (w/rank + 1 1) 2 2) (i. 3 4) (i. 2 3 4))
  255. #3(((0 2 4 6) (8 10 12 14) (16 18 20 22)) ((12 14 16 18) (20 22 24 26) (28 30 32 34))))
  256. ; re$* provides a case with output rank > input rank. Also a case where inner op rank is larger than out.
  257. ; note that J $ uses the list of items to fill the shape, so s $ a ~ (re$* s (from a 0)).
  258. (define (re$* s a)
  259. (let ((rs (tally s)))
  260. (apply make-shared-array
  261. (if (array? a) a (make-typed-array (array-type* a) a))
  262. (lambda i (drop i rs))
  263. (append (vector->list s) ($ a)))))
  264. ; (2 3) $ 1 2 $ 1 2
  265. (T (ply (verb re$* #f 1 '_) #(2 3) #(1 2))
  266. #3(((1 2) (1 2) (1 2)) ((1 2) (1 2) (1 2))))
  267. ; (2 3) ($"1 0) 1 2 $ 1 2
  268. (T (ply (w/rank (verb re$* #f 1 '_) 1 0) #(2 3) #(1 2))
  269. #3(((1 1 1) (1 1 1)) ((2 2 2) (2 2 2))))
  270. ; exercise a case with in rank 0, out rank > 0, where there's a work around array-map's output.
  271. ; (2 3) ($"1 0) 1 3 $ 1 2 3
  272. (T (ply (verb (cut re$* #(2 3) <>) #f 0) #(1 2 3))
  273. #3(((1 1 1) (1 1 1)) ((2 2 2) (2 2 2)) ((3 3 3) (3 3 3))))
  274. ; This is J $. J considers a scalar to have 1 item, so that's a special case.
  275. ; @TODO Don't reuse reshape, we know more here and can avoid work.
  276. ; @TODO interesting case for oshape (can do better than #f).
  277. (define (reshape-J s A)
  278. (if (zero? (rank A))
  279. (apply make-array A (vector->list s))
  280. (apply reshape A (append (vector->list s) (cdr ($ A))))))
  281. ; (2 3) $ 1 2
  282. (T (ply (verb reshape-J #f 1 '_) #(2 3) #(1 2))
  283. #2((1 2 1) (2 1 2)))
  284. ; (2 3) $ 2 2 $ 1 2 3 4
  285. (T (ply (verb reshape-J #f 1 '_) #(2 3) #2((1 2) (3 4)))
  286. #3(((1 2) (3 4) (1 2)) ((3 4) (1 2) (3 4))))
  287. ; (2 3) ($"1 0) 1 2
  288. (T (ply (w/rank (verb reshape-J #f 1 '_) 1 0) #(2 3) #(1 2))
  289. #3(((1 1 1) (1 1 1)) ((2 2 2) (2 2 2))))
  290. ; empty arrays.
  291. (T (ply + (i. 0 2) 7) #2:0:2())
  292. (T (ply + (i. 2 0) 7) #2(() ()))
  293. ; ------------------------
  294. ; other tests with higher rank arrays.
  295. ; ------------------------
  296. ; single ply; marred by array copying and no-op looping.
  297. ; see w/rank chain in (0 0 0 1) -> (0 0 1 1) -> (0 1 1 1) out.
  298. (define (_meshgrid . l)
  299. (let ((n (length l)))
  300. (apply
  301. ply/t 'f64
  302. (let loop ((i (- n 1)))
  303. (if (zero? i)
  304. vector
  305. (apply w/rank (loop (- i 1)) (append (make-list (- n i) 0) (make-list i 1)))))
  306. l)))
  307. (define (_meshgrid-last . l)
  308. (let ((n (length l)))
  309. (apply
  310. ply/t 'f64
  311. (let loop ((i (- n 1)))
  312. (if (zero? i)
  313. vector
  314. (apply w/rank (loop (- i 1)) (append (make-list i 1) (make-list (- n i) 0)))))
  315. l)))
  316. (T (apply _meshgrid (map i. (iota 4 1)))
  317. (apply ply/t 'f64 (w/rank (w/rank (w/rank vector 0 0 0 1) 0 0 1 1) 0 1 1 1)
  318. (map i. (iota 4 1)))
  319. #5f64(((((0 0 0 0) (0 0 0 1) (0 0 0 2) (0 0 0 3))
  320. ((0 0 1 0) (0 0 1 1) (0 0 1 2) (0 0 1 3))
  321. ((0 0 2 0) (0 0 2 1) (0 0 2 2) (0 0 2 3)))
  322. (((0 1 0 0) (0 1 0 1) (0 1 0 2) (0 1 0 3))
  323. ((0 1 1 0) (0 1 1 1) (0 1 1 2) (0 1 1 3))
  324. ((0 1 2 0) (0 1 2 1) (0 1 2 2) (0 1 2 3))))))
  325. (T (apply _meshgrid-last (map i. (iota 4 1)))
  326. (apply ply/t 'f64 (w/rank (w/rank (w/rank vector 1 0 0 0) 1 1 0 0) 1 1 1 0)
  327. (map i. (iota 4 1)))
  328. #5f64(((((0 0 0 0)) ((0 1 0 0))) (((0 0 1 0)) ((0 1 1 0))) (((0 0 2 0)) ((0 1 2 0))))
  329. ((((0 0 0 1)) ((0 1 0 1))) (((0 0 1 1)) ((0 1 1 1))) (((0 0 2 1)) ((0 1 2 1))))
  330. ((((0 0 0 2)) ((0 1 0 2))) (((0 0 1 2)) ((0 1 1 2))) (((0 0 2 2)) ((0 1 2 2))))
  331. ((((0 0 0 3)) ((0 1 0 3))) (((0 0 1 3)) ((0 1 1 3))) (((0 0 2 3)) ((0 1 2 3))))))
  332. ; out, of which the meshgrid loop above is a case.
  333. (T (out * #(10 20 30) (i. 5))
  334. #2((0 10 20 30 40) (0 20 40 60 80) (0 30 60 90 120)))
  335. ; out with op ranks != 0.
  336. (T-eps 0
  337. (out _sqrmd (i. 3 2) (i. 4 2))
  338. #2((0 8 32 72) (8 0 8 32) (32 8 0 8)))
  339. ; out with different ranks. @TODO A case with rank '_ or negative.
  340. (define (_cons a b) (list->vector (cons a (vector->list b))))
  341. (T (out (verb _cons #f 0 1) (i. 2) (i. 3 4))
  342. #3(((0 0 1 2 3) (0 4 5 6 7) (0 8 9 10 11))
  343. ((1 0 1 2 3) (1 4 5 6 7) (1 8 9 10 11))))
  344. (T (out (verb _cons #f 1 1) (i. 2) (i. 3 4))
  345. #2((#(0 1) 0 1 2 3) (#(0 1) 4 5 6 7) (#(0 1) 8 9 10 11)))
  346. ; with more args, giving oshape. @BUG Mismatched shape/rank/args are not caught.
  347. (T (out (verb vector '(3) 0 0 0) #(1 2) #(10 20) #(100 200))
  348. #4((((1 10 100) (1 10 200)) ((1 20 100) (1 20 200)))
  349. (((2 10 100) (2 10 200)) ((2 20 100) (2 20 200)))))
  350. ; test against once array-slice-for-each bug.
  351. (T (out (verb list '() 1 1) #2((10 45)(10 0)) #2((a b) (c d)))
  352. #2(((#1(10 45) #1(a b)) (#1(10 45) #1(c d))) ((#1(10 0) #1(a b)) (#1(10 0) #1(c d)))))
  353. ; profile giving oshape or not. @BUG Giving it is actually slower.
  354. ; ,profile (out (verb vector '(3) 0 0 0) (i. 100) (i. 100) (i. 100))
  355. ; ,profile (out (verb vector #f 0 0 0) (i. 100) (i. 100) (i. 100))
  356. ; ------------------------
  357. ; ply-n/o
  358. ; ------------------------
  359. (define o (vector 9 4))
  360. (ply-n/o (verb (lambda (v) (set! o (ply + v o))) #f 1)
  361. (i. 10 2))
  362. (T o #(99 104))
  363. ; ------------------------
  364. ; linspace.
  365. ; ------------------------
  366. (T (linspace. 0 10 0) #())
  367. (T (linspace. 0 10 1) #(0))
  368. (T (linspace. 0 10 2) #(0 10))
  369. (T (linspace. 0 10 3) #(0 5 10))
  370. (T (linspace. 0 10 4) #(0 10/3 20/3 10))
  371. (T (linspace-m. 0 10 0) #())
  372. (T (linspace-m. 0 10 1) #())
  373. (T (linspace-m. 0 10 2) #(0))
  374. (T (linspace-m. 0 10 3) #(0 5))
  375. (T (linspace-m. 0 10 4) #(0 10/3 20/3))
  376. ; ------------------------
  377. ; some tests about the need for optimization.
  378. ; ------------------------
  379. ; cf uniform-grid-cube-points.
  380. (define (_uniform-grid-cube-points rank n)
  381. (reshape (apply _meshgrid-last (make-list rank (linspace. 0 1 n)))
  382. (expt n rank) rank))
  383. (define (test-each rank n ext)
  384. (transpose-array
  385. (ply + (transpose-array (ply * ext (_uniform-grid-cube-points rank n)) 1 0)
  386. (reshape (* -.5 ext) rank))
  387. 1 0))
  388. ; (ext * ugc) ("+1 1) (rank $ -.5 * ext)
  389. (define (test-each* rank n ext)
  390. (ply (w/rank + 1 1)
  391. (ply * ext (_uniform-grid-cube-points rank n))
  392. (reshape (* -.5 ext) rank)))
  393. (define (test-each** rank n ext)
  394. (ply* (w/rank + 1 1)
  395. (ply* * ext (_uniform-grid-cube-points rank n))
  396. (reshape (* -.5 ext) rank)))
  397. (T (test-each 2 100 1) (test-each* 2 100 1) (test-each** 2 100 1))
  398. (T (test-each 3 30 1) (test-each* 3 30 1) (test-each** 3 30 1))
  399. ; maybe
  400. ; (+ (each (* ext (uniform-grid-cube-points rank n)))
  401. ; (reshape (* -.5 ext) rank))
  402. ; ,profile (test-each 2 100 1)
  403. ; ,profile (test-each* 2 100 1)
  404. ; ,profile (test-each 3 30 1)
  405. ; ,profile (test-each* 3 30 1)
  406. ; -----------------------------------------------
  407. ; with precomputed nested frames & ranks, or not.
  408. ; -----------------------------------------------
  409. (define a (i. 3 2))
  410. (define b (i. 3))
  411. (define c (i. 2))
  412. (T (ply (w/rank + 1 0) a b) (ply* (w/rank + 1 0) a b) #2((0 1) (3 4) (6 7)))
  413. (T (ply (w/rank + 1 1) a c) (ply* (w/rank + 1 1) a c) #2((0 2) (2 4) (4 6)))
  414. ; -----------------------------------------------
  415. ; developing (from)
  416. ; -----------------------------------------------
  417. ; How to do cartesian selection with arbitrary indices in a single ply.
  418. ; @TODO this could be used e.g. in (from), after the scalars and J-selectors have been 'beaten'.
  419. ; Simple enough along a single dimension,
  420. (ply (w/rank (verb array-cell-ref #f '_ 0) 3 1) (i. 10 10 10) #(1 2))
  421. (ply (w/rank (verb array-cell-ref #f '_ 0) 2 1) (i. 10 10 10) #(1 2))
  422. (ply (w/rank (verb array-cell-ref #f '_ 0) 1 1) (i. 10 10 10) #(1 2))
  423. ; Let's say we have index vectors a, b, c. Remember what prefix-frame does!
  424. ; we start with -> (w/rank '_ 0 1 1) -> (w/rank '_ 0 0 1) -> (w/rank '_ 0 0 0)
  425. ; [---] [A] | [---] [AB] | [---] [ABC] | [---]
  426. ; [a] [a] | [aB] | [aBC] |
  427. ; [b] [A] | [b] [Ab] | [AbC] |
  428. ; [c] [A] | [c] [AB] | [c] [ABc] |
  429. ; The last w/rank is redundant, so:
  430. (T (ply (w/rank (w/rank (verb array-cell-ref #f '_ 0 0 0) '_ 0 0 1) '_ 0 1 1)
  431. (i. 10 10 10)
  432. #(1 2)
  433. #(3 4 5)
  434. #(6 7 8 9))
  435. (ply (w/rank (verb array-cell-ref #f '_ 0) 1 1)
  436. (ply (w/rank (verb array-cell-ref #f '_ 0) 2 1)
  437. (ply (w/rank (verb array-cell-ref #f '_ 0) 3 1)
  438. (i. 10 10 10)
  439. #(1 2))
  440. #(3 4 5))
  441. #(6 7 8 9))
  442. #3(((136 137 138 139) (146 147 148 149) (156 157 158 159))
  443. ((236 237 238 239) (246 247 248 249) (256 257 258 259))))
  444. ; This gives -> (w/rank '_ 0 2 1) -> (w/rank '_ 0 0 1) -> etc.
  445. ; [---] [A] | [---] [ABC] | [---]
  446. ; [a] [a] | [aBC] |
  447. ; [bc] [A] | [bc] [Abc] |
  448. ; [d] [A] | [d] [ABC] | [d]
  449. (T (ply (w/rank (w/rank (verb array-cell-ref #f '_ 0 0 0) '_ 0 0 1) '_ 0 2 1)
  450. (i. 10 10 10)
  451. #(0 1)
  452. #2((2 3 4) (5 6 7))
  453. #(8 9))
  454. #4(((( 28 29) ( 38 39) ( 48 49)) (( 58 59) ( 68 69) ( 78 79)))
  455. (((128 129) (138 139) (148 149)) ((158 159) (168 169) (178 179)))))
  456. ; benchmarks
  457. ; 1. single ply saves much array-copy.
  458. ; 2. fixing args of inf rank (relative to the loop) should be done by ply.
  459. (define i10 (i. 10 10 10))
  460. (define i100 (i. 100 100 100))
  461. (define (test0 iN)
  462. (repeat 1000 (ply (w/rank (w/rank (verb (cut array-cell-ref iN <> <> <>) '() 0 0 0) 0 0 1) 0 1 1)
  463. #(1 2 3) #(4 5 6 7) #(6 7 8 9))))
  464. (define (test1 iN)
  465. (repeat 1000 (ply (w/rank (w/rank (verb (cut array-cell-ref iN <> <> <>) #f 0 0 0) 0 0 1) 0 1 1)
  466. #(1 2 3) #(4 5 6 7) #(6 7 8 9))))
  467. (define (test2 iN)
  468. (repeat 1000 (ply (w/rank (w/rank (verb array-cell-ref #f '_ 0 0 0) '_ 0 0 1) '_ 0 1 1)
  469. iN #(1 2 3) #(4 5 6 7) #(6 7 8 9))))
  470. (define (test3 iN)
  471. (repeat 1000 (ply (w/rank (verb array-cell-ref #f '_ 0) 1 1)
  472. (ply (w/rank (verb array-cell-ref #f '_ 0) 2 1)
  473. (ply (w/rank (verb array-cell-ref #f '_ 0) 3 1)
  474. iN #(1 2 3))
  475. #(4 5 6 7))
  476. #(6 7 8 9))))
  477. (define (crude-median . a)
  478. (list-ref (sort a <) (ceiling (/ (- (length a) 1) 2))))
  479. (define (median-time n proc)
  480. (apply crude-median (map-in-order (lambda (i) (time (proc))) (iota n))))
  481. (let ((t0 (time (test0 i10)))
  482. (t1 (time (test1 i10)))
  483. (t2 (time (test2 i10)))
  484. (t3 (time (test3 i10))))
  485. (format! "\n~:{test~a i10 ~a\n~}" (zip (iota 4) (list t0 t1 t2 t3)))
  486. ; t2 should be < t3, but too variable too enforce.
  487. (assert (and (< t1 t2) (< t1 t3))))
  488. (let ((t0 (time (test0 i100)))
  489. (t1 (time (test1 i100)))
  490. (t2 (time (test2 i100)))
  491. (t3 (time (test3 i100))))
  492. (format! "~:{test~a i100 ~a\n~}" (zip (iota 4) (list t0 t1 t2 t3)))
  493. (assert (< t1 t2 t3)))
  494. ; from
  495. (T (from #2f64((1 2 3 4) (5 6 7 8)) (- 2 1) (J 2 0 2))
  496. #f64(5.0 7.0))
  497. (T (from #2f64((1 2 3 4) (5 6 7 8)) (- 2 1) (J 2 (- 4 2)))
  498. #f64(7.0 8.0))
  499. (T (from #2f64((1 2 3 4) (5 6 7 8)) (- 2 1) (J 2 (- 4 4)))
  500. #f64(5.0 6.0))
  501. (T (from #2f64((1 2 3 4) (5 6 7 8)) (- 2 1) (J 2 (- 4 4) 2))
  502. #f64(5.0 7.0))
  503. (T (from (i. 2 2) #(0 1) #(0 1)) #2((0 1) (2 3)))
  504. (T (from (i. 2 2) #(1 0) #(0 1)) #2((2 3) (0 1)))
  505. (T (from (i. 2 2) #(0 1) #(1 0)) #2((1 0) (3 2)))
  506. (T (from (i. 2 2) #(1 0) #(1 0)) #2((3 2) (1 0)))
  507. (T (from (i. 2 2) #t #(0 1)) #2((0 1) (2 3)))
  508. (T (from (i. 2 2) #t #(1 0)) #2((1 0) (3 2)))
  509. (T (from (i. 2 2) #(0 1) #t) #2((0 1) (2 3)))
  510. (T (from (i. 2 2) #(1 0) #t) #2((2 3) (0 1)))
  511. (T (from (i. 2 2) #(0 1)) #2((0 1) (2 3)))
  512. (T (from (i. 2 2) #(1 0)) #2((2 3) (0 1)))
  513. (T (from (i. 2 2 2) #(0 1) #(0 1) #(0 1)) #3(((0 1) (2 3)) ((4 5) (6 7))))
  514. (T (from (i. 2 2 2) #(0 1) #(0 1) #(1 0)) #3(((1 0) (3 2)) ((5 4) (7 6))))
  515. (T (from (i. 2 2 2) #(0 1) #(1 0) #(0 1)) #3(((2 3) (0 1)) ((6 7) (4 5))))
  516. (T (from (i. 2 2 2) #(0 1) #(1 0) #(1 0)) #3(((3 2) (1 0)) ((7 6) (5 4))))
  517. (T (from (i. 2 2 2) #(1 0) #(0 1) #(0 1)) #3(((4 5) (6 7)) ((0 1) (2 3))))
  518. (T (from (i. 2 2 2) #(1 0) #(0 1) #(1 0)) #3(((5 4) (7 6)) ((1 0) (3 2))))
  519. (T (from (i. 2 2 2) #(1 0) #(1 0) #(0 1)) #3(((6 7) (4 5)) ((2 3) (0 1))))
  520. (T (from (i. 2 2 2) #(1 0) #(1 0) #(1 0)) #3(((7 6) (5 4)) ((3 2) (1 0))))
  521. (T (from (i. 2 2 2) #t #t #t) #3(((0 1) (2 3)) ((4 5) (6 7))))
  522. (T (from (i. 2 2 2) #t #t #(1 0)) #3(((1 0) (3 2)) ((5 4) (7 6))))
  523. (T (from (i. 2 2 2) #t #(1 0) #t) #3(((2 3) (0 1)) ((6 7) (4 5))))
  524. (T (from (i. 2 2 2) #t #(1 0) #(1 0)) #3(((3 2) (1 0)) ((7 6) (5 4))))
  525. (T (from (i. 2 2 2) #(1 0) #t #t) #3(((4 5) (6 7)) ((0 1) (2 3))))
  526. (T (from (i. 2 2 2) #(1 0) #t #(1 0)) #3(((5 4) (7 6)) ((1 0) (3 2))))
  527. (T (from (i. 2 2 2) #(1 0) #(1 0) #t) #3(((6 7) (4 5)) ((2 3) (0 1))))
  528. (T (from (i. 2 2 2) #(1 0) #(1 0) #(1 0)) #3(((7 6) (5 4)) ((3 2) (1 0))))
  529. ; TODONOW
  530. (T (ply (w/rank (w/rank (verb array-cell-ref #f '_ 0 0) 2 0 1) 2 1 1) (i. 2 2 2) #(1 0) #(1 0))
  531. #3(((3 2) (1 0)) ((7 6) (5 4))))
  532. ; with higher rank indices.
  533. (T (from (i. 2 2) #(0 1) #2((0 1) (1 0)))
  534. (from (i. 2 2) #t #2((0 1) (1 0)))
  535. #3(((0 1) (1 0)) ((2 3) (3 2))))
  536. (T (from (i. 2 2) #(1 0) #2((0 1) (1 0)))
  537. #3(((2 3) (3 2)) ((0 1) (1 0))))
  538. (T (from (i. 2 2) #2((0 1) (1 0)))
  539. (from (i. 2 2) #2((0 1) (1 0)) #t)
  540. (from (i. 2 2) #2((0 1) (1 0)) #(0 1))
  541. #3(((0 1) (2 3)) ((2 3) (0 1))))
  542. (T (from (i. 2 2) #2((0 1) (1 0)) #(1 0))
  543. #3(((1 0) (3 2)) ((3 2) (1 0))))
  544. ; with higher rank indices and empty axis in the middle.
  545. (T (from (i. 2 2 2) #2((0 1) (1 0)) #(0 1) #(0 1))
  546. (from (i. 2 2 2) #2((0 1) (1 0)) #t #(0 1))
  547. #4((((0 1) (2 3)) ((4 5) (6 7))) (((4 5) (6 7)) ((0 1) (2 3)))))
  548. (T (from (i. 2 2 2) #2((0 1) (1 0)) #(1 0) #(0 1))
  549. #4((((2 3) (0 1)) ((6 7) (4 5))) (((6 7) (4 5)) ((2 3) (0 1)))))
  550. ; -------------------------
  551. ; more indexing examples (cf numpy)
  552. ; -------------------------
  553. (define z (i. 5 5))
  554. (define i (i. 2 2))
  555. ; z[i]
  556. (T (from z i)
  557. #3(((0 1 2 3 4) (5 6 7 8 9)) ((10 11 12 13 14) (15 16 17 18 19))))
  558. (T (from z i i) ;
  559. #4((((0 1) (2 3)) ((5 6) (7 8))) (((10 11) (12 13)) ((15 16) (17 18)))))
  560. ; z[i, i] in numpy
  561. (T (ply (cut from z <> <>) i i)
  562. #2((0 6) (12 18)))
  563. ; idem
  564. (T (ply (verb from #f '_ 0 0) z i i)
  565. #2((0 6) (12 18)))
  566. ; p
  567. (T (from z i #2((0 1 0 1) (2 3 2 3))) ; (cat 1 i i)
  568. #4((((0 1 0 1) (2 3 2 3)) ((5 6 5 6) (7 8 7 8)))
  569. (((10 11 10 11) (12 13 12 13)) ((15 16 15 16) (17 18 17 18)))))
  570. ; from the doc.
  571. (T (from (i. 2 3) 0) #(0 1 2))
  572. (T (from (i. 2 3) 0 #t) #(0 1 2))
  573. (T (from (i. 2 3) #t 0) #(0 3))
  574. (T (from #(#(0 1) #(2)) 1) #(2))
  575. (assert-fail (from #(#(0 1) #(2)) 1 0))
  576. (T (from (i. 10 2) (J 2 2) #t) #2((4 5) (6 7)))
  577. (T (from #(1 2 3) #2((0 1) (1 2) (2 0))) #2((1 2) (2 3) (3 1)))
  578. (T (from (i. 10 10) #(3 4) #(7 9 2)) #2((37 39 32) (47 49 42)))
  579. ; --------------------------------
  580. ; reshape, raveling version.
  581. ; --------------------------------
  582. ; used in one of the reshape cases.
  583. (T (index-rect-lsd-first '(2 3 5) '(0 0 0)) 0)
  584. (T (index-rect-lsd-first '(2 3 5) '(1 0 0)) 1)
  585. (T (index-rect-lsd-first '(2 3 5) '(0 1 0)) 2)
  586. (T (index-rect-lsd-first '(2 3 5) '(0 0 1)) 6)
  587. (T (index-rect-lsd-first '(2 3 5) '(1 1 1)) 9)
  588. (T (index-rect '() '()) 0)
  589. (T (index-rect '(2 3 5) '(0 0 0)) 0)
  590. (T (index-rect '(2 3 5) '(1 0 0)) 15)
  591. (T (index-rect '(2 3 5) '(0 1 0)) 5)
  592. (T (index-rect '(2 3 5) '(0 0 1)) 1)
  593. (T (index-rect '(2 3 5) '(1 1 1)) 21)
  594. ; select ravel.
  595. (T (reshape #2((1 2) (3 4)) 2 3) #2((1 2 3) (4 1 2)))
  596. (T (reshape #2((1 2) (3 4)) 2 4 2) #3(((1 2) (3 4) (1 2) (3 4)) ((1 2) (3 4) (1 2) (3 4))))
  597. (T (reshape #(1 2 3 4 5 6 7 8) 2 2 2) #3(((1 2) (3 4)) ((5 6) (7 8))))
  598. (T (reshape #(1 2 3 4 5 6 7 8) 2 2) #2((1 2) (3 4)))
  599. ; copy case.
  600. (T (reshape #2((1 2) (3 4)) 4 3) #2((1 2 3) (4 1 2) (3 4 1) (2 3 4)))
  601. ; copy, but maybe not necessary.
  602. (T (reshape #2((1 2) (3 4)) 4 4 2)
  603. #3(((1 2) (3 4) (1 2) (3 4))
  604. ((1 2) (3 4) (1 2) (3 4))
  605. ((1 2) (3 4) (1 2) (3 4))
  606. ((1 2) (3 4) (1 2) (3 4))))
  607. ; copy case, but maybe not necessary.
  608. (T (reshape #2((1 2) (3 4)) 4 2) #2((1 2) (3 4) (1 2) (3 4)))
  609. ; same size case.
  610. (T (reshape #(1 2 3 4) 1 2 2) #3(((1 2) (3 4))))
  611. (T (reshape #(1 2 3 4) 2 2) #2((1 2) (3 4)))
  612. (T (reshape #(1 2 3 4) 2 2 1) #3(((1) (2)) ((3) (4))))
  613. ; tile cases.
  614. (T (reshape #2((1 2) (3 4)) 4 2 2) #3(((1 2) (3 4)) ((1 2) (3 4)) ((1 2) (3 4)) ((1 2) (3 4))))
  615. (T (reshape #(1 2 3 4) 2 2 2) #3(((1 2) (3 4)) ((1 2) (3 4))))
  616. (T (reshape #(1 2 3 4) 2 3 2) #3(((1 2) (3 4) (1 2)) ((3 4) (1 2) (3 4))))
  617. (T (reshape #(9) 3) #(9 9 9))
  618. ; select cases,
  619. (T (reshape #2((1 2) (3 4)) 2 2) #2((1 2) (3 4)))
  620. (T (reshape #2((1 2) (3 4)) 2) #(1 2))
  621. ; take case.
  622. (T (reshape #(1 2 3 4) 1 1 1) #3(((1))))
  623. (T (reshape #(1 2 3 4 5 6 7 8) 2 3) #2((1 2 3) (4 5 6)))
  624. ; cases that need copy vs cases that do not. @TODO This for every case above.
  625. (define A #2((1 2 3) (4 5 6) (7 8 9)))
  626. (define B (from A (J 3) (J 2)))
  627. (assert (eq? (shared-array-root A) (shared-array-root B)))
  628. (T B #2((1 2) (4 5) (7 8)))
  629. (define Arow (reshape A 9))
  630. (T Arow #(1 2 3 4 5 6 7 8 9))
  631. (assert (eq? (shared-array-root A) (shared-array-root Arow)))
  632. (define Brow (reshape B 6))
  633. (T Brow #(1 2 4 5 7 8))
  634. (define A #(1 2 3 4))
  635. (assert (eq? (shared-array-root A) (shared-array-root (reshape A 2 2 2))))
  636. ; was col->array, row->array
  637. (let ((a #f64(1 2 3 4)))
  638. (T (reshape a #f 1) #2f64((1) (2) (3) (4)))
  639. (T (reshape a 1 #f) #2f64((1 2 3 4))))
  640. ; --------------------------------
  641. ; axis ops.
  642. ; --------------------------------
  643. (T (rollaxis (i. 2 3 4 5) 0 -1)
  644. (transpose-array (i. 2 3 4 5) 3 0 1 2))
  645. (T (rollaxis (i. 2 3 4 5) -1 0)
  646. (transpose-array (i. 2 3 4 5) 1 2 3 0))
  647. (T (rollaxis (i. 2 3 4 5) 0 2)
  648. (transpose-array (i. 2 3 4 5) 2 0 1 3))
  649. (T (rollaxis (i. 2 3 4 5) 3 1)
  650. (transpose-array (i. 2 3 4 5) 0 2 3 1))
  651. (define (axes-to-front a . x)
  652. (let ((xy (sort (zip x (iota (length x)))
  653. (lambda (a b) (< (car a) (car b))))))
  654. (apply transpose-array a
  655. (let loop ((y '()) (xy xy) (i (length x)) (j 0))
  656. (cond ((= j (rank a))
  657. (reverse! y))
  658. ; one of x.
  659. ((and (pair? xy) (= j (first (car xy))))
  660. (loop (cons (second (car xy)) y)
  661. (cdr xy)
  662. i
  663. (+ j 1)))
  664. ; one not of x.
  665. (else
  666. (loop (cons i y)
  667. xy
  668. (+ 1 i)
  669. (+ 1 j))))))))
  670. ; @TODO Probably should test with perm of comb.
  671. (define (combinations l k)
  672. (cond ((zero? k)
  673. '(()))
  674. ((null? l)
  675. '())
  676. (else
  677. (append
  678. (map (cute cons (car l) <>)
  679. (combinations (cdr l) (- k 1)))
  680. (combinations (cdr l) k)))))
  681. (let ((I (i. 2 3 4 5)))
  682. (for-each
  683. (lambda (i)
  684. (T (map (cute list-ref ($ I) <>) (append i (lset-difference = (iota 4) i)))
  685. ($ (apply axes-to-front I i))))
  686. (append-map
  687. (cute combinations (iota (rank I)) <>)
  688. (iota (rank I)))))
  689. ; --------------------------------
  690. ; ply! with suffix matching. @TODO Do I want suffix matching?
  691. ; --------------------------------
  692. (T (ply! (make-array 0 4) (verb (const 2) '()))
  693. #(2 2 2 2))
  694. (T (ply! (make-array 0 4) (const 2))
  695. #(2 2 2 2))
  696. (T (ply! (make-array 0 4) values 9)
  697. #(9 9 9 9))
  698. (T (ply! (make-array 0 4 3) (cut iota. 3 <>) #(1 2 3 4))
  699. #2((1 2 3) (2 3 4) (3 4 5) (4 5 6)))
  700. ; suffix matching.
  701. (T (ply! (make-array 0 4 3) values #(1 2 3))
  702. #2((1 2 3) (1 2 3) (1 2 3) (1 2 3)))
  703. ; prefix matching.
  704. (T (ply!! (make-array 0 4 3) values #(1 2 3 4))
  705. #2((1 1 1) (2 2 2) (3 3 3) (4 4 4)))
  706. (T (ply! (i. 4 3 3) (const #(1 2 3)))
  707. (reshape #(1 2 3) 4 3 3))
  708. (T (ply! (i. 4 3 3) values (out * #(1 2 3) #(1 2 3)))
  709. (reshape (out * #(1 2 3) #(1 2 3)) 4 3 3))
  710. (T (ply! (i. 4 3 3) (w/rank + 1 0) #(1 2 3) #(10 20 30))
  711. (reshape (ply (w/rank + 1 0) #(1 2 3) #(10 20 30)) 4 3 3))
  712. ; --------------------------------
  713. ; Regression test for match-frame (@TODO exact test).
  714. ; --------------------------------
  715. (define q (reshape #(1 2 3) 6 2 8 3))
  716. (define w (reshape #(10 20 30) 2 3))
  717. (define y #2((10 20 30) (10 20 30)))
  718. (T (ply (w/rank (w/rank + 1 1) -1 '_) q w)
  719. (ply (w/rank (w/rank + 1 1) -1 '_) q y))
  720. ; --------------------------------
  721. ; Regression test for array-map/frame (null? case)
  722. ; --------------------------------
  723. (assert (equal? #f64(1 2) (ply/t 'f64 (verb identity #f 1) #(1 2)))
  724. "bad type conversion")
  725. ; --------------------------------
  726. ; There might be more bugs (@TODO research)
  727. ; --------------------------------
  728. ;; ; down to make-shared-array.
  729. ;; (import (srfi srfi-1))
  730. ;; (define a (make-shared-array #0(0) (lambda i '()) 6 2 3)) ; works, should it?
  731. ;; (define a (make-array 0 6 2 3)) ; doesn't work.
  732. ;; (apply make-shared-array a
  733. ;; (lambda i (format #t "$a ~a\n" (array-dimensions a)) (pk 'attempt (append (take i 1) (take i 1) (take-right i 1))))
  734. ;; '(6 2 8 3))
  735. ;; ; rank 0 arrays; (array-map/frame) has a case (null? f) that hands off #0() to op, which 0-rank verbs may not take. Probably should be handled in λ → verb conversion.
  736. ;; (ply + #0(99))
  737. ;; (from #(1 2 3) #0(1))
  738. ; --------------------------------
  739. ; experiments.
  740. ; --------------------------------
  741. ; (out op ...) supports variable arity but (ply (outv op) ...) doesn't.
  742. ; to fix that, have nested-op-frames actualize op with then-known arity.
  743. (define (outv op)
  744. (let* ((op (if (verb? op) op (verb op)))
  745. (ri (verb-ri op))
  746. (n (begin (assert (list? ri) "outv requires known input ranks")
  747. (length ri)))
  748. (infs (make-list n '_)))
  749. (let loop ((i 1))
  750. (if (>= i n)
  751. op
  752. (apply w/rank (loop (+ i 1)) (append (take ri i) (drop infs i)))))))
  753. (T (ply/t 'f64 (outv (verb sqrm-reduce '() 1 1)) (i. 5 4 3) (i. 6 7 3))
  754. (out/t 'f64 (verb sqrm-reduce '() 1 1) (i. 5 4 3) (i. 6 7 3)))