2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
31 template <typename FloatType
>
32 LookupTable
<FloatType
>::LookupTable()
37 template <typename FloatType
>
38 LookupTable
<FloatType
>::LookupTable (const std::function
<FloatType (size_t)>& functionToApproximate
,
39 size_t numPointsToUse
)
41 initialise (functionToApproximate
, numPointsToUse
);
44 //==============================================================================
45 template <typename FloatType
>
46 void LookupTable
<FloatType
>::initialise (const std::function
<FloatType (size_t)>& functionToApproximate
,
47 size_t numPointsToUse
)
49 data
.resize (static_cast<int> (getRequiredBufferSize (numPointsToUse
)));
51 for (size_t i
= 0; i
< numPointsToUse
; ++i
)
53 auto value
= functionToApproximate (i
);
55 jassert (! std::isnan (value
));
56 jassert (! std::isinf (value
));
57 // Make sure functionToApproximate returns a sensible value for the entire specified range.
58 // E.g., this won't work for zero: [] (size_t i) { return 1.0f / i; }
60 data
.getReference (static_cast<int> (i
)) = value
;
66 template <typename FloatType
>
67 void LookupTable
<FloatType
>::prepare() noexcept
69 auto guardIndex
= static_cast<int> (getGuardIndex());
70 data
.getReference (guardIndex
) = data
.getUnchecked (guardIndex
- 1);
73 template <typename FloatType
>
74 void LookupTableTransform
<FloatType
>::initialise (const std::function
<FloatType (FloatType
)>& functionToApproximate
,
75 FloatType minInputValueToUse
,
76 FloatType maxInputValueToUse
,
79 jassert (maxInputValueToUse
> minInputValueToUse
);
81 minInputValue
= minInputValueToUse
;
82 maxInputValue
= maxInputValueToUse
;
83 scaler
= FloatType (numPoints
- 1) / (maxInputValueToUse
- minInputValueToUse
);
84 offset
= -minInputValueToUse
* scaler
;
86 const auto initFn
= [functionToApproximate
, minInputValueToUse
, maxInputValueToUse
, numPoints
] (size_t i
)
88 return functionToApproximate (
90 minInputValueToUse
, maxInputValueToUse
,
91 jmap (FloatType (i
), FloatType (0), FloatType (numPoints
- 1), minInputValueToUse
, maxInputValueToUse
))
95 lookupTable
.initialise (initFn
, numPoints
);
98 //==============================================================================
99 template <typename FloatType
>
100 double LookupTableTransform
<FloatType
>::calculateMaxRelativeError (const std::function
<FloatType (FloatType
)>& functionToApproximate
,
101 FloatType minInputValue
,
102 FloatType maxInputValue
,
104 size_t numTestPoints
)
106 jassert (maxInputValue
> minInputValue
);
108 if (numTestPoints
== 0)
109 numTestPoints
= 100 * numPoints
; // use default
111 LookupTableTransform
transform (functionToApproximate
, minInputValue
, maxInputValue
, numPoints
);
115 for (size_t i
= 0; i
< numTestPoints
; ++i
)
117 auto inputValue
= jmap (FloatType (i
), FloatType (0), FloatType (numTestPoints
- 1), minInputValue
, maxInputValue
);
118 auto approximatedOutputValue
= transform
.processSample (inputValue
);
119 auto referenceOutputValue
= functionToApproximate (inputValue
);
121 maxError
= jmax (maxError
, calculateRelativeDifference ((double) referenceOutputValue
, (double) approximatedOutputValue
));
127 //==============================================================================
128 template <typename FloatType
>
129 double LookupTableTransform
<FloatType
>::calculateRelativeDifference (double x
, double y
) noexcept
131 static const auto eps
= std::numeric_limits
<double>::min();
133 auto absX
= std::abs (x
);
134 auto absY
= std::abs (y
);
135 auto absDiff
= std::abs (x
- y
);
140 return absDiff
/ absY
;
142 return absDiff
; // return the absolute error if both numbers are too close to zero
145 return absDiff
/ std::min (absX
, absY
);
148 //==============================================================================
149 template class LookupTable
<float>;
150 template class LookupTable
<double>;
152 template class LookupTableTransform
<float>;
153 template class LookupTableTransform
<double>;