dlasd2/slasd2: Increase deflation tolerance to match dlasd7/slasd7#1286
Conversation
Fix DBDSDC/SBDSDC returning non-orthogonal U/V for bidiagonal matrices with many nearly-equal singular values (e.g., all singular values ≈ 1). The divide-and-conquer bidiagonal SVD has two code paths: - Full vector path (DLASD2/SLASD2): deflation tolerance = 8 * EPS - Compact path (DLASD7/SLASD7): deflation tolerance = 64 * EPS With the weaker tolerance (8*EPS), singular values differing by only ~10*EPS (e.g., ~2e-15 for double precision) escape deflation. The subsequent Z computation in DLASD3 then suffers catastrophic cancellation from denominators (σ_i - σ_j) that are tiny, polluting the singular vectors and causing loss of orthogonality. Raise DLASD2 and SLASD2 to 64*EPS, matching DLASD7 and SLASD7, so more close singular values are deflated and the singular-vector computation remains stable. Closes Reference-LAPACK#255
… #1286) Raise the deflation tolerance from 8*eps to 64*eps so near-equal singular values are deflated, preventing loss of orthogonality in the divide-and-conquer bidiagonal SVD. Port of Reference-LAPACK 0e0f2359 (Reference-LAPACK/lapack#1286).
… #1286) Raise the deflation tolerance from 8*eps to 64*eps so near-equal singular values are deflated, preventing loss of orthogonality in the divide-and-conquer bidiagonal SVD. Port of Reference-LAPACK 0e0f2359 (Reference-LAPACK/lapack#1286).
|
One of OpenBLAS' codspeed benchmarks in CI is flagging a large change in the result of an SGESDD call (via comparing the original to a reconstruction of the source matrix from its computed diagonal) with where our thresholds are 1e-5 for absolute and 1.e-7 for relative difference - note the relative difference hitting 1.e-2 - the CI job terminated there before trying DGESDD, but its results would probably be similarly "off". Is this magnitude of difference to previous LAPACK behaviour expected for the SVD of a "benign" 1000-by-222 matrix of random numbers ? Note the python code for the benchmark lives at https://github.com/OpenMathLib/OpenBLAS/blob/develop/benchmark/pybench/ |
|
I ran reference LAPACK SGESDD on a 1000x222 random matrix (uniform [0,1)) using both tolerance values ( 1. The tolerance change makes no difference for well-conditioned random matrices. 2. The 3. The 1.9% "relative difference" is from elements near zero. 4. The tolerance change fixes a real catastrophic bug (issue #255). The CodSpeed benchmark's |
|
Should a similar change be made in the eigenvalue D&C code? (Output edited for brevity.) |
|
good catch: #1317 |
Fix DBDSDC/SBDSDC returning non-orthogonal U/V for bidiagonal matrices with many nearly-equal singular values (e.g., all singular values ≈ 1).
The divide-and-conquer bidiagonal SVD has two code paths:
With the weaker tolerance (8EPS), singular values differing by only ~10EPS (e.g., ~2e-15 for double precision) escape deflation. The subsequent Z computation in DLASD3 then suffers catastrophic cancellation from denominators (σ_i - σ_j) that are tiny, polluting the singular vectors and causing loss of orthogonality.
Raise DLASD2 and SLASD2 to 64*EPS, matching DLASD7 and SLASD7, so more close singular values are deflated and the singular-vector computation remains stable.
Closes #255