29#include "poisson_exceptions.h"
30#include "binary_node.h"
59 template<
int Degree >
inline bool LeftOverlap(
unsigned int,
int offset )
62 if( Degree & 1 )
return (offset < 1+Degree) && (offset > -1-Degree );
63 else return (offset < Degree) && (offset > -2-Degree );
65 template<
int Degree >
inline bool RightOverlap(
unsigned int,
int offset )
68 if( Degree & 1 )
return (offset > 2-1-Degree) && (offset < 2+1+Degree );
69 else return (offset > 2-2-Degree) && (offset < 2+ Degree );
71 template<
int Degree >
inline int ReflectLeft(
unsigned int,
int offset )
73 if( Degree&1 )
return -offset;
74 else return -1-offset;
76 template<
int Degree >
inline int ReflectRight(
unsigned int depth ,
int offset )
79 if( Degree&1 )
return r -offset;
80 else return r-1-offset;
83 template<
int Degree ,
class Real >
93 template<
int Degree ,
class Real >
108 vvDotTable = dvDotTable = ddDotTable = NULL;
109 valueTables = dValueTables=NULL;
110 baseFunctions = NULL;
115 template<
int Degree,
class Real>
118 this->useDotRatios = useDotRatios;
119 this->reflectBoundary = reflectBoundary;
129 for(
int i=0 ; i<=Degree ; i++ ) baseBSpline[i] = Polynomial< Degree >::BSplineComponent( i ).shift(
double(-(Degree+1)/2) + i - 0.5 );
133 for(
int i=0 ; i<Degree+3 ; i++ )
135 sPolys[i].
start = double(-(Degree+1)/2) + i - 1.5;
137 if( i<=Degree ) sPolys[i].
p +=
baseBSpline[i ].shift( -1 );
138 if( i>=1 && i<=Degree+1 ) sPolys[i].
p +=
baseBSpline[i-1];
139 for(
int j=0 ; j<i ; j++ ) sPolys[i].p -= sPolys[j].p;
142 for(
int i=0 ; i<Degree+3 ; i++ )
144 sPolys[i].
start = double(-(Degree+1)/2) + i - 0.5;
147 if( i>=1 && i<=Degree+1 ) sPolys[i].
p +=
baseBSpline[i-1].shift( 1 );
148 for(
int j=0 ; j<i ; j++ ) sPolys[i].p -= sPolys[j].p;
162 if( reflectBoundary )
174 template<
int Degree,
class Real>
195 double vvIntegrals[Degree+1][Degree+1];
196 double vdIntegrals[Degree+1][Degree ];
197 double dvIntegrals[Degree ][Degree+1];
198 double ddIntegrals[Degree ][Degree ];
199 int vvSums[Degree+1][Degree+1];
200 int vdSums[Degree+1][Degree ];
201 int dvSums[Degree ][Degree+1];
202 int ddSums[Degree ][Degree ];
208 for(
int d1=0 ; d1<=
depth ; d1++ )
209 for(
int off1=0 ; off1<(1<<d1) ; off1++ )
219 for(
int i=0 ; i<int(b1.size()) ; i++ )
for(
int j=0 ; j<=Degree ; j++ )
221 if( b1[i][j] && start1==-1 ) start1 = i;
222 if( b1[i][j] ) end1 = i+1;
224 for(
int d2=d1 ; d2<=
depth ; d2++ )
226 for(
int off2=0 ; off2<(1<<d2) ; off2++ )
228 int start2 = off2-Degree;
229 int end2 = off2+Degree+1;
230 if( start2>=end1 || start1>=end2 )
continue;
231 start2 = std::max< int >( start1 , start2 );
232 end2 = std::min< int >( end1 , end2 );
233 if( d1==d2 && off2<off1 )
continue;
240 int idx1 =
Index( ii , jj ) , idx2 =
Index( jj , ii );
242 memset( vvSums , 0 ,
sizeof(
int ) * ( Degree+1 ) * ( Degree+1 ) );
243 memset( vdSums , 0 ,
sizeof(
int ) * ( Degree+1 ) * ( Degree ) );
244 memset( dvSums , 0 ,
sizeof(
int ) * ( Degree ) * ( Degree+1 ) );
245 memset( ddSums , 0 ,
sizeof(
int ) * ( Degree ) * ( Degree ) );
246 for(
int i=start2 ; i<end2 ; i++ )
248 for(
int j=0 ; j<=Degree ; j++ )
for(
int k=0 ; k<=Degree ; k++ ) vvSums[j][k] += b1[i][j] * b2[i][k];
249 for(
int j=0 ; j<=Degree ; j++ )
for(
int k=0 ; k< Degree ; k++ ) vdSums[j][k] += b1[i][j] * db2[i][k];
250 for(
int j=0 ; j< Degree ; j++ )
for(
int k=0 ; k<=Degree ; k++ ) dvSums[j][k] += db1[i][j] * b2[i][k];
251 for(
int j=0 ; j< Degree ; j++ )
for(
int k=0 ; k< Degree ; k++ ) ddSums[j][k] += db1[i][j] * db2[i][k];
253 double vvDot = 0 , dvDot = 0 , vdDot = 0 , ddDot = 0;
254 for(
int j=0 ; j<=Degree ; j++ )
for(
int k=0 ; k<=Degree ; k++ ) vvDot += vvIntegrals[j][k] * vvSums[j][k];
255 for(
int j=0 ; j<=Degree ; j++ )
for(
int k=0 ; k< Degree ; k++ ) vdDot += vdIntegrals[j][k] * vdSums[j][k];
256 for(
int j=0 ; j< Degree ; j++ )
for(
int k=0 ; k<=Degree ; k++ ) dvDot += dvIntegrals[j][k] * dvSums[j][k];
257 for(
int j=0 ; j< Degree ; j++ )
for(
int k=0 ; k< Degree ; k++ ) ddDot += ddIntegrals[j][k] * ddSums[j][k];
264 if( fabs(vvDot)<1e-15 )
continue;
284 for(
int i=0 ; i<int(b1.size()) ; i++ )
for(
int j=0 ; j<=Degree ; j++ )
286 if( b1[i][j] && start1==-1 ) start1 = i;
287 if( b1[i][j] ) end1 = i+1;
292 template<
int Degree,
class Real>
301 template<
int Degree ,
class Real >
307 double _start = ( off + 0.5 - 0.5*(Degree+1) ) / res - smooth;
308 double _end = ( off + 0.5 + 0.5*(Degree+1) ) / res + smooth;
312 start = int( floor( _start * (
sampleCount-1) + 1 ) );
313 if( start<0 ) start = 0;
320 template<
int Degree,
class Real>
348 template<
int Degree,
class Real>
370 template<
int Degree,
class Real>
377 template<
int Degree,
class Real>
379 template<
int Degree,
class Real>
382 if( i1>i2 )
return ((i1*i1+i1)>>1)+i2;
383 else return ((i2*i2+i2)>>1)+i1;
385 template<
int Degree,
class Real>
390 index = ((i2*i2+i2)>>1)+i1;
395 index = ((i1*i1+i1)>>1)+i2;
404 template<
int Degree >
410 for(
int i=0 ; i<=Degree ; i++ )
412 int idx = -
_off + offset + i;
413 if( idx>=0 && idx<res ) (*this)[idx][i] = 1;
418 if( Degree&1 )
_addLeft( offset-res , boundary ) ,
_addRight( offset+res , boundary );
422 template<
int Degree >
425 int res = int( this->size() );
427 for(
int i=0 ; i<=Degree ; i++ )
429 int idx = -
_off + offset + i;
430 if( idx>=0 && idx<res ) (*this)[idx][i] += boundary , set =
true;
432 if( set )
_addLeft( offset-2*res , boundary );
434 template<
int Degree >
437 int res = int( this->size() );
439 for(
int i=0 ; i<=Degree ; i++ )
441 int idx = -
_off + offset + i;
442 if( idx>=0 && idx<res ) (*this)[idx][i] += boundary , set =
true;
444 if( set )
_addRight( offset+2*res , boundary );
446 template<
int Degree >
457 template<
int Degree >
460 d.resize( this->size() );
462 for(
int i=0 ; i<int(this->size()) ; i++ )
for(
int j=0 ; j<=Degree ; j++ )
464 if( j-1>=0 ) d[i][j-1] -= (*this)[i][j];
465 if( j<Degree ) d[i][j ] += (*this)[i][j];
471 template<
int Degree1 ,
int Degree2 >
474 for(
int i=0 ; i<=Degree1 ; i++ )
477 for(
int j=0 ; j<=Degree2 ; j++ )
480 integrals[i][j] = ( p1 * p2 ).integral( 0 , 1 );
PPolynomial< Degree > baseFunction
static const int DD_DOT_FLAG
PPolynomial< Degree-1 > dRightBaseFunction
static const int VV_DOT_FLAG
BSplineComponents * baseBSplines
void set(int maxDepth, bool useDotRatios=true, bool reflectBoundary=false)
static int SymmetricIndex(int i1, int i2)
static const int D_VALUE_FLAG
virtual void setValueTables(int flags, double smooth=0)
PPolynomial< Degree-1 > dBaseFunction
virtual void clearDotTables(int flags)
PPolynomial< Degree > rightBaseFunction
static const int DV_DOT_FLAG
virtual void setDotTables(int flags)
PPolynomial< Degree-1 > dLeftBaseFunction
PPolynomial< Degree > leftBaseFunction
virtual void clearValueTables(void)
PPolynomial< Degree > * baseFunctions
void setSampleSpan(int idx, int &start, int &end, double smooth=0) const
int Index(int i1, int i2) const
BSplineComponents rightBSpline
BSplineComponents baseBSpline
static const int VALUE_FLAG
BSplineComponents leftBSpline
static void CenterAndWidth(int depth, int offset, Real ¢er, Real &width)
static int CumulativeCenterCount(int maxDepth)
static int CenterIndex(int depth, int offSet)
static int CornerCount(int depth)
static int CenterCount(int depth)
static void DepthAndOffset(int idx, int &depth, int &offset)
static PPolynomial BSpline(double radius=0.5)
PPolynomial< Degree-1 > derivative(void) const
PPolynomial< Degree+1 > MovingAverage(double radius)
An exception that is thrown when the arguments number or type is wrong/unhandled.
static Polynomial BSplineComponent(int i)
StartingPolynomial shift(double t) const
bool RightOverlap(unsigned int, int offset)
bool LeftOverlap(unsigned int, int offset)
int ReflectLeft(unsigned int, int offset)
void SetBSplineElementIntegrals(double integrals[Degree1+1][Degree2+1])
int ReflectRight(unsigned int depth, int offset)
void differentiate(BSplineElements< Degree-1 > &d) const
void _addRight(int offset, int boundary)
void _addLeft(int offset, int boundary)
void upSample(BSplineElements &high) const