Audit finding
- ID:
AUD-004
- Status: Verified defect
- Severity: High
- Confidence: High
- Audited revision:
2f479320d805a1f9f35ebe4afaaeeded48913a94
Problem
SingularValueDecomposition::Decompose() invokes a bounded, void diagonalization and always returns true, even when all iterations expire.
Source:
|
OPTIMIZE_FOR_SPEED bool SingularValueDecomposition<T, Rows, Cols>::Decompose( |
|
const math::Matrix<T, Rows, Cols>& a) |
|
{ |
|
math::Matrix<T, Rows, Cols> bidiag = a; |
|
|
|
LeftVectors leftVecs{}; |
|
RightVectors rightVecs{}; |
|
Betas leftBeta{}; |
|
Betas rightBeta{}; |
|
|
|
Bidiagonalize(bidiag, leftVecs, leftBeta, rightVecs, rightBeta); |
|
ExtractBidiagonal(bidiag); |
|
AccumulateU(leftVecs, leftBeta); |
|
AccumulateV(rightVecs, rightBeta); |
|
DiagonalizeGolubKahan(); |
|
MakeSingularValuesPositive(); |
|
SortDescending(); |
|
|
|
return true; |
|
} |
|
|
|
template<typename T, std::size_t Rows, std::size_t Cols> |
|
bool SingularValueDecomposition<T, Rows, Cols>::NextBlock(std::size_t& p, std::size_t& q) |
|
{ |
|
for (std::size_t i = 0; i < Cols - 1; ++i) |
|
{ |
|
T thresh = T{ 1e-6f } * (math::Abs(sigma.at(i, 0)) + math::Abs(sigma.at(i + 1, 0))); |
|
if (math::Abs(superdiag.at(i, 0)) <= thresh) |
|
superdiag.at(i, 0) = T{}; |
|
} |
|
|
|
std::size_t right = Cols - 1; |
|
while (right > 0) |
|
{ |
|
T thresh = T{ 1e-6f } * (math::Abs(sigma.at(right - 1, 0)) + math::Abs(sigma.at(right, 0))); |
Reproduction
For a 3x3 matrix whose only nonzero entry is A(0,1)=1, the singular values must be (1,0,0). The implementation returns success with (0,0,0). The zero-diagonal/nonzero-superdiagonal block makes the QR sweep ineffective until the 270-iteration limit expires.
Acceptance criteria
Audit finding
AUD-0042f479320d805a1f9f35ebe4afaaeeded48913a94Problem
SingularValueDecomposition::Decompose()invokes a bounded,voiddiagonalization and always returnstrue, even when all iterations expire.Source:
numerical-toolbox-cpp/numerical/solvers/SingularValueDecomposition.hpp
Lines 147 to 181 in 2f47932
Reproduction
For a
3x3matrix whose only nonzero entry isA(0,1)=1, the singular values must be(1,0,0). The implementation returns success with(0,0,0). The zero-diagonal/nonzero-superdiagonal block makes the QR sweep ineffective until the 270-iteration limit expires.Acceptance criteria