Skip to content

Commit 1c4c360

Browse files
authored
Merge branch 'main' into testsuite
2 parents c110afc + 13a1771 commit 1c4c360

File tree

29 files changed

+1382
-225
lines changed

29 files changed

+1382
-225
lines changed

.github/workflows/Documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
arch:
2626
- x64
2727
steps:
28-
- uses: actions/checkout@v5
28+
- uses: actions/checkout@v6
2929
- uses: julia-actions/setup-julia@latest
3030
with:
3131
version: ${{ matrix.version }}

.github/workflows/DocumentationCleanup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
contents: write
1717
steps:
1818
- name: Checkout gh-pages branch
19-
uses: actions/checkout@v5
19+
uses: actions/checkout@v6
2020
with:
2121
ref: gh-pages
2222
- name: Delete preview and history + push changes

Project.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MatrixAlgebraKit"
22
uuid = "6c742aac-3347-4629-af66-fc926824e5e4"
33
authors = ["Jutho <[email protected]> and contributors"]
4-
version = "0.5.0"
4+
version = "0.6.0"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -12,13 +12,15 @@ ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
1212
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
1313
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
1414
GenericSchur = "c145ed77-6b09-5dd9-b285-bf645a82121e"
15+
Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6"
1516

1617
[extensions]
1718
MatrixAlgebraKitChainRulesCoreExt = "ChainRulesCore"
1819
MatrixAlgebraKitAMDGPUExt = "AMDGPU"
1920
MatrixAlgebraKitCUDAExt = "CUDA"
2021
MatrixAlgebraKitGenericLinearAlgebraExt = "GenericLinearAlgebra"
2122
MatrixAlgebraKitGenericSchurExt = "GenericSchur"
23+
MatrixAlgebraKitMooncakeExt = "Mooncake"
2224

2325
[compat]
2426
AMDGPU = "2"
@@ -31,6 +33,7 @@ GenericSchur = "0.5.6"
3133
JET = "0.9, 0.10"
3234
LinearAlgebra = "1"
3335
Random = "1"
36+
Mooncake = "0.4.174"
3437
SafeTestsets = "0.1"
3538
StableRNGs = "1"
3639
Test = "1"
@@ -45,11 +48,12 @@ ChainRulesTestUtils = "cdddcdb0-9152-4a09-a978-84456f9df70a"
4548
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
4649
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
4750
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
51+
Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6"
4852
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
4953
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
5054
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5155
TestExtras = "5ed8adda-3752-4e41-b88a-e8b09835ee3a"
5256
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
5357

5458
[targets]
55-
test = ["Aqua", "JET", "SafeTestsets", "Test", "TestExtras", "ChainRulesCore", "ChainRulesTestUtils", "StableRNGs", "Zygote", "CUDA", "AMDGPU", "GenericLinearAlgebra", "GenericSchur", "Random"]
59+
test = ["Aqua", "JET", "SafeTestsets", "Test", "TestExtras", "ChainRulesCore", "ChainRulesTestUtils", "StableRNGs", "Zygote", "CUDA", "AMDGPU", "GenericLinearAlgebra", "GenericSchur", "Random", "Mooncake"]

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ makedocs(;
5757
],
5858
"Developer Interface" => "dev_interface.md",
5959
"Library" => "library.md",
60+
"Changelog" => "changelog.md",
6061
],
6162
checkdocs = :exports,
6263
doctest = true,

docs/src/changelog.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## Guidelines for updating this changelog
9+
10+
When making changes to this project, please update the "Unreleased" section with your changes under the appropriate category:
11+
12+
- **Added** for new features.
13+
- **Changed** for changes in existing functionality.
14+
- **Deprecated** for soon-to-be removed features.
15+
- **Removed** for now removed features.
16+
- **Fixed** for any bug fixes.
17+
- **Security** in case of vulnerabilities.
18+
19+
When releasing a new version, move the "Unreleased" changes to a new version section with the release date.
20+
21+
[Unreleased]: https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/compare/v0.6.0...HEAD
22+
[0.6.0]: https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/releases/tag/v0.6.0
23+
24+
## [Unreleased]
25+
26+
### Added
27+
28+
### Changed
29+
30+
### Deprecated
31+
32+
### Removed
33+
34+
### Fixed
35+
36+
### Security
37+
38+
## [0.6.0] - 2025-11-14
39+
40+
### Added
41+
- New `project_isometric` function for projecting matrices onto isometric manifold ([#67](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/67))
42+
- New `PolarNewton` algorithm for polar decomposition ([#67](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/67))
43+
- New matrix property functions: `ishermitian`, `isantihermitian`, `hermitianpart!`, `hermitianpart`, `antihermitianpart!`, and `antihermitianpart` ([#64](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/64))
44+
- Support for `BigFloat` via new `GenericLinearAlgebra` extension ([#87](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/87))
45+
- Mooncake reverse-mode AD rules ([#85](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/85))
46+
- GPU support for image and null space computations ([#82](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/82))
47+
- GPU support for polar decomposition ([#83](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/83))
48+
- GPU support for new projection operations ([#81](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/81))
49+
- Output truncation error for truncated decompositions ([#75](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/75))
50+
- Documentation for truncated decomposition keyword arguments ([#71](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/71))
51+
- Default algorithm implementations for GPU wrapper array types ([#49](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/49))
52+
53+
### Changed
54+
55+
- Made `gaugefix!` optional ([#95](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/95))
56+
- Renamed `isisometry` to `isisometric` for consistency with `project_isometric` ([#73](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/73))
57+
- Refactored `left_orth`, `right_orth`, `left_null` and `right_null` interface ([#79](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/79))
58+
- Improved GPU support for SVD operations ([#80](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/80))
59+
- Loosened strictness on hermitian checks ([#78](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/78))
60+
- Updated pullback tolerances ([#92](https://github.com/QuantumKitHub/MatrixAlgebraKit.jl/pull/92))
61+
62+
### Removed
63+
64+
### Fixed

docs/src/user_interface/decompositions.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ eigh_trunc
7272
eigh_vals
7373
```
7474

75+
!!! note "Gauge Degrees of Freedom"
76+
The eigenvectors returned by these functions have residual phase degrees of freedom.
77+
By default, MatrixAlgebraKit applies a gauge fixing convention to ensure reproducible results.
78+
See [Gauge choices](@ref sec_gaugefix) for more details.
79+
7580
Alongside these functions, we provide a LAPACK-based implementation for dense arrays, as provided by the following algorithms:
7681

7782
```@autodocs; canonical=false
@@ -89,6 +94,11 @@ eig_trunc
8994
eig_vals
9095
```
9196

97+
!!! note "Gauge Degrees of Freedom"
98+
The eigenvectors returned by these functions have residual phase degrees of freedom.
99+
By default, MatrixAlgebraKit applies a gauge fixing convention to ensure reproducible results.
100+
See [Gauge choices](@ref sec_gaugefix) for more details.
101+
92102
Alongside these functions, we provide a LAPACK-based implementation for dense arrays, as provided by the following algorithms:
93103

94104
```@autodocs; canonical=false
@@ -137,6 +147,11 @@ svd_vals
137147
svd_trunc
138148
```
139149

150+
!!! note "Gauge Degrees of Freedom"
151+
The singular vectors returned by these functions have residual phase degrees of freedom.
152+
By default, MatrixAlgebraKit applies a gauge fixing convention to ensure reproducible results.
153+
See [Gauge choices](@ref sec_gaugefix) for more details.
154+
140155
MatrixAlgebraKit again ships with LAPACK-based implementations for dense arrays:
141156

142157
```@autodocs; canonical=false
@@ -371,3 +386,48 @@ norm(A * N1') < 1e-14 && norm(A * N2') < 1e-14 &&
371386
# output
372387
true
373388
```
389+
390+
## [Gauge choices](@id sec_gaugefix)
391+
392+
Both eigenvalue and singular value decompositions have residual gauge degrees of freedom even when the eigenvalues or singular values are unique.
393+
These arise from the fact that even after normalization, the eigenvectors and singular vectors are only determined up to a phase factor.
394+
395+
### Phase Ambiguity in Decompositions
396+
397+
For the eigenvalue decomposition `A * V = V * D`, if `v` is an eigenvector with eigenvalue `λ` and `|v| = 1`, then so is `e^(iθ) * v` for any real phase `θ`.
398+
When `λ` is non-degenerate (i.e., has multiplicity 1), the eigenvector is unique up to this phase.
399+
400+
Similarly, for the singular value decomposition `A = U * Σ * Vᴴ`, the singular vectors `u` and `v` corresponding to a non-degenerate singular value `σ` are unique only up to a common phase.
401+
We can replace `u → e^(iθ) * u` and `vᴴ → e^(-iθ) * vᴴ` simultaneously.
402+
403+
### Gauge Fixing Convention
404+
405+
To remove this phase ambiguity and ensure reproducible results, MatrixAlgebraKit implements a gauge fixing convention by default.
406+
The convention ensures that **the entry with the largest magnitude in each eigenvector or left singular vector is real and positive**.
407+
408+
For eigenvectors, this means that for each column `v` of `V`, we multiply by `conj(sign(v[i]))` where `i` is the index of the entry with largest absolute value.
409+
410+
For singular vectors, we apply the phase factor to both `u` and `v` based on the entry with largest magnitude in `u`.
411+
This preserves the decomposition `A = U * Σ * Vᴴ` while fixing the gauge.
412+
413+
### Disabling Gauge Fixing
414+
415+
Gauge fixing is enabled by default for all eigenvalue and singular value decompositions.
416+
If you prefer to obtain the raw results from the underlying computational routines without gauge fixing, you can disable it using the `fixgauge` keyword argument:
417+
418+
```julia
419+
# With gauge fixing (default)
420+
D, V = eigh_full(A)
421+
422+
# Without gauge fixing
423+
D, V = eigh_full(A; fixgauge = false)
424+
```
425+
426+
The same keyword is available for `eig_full`, `eig_trunc`, `svd_full`, `svd_compact`, and `svd_trunc` functions.
427+
Additionally, the default value can also be controlled with a global toggle using [`MatrixAlgebraKit.default_fixgauge`](@ref).
428+
429+
```@docs; canonical=false
430+
MatrixAlgebraKit.gaugefix!
431+
MatrixAlgebraKit.default_fixgauge
432+
```
433+

ext/MatrixAlgebraKitGenericLinearAlgebraExt.jl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module MatrixAlgebraKitGenericLinearAlgebraExt
22

33
using MatrixAlgebraKit
4-
using MatrixAlgebraKit: sign_safe, check_input, diagview
4+
using MatrixAlgebraKit: sign_safe, check_input, diagview, gaugefix!, default_fixgauge
55
using GenericLinearAlgebra: svd!, svdvals!, eigen!, eigvals!, Hermitian, qr!
66
using LinearAlgebra: I, Diagonal, lmul!
77

@@ -13,18 +13,26 @@ for f! in (:svd_compact!, :svd_full!, :svd_vals!)
1313
@eval MatrixAlgebraKit.initialize_output(::typeof($f!), A::AbstractMatrix, ::GLA_QRIteration) = nothing
1414
end
1515

16-
function MatrixAlgebraKit.svd_compact!(A::AbstractMatrix, USVᴴ, ::GLA_QRIteration)
16+
function MatrixAlgebraKit.svd_compact!(A::AbstractMatrix, USVᴴ, alg::GLA_QRIteration)
1717
F = svd!(A)
1818
U, S, Vᴴ = F.U, Diagonal(F.S), F.Vt
19-
return MatrixAlgebraKit.gaugefix!(svd_compact!, U, S, Vᴴ, size(A)...)
19+
20+
do_gauge_fix = get(alg.kwargs, :fixgauge, default_fixgauge())::Bool
21+
do_gauge_fix && gaugefix!(svd_compact!, U, Vᴴ)
22+
23+
return U, S, Vᴴ
2024
end
2125

22-
function MatrixAlgebraKit.svd_full!(A::AbstractMatrix, USVᴴ, ::GLA_QRIteration)
26+
function MatrixAlgebraKit.svd_full!(A::AbstractMatrix, USVᴴ, alg::GLA_QRIteration)
2327
F = svd!(A; full = true)
2428
U, Vᴴ = F.U, F.Vt
2529
S = MatrixAlgebraKit.zero!(similar(F.S, (size(U, 2), size(Vᴴ, 1))))
2630
diagview(S) .= F.S
27-
return MatrixAlgebraKit.gaugefix!(svd_full!, U, S, Vᴴ, size(A)...)
31+
32+
do_gauge_fix = get(alg.kwargs, :fixgauge, default_fixgauge())::Bool
33+
do_gauge_fix && gaugefix!(svd_full!, U, Vᴴ)
34+
35+
return U, S, Vᴴ
2836
end
2937

3038
function MatrixAlgebraKit.svd_vals!(A::AbstractMatrix, S, ::GLA_QRIteration)

0 commit comments

Comments
 (0)