lobpcg::TruncatedSvd maps non-converged LOBPCG results to Ok, hiding convergence failure
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
Hướng nghiên cứu
Start in src/lobpcg/svd.rs at TruncatedSvd::decompose and inspect LobpcgResult handling around lines 162-172, then review the result type and the maxiter setup around line 105. Check src/generate.rs and issue #336 for the separate RNG concern. Done means non-convergence is no longer silently reported as success, with the chosen result API covered by appropriate tests.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
lobpcg::TruncatedSvd::decompose maps a non-converged LOBPCG result onto Ok(..), so callers cannot distinguish a converged decomposition from a failed one and may silently receive wrong singular values.
Version inspected: ndarray-linalg 0.17.0 (source from crates.io).
Where
match res {
LobpcgResult::Ok(vals, vecs, _) | LobpcgResult::Err(vals, vecs, _, _) => {
Ok(TruncatedSvdResult {
problem: self.problem,
eigvals: vals,
eigvecs: vecs,
ngm: n > m,
})
}
LobpcgResult::NoResult(err) => Err(err),
}
LobpcgResult::Err(..) carries the error as its fourth field and it is dropped on the floor. Returning the partial result is reasonable; giving the caller no way to learn that it is partial is the problem.
Contributing factor: maxiter defaults to problem.len_of(Axis(0)) * 2 (svd.rs:105), which is a small iteration budget for small inputs — exactly where I measured the worst errors in the sibling implementation.
Evidence
I want to be straightforward about what I did and did not run.
Verified by source inspection in ndarray-linalg 0.17.0: the LobpcgResult::Err(..) => Ok(..) mapping above, and the maxiter default.
Not executed against ndarray-linalg: I do not have a LAPACK backend configured locally, so I could not run a reproduction through this crate.
Measured in linfa-linalg 0.2.1, whose lobpcg::TruncatedSvd is the same algorithm with the same structure (Err((_, Some(Lobpcg{..}))) => Ok(..), same 2 * n_samples default, same epsilon * correction * λ_max cutoff). Taking X = U diag(4, 3, 2, 1) Vᵀ with U (8×4) and V (4×4) built from Sylvester–Hadamard columns, so the singular values are exactly [4, 3, 2, 1] by construction:
k=1 returned Ok sigma=[4.0] max rel err=2.220e-16
k=2 returned Ok sigma=[4.0, 3.0] max rel err=4.441e-16
k=3 returned Ok sigma=[3.94368, 2.67522, 1.477172] max rel err=2.614e-1 <== WRONG
k=4 returned Ok sigma=[4.0, 3.0, 2.0, 1.0] max rel err=2.517e-15
A 26% error reported as success, with neighbouring block sizes exact to machine precision. I would expect the same behaviour here given the shared structure, but I have not confirmed the exact numbers under LAPACK — if that distinction matters to you, treat the code-level finding as the claim and the numbers as indicative.
Filed in parallel as rust-ml/linfa-linalg#20.
Secondary: the result is not reproducible
decompose initialises its starting block with generate::random(..) (svd.rs:132), and generate::random uses thread_rng() (src/generate.rs:36). There is no new_with_rng equivalent, so successive runs of the same program on the same input can land on different subspaces and different component signs. Combined with the silent non-convergence above, that makes the failure intermittent as well as quiet. This overlaps with #336.
Suggested remedies
- Surface convergence to the caller — e.g. a
converged: boolor the residual norms onTruncatedSvdResult— rather than discarding the error. - Or return
Errby default, with the partial result available through an explicit opt-in. - Consider a seedable entry point (
new_with_rng) so results are reproducible;linfa-linalghas one.
Glad to put up a PR if you have a preference on direction.
- Ngôn ngữ chính
- Rust
- Star
- 452
- Fork
- 95
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rust-ndarray/ndarray-linalg
-
Thin SVDĐang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 38/100
rust-ndarray/ndarray-linalg#414 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
rust-ndarray/ndarray-linalg#413 · 1 bình luận ·
-
Cyclically Tridiagonal Matrices?Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
rust-ndarray/ndarray-linalg#404 ·
-
SIGSEGV on qr decompositionĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
rust-ndarray/ndarray-linalg#402 · 1 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
rust-ndarray/ndarray-linalg#401 · 2 reaction ·
Tất cả issue của rust-ndarray/ndarray-linalg
Issue tương tự
-
Signals (Failure Detector): a tool call and its own execution are reported as a repeated callĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
check: a failed re-read of the model file before binding is labelled E_THETA_LEVEL_BINDING on [parameters]Có thể đã có người làm @TeunP đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 80/100
Devolutions/picky-rs#546 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày