Skip to content
Snippets Groups Projects
Verified Commit c785a81d authored by Sébastien Villemot's avatar Sébastien Villemot
Browse files

k-order MEX: fix crash on Octave when higher-order derivatives have numerical zero

In Octave, when some values given to the sparse() function are numerically
zero, then the nzmax of the generated sparse matrix is shrinked accordingly;
while under MATLAB, the nzmax is the length of the vector of values, zeros
included.

The check at the top of
DynamicModelMFile::unpackSparseMatrixAndCopyIntoTwoDMatData() would then fail
under Octave if some higher-derivatives had an element which is symbolically
non-zero but numerically zero.

We therefore relax the check, and accordingly adapt the code that handles
numerical zeros.

This bug was uncovered by tests/pruning/AnSchorfheide_pruned_state_space.mod,
which was failing under Octave.

(cherry picked from commit 144bdf34)
parent baf44191
Branches
Tags
1 merge request!1815WIP Cherry-picks for 4.6
/*
* Copyright © 2010-2019 Dynare Team
* Copyright © 2010-2020 Dynare Team
*
* This file is part of Dynare.
*
......@@ -35,11 +35,13 @@ DynamicModelMFile::unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray *sparseMat,
{
int totalCols = mxGetN(sparseMat);
mwIndex *rowIdxVector = mxGetIr(sparseMat);
mwSize sizeRowIdxVector = mxGetNzmax(sparseMat);
mwIndex *colIdxVector = mxGetJc(sparseMat);
assert(tdm.ncols() == 3);
assert(tdm.nrows() == sizeRowIdxVector);
/* Under MATLAB, the following check always holds at equality; under Octave,
there may be an inequality, because Octave diminishes nzmax if one gives
zeros in the values vector when calling sparse(). */
assert(tdm.nrows() >= mxGetNzmax(sparseMat));
double *ptr = mxGetPr(sparseMat);
......@@ -55,11 +57,11 @@ DynamicModelMFile::unpackSparseMatrixAndCopyIntoTwoDMatData(mxArray *sparseMat,
output_row++;
}
/* If there are less elements than Nzmax (that might happen if some
/* If there are less elements than expected (that might happen if some
derivative is symbolically not zero but numerically zero at the evaluation
point), then fill in the matrix with empty entries, that will be
recognized as such by KordpDynare::populateDerivativesContainer() */
while (output_row < static_cast<int>(sizeRowIdxVector))
while (output_row < tdm.nrows())
{
tdm.get(output_row, 0) = 0;
tdm.get(output_row, 1) = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment