test-reduce.scm 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. ; (c) Daniel Llorens - 2012-2013
  2. ; Tests for (ploy reduce)
  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 test)
  8. (ploy ploy) (ploy reduce) (ploy as-array))
  9. ; -----------------------------
  10. ; reductions: over, folda/foldb, dot.
  11. ; -----------------------------
  12. ; null cases.
  13. (T 3 (folda + 3 #()) (foldb + 3 #()))
  14. (define v-max-sum (verb (lambda (c v) (max c (apply + (vector->list v)))) '() 0 1))
  15. ; there's 1 item, so (max c (+ first item)).
  16. (T 0
  17. (folda v-max-sum -1 #2(()))
  18. (foldb v-max-sum -1 #2(())))
  19. ; no items, so c.
  20. (T -1
  21. (folda v-max-sum -1 #2())
  22. (foldb v-max-sum -1 #2()))
  23. ; these examples from fig. 6.4 ss. of Rich2006.
  24. ; @TODO There's a reason why m +/, d $ work with items. Think about that.
  25. (define +/ (verb (cut over (lambda (x y) (ply + x y)) <>) #f '_))
  26. (define +/a (verb (cut folda + 0 <>) #f '_))
  27. (define +/b (verb (cut foldb + 0 <>) #f '_))
  28. (apply T
  29. #2((6 22 38) (54 70 86))
  30. (map (cute ply <> (i. 2 3 4))
  31. (list (w/rank +/ 1)
  32. (w/rank +/ -2)
  33. (w/rank (w/rank +/ 1) 2)
  34. (w/rank +/a 1)
  35. (w/rank +/a -2)
  36. (w/rank (w/rank +/a 1) 2)
  37. (w/rank +/b 1)
  38. (w/rank +/b -2)
  39. (w/rank (w/rank +/b 1) 2))))
  40. (apply T
  41. #2((12 15 18 21) (48 51 54 57))
  42. (map (cute ply <> (i. 2 3 4))
  43. (list (w/rank +/ 2)
  44. (w/rank +/ -1)
  45. (w/rank +/a 2)
  46. (w/rank +/a -1)
  47. (w/rank +/b 2)
  48. (w/rank +/b -1))))
  49. (apply T
  50. #2((12 14 16 18) (20 22 24 26) (28 30 32 34))
  51. (map (cute ply <> (i. 2 3 4))
  52. (list (w/rank +/ 3)
  53. +/
  54. (w/rank +/a 3)
  55. +/a
  56. (w/rank +/b 3)
  57. +/b)))
  58. ; other cases. @TODO Also benchmark :(
  59. (define A (make-random-array '(10000 2) #:type #t))
  60. (define B (array->list A))
  61. (define max/ (verb (cut over (lambda (a b) (ply max a b)) <>) #f '_))
  62. (define max/a (verb (cut folda max -inf.0 <>) #f '_))
  63. (define max/b (verb (cut foldb max -inf.0 <>) #f '_))
  64. (T-eps 0.0
  65. (list->array 1 (fold (lambda (a b) (map max a b)) (car B) (cdr B)))
  66. (ply max/ A)
  67. (ply max/a A)
  68. (ply max/b A))
  69. (T-eps 0.0
  70. (list->array 1 (map (lambda (a) (fold max (car a) (cdr a))) B))
  71. (ply (w/rank max/ -1) A)
  72. (ply (w/rank max/a -1) A)
  73. (ply (w/rank max/b -1) A))
  74. ; @TODO folda uses ply on each op application, so on each scalar. Very slow.
  75. ; @TODO foldb suffers from apply map from.
  76. (define (_sqr a) (* a a))
  77. (define a (i. 10000))
  78. (T-eps 0.0 (folda (lambda (c a) (+ c (_sqr a))) 0 a)
  79. (foldb (lambda (c a) (+ c (_sqr a))) 0 a)
  80. (let ((end (tally a)))
  81. (let loop ((i 0) (ac 0))
  82. (if (= i end)
  83. ac
  84. (loop (+ 1 i) (+ ac (_sqr (array-ref a i)))))))
  85. (let ((ac 0))
  86. (array-for-each (lambda (a) (set! ac (+ ac (* a a)))) a)
  87. ac))
  88. ; exercise folda / foldb with w/rank-using op. Args are rank 1 & 2.
  89. (define* (xdota + * A B)
  90. (folda (w/rank ((@@ (ploy reduce) _madd) + *) '_ 0 1) 0 A B))
  91. (define* (xdotb + * A B)
  92. (foldb (w/rank ((@@ (ploy reduce) _madd) + *) '_ 0 1) 0 A B))
  93. (T-eps 0.0
  94. (dot + * (i. 100) (i. 100 20))
  95. (xdota + * (i. 100) (i. 100 20))
  96. (xdotb + * (i. 100) (i. 100 20))
  97. ;; (blas-dgemv (as-array (i. 100 20) #:type 'f64) (as-array (i. 100) #:type 'f64) 1. 'transpose)
  98. )
  99. ; @TODO Think about these:
  100. ;; (folda (w/rank + 0 1) 0 (i. 10 3)) ; works, it shouldn't (first op is (+ 0 #(...)), but next?)
  101. ;; (folda (w/rank + 1 1) 0 (i. 10 3)) ; doesn't work, probably ok (0 is not rank 1).
  102. ;; (folda (w/rank + 1 1) #(0 0 0) (i. 10 3)) ; works, properly
  103. ;; (folda (w/rank + 0 0) #(0 0 0) (i. 10 3)) ; works, properly
  104. ;; (folda + #(0 0 0) (i. 10 3)) ; works, properly
  105. ;; (ply (w/rank (verb (cut folda + 0 <>) #f '_) 1) (i. 10 3)) ; works, properly
  106. ; --------------------------------
  107. ; dot and dot variants
  108. ; --------------------------------
  109. (define A #2((1 2) (3 4)))
  110. (define B #2((1 3) (2 4)))
  111. (define C #2((1 2 3) (4 5 6)))
  112. (define a #1(10 20))
  113. (define b #1(10 20 30))
  114. (T (dot + * a a) 500)
  115. (T (dot + * A a) #(50 110))
  116. (T (dot + * A B) #2((5 11) (11 25)))
  117. (T (dot + * C b) #(140 320))
  118. ; outer product versions (k i ... j ...)
  119. ; @TODO Find the transformation between all of these.
  120. ; @TODO Remove temporary / map / from overhead.
  121. ;; A: i ... k
  122. ;; B: k j ...
  123. ;; A must be transposed to place the fold axis first:
  124. ;; a: k i ...
  125. ;; b: k j ...
  126. ;; so w/rank layout under the fold is
  127. ;; c: i ... | j ... -> cell rank from j ...
  128. ;; a: i ... | -> cell rank 0
  129. ;; b: | j ... -> cell rank from j ...
  130. (define (make-kij fold-op)
  131. (lambda* (+_ *_ A B #:key type)
  132. (let ((type (or type (array-type* A))))
  133. (fold-op type
  134. (w/rank ((@@ (ploy reduce) _madd) +_ *_) (- (rank B) 1) 0 '_)
  135. (apply reshape 0 (append (drop-right ($ A) 1) (drop ($ B) 1)))
  136. (rollaxis A -1 0) B))))
  137. (define kij-dota (make-kij folda/t))
  138. (define kij-dotb (make-kij foldb/t))
  139. (T
  140. (dot + * (i. 20 30) (i. 30 40 10))
  141. (kij-dota + * (i. 20 30) (i. 30 40 10))
  142. (kij-dotb + * (i. 20 30) (i. 30 40 10))
  143. )