test_Polynomial.praat 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # test_Polynomial.praat
  2. # djmw 20160509
  3. appendInfoLine: "test_Polynomial.praat"
  4. for i to 100
  5. @test_roots
  6. @test_products
  7. endfor
  8. appendInfoLine: "test_Polynomial.praat OK"
  9. procedure test_roots
  10. # random polynomials can behave very wildly. Therefore we cannot
  11. # be too strict in checking the differences between generated and
  12. # measured roots.
  13. # Once in a while the precision is not as good as wanted and a notification will be given.
  14. .eps1 = 2e-6
  15. .eps2 = 1e-6
  16. appendInfoLine: tab$, "roots"
  17. for .i to 20
  18. .xmin = -2
  19. .xmax = randomUniform (1, 2)
  20. .numberOfRoots = randomInteger (2, 20)
  21. appendInfoLine: tab$, tab$, .i, ": ", .numberOfRoots, " random roots in [",.xmin, ",", .xmax, "]"
  22. .rootsTable = Create TableOfReal: "r", .numberOfRoots, 1
  23. Formula: ~ randomUniform (.xmin, .xmax)
  24. Sort by column: 1, 0
  25. .roots$ = ""
  26. for .j to .numberOfRoots
  27. .root [.j] = Get value: .j, 1
  28. .roots$ = .roots$ + string$ (.root [.j]) + if .j == .numberOfRoots then "" else " " fi
  29. endfor
  30. .p = Create Polynomial from real zeros: "p", .xmin, .xmax, .roots$
  31. # divide by a root
  32. for .j to .numberOfRoots
  33. .rootj = .root [.j]
  34. .remainder = Get remainder after division: .rootj
  35. .test = abs (.remainder / .rootj)
  36. assert .test < .eps1; '.remainder' '.rootj'
  37. endfor
  38. .root [0] = .xmin
  39. .root [.numberOfRoots + 1] = .xmax
  40. .eps2 = .numberOfRoots * 1e-6
  41. for .j to .numberOfRoots
  42. .xmini = randomUniform (.root [.j-1], .root [.j])
  43. .xmaxi = randomUniform (.root [.j], .root [.j+1])
  44. .root = Get one real root: .xmini, .xmaxi
  45. .rootj = .root [.j]
  46. .dif = abs (.rootj - .root)
  47. if .dif > .eps2 * abs (.rootj)
  48. appendInfoLine: "Possible precision problem for ", .numberOfRoots, " roots: ", .roots$
  49. appendInfoLine: .dif, "(= abs(root-rootFound):", .rootj, "-", .root, ") for ", .j, "th root)"
  50. endif
  51. ;assert .dif < .eps2 * abs (.root [.j]); '.root' '.rootj' '.j'
  52. endfor
  53. removeObject: .p, .rootsTable
  54. endfor
  55. endproc
  56. procedure test_products
  57. .eps = 1e-15
  58. .p = Create Polynomial from product terms: "p", -3, 3, "1 2 -1 -2"
  59. .coefs$ = "1 0 -1 0 0 0 -1 0 1"
  60. .strings = Create Strings as tokens: .coefs$
  61. .ntokens = Get number of strings
  62. for .i to .ntokens
  63. selectObject: .strings
  64. .coef$ = Get string: .i
  65. selectObject: .p
  66. .coef = Get coefficient: .i
  67. assert abs (number (.coef$) - .coef) < .eps; '.coef' '.coef$'
  68. endfor
  69. removeObject: .p, .strings
  70. endproc