Skip to content

Commit a5c4039

Browse files
enpemeta-codesync[bot]
authored andcommitted
Scale constant-spectrum tolerance by precision
Summary: ConstantInputSpectrumStress used a fixed 1e-3 absolute bound for theoretically-zero non-DC components. A deterministic 20x23 constant-255 transform in explicit float produces 0.005859375 residual (4.9952e-8 of its 117300 DC magnitude), proving the fixed bound rejects ordinary single-precision roundoff. The test now bounds leakage by max(1, abs(expectedDC)) * NumericT<T>::eps(): a precision-derived 1e-6 relative budget for float and 1e-12 for double. This is 100x stricter than the abandoned D111055971 proposal of 1e-4, preserves the only-DC invariant, and strengthens low-magnitude and double validation. Existing DC real and imaginary checks are unchanged. An explicit-float 20x23 regression covers the affected precision on double-default hosts. ___ Differential Revision: D115898011 fbshipit-source-id: 48c7a05b78114e237626a9bfe34d8bd4b3d4094c
1 parent 0939eea commit a5c4039

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

impl/ocean/test/testcv/TestFrequencyAnalysis.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
#include "ocean/cv/FrequencyAnalysis.h"
2020

2121
#include "ocean/math/Complex.h"
22+
#include "ocean/math/FourierTransformation.h"
2223
#include "ocean/math/Numeric.h"
2324

25+
#include <algorithm>
2426
#include <vector>
2527

2628
namespace Ocean
@@ -188,6 +190,18 @@ FrameType::PixelFormat randomPixelFormat(RandomGenerator& randomGenerator)
188190
return FrameType::FORMAT_RGBA32;
189191
}
190192

193+
/**
194+
* Returns an absolute error bound for a theoretically-zero DFT component.
195+
* Forward-transform roundoff scales with the input L1 norm, which is the DC
196+
* magnitude for a constant non-negative input. NumericT<T>::eps() supplies
197+
* Ocean's precision-specific relative comparison budget.
198+
*/
199+
template <typename T>
200+
T constantSpectrumComponentTolerance(const T expectedDC)
201+
{
202+
return std::max(T(1), NumericT<T>::abs(expectedDC)) * NumericT<T>::eps();
203+
}
204+
191205
} // namespace
192206

193207
bool TestFrequencyAnalysis::testRoundTripIdentity(const double testDuration, Worker& worker)
@@ -487,6 +501,26 @@ bool TestFrequencyAnalysis::testConstantInputSpectrumStress(const double testDur
487501
RandomGenerator randomGenerator;
488502
Validation validation(randomGenerator);
489503

504+
// Exercise the single-precision implementation deterministically, including on
505+
// hosts where Ocean's default Scalar is double.
506+
{
507+
constexpr unsigned int width = 20u;
508+
constexpr unsigned int height = 23u;
509+
constexpr float value = 255.0f;
510+
511+
std::vector<float> spatial(width * height, value);
512+
std::vector<float> frequencies(width * height * 2u);
513+
FourierTransformation::spatialToFrequency2<float>(spatial.data(), width, height, frequencies.data());
514+
515+
constexpr float expectedDC = float(width * height) * value;
516+
const float componentTolerance = constantSpectrumComponentTolerance(expectedDC);
517+
for (size_t n = 1u; n < size_t(width * height); ++n)
518+
{
519+
OCEAN_EXPECT_TRUE(validation, NumericF::abs(frequencies[n * 2u + 0u]) <= componentTolerance);
520+
OCEAN_EXPECT_TRUE(validation, NumericF::abs(frequencies[n * 2u + 1u]) <= componentTolerance);
521+
}
522+
}
523+
490524
const Timestamp startTimestamp(true);
491525
do
492526
{
@@ -513,6 +547,7 @@ bool TestFrequencyAnalysis::testConstantInputSpectrumStress(const double testDur
513547
// DC == width * height * value (real, imag ~0)
514548
const Complex dc = frequencies[c * channelStride + 0u];
515549
const Scalar expectedDC = Scalar(width) * Scalar(height) * Scalar(value);
550+
const Scalar componentTolerance = constantSpectrumComponentTolerance(expectedDC);
516551

517552
OCEAN_EXPECT_TRUE(validation, Numeric::abs(dc.real() - expectedDC) <= tolerance + Numeric::abs(expectedDC) * Scalar(1e-5));
518553
OCEAN_EXPECT_TRUE(validation, Numeric::abs(dc.imag()) <= tolerance);
@@ -521,8 +556,8 @@ bool TestFrequencyAnalysis::testConstantInputSpectrumStress(const double testDur
521556
for (unsigned int k = 1u; k < channelStride; ++k)
522557
{
523558
const Complex& f = frequencies[c * channelStride + k];
524-
OCEAN_EXPECT_TRUE(validation, Numeric::abs(f.real()) <= tolerance);
525-
OCEAN_EXPECT_TRUE(validation, Numeric::abs(f.imag()) <= tolerance);
559+
OCEAN_EXPECT_TRUE(validation, Numeric::abs(f.real()) <= componentTolerance);
560+
OCEAN_EXPECT_TRUE(validation, Numeric::abs(f.imag()) <= componentTolerance);
526561
}
527562
}
528563
}

0 commit comments

Comments
 (0)