[Insight-developers] correct form of dimension specific code.

Miller, James V (Research) millerjv at crd.ge.com
Fri Oct 7 07:49:13 EDT 2005


Richard, 

It can be tricky to put in dimension specific code.  All the code has 
to be compilable regardless of dimension.  So if you use an if block
on dimension, the code inside that block will need to compile even if the
image is not of that dimension.  One bad example is 

Index<InputImageDimension> index;

if (InputImageDimension == 3)
  {
  index[2] = 100;
  }

If InputImageDimension is 2, then the code inside the if block will access past 
the end of the array.  This will probably cause a compiler warning.


It is tempting to provide separate functions for each dimension, like:

  switch (InputImageDimension)
    {
    case 2: this->ComputeThreshold2D();  break;
    case 3: this->ComputeThreshold3D();  break;
    default: this->ComputeThreshold(); break;
    }

However, this requires that ComputeThreshold2D(), ComputeThreshold3D() and 
ComputeThreshold() can all be compiled regardless of image dimension.  So this
technique has not addressed the issue.


One pattern that does work frequently is to use function overloading. 

  struct DispatchBase {};
  template<signed int VDimension>
  struct Dispatch : DispatchBase {};
  
  /** This method computes the threshold by averaging the intensity
   *  in direction perpendicular to the image gradient. */
  virtual PixelType ComputeThreshold( const Dispatch<2> &,
                                      const NeighborhoodType & neighborhood ) const;
  virtual PixelType ComputeThreshold( const Dispatch<3> &,
                                      const NeighborhoodType & neighborhood ) const;
  virtual PixelType ComputeThreshold( const DispatchBase &,
                                      const NeighborhoodType & neighborhood ) const;


Here we use three functions called ComputeThreshold() that differ in the type
of the first parameter.  The version whose first parameter is Dispatch<2> is used
for 2D images. The code inside that function can use optimizations for 2D images.
The version whose first parameter is Dispatch<3> is used for 3D images.  The version 
whose first parameter is DispatchBase is used for any other image dimension.

In your code, when you want to call the correct ComputeThreshold() method, you simply
call ComputeThreshold() with a Dispatch templated over image dimension, 

   this->ComputeThreshold(Dispatch<InputImageDimension>, neighborhood);

If your image is 2D, it will end up compiling and calling 
ComputeThreshold(Dispatch<2>, ...).  If your image is 3D, it will end up calling
ComputeThreshold(Dispatch<3>, ...).  If your image is any other dimension, it
will call the more general ComputeThreshold(DispatchBase, ...).

This is best pattern we can use until we drop support for compilers that do not
allow partial specialization.

For the specific optimizations that you want to perform, there could be other 
techniques that may be appropriate.  The Dispatch pattern is a general solution.

Jim


-----Original Message-----
From: insight-developers-bounces+millerjv=crd.ge.com at itk.org
[mailto:insight-developers-bounces+millerjv=crd.ge.com at itk.org]On Behalf
Of Richard Beare
Sent: Thursday, October 06, 2005 9:52 PM
To: insight-developers at itk.org
Subject: [Insight-developers] correct form of dimension specific code.


Hi,
I realise that the need to write dimension specific code has been much
reduced by iterators, but there are some optimizations that I can't
see how to achieve without exploiting dimension information. I was
wondering what the correct way of doing this in itk's c++ style? Does
an if block dependent on a template parameter have the correct
behaviour, or is something else more appropriate? If nothing else this
capability will provide a mechanism to compare the optimization
approaches.

Thanks
_______________________________________________
Insight-developers mailing list
Insight-developers at itk.org
http://www.itk.org/mailman/listinfo/insight-developers


More information about the Insight-developers mailing list