void FunctionData<Degree, Real>::setDotTables(const int& flags) { clearDotTables (flags); int size; size = (res*res+res)>>1; if (flags & DOT_FLAG) { dotTable = new Real[size]; memset(dotTable,0,sizeof(Real)*size); } if (flags & D_DOT_FLAG) { dDotTable = new Real[size]; memset(dDotTable,0,sizeof(Real)*size); } if (flags & D2_DOT_FLAG) { d2DotTable = new Real[size]; memset(d2DotTable,0,sizeof(Real)*size); } double t1,t2; t1 = baseFunction.polys[0].start; t2 = baseFunction.polys[baseFunction.polyCount-1].start; for(int i = 0; i < res; i++) { double c1, c2, w1, w2; BinaryNode<double>::CenterAndWidth (i, c1, w1); double start1 = t1*w1+c1; double end1 = t2*w1+c1; for(int j = 0; j <= i; j++) { BinaryNode<double>::CenterAndWidth (j, c2, w2); int idx = SymmetricIndex (i, j); double start = t1*w2+c2; double end = t2*w2+c2; if (start < start1) start = start1; if (end > end1) end = end1; if (start >= end) continue; BinaryNode<double>::CenterAndWidth (j, c2, w2); Real dot = dotProduct (c1, w1, c2, w2); if (fabs(dot) < 1e-15) continue; if (flags & DOT_FLAG) dotTable[idx] = dot; if (useDotRatios) { if (flags & D_DOT_FLAG) dDotTable [idx] = -dDotProduct(c1,w1,c2,w2)/dot; if (flags & D2_DOT_FLAG) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2)/dot; } else { if (flags & D_DOT_FLAG) dDotTable[idx] = dDotProduct(c1,w1,c2,w2); if (flags & D2_DOT_FLAG) d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2); } } } }
void BSplineData<Degree,Real>::setDotTables( int flags ) { clearDotTables( flags ); int size = ( functionCount*functionCount + functionCount )>>1; int fullSize = functionCount*functionCount; if( flags & VV_DOT_FLAG ) { vvDotTable = new Real[size]; memset( vvDotTable , 0 , sizeof(Real)*size ); } if( flags & DV_DOT_FLAG ) { dvDotTable = new Real[fullSize]; memset( dvDotTable , 0 , sizeof(Real)*fullSize ); } if( flags & DD_DOT_FLAG ) { ddDotTable = new Real[size]; memset( ddDotTable , 0 , sizeof(Real)*size ); } double vvIntegrals[Degree+1][Degree+1]; double vdIntegrals[Degree+1][Degree ]; double dvIntegrals[Degree ][Degree+1]; double ddIntegrals[Degree ][Degree ]; int vvSums[Degree+1][Degree+1]; int vdSums[Degree+1][Degree ]; int dvSums[Degree ][Degree+1]; int ddSums[Degree ][Degree ]; SetBSplineElementIntegrals< Degree , Degree >( vvIntegrals ); SetBSplineElementIntegrals< Degree , Degree-1 >( vdIntegrals ); SetBSplineElementIntegrals< Degree-1 , Degree >( dvIntegrals ); SetBSplineElementIntegrals< Degree-1 , Degree-1 >( ddIntegrals ); for( int d1=0 ; d1<=depth ; d1++ ) for( int off1=0 ; off1<(1<<d1) ; off1++ ) { int ii = BinaryNode< Real >::CenterIndex( d1 , off1 ); BSplineElements< Degree > b1( 1<<d1 , off1 , reflectBoundary ? BSplineElements<Degree>::NEUMANN : BSplineElements< Degree>::NONE ); BSplineElements< Degree-1 > db1; b1.differentiate( db1 ); int start1 , end1; start1 = -1; for( int i=0 ; i<int(b1.size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ ) { if( b1[i][j] && start1==-1 ) start1 = i; if( b1[i][j] ) end1 = i+1; } for( int d2=d1 ; d2<=depth ; d2++ ) { for( int off2=0 ; off2<(1<<d2) ; off2++ ) { int start2 = off2-Degree; int end2 = off2+Degree+1; if( start2>=end1 || start1>=end2 ) continue; start2 = std::max< int >( start1 , start2 ); end2 = std::min< int >( end1 , end2 ); if( d1==d2 && off2<off1 ) continue; int jj = BinaryNode< Real >::CenterIndex( d2 , off2 ); BSplineElements< Degree > b2( 1<<d2 , off2 , reflectBoundary ? BSplineElements<Degree>::NEUMANN : BSplineElements< Degree>::NONE ); BSplineElements< Degree-1 > db2; b2.differentiate( db2 ); int idx = SymmetricIndex( ii , jj ); int idx1 = Index( ii , jj ) , idx2 = Index( jj , ii ); memset( vvSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree+1 ) ); memset( vdSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree ) ); memset( dvSums , 0 , sizeof( int ) * ( Degree ) * ( Degree+1 ) ); memset( ddSums , 0 , sizeof( int ) * ( Degree ) * ( Degree ) ); for( int i=start2 ; i<end2 ; i++ ) { for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) vvSums[j][k] += b1[i][j] * b2[i][k]; for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) vdSums[j][k] += b1[i][j] * db2[i][k]; for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) dvSums[j][k] += db1[i][j] * b2[i][k]; for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) ddSums[j][k] += db1[i][j] * db2[i][k]; } double vvDot = 0 , dvDot = 0 , vdDot = 0 , ddDot = 0; for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) vvDot += vvIntegrals[j][k] * vvSums[j][k]; for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) vdDot += vdIntegrals[j][k] * vdSums[j][k]; for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) dvDot += dvIntegrals[j][k] * dvSums[j][k]; for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) ddDot += ddIntegrals[j][k] * ddSums[j][k]; vvDot /= (1<<d2); ddDot *= (1<<d2); vvDot /= ( b1.denominator * b2.denominator ); dvDot /= ( b1.denominator * b2.denominator ); vdDot /= ( b1.denominator * b2.denominator ); ddDot /= ( b1.denominator * b2.denominator ); if( fabs(vvDot)<1e-15 ) continue; if( flags & VV_DOT_FLAG ) vvDotTable [idx] = Real( vvDot ); if( useDotRatios ) { if( flags & DV_DOT_FLAG ) dvDotTable[idx1] = Real( dvDot / vvDot ); if( flags & DV_DOT_FLAG ) dvDotTable[idx2] = Real( vdDot / vvDot ); if( flags & DD_DOT_FLAG ) ddDotTable[idx ] = Real( ddDot / vvDot ); } else { if( flags & DV_DOT_FLAG ) dvDotTable[idx1] = Real( dvDot ); if( flags & DV_DOT_FLAG ) dvDotTable[idx2] = Real( dvDot ); if( flags & DD_DOT_FLAG ) ddDotTable[idx ] = Real( ddDot ); } } BSplineElements< Degree > b; b = b1; b.upSample( b1 ); b1.differentiate( db1 ); start1 = -1; for( int i=0 ; i<int(b1.size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ ) { if( b1[i][j] && start1==-1 ) start1 = i; if( b1[i][j] ) end1 = i+1; } } } }