1 from __future__
import print_function
13 Mij=symbols(
'Mij[:36]')
16 [(x1[0] - x2[0])**2, (x1[1] - x2[1])**2, (x1[2] - x2[2])**2, (x1[1] - x2[1])*(x1[2] - x2[2]), (x1[0] - x2[0])*(x1[2] - x2[2]), (x1[0] - x2[0])*(x1[1] - x2[1])],
17 [(x2[0] - x3[0])**2, (x2[1] - x3[1])**2, (x2[2] - x3[2])**2, (x2[1] - x3[1])*(x2[2] - x3[2]), (x2[0] - x3[0])*(x2[2] - x3[2]), (x2[0] - x3[0])*(x2[1] - x3[1])],
18 [(x3[0] - x1[0])**2, (x3[1] - x1[1])**2, (x3[2] - x1[2])**2, (x3[1] - x1[1])*(x3[2] - x1[2]), (x3[0] - x1[0])*(x3[2] - x1[2]), (x3[0] - x1[0])*(x3[1] - x1[1])],
19 [(x1[0] - x4[0])**2, (x1[1] - x4[1])**2, (x1[2] - x4[2])**2, (x1[1] - x4[1])*(x1[2] - x4[2]), (x1[0] - x4[0])*(x1[2] - x4[2]), (x1[0] - x4[0])*(x1[1] - x4[1])],
20 [(x2[0] - x4[0])**2, (x2[1] - x4[1])**2, (x2[2] - x4[2])**2, (x2[1] - x4[1])*(x2[2] - x4[2]), (x2[0] - x4[0])*(x2[2] - x4[2]), (x2[0] - x4[0])*(x2[1] - x4[1])],
21 [(x3[0] - x4[0])**2, (x3[1] - x4[1])**2, (x3[2] - x4[2])**2, (x3[1] - x4[1])*(x3[2] - x4[2]), (x3[0] - x4[0])*(x3[2] - x4[2]), (x3[0] - x4[0])*(x3[1] - x4[1])]])
23 R=Matrix([[1], [1], [1], [1], [1], [1]])
26 tetrahedron = {x1[0]:1, x1[1]:0, x1[2]:-4/sqrt(2),
27 x2[0]:-1, x2[1]:0, x2[2]:-4/sqrt(2),
28 x3[0]:0, x3[1]:2, x3[2]:4/sqrt(2),
29 x4[0]:0, x4[1]:-2, x4[2]:4/sqrt(2)}
31 Mi = M.evalf(subs=tetrahedron)
33 Sxx, Syy, Szz, Syz, Sxz, Sxy = Mi.inv()*R
35 SteinerEllipse = Matrix([
40 print(
"SteinerEllipse = ")
41 pprint(SteinerEllipse)
43 if Sxx==1./2**2
and Syy==1./4**2
and Szz==1./8**2
and Syz==0.0
and Sxz==0.0
and Sxy==0.0:
51 pyname=sys.argv[0].split(
'/')[-1]
54 hname=pyname[:-3]+
".h"
55 macro = pyname[:-3].upper()+
"_H"
56 header=
"""/* Start of code generated by %s. Warning - be careful about modifying
57 any of the generated code directly. Any changes/fixes should be done
58 in the code generation script generation.*/\n
66 void generate_Steiner_ellipse(const double *x1, const double *x2, const double *x3, const double *x4, double *sm);
71 """%(pyname, macro, macro)
73 hfile = open(hname,
'w')
78 cxxname=pyname[:-3]+
".cpp"
81 /* Start of code generated by %s. Warning - be careful about modifying
82 any of the generated code directly. Any changes/fixes should be done
83 in the code generation script generation.
87 #include <Eigen/Dense>
94 void pragmatic::generate_Steiner_ellipse(const double *x1, const double *x2, const double *x3, const double *x4, double *sm){
95 // # From http://en.wikipedia.org/wiki/Steiner_ellipse
97 Eigen::Matrix<double, 6, 6> M;
102 src+=ccode(M[i,j], contract=
False)
103 if not (i==5
and j==5):
110 Eigen::Matrix<double, 6, 1> R;
112 Eigen::Matrix<double, 6, 1> S;
114 M.svd().solve(R, &S);
116 sm[0] = S[0]; sm[1] = S[5]; sm[2] = S[4];
117 sm[3] = S[1]; sm[4] = S[3];
122 /* End of code generated by %s. Warning - be careful about
123 modifying any of the generated code directly. Any changes/fixes
124 should be done in the code generation script generation.*/\n"""%pyname
126 cxxfile = open(cxxname,
"w")
131 testname=
"test_"+pyname[:-3]+
".cpp"
140 double x1[]={ 1, 0, -4/sqrt(2)};
141 double x2[]={-1, 0, -4/sqrt(2)};
142 double x3[]={ 0, 2, 4/sqrt(2)};
143 double x4[]={ 0, -2, 4/sqrt(2)};
145 pragmatic::generate_Steiner_ellipse(x1, x2, x3, x4, sm);
148 if(fabs(sm[0]-1./sqrt(2))<DBL_EPSILON && fabs(sm[1])<DBL_EPSILON && fabs(sm[2])<DBL_EPSILON &&
149 fabs(sm[3]-1./sqrt(4))<DBL_EPSILON && fabs(sm[4])<DBL_EPSILON &&
150 fabs(sm[5]-1./sqrt(8))<DBL_EPSILON){
151 std::cout<<"pass"<<std::endl;
153 std::cout<<"fail"<<std::endl;
160 testfile = open(testname,
"w")
161 testfile.write(testsrc)