1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#ifndef __UTIL_MATH_CDF_H__
#define __UTIL_MATH_CDF_H__
#include "util/algorithm.h"
#include "util/math.h"
#include "util/vector.h"
CCL_NAMESPACE_BEGIN
/* Evaluate CDF of a given functor with given range and resolution. */
template<typename Functor>
void util_cdf_evaluate(
const int resolution, const float from, const float to, Functor functor, vector<float> &cdf)
{
const int cdf_count = resolution + 1;
const float range = to - from;
cdf.resize(cdf_count);
cdf[0] = 0.0f;
/* Actual CDF evaluation. */
for (int i = 0; i < resolution; ++i) {
float x = from + range * (float)i / (resolution - 1);
float y = functor(x);
cdf[i + 1] = cdf[i] + fabsf(y);
}
/* Normalize the CDF. */
for (int i = 0; i <= resolution; i++) {
cdf[i] /= cdf[resolution];
}
}
/* Invert pre-calculated CDF function. */
void util_cdf_invert(const int resolution,
const float from,
const float to,
const vector<float> &cdf,
const bool make_symmetric,
vector<float> &inv_cdf);
/* Evaluate inverted CDF of a given functor with given range and resolution. */
template<typename Functor>
void util_cdf_inverted(const int resolution,
const float from,
const float to,
Functor functor,
const bool make_symmetric,
vector<float> &inv_cdf)
{
vector<float> cdf;
/* There is no much smartness going around lower resolution for the CDF table,
* this just to match the old code from pixel filter so it all stays exactly
* the same and no regression tests are failed.
*/
util_cdf_evaluate(resolution - 1, from, to, functor, cdf);
util_cdf_invert(resolution, from, to, cdf, make_symmetric, inv_cdf);
}
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H_CDF__ */
|