diff --git a/src/utils/uflakefit.cpp b/src/utils/uflakefit.cpp
new file mode 100644
index 00000000..c650d349
--- /dev/null
+++ b/src/utils/uflakefit.cpp
@@ -0,0 +1,199 @@
+/*
+ This file is part of Mitsuba, a physically based rendering system.
+
+ Copyright (c) 2007-2010 by Wenzel Jakob and others.
+
+ Mitsuba is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License Version 3
+ as published by the Free Software Foundation.
+
+ Mitsuba is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "/Users/wenzel/mitsuba/lookup.h"
+
+MTS_NAMESPACE_BEGIN
+
+class UFlakeFit : public Utility {
+public:
+ struct Reference {
+ Reference(size_t res, size_t nSines) : m_res(res), m_sines(nSines) {
+ m_directions = new Vector[m_res];
+ m_result = new Float[m_res];
+ m_error = new Float[m_res];
+ for (size_t i=0; i timer = new Timer();
+ Float base = refAvgAbsErr;
+ do {
+ min[0] = M_PI/2 * (1.0 - std::pow((Float) 2, - (Float) attempt)),
+ max[0] = M_PI/2 * (1.0 + std::pow((Float) 2, - (Float) attempt));
+ NDIntegrator quad(m_res, 2, 200000, 0, 1e-8f);
+ quad.integrateVectorized(boost::bind(
+ &Reference::f, this, _1, _2, _3), min, max, m_result, m_error, evals);
+ Float maxError = 0;
+ for (size_t i=0; igetMilliseconds());
+ ++attempt;
+ } while (evals < 20000);
+
+ Eigen::MatrixXd A(m_res, m_sines);
+ Eigen::VectorXd b(m_res);
+ for (size_t i=0; i