32 template<
int Degree,
class Real>
35 dotTable=dDotTable=d2DotTable=NULL;
36 valueTables=dValueTables=NULL;
40 template<
int Degree,
class Real>
45 if( dotTable)
delete[] dotTable;
46 if( dDotTable)
delete[] dDotTable;
47 if(d2DotTable)
delete[] d2DotTable;
48 if( valueTables)
delete[] valueTables;
49 if(dValueTables)
delete[] dValueTables;
51 dotTable=dDotTable=d2DotTable=NULL;
52 valueTables=dValueTables=NULL;
56 template<
int Degree,
class Real>
57 #if BOUNDARY_CONDITIONS
59 #else // !BOUNDARY_CONDITIONS
61 #endif // BOUNDARY_CONDITIONS
63 this->normalize = normalize;
64 this->useDotRatios = useDotRatios;
65 #if BOUNDARY_CONDITIONS
66 this->reflectBoundary = reflectBoundary;
67 #endif // BOUNDARY_CONDITIONS
71 res2 = (1<<(depth+1))+1;
80 baseFunction=F/sqrt((F*F).integral(F.polys[0].start,F.polys[F.polyCount-1].start));
83 baseFunction=F/F.integral(F.polys[0].start,F.polys[F.polyCount-1].start);
88 dBaseFunction = baseFunction.derivative();
89 #if BOUNDARY_CONDITIONS
90 leftBaseFunction = baseFunction + baseFunction.shift( -1 );
91 rightBaseFunction = baseFunction + baseFunction.shift( 1 );
92 dLeftBaseFunction = leftBaseFunction.derivative();
93 dRightBaseFunction = rightBaseFunction.derivative();
94 #endif // BOUNDARY_CONDITIONS
96 for(
int i=0 ; i<res ; i++ )
99 #if BOUNDARY_CONDITIONS
100 if( reflectBoundary )
104 if ( off==0 ) baseFunctions[i] = leftBaseFunction.scale( w1 ).shift( c1 );
105 else if( off==((1<<d)-1) ) baseFunctions[i] = rightBaseFunction.scale( w1 ).shift( c1 );
106 else baseFunctions[i] = baseFunction.scale( w1 ).shift( c1 );
108 else baseFunctions[i] = baseFunction.scale(w1).shift(c1);
109 #else // !BOUNDARY_CONDITIONS
110 baseFunctions[i] = baseFunction.scale(w1).shift(c1);
111 #endif // BOUNDARY_CONDITIONS
116 baseFunctions[i]/=sqrt(w1);
119 baseFunctions[i]/=w1;
124 template<
int Degree,
class Real>
127 clearDotTables( flags );
129 size = ( res*res + res )>>1;
130 if( flags & DOT_FLAG )
132 dotTable =
new Real[size];
133 memset( dotTable , 0 ,
sizeof(Real)*size );
135 if( flags & D_DOT_FLAG )
137 dDotTable =
new Real[size];
138 memset( dDotTable , 0 ,
sizeof(Real)*size );
140 if( flags & D2_DOT_FLAG )
142 d2DotTable =
new Real[size];
143 memset( d2DotTable , 0 ,
sizeof(Real)*size );
146 t1 = baseFunction.polys[0].start;
147 t2 = baseFunction.polys[baseFunction.polyCount-1].start;
148 for(
int i=0 ; i<res ; i++ )
150 double c1 , c2 , w1 , w2;
152 #if BOUNDARY_CONDITIONS
153 int d1 , d2 , off1 , off2;
156 if ( reflectBoundary && off1==0 ) boundary1 = -1;
157 else if( reflectBoundary && off1==( (1<<d1)-1 ) ) boundary1 = 1;
158 #endif // BOUNDARY_CONDITIONS
159 double start1 = t1 * w1 + c1;
160 double end1 = t2 * w1 + c1;
161 for(
int j=0 ; j<=i ; j++ )
164 #if BOUNDARY_CONDITIONS
167 if ( reflectBoundary && off2==0 ) boundary2 = -1;
168 else if( reflectBoundary && off2==( (1<<d2)-1 ) ) boundary2 = 1;
169 #endif // BOUNDARY_CONDITIONS
170 int idx = SymmetricIndex( i , j );
172 double start = t1 * w2 + c2;
173 double end = t2 * w2 + c2;
174 #if BOUNDARY_CONDITIONS
175 if( reflectBoundary )
177 if( start<0 ) start = 0;
178 if( start>1 ) start = 1;
179 if( end <0 ) end = 0;
180 if( end >1 ) end = 1;
182 #endif // BOUNDARY_CONDITIONS
184 if( start< start1 ) start = start1;
185 if( end > end1 ) end = end1;
186 if( start>= end )
continue;
188 #if BOUNDARY_CONDITIONS
189 Real
dot = dotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 );
190 #else // !BOUNDARY_CONDITIONS
191 Real dot = dotProduct( c1 , w1 , c2 , w2 );
192 #endif // BOUNDARY_CONDITIONS
193 if( fabs(dot)<1e-15 )
continue;
194 if( flags & DOT_FLAG ) dotTable[idx]=
dot;
197 #if BOUNDARY_CONDITIONS
198 if( flags & D_DOT_FLAG ) dDotTable[idx] = -dDotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ) /
dot;
199 if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 ) /
dot;
200 #else // !BOUNDARY_CONDITIONS
201 if( flags & D_DOT_FLAG ) dDotTable[idx] = -dDotProduct(c1,w1,c2,w2)/
dot;
202 if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2)/
dot;
203 #endif // BOUNDARY_CONDITIONS
207 #if BOUNDARY_CONDITIONS
208 if( flags & D_DOT_FLAG ) dDotTable[idx] = dDotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 );
209 if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct( c1 , w1 , c2 , w2 , boundary1 , boundary2 );
210 #else // !BOUNDARY_CONDTIONS
211 if( flags & D_DOT_FLAG ) dDotTable[idx] = dDotProduct(c1,w1,c2,w2);
212 if( flags & D2_DOT_FLAG ) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2);
213 #endif // BOUNDARY_CONDITIONS
218 template<
int Degree,
class Real>
221 if((flags & DOT_FLAG) && dotTable)
226 if((flags & D_DOT_FLAG) && dDotTable)
231 if((flags & D2_DOT_FLAG) && d2DotTable)
237 template<
int Degree,
class Real>
241 if( flags & VALUE_FLAG ) valueTables =
new Real[res*res2];
242 if( flags & D_VALUE_FLAG ) dValueTables =
new Real[res*res2];
245 for(
int i=0 ; i<res ; i++ )
249 function=baseFunctions[i].MovingAverage(smooth);
250 dFunction=baseFunctions[i].derivative().MovingAverage(smooth);
254 function=baseFunctions[i];
255 dFunction=baseFunctions[i].derivative();
257 for(
int j=0 ; j<res2 ; j++ )
259 double x=double(j)/(res2-1);
260 if(flags & VALUE_FLAG){ valueTables[j*res+i]=Real(
function(x));}
261 if(flags & D_VALUE_FLAG){dValueTables[j*res+i]=Real(dFunction(x));}
265 template<
int Degree,
class Real>
268 if(flags & VALUE_FLAG){ valueTables=
new Real[res*res2];}
269 if(flags & D_VALUE_FLAG){dValueTables=
new Real[res*res2];}
272 for(
int i=0;i<res;i++){
273 if(valueSmooth>0) {
function=baseFunctions[i].MovingAverage(valueSmooth);}
274 else {
function=baseFunctions[i];}
275 if(normalSmooth>0) {dFunction=baseFunctions[i].derivative().MovingAverage(normalSmooth);}
276 else {dFunction=baseFunctions[i].derivative();}
278 for(
int j=0;j<res2;j++){
279 double x=double(j)/(res2-1);
280 if(flags & VALUE_FLAG){ valueTables[j*res+i]=Real(
function(x));}
281 if(flags & D_VALUE_FLAG){dValueTables[j*res+i]=Real(dFunction(x));}
287 template<
int Degree,
class Real>
289 if( valueTables){
delete[] valueTables;}
290 if(dValueTables){
delete[] dValueTables;}
291 valueTables=dValueTables=NULL;
294 #if BOUNDARY_CONDITIONS
295 template<
int Degree,
class Real>
299 if ( boundary1==-1 ) b1 = & leftBaseFunction;
300 else if( boundary1== 0 ) b1 = & baseFunction;
301 else if( boundary1== 1 ) b1 = &rightBaseFunction;
302 if ( boundary2==-1 ) b2 = & leftBaseFunction;
303 else if( boundary2== 0 ) b2 = & baseFunction;
304 else if( boundary2== 1 ) b2 = &rightBaseFunction;
305 double r=fabs( baseFunction.polys[0].start );
309 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/sqrt(width1*width2));
311 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/(width1*width2));
313 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1);
316 template<
int Degree,
class Real>
321 if ( boundary1==-1 ) b1 = & dLeftBaseFunction;
322 else if( boundary1== 0 ) b1 = & dBaseFunction;
323 else if( boundary1== 1 ) b1 = &dRightBaseFunction;
324 if ( boundary2==-1 ) b2 = & leftBaseFunction;
325 else if( boundary2== 0 ) b2 = & baseFunction;
326 else if( boundary2== 1 ) b2 = & rightBaseFunction;
327 double r=fabs(baseFunction.polys[0].start);
330 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/sqrt(width1*width2));
332 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/(width1*width2));
334 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r));
337 template<
int Degree,
class Real>
341 if ( boundary1==-1 ) b1 = & dLeftBaseFunction;
342 else if( boundary1== 0 ) b1 = & dBaseFunction;
343 else if( boundary1== 1 ) b1 = &dRightBaseFunction;
344 if ( boundary2==-1 ) b2 = & dLeftBaseFunction;
345 else if( boundary2== 0 ) b2 = & dBaseFunction;
346 else if( boundary2== 1 ) b2 = &dRightBaseFunction;
347 double r=fabs(baseFunction.polys[0].start);
351 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/sqrt(width1*width2));
353 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/(width1*width2));
355 return Real(((*b1)*b2->scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2);
358 #else // !BOUNDARY_CONDITIONS
359 template<
int Degree,
class Real>
361 double r=fabs(baseFunction.polys[0].start);
365 return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/sqrt(width1*width2));
367 return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1/(width1*width2));
369 return Real((baseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)*width1);
372 template<
int Degree,
class Real>
374 double r=fabs(baseFunction.polys[0].start);
377 return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/sqrt(width1*width2));
379 return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/(width1*width2));
381 return Real((dBaseFunction*baseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r));
384 template<
int Degree,
class Real>
386 double r=fabs(baseFunction.polys[0].start);
389 return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/sqrt(width1*width2));
391 return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2/(width1*width2));
393 return Real((dBaseFunction*dBaseFunction.scale(width2/width1).shift((center2-center1)/width1)).integral(-2*r,2*r)/width2);
396 #endif // BOUNDARY_CONDITIONS
397 template<
int Degree,
class Real>
400 if( i1>i2 )
return ((i1*i1+i1)>>1)+i2;
401 else return ((i2*i2+i2)>>1)+i1;
403 template<
int Degree,
class Real>
408 index = ((i2*i2+i2)>>1)+i1;
412 index = ((i1*i1+i1)>>1)+i2;
Scalar dot(const VectorT< Scalar, N > &_v1, const VectorT< Scalar, N > &_v2)