numintsynth.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. # Synthesize a procedure to numerically integrate the 3rd order poly spiral
  2. tex = False
  3. if tex:
  4. mulsym = ' '
  5. else:
  6. mulsym = ' * '
  7. class Poly:
  8. def __init__(self, p0, coeffs):
  9. self.p0 = p0
  10. self.coeffs = coeffs
  11. def eval(self, x):
  12. y = x ** self.p0
  13. z = 0
  14. for c in coeffs:
  15. z += y * c
  16. y *= x
  17. return z
  18. def add(poly0, poly1, nmax):
  19. lp0 = len(poly0.coeffs)
  20. lp1 = len(poly1.coeffs)
  21. p0 = min(poly0.p0, poly1.p0)
  22. n = min(max(poly0.p0 + lp0, poly1.p1 + lp1), nmax) - p0
  23. if n <= 0: return Poly(0, [])
  24. coeffs = []
  25. for i in range(n):
  26. c = 0
  27. if i >= poly0.p0 - p0 and i < lp0 + poly0.p0 - p0:
  28. c += poly0.coeffs[i + p0 - poly0.p0]
  29. if i >= poly1.p0 - p0 and i < lp1 + poly1.p0 - p0:
  30. c += poly1.coeffs[i + p0 - poly1.p0]
  31. coeffs.append(c)
  32. return Poly(p0, coeffs)
  33. def pr(str):
  34. if tex:
  35. print str, '\\\\'
  36. else:
  37. print '\t' + str + ';'
  38. def prd(str):
  39. if tex:
  40. print str, '\\\\'
  41. else:
  42. print '\tdouble ' + str + ';'
  43. def polymul(p0, p1, degree, basename, suppress_odd = False):
  44. result = []
  45. for i in range(min(degree, len(p0) + len(p1) - 1)):
  46. terms = []
  47. for j in range(i + 1):
  48. if j < len(p0) and i - j < len(p1):
  49. t0 = p0[j]
  50. t1 = p1[i - j]
  51. if t0 != None and t1 != None:
  52. terms.append(t0 + mulsym + t1)
  53. if terms == []:
  54. result.append(None)
  55. else:
  56. var = basename % i
  57. if (j % 2 == 0) or not suppress_odd:
  58. prd(var + ' = ' + ' + '.join(terms))
  59. result.append(var)
  60. return result
  61. def polysquare(p0, degree, basename):
  62. result = []
  63. for i in range(min(degree, 2 * len(p0) - 1)):
  64. terms = []
  65. for j in range((i + 1)/ 2):
  66. if i - j < len(p0):
  67. t0 = p0[j]
  68. t1 = p0[i - j]
  69. if t0 != None and t1 != None:
  70. terms.append(t0 + mulsym + t1)
  71. if len(terms) >= 1:
  72. if tex and len(terms) == 1:
  73. terms = ['2 ' + terms[0]]
  74. else:
  75. terms = ['2' + mulsym + '(' + ' + '.join(terms) + ')']
  76. if (i % 2) == 0:
  77. t = p0[i / 2]
  78. if t != None:
  79. if tex:
  80. terms.append(t + '^2')
  81. else:
  82. terms.append(t + mulsym + t)
  83. if terms == []:
  84. result.append(None)
  85. else:
  86. var = basename % i
  87. prd(var + ' = ' + ' + '.join(terms))
  88. result.append(var)
  89. return result
  90. def mkspiro(degree):
  91. if tex:
  92. us = ['u = 1']
  93. vs = ['v =']
  94. else:
  95. us = ['u = 1']
  96. vs = ['v = 0']
  97. if tex:
  98. tp = [None, 't_{11}', 't_{12}', 't_{13}', 't_{14}']
  99. else:
  100. tp = [None, 't1_1', 't1_2', 't1_3', 't1_4']
  101. if tex:
  102. prd(tp[1] + ' = k_0')
  103. prd(tp[2] + ' = \\frac{k_1}{2}')
  104. prd(tp[3] + ' = \\frac{k_2}{6}')
  105. prd(tp[4] + ' = \\frac{k_3}{24}')
  106. else:
  107. prd(tp[1] + ' = km0')
  108. prd(tp[2] + ' = .5 * km1')
  109. prd(tp[3] + ' = (1./6) * km2')
  110. prd(tp[4] + ' = (1./24) * km3')
  111. tlast = tp
  112. coef = 1.
  113. for i in range(1, degree - 1):
  114. tmp = []
  115. tcoef = coef
  116. #print tlast
  117. for j in range(len(tlast)):
  118. c = tcoef / (j + 1)
  119. if (j % 2) == 0 and tlast[j] != None:
  120. if tex:
  121. tmp.append('\\frac{%s}{%.0f}' % (tlast[j], 1./c))
  122. else:
  123. if c < 1e-9:
  124. cstr = '%.16e' % c
  125. else:
  126. cstr = '(1./%d)' % int(.5 + (1./c))
  127. tmp.append(cstr + ' * ' + tlast[j])
  128. tcoef *= .5
  129. if tmp != []:
  130. sign = ('+', '-')[(i / 2) % 2]
  131. var = ('u', 'v')[i % 2]
  132. if tex:
  133. if i == 1: pref = ''
  134. else: pref = sign + ' '
  135. str = pref + (' ' + sign + ' ').join(tmp)
  136. else:
  137. str = var + ' ' + sign + '= ' + ' + '.join(tmp)
  138. if var == 'u': us.append(str)
  139. else: vs.append(str)
  140. if i < degree - 1:
  141. if tex:
  142. basename = 't_{%d%%d}' % (i + 1)
  143. else:
  144. basename = 't%d_%%d' % (i + 1)
  145. if i == 1:
  146. tnext = polysquare(tp, degree - 1, basename)
  147. t2 = tnext
  148. elif i == 3:
  149. tnext = polysquare(t2l, degree - 1, basename)
  150. elif (i % 2) == 0:
  151. tnext = polymul(tlast, tp, degree - 1, basename, True)
  152. else:
  153. tnext = polymul(t2l, t2, degree - 1, basename)
  154. t2l = tlast
  155. tlast = tnext
  156. coef /= (i + 1)
  157. if tex:
  158. pr(' '.join(us))
  159. pr(' '.join(vs))
  160. else:
  161. for u in us:
  162. pr(u)
  163. for v in vs:
  164. pr(v)
  165. if __name__ == '__main__':
  166. mkspiro(12)