Initializing itk::vector or numeric type with the same command

Hello,

I would like one of my filters to work with ImageType = itk::Image<float, 3> as well as with ImageType = itk::Image<itk::Vector<float, 5>, 3>. Computation on the pixels only involves operators that are overloaded for itk::Vector, like +, -, multiplication by a scalar, etc… so that part is not a problem. What is a problem, though, is the initialization of the image’s pixels to 0. I’d like to have a command to set a pixel to either 0, or to an itk::Vector filled with zeros. At first, I thought that itk::NumericTraits::Zero would be fine for both cases, but my compiler throws warnings for the vector part.

Is there a way to do what I need ? Would it be possible, for example, to add a specialization to itk::NumericTraits to handle the case where the template type is an itk::Vector ?

Hi Cyril,

What kind of warnings do you get? Would you also get these warnings if you would initialize the pixel values by PixelType{}, instead of itk::NumericTraits<PixelType>::Zero?

Kind regards, Niels

Hi Niels,

Here is the warning:

In file included from /Users/srit/src/rtk/rtk/include/rtkMechlemOneStepSpectralReconstructionFilter.h:263:
/Users/srit/src/rtk/rtk/include/rtkMechlemOneStepSpectralReconstructionFilter.hxx:58:90: warning: instantiation of variable ‘itk::NumericTraits<itk::Vector<float, 3> >::Zero’ required here, but no
definition is available [-Wundefined-var-template]
m_ProjectionsSource->SetConstant(itk::NumericTraits::Zero);
^
/Users/srit/src/rtk/rtk/include/rtkMechlemOneStepSpectralReconstructionFilter.h:125:17: note: in instantiation of member function
‘rtk::MechlemOneStepSpectralReconstructionFilter<itk::Image<itk::Vector<float, 3>, 3>, itk::Image<itk::Vector<float, 5>, 3>, itk::Image<itk::Vector<float, 150>, 2>
>::MechlemOneStepSpectralReconstructionFilter’ requested here
itkNewMacro(Self)
^
/Users/srit/src/rtk/rtk/applications/rtkspectralonestep/rtkspectralonestep.cxx:171:66: note: in instantiation of member function
‘rtk::MechlemOneStepSpectralReconstructionFilter<itk::Image<itk::Vector<float, 3>, 3>, itk::Image<itk::Vector<float, 5>, 3>, itk::Image<itk::Vector<float, 150>, 2> >::New’ requested here
MechlemFilterType::Pointer mechlemOneStep = MechlemFilterType::New();
^
/Users/srit/src/itk/itk/Modules/Core/Common/include/itkNumericTraitsVectorPixel.h:222:38: note: forward declaration of template entity is here
static const Self ITKCommon_EXPORT Zero;
^
/Users/srit/src/rtk/rtk/include/rtkMechlemOneStepSpectralReconstructionFilter.hxx:58:90: note: add an explicit instantiation declaration to suppress this warning if
‘itk::NumericTraits<itk::Vector<float, 3> >::Zero’ is explicitly instantiated in another translation unit
m_ProjectionsSource->SetConstant(itk::NumericTraits::Zero);

Following your suggestion, I tried using PixelType{} instead of itk::NumericTraits::Zero. It compiles without warning when PixelType = itk::Vector<float, 5>, but fails to compile when PixelType=float. Also, I did not know about this syntax. Can you direct me to some documentation on it ?

Regards,
Cyril

@cyril.mory Now I see your point: it appears that itk::NumericTraits<T>::Zero is only instantiated for a limited number of types (T): https://github.com/Kitware/ITK/blob/v5.0a02/Modules/Core/Common/src/itkNumericTraits.cxx @blowekamp @hjmjohnson Maybe you guys can elaborate on whether or not itk::NumericTraits<itk::Vector<float, 3> >::Zero should be supported…?

Can you tell us the error message you got from PixelType{}, when PixelType = float? Do you get the same error message when you do PixelType() instead?

In general, both Type{} and Type() should yield an initialized object of the specified type, in C++. For a scalar type (like float), it should yield zero. If you want to know more, please search for C++ value-initialization, default-initialization, uniform initialization syntax, braced initialization, aggregate initialization, initializer list, etc.!

1 Like

My bad, I tried it again PixelType{} with PixelType = float and it compiles without problem. I must have done something wrong the first time. Now I’ll just have to replace the itk::NumericTraits<T>::Zero with T{} everywhere in my code.

Still, I’m interested in Bradley and Hans’ answers on whether or not itk::NumericTraits<itk::Vector<float, 3> >::Zero should be supported.

Thanks for the information on braced initialization, too.

1 Like

Sorry, that was not the end of it: using PixelType{}, my code compiles fine, but returns incorrect results.
Only the first element of the vector is correctly initialized to zero. So for the time being, I’ll stick to itk::NumericTraits, which throws warnings but seems to do the job.

typedef itk::Vector<float, 5> VectorType;
std::cout << VectorType{} << std::endl;
std::cout << VectorType() << std::endl;
std::cout << itk::NumericTraits<VectorType>::Zero << std::endl;

returns:

[0, 4.56095e-41, -0.000420635, 4.59149e-41, 0]
[0, 4.56095e-41, -0.000420635, 4.59149e-41, 0]
[0, 0, 0, 0, 0]

I’m still using ITK 4.13.0, if that matters.

That should work.

After looking again, I believe that the NumericTraits<>::ZeroValue() constexpr function is preferred over the static variable Zero.

There are several ITK array-like classes which are plain old data (POD) and do not perform initialization.

Indeed, with NumericTraits<>::ZeroValue() instead of NumericTraits<>::Zero, I get the correct behavior and the warnings disappear.

Thanks !

2 Likes