2 from __future__ import print_function
4 from sympy.vector.vector import *
7 from sympy.utilities.lambdify import lambdify, implemented_function
10 from moedebug import *
13 if not dbg_enabled(): return
17 if not dbg_enabled(): return
19 print('\n ' + vn + '\n')
24 N = CoordSysCartesian('N')
28 def vector_symbols(vnames):
30 for vname in vnames.split(' '):
32 for cname in 'i j k'.split(' '):
33 v += getattr(N, cname) * symbols(vname + '_' + cname)
37 A, B, C, D = vector_symbols('A B C D')
38 p = vector_symbols('p')
40 E, H = vector_symbols('E H')
41 F0, G0 = vector_symbols('F0 G0')
42 En, Hn = vector_symbols('En Hn')
44 EFl, GHl = symbols('EFl GHl')
46 def vector_component(v, ix):
47 return v.components[N.base_vectors()[ix]]
49 # x array in numerical algorithm has:
50 # N x 3 coordinates of points 0..N-3
51 # 1 EFl = length parameter |EF| for point 1
52 # 1 GHl = length parameter |GH| for point N-2
54 # fixed array in numerical algorithm has:
68 cost_ABCD = (QR & QR) / (BC & BC)
76 # diff_A_i = cost_ABCD.diff(vector_component(A, 0))
82 def ourccode(*a, **kw):
83 return ccode(*a, user_functions={'sinc':'sinc'}, **kw)
89 for l in s.split('\n'):
92 def cse_prep_cprint(v, tmp_prefix):
93 # => v, but also having cprint'd the common subexpression assignments
94 sym_iter = map((lambda i: symbols('%s%d' % (tmp_prefix,i))),
96 (defs, vs) = cse(v, symbols=sym_iter)
97 for defname, defval in defs:
98 cprint('double '+ourccode(defval, assign_to=defname))
101 def cassign(v, assign_to, tmp_prefix):
102 v = cse_prep_cprint(v, tmp_prefix)
103 cprint(ourccode(v, assign_to=assign_to))
105 def cassign_vector(v, assign_to, tmp_prefix):
106 ijk = 'i j k'.split(' ')
107 for ii in range(0, len(ijk)):
108 x = v & getattr(N, ijk[ii])
109 cassign(x, '%s[%d]' % (assign_to, ii), '%s_%s' % (tmp_prefix, ijk[ii]))
111 def gen_diff(current, smalls):
114 j = zeros(len(params),0)
118 d = diff(current, paramv)
122 j = cse_prep_cprint(j, 'jtmp')
123 for ix in range(0, j.cols):
124 cprint(ourccode(j.col(ix), 'J_COL'))
125 cprint('J_END_COL(%d)' % ix)
129 cprint('if (!IS_SMALL(' + ourccode(small) + ')) {')
130 gen_diff(current, smalls)
131 cprint('} else { /* %s small */' % small)
132 gen_diff(current.replace(
134 1 - small*small/factorial(3) - small**4/factorial(5),
138 cprint('} /* %s small */' % small)
141 cprintraw('// AUTOGENERATED - DO NOT EDIT\n')
143 def gen_point_coords_macro(macro_basename):
144 ijk = 'i j k'.split(' ')
145 for ii in range(0, len(ijk)):
146 cprintraw('#define %s_%s (%s[%d])'
147 % (macro_basename, ijk[ii], macro_basename, ii))
149 def gen_point_index_macro(macro_basename, c_array_name, base_index):
150 cprintraw('#define %s (&%s[%s])'
151 % (macro_basename, c_array_name, base_index))
152 gen_point_coords_macro(macro_basename)
154 def gen_point_references():
155 abcd = 'A B C D'.split(' ')
157 gen_point_index_macro('E', 'INPUT', '3*0')
158 gen_point_index_macro('F0', 'INPUT', '3*1')
159 gen_point_index_macro('G0', 'INPUT', '3*(NP-2)')
160 gen_point_index_macro('H', 'INPUT', '3*(NP-1)')
161 cprintraw( '#define NINPUT ( 3*(NP-0) )')
163 gen_point_index_macro('En', 'PREP', '3*0')
164 gen_point_index_macro('Hn', 'PREP', '3*1')
165 cprintraw( '#define NPREP (3*2)')
167 cprintraw('#define NX_DIRECT 3*(NP-4)')
168 cprint('#define POINT(PP) (')
169 cprint(' (PP) == 0 ? E :')
170 cprint(' (PP) == 1 ? F :')
171 cprint(' (PP) == NP-2 ? G :')
172 cprint(' (PP) == NP-1 ? H :')
173 cprint(' &X[3*((PP)-2)]')
176 cprintraw('#define EFl X[ NX_DIRECT + 0 ]')
177 cprintraw('#define GHl X[ NX_DIRECT + 1 ]')
178 cprintraw('#define NX ( NX_DIRECT + 2 )')
180 for ai in range(0, len(abcd)):
181 cprintraw('#define %s POINT(P%+d)' % (abcd[ai], ai))
182 gen_point_coords_macro(abcd[ai])
187 cprint('#define PREPARE')
188 cprint('memcpy(X, &INPUT[3*2], sizeof(double) * NX_DIRECT);')
189 cassign_vector((F0 - E).normalize(), 'En', 'tmp_En')
190 cassign_vector((G0 - H).normalize(), 'Hn', 'tmp_Hn')
193 def gen_calculate_FG():
194 cprint('#define CALCULATE_F_G')
195 cassign_vector(F,'F','tmp_F')
196 cassign_vector(G,'G','tmp_G')
199 def gen_calculate_cost():
200 cprint('#define CALCULATE_COST')
201 cassign(cost_ABCD,'P_cost','tmp_P_cost')
206 gen_point_references()
212 # https://github.com/sympy/sympy/issues/13642
213 # "lambdify sinc gives wrong answer!"
215 sinc_fixed = Function('sinc_fixed')
216 implemented_function(sinc_fixed, lambda x: np.sinc(x/np.pi))
217 out = out.subs(sinc,sinc_fixed)
218 p = list(map(eval,params))
219 return lambdify(p, out)