@@ -19,15 +19,16 @@ truncfilter
1919truncerror
2020```
2121
22- ## Combining Strategies
23-
2422Truncation strategies can be combined using the ` & ` operator to create intersection-based truncation.
2523When strategies are combined, only the values that satisfy all conditions are kept.
2624
27- For example, to keep at most 10 eigenvalues while also discarding all values below ` 1e-6 ` :
25+ ``` jldoctest
26+ julia> using MatrixAlgebraKit
27+
28+ julia> combined_trunc = truncrank(10) & trunctol(; atol = 1e-6);
2829
29- ``` julia
30- combined_trunc = truncrank( 10 ) & trunctol(; atol = 1e-6 )
30+ julia> typeof(combined_trunc)
31+ MatrixAlgebraKit.TruncationIntersection{Tuple{MatrixAlgebraKit.TruncationByOrder{typeof(abs)}, MatrixAlgebraKit.TruncationByValue{Float64, Int64, typeof(abs)}}}
3132```
3233
3334## Using Truncations in Decompositions
@@ -38,81 +39,121 @@ Truncation strategies can be used with truncated decomposition functions in two
3839
3940The simplest approach is to pass a ` NamedTuple ` with the truncation parameters:
4041
41- ``` julia
42- using MatrixAlgebraKit
42+ ``` jldoctest truncations
43+ julia> using MatrixAlgebraKit
4344
44- # Create a symmetric matrix
45- A = randn(100 , 100 )
46- A = A + A' # Make symmetric
45+ julia> # Create a symmetric matrix with known values
46+ A = [4.0 2.0 1.0; 2.0 5.0 3.0; 1.0 3.0 6.0];
4747
48- # Keep only the 10 largest eigenvalues
49- D, V = eigh_trunc(A; trunc = (maxrank = 10 ,))
48+ julia> # Keep only the 2 largest eigenvalues
49+ D, V = eigh_trunc(A; trunc = (maxrank = 2 ,));
5050
51- # Keep eigenvalues with absolute value above tolerance
52- D, V = eigh_trunc(A; trunc = (atol = 1e-6,) )
51+ julia> size(D)
52+ (2, 2 )
5353
54- # Combine multiple criteria
55- D, V = eigh_trunc(A; trunc = (maxrank = 20, atol = 1e-10, rtol = 1e-8))
54+ julia> size(V)
55+ (3, 2)
56+ ```
57+
58+ You can also use tolerance-based truncation or combine multiple criteria:
59+
60+ ``` jldoctest truncations
61+ julia> # Keep eigenvalues with absolute value above tolerance
62+ D, V = eigh_trunc(A; trunc = (atol = 1e-6,));
63+
64+ julia> size(D, 1) # All eigenvalues are above 1e-6
65+ 3
66+
67+ julia> # Combine multiple criteria
68+ D, V = eigh_trunc(A; trunc = (maxrank = 2, atol = 1e-10));
69+
70+ julia> size(D)
71+ (2, 2)
5672```
5773
5874### 2. Using explicit ` TruncationStrategy ` objects
5975
6076For more control, you can construct ` TruncationStrategy ` objects directly:
6177
62- ```julia
63- # Keep the 5 largest eigenvalues
64- strategy = truncrank(5)
65- D, V = eigh_trunc(A; trunc = strategy)
78+ ``` jldoctest truncations
79+ julia> # Keep the 2 largest eigenvalues
80+ strategy = truncrank(2);
81+
82+ julia> D, V = eigh_trunc(A; trunc = strategy);
6683
67- # Keep eigenvalues above an absolute tolerance
68- strategy = trunctol(; atol = 1e-6)
69- D, V = eigh_trunc(A; trunc = strategy)
84+ julia> size(D)
85+ (2, 2)
7086
71- # Combine strategies: keep at most 10 eigenvalues, all above 1e-8
72- strategy = truncrank(10) & trunctol(; atol = 1e-8)
73- D, V = eigh_trunc(A; trunc = strategy)
87+ julia> # Combine strategies: keep at most 2 eigenvalues, all above 1e-8
88+ strategy = truncrank(2) & trunctol(; atol = 1e-8);
89+
90+ julia> D, V = eigh_trunc(A; trunc = strategy);
91+
92+ julia> size(D)
93+ (2, 2)
7494```
7595
7696## Complete Example
7797
7898Here's a complete example demonstrating different truncation approaches:
7999
80- ``` julia
81- using MatrixAlgebraKit
82- using LinearAlgebra
83-
84- # Generate a test matrix with known spectrum
85- n = 50
86- A = randn(n, n)
87- A = A + A' # Make symmetric
88-
89- # 1. No truncation - keep all eigenvalues
90- D_full, V_full = eigh_trunc(A; trunc = nothing)
91- @assert size(D_full) == (n, n)
92-
93- # 2. Keep only the 10 largest eigenvalues
94- D_rank, V_rank = eigh_trunc(A; trunc = (maxrank = 10,))
95- @assert size(D_rank) == (10, 10)
96- @assert size(V_rank) == (n, 10)
97-
98- # 3. Keep eigenvalues with absolute value above a threshold
99- D_tol, V_tol = eigh_trunc(A; trunc = (atol = 1e-6,))
100- println("Kept $(size(D_tol, 1 )) eigenvalues above tolerance")
101-
102- # 4. Combine rank and tolerance truncation
103- strategy = truncrank(15) & trunctol(; atol = 1e-8)
104- D_combined, V_combined = eigh_trunc(A; trunc = strategy)
105- println("Kept $(size(D_combined, 1 )) eigenvalues (max 15, all above 1e-8)")
106-
107- # 5. Truncated SVD example
108- B = randn(100, 80)
109- U, S, Vh = svd_trunc(B; trunc = (maxrank = 20,))
110- @assert size(S) == (20, 20)
111- @assert size(U) == (100, 20)
112- @assert size(Vh) == (20, 80)
113-
114- # Verify the truncated decomposition is accurate
115- @assert norm(B - U * S * Vh) ≈ norm(svd(B).S[21:end])
100+ ``` jldoctest complete_example
101+ julia> using MatrixAlgebraKit, LinearAlgebra
102+
103+ julia> # Create a symmetric test matrix with known spectrum
104+ A = [10.0 2.0 1.0 0.5;
105+ 2.0 8.0 1.5 0.3;
106+ 1.0 1.5 6.0 0.2;
107+ 0.5 0.3 0.2 4.0];
108+
109+ julia> # 1. No truncation - keep all eigenvalues
110+ D_full, V_full = eigh_trunc(A; trunc = nothing);
111+
112+ julia> size(D_full)
113+ (4, 4)
114+
115+ julia> # 2. Keep only the 2 largest eigenvalues
116+ D_rank, V_rank = eigh_trunc(A; trunc = (maxrank = 2,));
117+
118+ julia> size(D_rank)
119+ (2, 2)
120+
121+ julia> size(V_rank)
122+ (4, 2)
123+
124+ julia> # 3. Keep eigenvalues with absolute value above a threshold
125+ D_tol, V_tol = eigh_trunc(A; trunc = (atol = 5.0,));
126+
127+ julia> size(D_tol, 1) >= 2 # At least 2 eigenvalues are above 5.0
128+ true
129+
130+ julia> # 4. Combine rank and tolerance truncation
131+ strategy = truncrank(3) & trunctol(; atol = 1e-8);
132+
133+ julia> D_combined, V_combined = eigh_trunc(A; trunc = strategy);
134+
135+ julia> size(D_combined, 1) <= 3
136+ true
137+
138+ julia> # 5. Truncated SVD example
139+ B = [3.0 2.0 1.0; 1.0 4.0 2.0; 2.0 1.0 5.0; 0.5 1.0 2.0];
140+
141+ julia> U, S, Vh = svd_trunc(B; trunc = (maxrank = 2,));
142+
143+ julia> size(S)
144+ (2, 2)
145+
146+ julia> size(U)
147+ (4, 2)
148+
149+ julia> size(Vh)
150+ (2, 3)
151+
152+ julia> # Verify the truncated decomposition approximates the original
153+ reconstruction_error = norm(B - U * S * Vh);
154+
155+ julia> reconstruction_error < 2.1 # Error is small (equals smallest discarded singular value)
156+ true
116157```
117158
118159## Truncation with SVD vs Eigenvalue Decompositions
@@ -129,12 +170,24 @@ When using truncations with different decomposition types, keep in mind:
129170
130171For specialized needs, you can use [ ` truncfilter ` ] ( @ref ) to define custom selection criteria:
131172
132- ``` julia
133- # Keep only positive eigenvalues
134- strategy = truncfilter(x -> x > 0)
135- D_positive, V_positive = eigh_trunc(A; trunc = strategy)
173+ ``` jldoctest custom_filters
174+ julia> using MatrixAlgebraKit
175+
176+ julia> A = [4.0 -1.0 2.0; -1.0 3.0 1.0; 2.0 1.0 -2.0];
177+
178+ julia> # Keep only positive eigenvalues
179+ strategy = truncfilter(x -> x > 0);
180+
181+ julia> D_positive, V_positive = eigh_trunc(A; trunc = strategy);
182+
183+ julia> size(D_positive, 1) >= 2 # At least 2 positive eigenvalues
184+ true
185+
186+ julia> # Keep eigenvalues in a specific range
187+ strategy = truncfilter(x -> 1.0 < abs(x) < 5.0);
188+
189+ julia> D_range, V_range = eigh_trunc(A; trunc = strategy);
136190
137- # Keep eigenvalues in a specific range
138- strategy = truncfilter(x -> 0.1 < abs(x) < 10.0)
139- D_range, V_range = eigh_trunc(A; trunc = strategy)
191+ julia> size(D_range, 1) >= 1 # At least 1 eigenvalue in range
192+ true
140193```
0 commit comments