18#ifndef __itkRecursiveBSplineTransformImplementation_h
19#define __itkRecursiveBSplineTransformImplementation_h
40template<
unsigned int OutputDimension,
unsigned int SpaceDimension,
unsigned int SplineOrder,
class TScalar >
53 ( SpaceDimension - 1 ) * ( SplineOrder + 1 ) );
59 RecursiveBSplineWeightFunctionType::NumberOfIndices );
67 const OffsetValueType * gridOffsetTable,
68 const double * weights1D )
72 for(
unsigned int j = 0; j < OutputDimension; ++j )
74 tmp_mu[ j ] = mu[ j ];
79 for(
unsigned int j = 0; j < OutputDimension; ++j )
84 OffsetValueType bot = gridOffsetTable[ SpaceDimension - 1 ];
85 for(
unsigned int k = 0; k <= SplineOrder; ++k )
92 for(
unsigned int j = 0; j < OutputDimension; ++j )
94 opp[ j ] += tmp_opp[ j ] * weights1D[ k + HelperConstVariable ];
105 ScalarType * & jacobians,
const double * weights1D,
double value )
107 for(
unsigned int k = 0; k <= SplineOrder; ++k )
111 ::GetJacobian( jacobians, weights1D, value * weights1D[ k + HelperConstVariable ] );
119 const double * weights1D,
double value )
121 for(
unsigned int k = 0; k <= SplineOrder; ++k )
126 value * weights1D[ k + HelperConstVariable ] );
133 unsigned long * & nzji,
134 const unsigned long parametersPerDim,
135 unsigned long currentIndex,
136 const OffsetValueType * gridOffsetTable )
138 const OffsetValueType bot = gridOffsetTable[ SpaceDimension - 1 ];
139 for(
unsigned int k = 0; k <= SplineOrder; ++k )
157 const OffsetValueType * gridOffsetTable,
158 const double * weights1D,
159 const double * derivativeWeights1D )
163 for(
unsigned int j = 0; j < OutputDimension; ++j )
165 tmp_mu[ j ] = mu[ j ];
170 for(
unsigned int n = 0; n < OutputDimension * ( SpaceDimension + 1 ); ++n )
175 OffsetValueType bot = gridOffsetTable[ SpaceDimension - 1 ];
176 for(
unsigned int k = 0; k <= SplineOrder; ++k )
183 for(
unsigned int n = 0; n < OutputDimension * SpaceDimension; ++n )
185 sj[ n ] += tmp_sj[ n ] * weights1D[ k + HelperConstVariable ];
189 for(
unsigned int j = 0; j < OutputDimension; ++j )
191 sj[ OutputDimension * SpaceDimension + j ]
192 += tmp_sj[ j ] * derivativeWeights1D[ k + HelperConstVariable ];
223 const OffsetValueType * gridOffsetTable,
224 const double * weights1D,
225 const double * derivativeWeights1D,
226 const double * hessianWeights1D )
228 const unsigned int helperDim1 = OutputDimension * SpaceDimension * ( SpaceDimension + 1 ) / 2;
229 const unsigned int helperDim2 = OutputDimension * ( SpaceDimension + 1 ) * ( SpaceDimension + 2 ) / 2;
233 for(
unsigned int j = 0; j < OutputDimension; ++j )
235 tmp_mu[ j ] = mu[ j ];
240 for(
unsigned int n = 0; n < helperDim2; ++n )
245 OffsetValueType bot = gridOffsetTable[ SpaceDimension - 1 ];
246 for(
unsigned int k = 0; k <= SplineOrder; ++k )
250 ::GetSpatialHessian( tmp_sh, tmp_mu, gridOffsetTable, weights1D, derivativeWeights1D, hessianWeights1D );
253 for(
unsigned int n = 0; n < helperDim1; ++n )
255 sh[ n ] += tmp_sh[ n ] * weights1D[ k + HelperConstVariable ];
259 for(
unsigned int n = 0; n < SpaceDimension; ++n )
261 for(
unsigned int j = 0; j < OutputDimension; ++j )
263 sh[ OutputDimension * n + helperDim1 + j ]
264 += tmp_sh[ OutputDimension * n * ( n + 1 ) / 2 + j ] * derivativeWeights1D[ k + HelperConstVariable ];
269 for(
unsigned int j = 0; j < OutputDimension; ++j )
271 sh[ helperDim2 - OutputDimension + j ]
272 += tmp_sh[ j ] * hessianWeights1D[ k + HelperConstVariable ];
286 const double * weights1D,
287 const double * derivativeWeights1D,
288 const double * directionCosines,
291 const unsigned int helperDim = OutputDimension - SpaceDimension + 1;
296 for(
unsigned int k = 0; k <= SplineOrder; ++k )
298 const double w = weights1D[ k + HelperConstVariable ];
299 const double dw = derivativeWeights1D[ k + HelperConstVariable ];
302 for(
unsigned int n = 0; n < helperDim; ++n )
304 tmp_jsj[ n ] = jsj[ n ] * w;
308 tmp_jsj[ helperDim ] = jsj[ 0 ] * dw;
322 const double * weights1D,
323 const double * derivativeWeights1D,
324 const double * hessianWeights1D,
325 const double * directionCosines,
328 const unsigned int helperDim = OutputDimension - SpaceDimension;
329 const unsigned int helperDimW = ( helperDim + 1 ) * ( helperDim + 2 ) / 2;
330 const unsigned int helperDimDW = helperDim + 1;
335 for(
unsigned int k = 0; k <= SplineOrder; ++k )
338 const double w = weights1D[ k + HelperConstVariable ];
339 const double dw = derivativeWeights1D[ k + HelperConstVariable ];
340 const double hw = hessianWeights1D[ k + HelperConstVariable ];
343 for(
unsigned int n = 0; n < helperDimW; ++n )
345 tmp_jsh[ n ] = jsh[ n ] * w;
349 for(
unsigned int n = 0; n < helperDimDW; ++n )
351 unsigned int nn = n * ( n + 1 ) / 2;
352 tmp_jsh[ n + helperDimW ] = jsh[ nn ] * dw;
356 tmp_jsh[ helperDimW + helperDimDW ] = jsh[ 0 ] * hw;
373template<
unsigned int OutputDimension,
unsigned int SplineOrder,
class TScalar >
388 RecursiveBSplineWeightFunctionType::NumberOfIndices );
396 const OffsetValueType * gridOffsetTable,
397 const double * weights1D )
399 for(
unsigned int j = 0; j < OutputDimension; ++j )
401 opp[ j ] = *( mu[ j ] );
408 ScalarType * & jacobians,
const double * weights1D,
double value )
410 unsigned long offset = 0;
411 for(
unsigned int j = 0; j < OutputDimension; ++j )
413 offset = j * BSplineNumberOfIndices * ( OutputDimension + 1 );
414 jacobians[ offset ] = value;
423 const double * weights1D,
double value )
425 for(
unsigned int j = 0; j < OutputDimension; ++j )
427 *( imageJacobian + j * BSplineNumberOfIndices ) = value * movingImageGradient[ j ];
435 unsigned long * & nzji,
436 const unsigned long parametersPerDim,
437 unsigned long currentIndex,
438 const OffsetValueType * gridOffsetTable )
440 for(
unsigned int j = 0; j < OutputDimension; ++j )
442 nzji[ j * BSplineNumberOfIndices ] = currentIndex + j * parametersPerDim;
452 const OffsetValueType * gridOffsetTable,
453 const double * weights1D,
454 const double * derivativeWeights1D )
456 for(
unsigned int j = 0; j < OutputDimension; ++j )
458 sj[ j ] = *( mu[ j ] );
467 const OffsetValueType * gridOffsetTable,
468 const double * weights1D,
469 const double * derivativeWeights1D,
470 const double * hessianWeights1D )
472 for(
unsigned int j = 0; j < OutputDimension; ++j )
474 sh[ j ] = *( mu[ j ] );
482 const double * weights1D,
483 const double * derivativeWeights1D,
484 const double * directionCosines,
492 for(
unsigned int j = 0; j < OutputDimension; ++j )
494 jsj_out[ j ] = jsj[ OutputDimension ] * directionCosines[ j ];
495 for(
unsigned int k = 1; k < OutputDimension; ++k )
497 jsj_out[ k ] += jsj[ OutputDimension - k ] * directionCosines[ k * OutputDimension + j ];
502 unsigned int offset = 0;
503 for(
unsigned int i = 0; i < OutputDimension; ++i )
505 offset = i * ( OutputDimension * ( BSplineNumberOfIndices * OutputDimension + 1 ) );
506 for(
unsigned int j = 0; j < OutputDimension; ++j )
508 jsj_out[ j + offset ] = jsj_out[ j ];
513 jsj_out += OutputDimension * OutputDimension;
521 const double * weights1D,
522 const double * derivativeWeights1D,
523 const double * hessianWeights1D,
524 const double * directionCosines,
527 double jsh_tmp[ OutputDimension * OutputDimension ];
528 double matrixProduct[ OutputDimension * OutputDimension ];
536 if( OutputDimension == 3 )
538 jsh_tmp[ 0 ] = jsh[ 9 ]; jsh_tmp[ 1 ] = jsh[ 8 ]; jsh_tmp[ 2 ] = jsh[ 7 ];
539 jsh_tmp[ 3 ] = jsh_tmp[ 1 ]; jsh_tmp[ 4 ] = jsh[ 5 ]; jsh_tmp[ 5 ] = jsh[ 4 ];
540 jsh_tmp[ 6 ] = jsh_tmp[ 2 ]; jsh_tmp[ 7 ] = jsh_tmp[ 5 ]; jsh_tmp[ 8 ] = jsh[ 2 ];
542 else if( OutputDimension == 2 )
544 jsh_tmp[ 0 ] = jsh[ 5 ]; jsh_tmp[ 1 ] = jsh[ 4 ];
545 jsh_tmp[ 2 ] = jsh_tmp[ 1 ]; jsh_tmp[ 3 ] = jsh[ 2 ];
549 for(
unsigned int j = 0; j < OutputDimension; ++j )
551 for(
unsigned int i = 0; i <= j; ++i )
553 jsh_tmp[ j * OutputDimension + i ] = jsh[ ( OutputDimension - j ) + ( OutputDimension - i ) * ( OutputDimension - i + 1 ) / 2 ];
556 jsh_tmp[ i * OutputDimension + j ] = jsh_tmp[ j * OutputDimension + i ];
563 for(
unsigned int i = 0; i < OutputDimension; ++i )
565 for(
unsigned int j = 0; j < OutputDimension; ++j )
567 double accum = directionCosines[ i ] * jsh_tmp[ j ];
568 for(
unsigned int k = 1; k < OutputDimension; ++k )
570 accum += directionCosines[ k * OutputDimension + i ] * jsh_tmp[ k * OutputDimension + j ];
572 matrixProduct[ i * OutputDimension + j ] = accum;
577 for(
unsigned int i = 0; i < OutputDimension; ++i )
579 for(
unsigned int j = 0; j < OutputDimension; ++j )
581 double accum = matrixProduct[ i * OutputDimension ] * directionCosines[ j ];
582 for(
unsigned int k = 1; k < OutputDimension; ++k )
584 accum += matrixProduct[ i * OutputDimension + k ] * directionCosines[ k * OutputDimension + j ];
586 jsh_out[ i * OutputDimension + j ] = accum;
591 unsigned long offset = 0;
592 for(
unsigned int i = 0; i < OutputDimension; ++i )
594 offset = i * ( OutputDimension * OutputDimension * ( BSplineNumberOfIndices * OutputDimension + 1 ) );
595 for(
unsigned int j = 0; j < OutputDimension * OutputDimension; ++j )
597 jsh_out[ j + offset ] = jsh_out[ j ];
602 jsh_out += OutputDimension * OutputDimension * OutputDimension;
Returns the weights over the support region used for B-spline interpolation/reconstruction.