[Insight-developers] 2-fold speed-up of itkBSplineDerivativeKernelFunction.h
wenjia
wenjia at robots.ox.ac.uk
Tue Jul 21 14:04:26 EDT 2009
Dear Developers,
Thank you for your effort in providing ITK, such an excellent library.
I have a suggestion about 2-fold speeding-up of itkBSplineDerivativeKernelFunction.h, which is used to calculate the derivative of a B-spline function. It uses the following equation for computation, calling itkBSplineKernelFunction twice.
/** Evaluate the function. */
inline double Evaluate( const double & u ) const
{
return ( m_KernelFunction->Evaluate( u + 0.5 ) -
m_KernelFunction->Evaluate( u - 0.5 ) );
}
The code is very clear for reading. However, m_KernelFunction->Evaluate( u + 0.5) and m_KernelFunction->Evaluate( u - 0.5 ) ) waste time in computing similar equations twice. Therefore, expanding the above equation, as follows, can give a two-fold speed up.
/** Zeroth order spline. */
inline double Evaluate (const Dispatch<0>&, const double & u) const
{
return 0;
}
/** First order spline */
inline double Evaluate ( const Dispatch<1>&, const double& u) const
{
if( u == -1 )
{
return 0.5;
}
else if( (u > -1) && (u < 0) )
{
return 1;
}
else if( u == 0 )
{
return 0;
}
else if( (u > 0) && (u < 1) )
{
return -1;
}
else if( u == 1 )
{
return -0.5;
}
else
{
return 0;
}
}
/** Second order spline. */
inline double Evaluate ( const Dispatch<2>&, const double& u) const
{
if( (u > -0.5) && (u < 0.5) )
{
return ( -2 * u );
}
else if( (u >= 0.5) && (u < 1.5) )
{
return ( -1.5 + u );
}
else if( (u > -1.5) && (u <= -0.5))
{
return ( 1.5 + u );
}
else
{
return 0;
}
}
/** Third order spline. */
inline double Evaluate ( const Dispatch<3>&, const double& u) const
{
if( (u >= 0) && (u < 1) )
{
return ( -2 * u + 1.5 * u * u );
}
else if( (u > -1 ) && (u < 0) )
{
return ( -2 * u - 1.5 * u * u );
}
else if( (u >= 1) && (u < 2) )
{
return ( -2 + 2 * u - 0.5 * u * u);
}
else if( (u > -2) && (u <= -1) )
{
return ( 2 + 2 * u + 0.5 * u * u);
}
else
{
return 0;
}
}
/** Unimplemented spline order */
inline double Evaluate ( const DispatchBase&, const double& ) const
{
itkExceptionMacro("Evaluate not implemented for spline order " << SplineOrder);
return 0.0; // This is to avoid compiler warning about missing
// return statement. It should never be evaluated.
}
Considering that itkBSplineDerivativeKernelFunction is usually called inside several levels of loops for time-consuming numerical compuation, speed is more important than brievity of the code. I think expanding the formula is a good choice.
Best regards,
Wenjia Bai
More information about the Insight-developers
mailing list