test-ffi-fftw.scm 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. ; Tests for (ffi fftw).
  2. ; (c) Daniel Llorens - 2014
  3. ; This is released and should depend only on (ffi fftw) and standard Guile.
  4. ; This library is free software; you can redistribute it and/or modify it under
  5. ; the terms of the GNU Lesser General Public License as published by the Free
  6. ; Software Foundation; either version 3 of the License, or (at your option) any
  7. ; later version.
  8. (import (ffi fftw) (srfi srfi-64) (srfi srfi-1))
  9. (set! test-log-to-file #f)
  10. (test-begin "ffi-fftw")
  11. ; Various sorts of arrays.
  12. (define (make-A-compact)
  13. (make-typed-array 'c64 0 2 2 2))
  14. (define (make-A-strided)
  15. (make-shared-array (make-typed-array 'c64 0 8 8 8) (lambda i (map * i '(2 3 4))) 2 2 2))
  16. (define (make-A-offset)
  17. (make-shared-array (make-typed-array 'c64 0 8 8 8) (lambda i (map + i '(2 3 4))) 2 2 2))
  18. ; Test variable rank feature for (fftw-dft!).
  19. (define (case-fftw-dft!-ones tag make-A make-B)
  20. (let ((case-name (format #f "fftw-dft! ones, ~a" tag))
  21. (ref (make-typed-array 'c64 1 2 2 2))
  22. (A (make-A))
  23. (B (make-B)))
  24. (array-fill! A 1.)
  25. (test-begin case-name)
  26. (array-fill! B 11.)
  27. (fftw-dft! 1 +1 A B)
  28. (test-equal B #3c64(((2 0) (2 0)) ((2 0) (2 0))))
  29. (test-equal A ref)
  30. (array-fill! B 22.)
  31. (fftw-dft! 2 +1 A B)
  32. (test-equal B #3c64(((4 0) (0 0)) ((4 0) (0 0))))
  33. (test-equal A ref)
  34. (array-fill! B 33.)
  35. (let ((C (fftw-dft! 3 +1 A B)))
  36. (test-equal B #3c64(((8 0) (0 0)) ((0 0) (0 0))))
  37. (test-equal A ref)
  38. (test-eq B C))
  39. (test-end case-name)))
  40. (case-fftw-dft!-ones "compact-compact" make-A-compact make-A-compact)
  41. (case-fftw-dft!-ones "compact-strided" make-A-compact make-A-strided)
  42. (case-fftw-dft!-ones "compact-offset" make-A-compact make-A-offset)
  43. (case-fftw-dft!-ones "strided-compact" make-A-strided make-A-compact)
  44. (case-fftw-dft!-ones "strided-strided" make-A-strided make-A-strided)
  45. (case-fftw-dft!-ones "strided-offset" make-A-strided make-A-offset)
  46. (case-fftw-dft!-ones "offset-compact" make-A-offset make-A-compact)
  47. (case-fftw-dft!-ones "offset-strided" make-A-offset make-A-strided)
  48. (case-fftw-dft!-ones "offset-offset" make-A-offset make-A-offset)
  49. ; Test variable rank feature for (fftw-dft).
  50. (define (case-fftw-dft-ones tag A)
  51. (let ((case-name (format #f "fftw-dft ones, ~a" tag)))
  52. (array-fill! A 1.)
  53. (test-begin case-name)
  54. (test-equal (fftw-dft 1 +1 A) #3c64(((2 0) (2 0)) ((2 0) (2 0))))
  55. (test-equal (fftw-dft 2 +1 A) #3c64(((4 0) (0 0)) ((4 0) (0 0))))
  56. (test-equal (fftw-dft 3 +1 A) #3c64(((8 0) (0 0)) ((0 0) (0 0))))
  57. (test-end case-name)))
  58. (case-fftw-dft-ones "fresh array" (make-A-compact))
  59. (case-fftw-dft-ones "strided" (make-A-strided))
  60. (case-fftw-dft-ones "offset" (make-A-offset))
  61. (case-fftw-dft-ones "reshaped scalar" (make-shared-array (make-typed-array 'c64 0.) (lambda i '()) 2 2 2))
  62. ; Test signs.
  63. (define i2pi (make-rectangular 0 (* 2 (acos -1))))
  64. (define (delta n i)
  65. (let ((A (apply make-typed-array 'c64 0. n)))
  66. (apply array-set! A 1 i)
  67. A))
  68. (define (delta-dft n i sign)
  69. (let ((A (apply make-typed-array 'c64 *unspecified* n)))
  70. (array-index-map!
  71. A (lambda k (exp (* sign i2pi (fold (lambda (i k n a) (+ a (* i k (/ n)))) 0 i k n)))))
  72. A))
  73. (define (array-absolute-error a b)
  74. (and (equal? (array-dimensions a) (array-dimensions b))
  75. (let ((err 0))
  76. (array-for-each (lambda (a b) (set! err (max err (magnitude (- a b))))) a b)
  77. err)))
  78. (define (delta-error sign . n)
  79. (let ((err 0.))
  80. (array-index-map!
  81. (apply make-shared-array (make-array #f) (lambda i '()) n)
  82. (lambda i
  83. (set! err (max err
  84. (array-absolute-error (delta-dft n i sign)
  85. (fftw-dft (length n) sign (delta n i)))))))
  86. err))
  87. (test-begin "fftw-dft deltas")
  88. (test-approximate 0 (delta-error +1 4) 1e-15)
  89. (test-approximate 0 (delta-error -1 4) 1e-15)
  90. (test-approximate 0 (delta-error +1 3 4) 2e-15)
  91. (test-approximate 0 (delta-error -1 3 4) 2e-15)
  92. (test-approximate 0 (delta-error +1 2 3 4) 5e-15)
  93. (test-approximate 0 (delta-error -1 2 3 4) 5e-15)
  94. (test-end "fftw-dft deltas")
  95. (define error-count (test-runner-fail-count (test-runner-current)))
  96. (test-end "ffi-fftw")
  97. (exit error-count)