MCPcopy Create free account
hub / github.com/bgrimstad/splinter / getSecondOrderFiniteDifferenceMatrix

Method getSecondOrderFiniteDifferenceMatrix

src/bsplinebuilder.cpp:216–312  ·  view source on GitHub ↗

* Function for generating second order finite-difference matrix, which is used for penalizing the * (approximate) second derivative in control point calculation for P-splines. */

Source from the content-addressed store, hash-verified

214* (approximate) second derivative in control point calculation for P-splines.
215*/
216SparseMatrix BSpline::Builder::getSecondOrderFiniteDifferenceMatrix(const BSpline &bspline) const
217{
218 unsigned int numVariables = bspline.getNumVariables();
219
220 // Number of (total) basis functions - defines the number of columns in D
221 unsigned int numCols = bspline.getNumBasisFunctions();
222 std::vector<unsigned int> numBasisFunctions = bspline.getNumBasisFunctionsPerVariable();
223
224 // Number of basis functions (and coefficients) in each variable
225 std::vector<unsigned int> dims;
226 for (unsigned int i = 0; i < numVariables; i++)
227 dims.push_back(numBasisFunctions.at(i));
228
229 std::reverse(dims.begin(), dims.end());
230
231 for (unsigned int i=0; i < numVariables; ++i)
232 if (numBasisFunctions.at(i) < 3)
233 throw Exception("BSpline::Builder::getSecondOrderDifferenceMatrix: Need at least three coefficients/basis function per variable.");
234
235 // Number of rows in D and in each block
236 int numRows = 0;
237 std::vector< int > numBlkRows;
238 for (unsigned int i = 0; i < numVariables; i++)
239 {
240 int prod = 1;
241 for (unsigned int j = 0; j < numVariables; j++)
242 {
243 if (i == j)
244 prod *= (dims[j] - 2);
245 else
246 prod *= dims[j];
247 }
248 numRows += prod;
249 numBlkRows.push_back(prod);
250 }
251
252 // Resize and initialize D
253 SparseMatrix D(numRows, numCols);
254 D.reserve(DenseVector::Constant(numCols,2*numVariables)); // D has no more than two elems per col per dim
255
256 int i = 0; // Row index
257 // Loop though each dimension (each dimension has its own block)
258 for (unsigned int d = 0; d < numVariables; d++)
259 {
260 // Calculate left and right products
261 int leftProd = 1;
262 int rightProd = 1;
263 for (unsigned int k = 0; k < d; k++)
264 {
265 leftProd *= dims[k];
266 }
267 for (unsigned int k = d+1; k < numVariables; k++)
268 {
269 rightProd *= dims[k];
270 }
271
272 // Loop through subblocks on the block diagonal
273 for (int j = 0; j < rightProd; j++)

Callers

nothing calls this directly

Calls 3

ExceptionClass · 0.85
getNumBasisFunctionsMethod · 0.45

Tested by

no test coverage detected