20 #if !defined(__MITSUBA_CORE_SHVECTOR_H_)
21 #define __MITSUBA_CORE_SHVECTOR_H_
23 #include <mitsuba/mitsuba.h>
30 #define SH_NORMTBL_SIZE 10
42 typedef Eigen::Matrix<Float, Eigen::Dynamic, Eigen::Dynamic>
Matrix;
48 for (
int i=0; i<bands; ++i) {
50 blocks[i] =
Matrix(dim, dim);
93 : m_bands(bands), m_coeffs(bands*bands) {
102 m_coeffs(v.m_coeffs) {
111 void serialize(
Stream *stream)
const;
116 for (
int m=-band; m<=band; ++m)
117 result += std::abs(
operator()(band,m));
124 m_coeffs = v.m_coeffs;
135 ptrdiff_t extendBy = v.m_coeffs.size() - m_coeffs.size();
137 m_coeffs.conservativeResize(v.m_coeffs.rows());
138 m_coeffs.tail(extendBy).setZero();
141 m_coeffs.head(m_coeffs.size()) += v.m_coeffs.head(m_coeffs.size());
147 SHVector vec(std::max(m_bands, v.m_bands));
148 if (m_bands > v.m_bands) {
149 vec.m_coeffs = m_coeffs;
150 vec.m_coeffs.head(v.m_coeffs.size()) += v.m_coeffs;
152 vec.m_coeffs = v.m_coeffs;
153 vec.m_coeffs.head(m_coeffs.size()) += m_coeffs;
160 ptrdiff_t extendBy = v.m_coeffs.size() - m_coeffs.size();
162 m_coeffs.conservativeResize(v.m_coeffs.rows());
163 m_coeffs.tail(extendBy).setZero();
166 m_coeffs.head(m_coeffs.size()) -= v.m_coeffs.head(m_coeffs.size());
172 SHVector vec(std::max(m_bands, v.m_bands));
173 if (m_bands > v.m_bands) {
174 vec.m_coeffs = m_coeffs;
175 vec.m_coeffs.head(v.m_coeffs.size()) -= v.m_coeffs;
177 vec.m_coeffs = -v.m_coeffs;
178 vec.m_coeffs.head(m_coeffs.size()) += m_coeffs;
185 ptrdiff_t extendBy = v.m_coeffs.size() - m_coeffs.size();
187 m_coeffs.conservativeResize(v.m_coeffs.rows());
188 m_coeffs.tail(extendBy).setZero();
191 m_coeffs.head(m_coeffs.size()) += v.m_coeffs.head(m_coeffs.size()) * f;
205 vec.m_coeffs = m_coeffs * f;
211 m_coeffs *= (
Float) 1 / f;
218 vec.m_coeffs = m_coeffs * (1/f);
225 vec.m_coeffs = -m_coeffs;
231 return m_coeffs[l*(l+1) + m];
236 return m_coeffs[l*(l+1) + m];
259 Float evalAzimuthallyInvariant(
const Vector &v)
const;
262 bool isAzimuthallyInvariant()
const;
266 return m_bands == v.m_bands && m_coeffs == v.m_coeffs;
271 return !operator==(v);
284 Float findMinimum(
int res)
const;
287 void addOffset(
Float value);
295 void convolve(
const SHVector &kernel);
298 template<
typename Functor>
void project(
const Functor &f,
int res = 32) {
302 hInt = (2*
M_PI)/(res*2);
304 for (
int l=0; l<m_bands; ++l)
305 for (
int m=-l; m<=l; ++m)
309 *cosPhi = (
Float *) alloca(
sizeof(
Float)*m_bands);
311 for (
int i=0; i<=res; ++i) {
312 Float theta = hExt*i, cosTheta = std::cos(theta);
313 Float weightExt = (i & 1) ? 4.0f : 2.0f;
314 if (i == 0 || i == res)
317 for (
int j=0; j<=res*2; ++j) {
319 Float weightInt = (j & 1) ? 4.0f : 2.0f;
320 if (j == 0 || j == 2*res)
323 for (
int m=0; m<m_bands; ++m) {
324 sinPhi[m] = std::sin((m+1)*phi);
325 cosPhi[m] = std::cos((m+1)*phi);
329 * weightExt*weightInt;
331 for (
int l=0; l<m_bands; ++l) {
332 for (
int m=1; m<=l; ++m) {
334 operator()(l, -m) += value *
SQRT_TWO * sinPhi[m-1] * L;
335 operator()(l, m) += value *
SQRT_TWO * cosPhi[m-1] * L;
338 operator()(l, 0) += value *
legendreP(l, 0, cosTheta) * normalization(l, 0);
343 for (
int l=0; l<m_bands; ++l)
344 for (
int m=-l; m<=l; ++m)
345 operator()(l,m) *= hExt*hInt/9;
349 template<
typename Functor>
Float l2Error(
const Functor &f,
int res = 32)
const {
353 hInt = (2*
M_PI)/(res*2);
354 Float error = 0.0f, denom=0.0f;
356 for (
int i=0; i<=res; ++i) {
357 Float theta = hExt*i;
358 Float weightExt = (i & 1) ? 4.0f : 2.0f;
359 if (i == 0 || i == res)
362 for (
int j=0; j<=res*2; ++j) {
364 Float weightInt = (j & 1) ? 4.0f : 2.0f;
365 if (j == 0 || j == 2*res)
369 Float value2 = eval(theta, phi);
370 Float diff = value1-value2;
371 Float weight = std::sin(theta)*weightInt*weightExt;
373 error += diff*diff*weight;
374 denom += value1*value1*weight;
382 std::string toString()
const;
387 return m_normalization[l*(l+1)/2 + m];
389 return computeNormalization(l, m);
402 static void staticInitialization();
405 static void staticShutdown();
411 static Float computeNormalization(
int l,
int m);
414 Eigen::Matrix<Float, Eigen::Dynamic, 1> m_coeffs;
415 static Float *m_normalization;
419 const size_t size = std::min(v1.m_coeffs.size(), v2.m_coeffs.size());
420 return v1.m_coeffs.head(size).dot(v2.m_coeffs.head(size));
460 inline
int I(
int l,
int m)
const {
return l*(l+1)/2 + m; }
463 inline int P(
int m)
const {
return m + m_bands; }
466 return -m_phiMap[depth][phiBlock][P(m)] * m_legendreMap[depth][zBlock][I(l, std::abs(m))];
474 Float integrate(
int depth,
int zBlock,
int phiBlock,
const SHVector &f)
const;
Implementation of 'Importance Sampling Spherical Harmonics' by W. Jarsz, N. Carr and H...
Definition: shvector.h:430
SHVector & operator*=(Float f)
Scalar multiplication.
Definition: shvector.h:197
int m_depth
Definition: shvector.h:477
SHRotation(int bands)
Construct a new rotation storage for the given number of bands.
Definition: shvector.h:47
int getBands() const
Return the number of stored SH coefficient bands.
Definition: shvector.h:106
SHVector & madd(Float f, const SHVector &v)
Add a scalar multiple of another vector.
Definition: shvector.h:184
Float *** m_legendreMap
Definition: shvector.h:479
int P(int m) const
Definition: shvector.h:463
Float lookupIntegral(int depth, int zBlock, int phiBlock, int l, int m) const
Definition: shvector.h:465
#define SQRT_TWO
Definition: constants.h:94
Stores the diagonal blocks of a spherical harmonic rotation matrix.
Definition: shvector.h:41
Float *** m_phiMap
Definition: shvector.h:478
SHVector(const SHVector &v)
Copy constructor.
Definition: shvector.h:101
int m_bands
Definition: shvector.h:476
Eigen::Matrix< Float, Eigen::Dynamic, Eigen::Dynamic > Matrix
Definition: shvector.h:42
Float * m_normalization
Definition: shvector.h:481
#define MTS_EXPORT_CORE
Definition: getopt.h:29
int m_dataSize
Definition: shvector.h:480
SHVector & operator+=(const SHVector &v)
Component-wise addition.
Definition: shvector.h:134
Normal normalize(const Normal &n)
Definition: normal.h:73
#define M_PI
Definition: constants.h:90
float legendreP(int l, float x)
Evaluate the l-th Legendre polynomial using recurrence (single precision)
SHVector operator-() const
Negation operator.
Definition: shvector.h:223
SHVector()
Construct an invalid SH vector.
Definition: shvector.h:87
bool operator==(const SHVector &v) const
Equality comparison operator.
Definition: shvector.h:265
SHVector & operator-=(const SHVector &v)
Component-wise subtraction.
Definition: shvector.h:159
SHVector & operator/=(Float f)
Scalar division.
Definition: shvector.h:210
SHVector(int bands)
Construct a new SH vector (initialized to zero)
Definition: shvector.h:92
Float energy(int band) const
Get the energy per band.
Definition: shvector.h:114
SHVector & operator=(const SHVector &v)
Assignment.
Definition: shvector.h:122
Float & operator()(int l, int m)
Access coefficient m (in {-l, ..., l}) on band l.
Definition: shvector.h:230
#define SAssert(cond)
``Static'' assertion (to be used outside of classes that derive from Object)
Definition: logger.h:79
Abstract seekable stream class.
Definition: stream.h:58
#define MTS_DECLARE_CLASS()
This macro must be used in the initial definition in classes that derive from Object.
Definition: class.h:158
bool operator!=(const SHVector &v) const
Equality comparison operator.
Definition: shvector.h:270
void clear()
Set all coefficients to zero.
Definition: shvector.h:129
Float l2Error(const Functor &f, int res=32) const
Compute the relative L2 error.
Definition: shvector.h:349
MTS_EXPORT_CORE Vector sphericalDirection(Float theta, Float phi)
Convert spherical coordinates to a direction.
SHVector operator+(const SHVector &v) const
Component-wise addition.
Definition: shvector.h:146
SHVector operator*(Float f) const
Scalar multiplication.
Definition: shvector.h:203
SHVector operator-(const SHVector &v) const
Component-wise subtraction.
Definition: shvector.h:171
static Float normalization(int l, int m)
Return a normalization coefficient.
Definition: shvector.h:385
Float dot(const SHVector &v1, const SHVector &v2)
Definition: shvector.h:418
const Float & operator()(int l, int m) const
Access coefficient m (in {-l, ..., l}) on band l.
Definition: shvector.h:235
Parent of all Mitsuba classes.
Definition: object.h:38
virtual std::string toString() const
Return a human-readable string representation of the object's contents.
void project(const Functor &f, int res=32)
Project the given function onto a SH basis (using a 2D composite Simpson's rule)
Definition: shvector.h:298
SHVector operator/(Float f) const
Scalar division.
Definition: shvector.h:216
Basic 3x3 matrix data type.
Definition: matrix.h:560
Stores a truncated real spherical harmonics representation of an L2-integrable function.
Definition: shvector.h:84
std::vector< Matrix > blocks
Definition: shvector.h:44
#define SH_NORMTBL_SIZE
Definition: shvector.h:30