forked from bartvdbraak/blender
Cycles: Add utility functions to evaluate CDF of a given functor
This commit is contained in:
parent
868717e312
commit
548ef2d88b
@ -12,6 +12,7 @@ set(SRC
|
||||
util_aligned_malloc.cpp
|
||||
util_cache.cpp
|
||||
util_logging.cpp
|
||||
util_math_cdf.cpp
|
||||
util_md5.cpp
|
||||
util_path.cpp
|
||||
util_string.cpp
|
||||
@ -49,6 +50,7 @@ set(SRC_HEADERS
|
||||
util_logging.h
|
||||
util_map.h
|
||||
util_math.h
|
||||
util_math_cdf.h
|
||||
util_math_fast.h
|
||||
util_md5.h
|
||||
util_opengl.h
|
||||
|
67
intern/cycles/util/util_math_cdf.cpp
Normal file
67
intern/cycles/util/util_math_cdf.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2011-2015 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "util_math_cdf.h"
|
||||
|
||||
#include "util_algorithm.h"
|
||||
#include "util_math.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* 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) {
|
||||
const float inv_resolution = 1.0f / (float)resolution;
|
||||
const float range = to - from;
|
||||
inv_cdf.resize(resolution);
|
||||
if(make_symmetric) {
|
||||
const int half_size = (resolution - 1) / 2;
|
||||
for(int i = 0; i <= half_size; i++) {
|
||||
float x = i / (float)half_size;
|
||||
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
|
||||
float t;
|
||||
if(index < cdf.size()) {
|
||||
t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
|
||||
} else {
|
||||
t = 0.0f;
|
||||
index = cdf.size() - 1;
|
||||
}
|
||||
float y = ((index + t) / (resolution - 1)) * (2.0f * range);
|
||||
inv_cdf[half_size+i] = 0.5f*(1.0f + y);
|
||||
inv_cdf[half_size-i] = 0.5f*(1.0f - y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i <= resolution; i++) {
|
||||
float x = from + range * (float)i * inv_resolution;
|
||||
int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin();
|
||||
float t;
|
||||
if(index < cdf.size()) {
|
||||
t = (x - cdf[index])/(cdf[index+1] - cdf[index]);
|
||||
} else {
|
||||
t = 0.0f;
|
||||
index = resolution;
|
||||
}
|
||||
inv_cdf[i] = (index + t) * inv_resolution;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
78
intern/cycles/util/util_math_cdf.h
Normal file
78
intern/cycles/util/util_math_cdf.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2011-2015 Blender Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#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,
|
||||
const 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,
|
||||
const 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__ */
|
Loading…
Reference in New Issue
Block a user