1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Singular Value Decomposition (SVD).
//!
//! Computes the SVD: A = U·Σ·V^T where:
//! - U is m×m orthogonal (left singular vectors)
//! - Σ is m×n diagonal (singular values, non-negative, descending)
//! - V is n×n orthogonal (right singular vectors)
//!
//! This module provides:
//!
//! - **Svd**: One-sided Jacobi algorithm. Simple and robust for small matrices.
//! - **SvdDc**: Divide-and-conquer algorithm. More efficient for large matrices.
//! - **ComplexSvd**: One-sided Jacobi algorithm for complex matrices.
//! - **ComplexSvdDc**: Divide-and-conquer algorithm for complex matrices. Uses complex
//! bidiagonalization to reduce to real bidiagonal form, then applies real D&C SVD.
//! - **QrSvd**: QR-based algorithm (Golub-Kahan-Reinsch). Classical LAPACK approach.
//! - **TruncatedSvd**: Computes only the k largest singular values. Efficient for
//! low-rank approximations and dimensionality reduction.
//! - **RandomizedSvd**: Randomized algorithm for fast truncated SVD of large matrices.
//! - **SelectiveSvd**: Computes only selected singular values/vectors (by index or value range).
//! Equivalent to LAPACK's GESVDX.
//! - **Bidiagonal reduction**: `gebrd`, `ormbr`/`unmbr`, `orgbr`/`ungbr` for
//! working with bidiagonal transformations.
//! - **ParallelSvdDc** (feature = "parallel"): Multi-threaded divide-and-conquer SVD
//! using Rayon for parallel execution.
//!
//! # Example
//!
//! ```
//! use oxiblas_lapack::svd::{Svd, SvdDc, TruncatedSvd};
//! use oxiblas_matrix::Mat;
//!
//! let a = Mat::from_rows(&[
//! &[1.0f64, 2.0],
//! &[3.0, 4.0],
//! &[5.0, 6.0],
//! ]);
//!
//! // Jacobi method (simple, robust)
//! let svd = Svd::compute(a.as_ref()).unwrap();
//!
//! // Divide-and-conquer (faster for large matrices)
//! let svd_dc = SvdDc::compute(a.as_ref()).unwrap();
//!
//! // Both compute the same singular values
//! let sigma = svd.singular_values();
//! assert!(sigma[0] >= sigma[1]);
//!
//! // Truncated SVD (k largest singular values)
//! let tsvd = TruncatedSvd::compute(a.as_ref(), 1).unwrap();
//! assert_eq!(tsvd.singular_values().len(), 1);
//! ```
//!
//! # Bidiagonal Reduction
//!
//! ```
//! use oxiblas_lapack::svd::{gebrd, orgbr, ormbr, BidiagVect, Side, Trans};
//! use oxiblas_matrix::Mat;
//!
//! let a = Mat::from_rows(&[
//! &[1.0f64, 2.0, 3.0],
//! &[4.0, 5.0, 6.0],
//! &[7.0, 8.0, 9.0],
//! &[10.0, 11.0, 12.0],
//! ]);
//!
//! // Compute bidiagonal reduction: A = Q * B * P^T
//! let factors = gebrd(a.as_ref()).unwrap();
//!
//! // Generate Q explicitly
//! let q = orgbr(&factors, BidiagVect::Q).unwrap();
//!
//! // Or apply Q to a matrix without forming it
//! let c = Mat::from_rows(&[&[1.0], &[2.0], &[3.0], &[4.0]]);
//! let qc = ormbr(&factors, BidiagVect::Q, Side::Left, Trans::NoTrans, c.as_ref()).unwrap();
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;