# itkMath FloatAlmostEqual question

**URL:** <https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493>\
**Category:** Algorithms\
**Created:** [December 23, 2018, 9:00am UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493 "2018-12-23T09:00:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [December 23, 2018, 9:00am UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493/1 "2018-12-23T09:00:48Z")

</div>

It looks like FloatAlmostEqual function (itkMath.h) does rather similar thing twice, in particular if floats are not almost equal - subtract, abs, compare (first to epsilon, then unit of least precision), isn’t it? It is not wrong, but may be it could impact performance?

[FloatAlmostEqual](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkMath.h#L300)

---

<div class="post-metadata">

**Author:** ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)\
**Post date:** [December 23, 2018, 11:09am UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493/2 "2018-12-23T11:09:58Z")

</div>

> [@mihail.isakov](#):
>
> It looks like FloatAlmostEqual function (itkMath.h) does rather similar thing twice, in particular if floats are not almost equal - subtract, abs, compare (first to epsilon, then unit of least precision), isn’t it?

I think this is intended. A pair of floating point numbers could have a large absolute difference, and still be considered “almost equal”:

```
EXPECT_TRUE(
itk::Math::FloatAlmostEqual(
  1.7976931348623158e+308, // <== Which is DBL_MAX.
  1.7976931348623156e+308 // <== Mind the last decimal digit!
));

```

In this case, the absolute difference is ~2.0e+292, while these two numbers only differ by one unit of least precision (ULP).

On the other hand, a pair of floating point numbers could have a large absolute ULP difference, and still be considered “almost equal”:

```
EXPECT_TRUE(
itk::Math::FloatAlmostEqual(
  2.2250738585072014e-308, // <== Which is DBL_MIN.
  0.0
));

```

My debugger tells me that DBL\_MIN is 4503599627370496 ULPs apart from 0.0, yet these numbers could be considered almost equal, right?

> [@mihail.isakov](#):
>
> It is not wrong, but may be it could impact performance?

That’s possible, of course. But do you have a specific application or image filter in mind, whose performance could be affected by this function?

---

<div class="post-metadata">

**Author:** ![mihail.isakov](https://discourse.itk.org/letter_avatar_proxy/v4/letter/m/c4cdca/32.png) [@mihail.isakov](https://discourse.itk.org/u/mihail.isakov)\
**Post date:** [December 23, 2018, 11:17am UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493/3 "2018-12-23T11:17:19Z")

</div>

Thank you for explanation.

> But do you have a specific application or image filter in mind, whose performance could be affected by this function?

```
./Modules/Numerics/Statistics/include/itkHistogramToTextureFeaturesFilter.hxx: if( Math::FloatAlmostEqual( pixelVarianceSquared, 0.0, 4, 2*NumericTraits<double>::epsilon() ) )
./Modules/Filtering/Thresholding/include/itkOtsuMultipleThresholdsCalculator.hxx: !Math::FloatAlmostEqual( maxVarBetween, varBetween, maxUlps) )
./Modules/Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_LowFrequencyThreshold) )
./Modules/Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_HighFrequencyThreshold) )
./Modules/Filtering/Path/include/itkPolyLineParametricPath.hxx: if ( input > endPoint || itk::Math::FloatAlmostEqual( input, endPoint ) )
./Modules/Filtering/FastMarching/include/itkFastMarchingImageFilterBase.hxx: if (itk::Math::FloatAlmostEqual<double>(cc, 0.0))
./Modules/Core/Common/include/itkVersor.hxx: if ( Math::FloatAlmostEqual<T>(vectorNorm, 0.0) )
./Modules/Core/Transform/include/itkBSplineTransform.hxx: if( Math::FloatAlmostEqual( index[j], maxLimit, 4 ) )
./Modules/Core/Transform/include/itkVersorRigid3DTransform.hxx: if (Math::FloatAlmostEqual<TParametersValueType>(norm, 0.0))

```

Edit: removed calls from tests

---

<div class="post-metadata">

**Author:** ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)\
**Post date:** [December 23, 2018, 11:39am UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493/4 "2018-12-23T11:39:06Z")

</div>

> [@mihail.isakov](#):
>
> ```auto
> Numerics/Statistics/include/itkHistogramToTextureFeaturesFilter.hxx: if( Math::FloatAlmostEqual( pixelVarianceSquared, 0.0, 4, 2*NumericTraits<double>::epsilon() ) )
> Filtering/Thresholding/include/itkOtsuMultipleThresholdsCalculator.hxx: !Math::FloatAlmostEqual( maxVarBetween, varBetween, maxUlps) )
> Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_LowFrequencyThreshold) )
> Filtering/ImageFrequency/include/itkFrequencyBandImageFilter.hxx: if ( Math::FloatAlmostEqual(scalarFrequency, this->m_HighFrequencyThreshold) )
> Filtering/Path/include/itkPolyLineParametricPath.hxx: if ( input > endPoint || itk::Math::FloatAlmostEqual( input, endPoint ) )
> Filtering/FastMarching/include/itkFastMarchingImageFilterBase.hxx: if (itk::Math::FloatAlmostEqual<double>(cc, 0.0))
> Core/Common/include/itkVersor.hxx: if ( Math::FloatAlmostEqual<T>(vectorNorm, 0.0) )
> Core/Transform/include/itkBSplineTransform.hxx: if( Math::FloatAlmostEqual( index[j], maxLimit, 4 ) )
> Core/Transform/include/itkVersorRigid3DTransform.hxx: if (Math::FloatAlmostEqual<TParametersValueType>(norm, 0.0))
> 
> ```

Interesting. I think you’re right: it seems to me that in some of these cases, the performance could be improved by doing something else than calling the current `FloatAlmostEqual` function. For example, instead of `FloatAlmostEqual(x, 0.0)`, I think I would prefer something like `abs(x) < DBL_MIN`. But I haven’t had a close look yet at these particular cases.

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [December 24, 2018, 2:48pm UTC](https://discourse.itk.org/t/itkmath-floatalmostequal-question/1493/6 "2018-12-24T14:48:26Z")

</div>

You are right, in some cases `FloatAlmostEqual` could be replaced by less general `std::abs(x)<epsilon`. But as that case is checked first in `FloatAlmostEqual`, and it should be in the predicted branch, the extra code in `FloatAlmostEqual` should not matter. Of course, to test this assumption a change should be made and performance compared with and without the change.
