Skip to content

Commit 27b57fc

Browse files
authored
Add MacaulyNullspaceSolver (#57)
* Add MacaulyNullspaceSolver * Fix format * Add doc
1 parent 6dad7ca commit 27b57fc

File tree

6 files changed

+104
-44
lines changed

6 files changed

+104
-44
lines changed

docs/src/atoms.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ FlatExtension
4646
The second approach is to first obtain the image space of the moment matrix,
4747
represented as a [`MacaulayNullspace`](@ref)
4848
and to then compute the multiplication matrices from this image space.
49+
This is implemented by the [`ImageSpaceSolver`](@ref).
50+
51+
```@docs
52+
MacaulayNullspace
53+
ImageSpaceSolver
54+
```
55+
4956
This image space is obtained from a low rank LDLT decomposition of the moment matrix.
5057
This decomposition can either be obtained by a cholesky or SVD decomposition from which we remove the rows corresponding to the negligeable eigen/singular values.
5158

@@ -55,7 +62,6 @@ ShiftCholeskyLDLT
5562
SVDLDLT
5663
low_rank_ldlt
5764
LowRankLDLT
58-
MacaulayNullspace
5965
```
6066

6167
The choice of cutoff between the significant and neglibeable eigen/singular values is

src/echelon.jl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,42 @@ Foundations of Computational Mathematics 8 (2008): 607-647.
7878
*Numerical polynomial algebra.*
7979
Society for Industrial and Applied Mathematics, 2004.
8080
"""
81-
struct Echelon end
81+
struct Echelon{S<:Union{Nothing,SemialgebraicSets.AbstractAlgebraicSolver}} <:
82+
MacaulayNullspaceSolver
83+
solver::S
84+
end
85+
Echelon() = Echelon(nothing)
86+
87+
# TODO remove in next breaking release
88+
function compute_support!(
89+
ν::MomentMatrix,
90+
rank_check::RankCheck,
91+
ldlt::LowRankLDLTAlgorithm,
92+
::Echelon,
93+
arg::SemialgebraicSets.AbstractAlgebraicSolver,
94+
)
95+
return compute_support!(ν, rank_check, ldlt, Echelon(arg))
96+
end
8297

8398
import RowEchelon
8499

85-
function solve(null::MacaulayNullspace, ::Echelon, args...)
100+
function solve(null::MacaulayNullspace, solver::Echelon)
101+
# Ideally, we should determine the pivots with a greedy sieve algorithm [LLR08, Algorithm 1]
102+
# so that we have more chance that low order monomials are in β and then more chance
103+
# so that the pivots form an order ideal. We just use `rref` which does not implement the sieve
104+
# v[i] * β to be in μ.x
105+
# but maybe it's sufficient due to the shift structure of the matrix.
106+
#
107+
# [LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp.
108+
# "Semidefinite characterization and computation of zero-dimensional real radical ideals."
109+
# Foundations of Computational Mathematics 8 (2008): 607-647.
110+
86111
# If M is multiplied by λ, W is multiplied by √λ
87112
# so we take √||M|| = √nM
88113
Z = Matrix(null.matrix')
89114
RowEchelon.rref!(Z, null.accuracy / sqrt(size(Z, 2)))
90115
#r, vals = solve_system(U', μ.x)
91116
# TODO determine what is better between rank_check and sqrt(rank_check) here
117+
args = isnothing(solver.solver) ? tuple() : (solver.solver,)
92118
return build_system(Z, null.basis, null.accuracy, args...)
93119
end

src/extract.jl

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,12 @@ using SemialgebraicSets
22
import CommonSolve: solve
33

44
"""
5-
compute_support!(ν::MomentMatrix, rank_check, [dec])
5+
function compute_support!(ν::MomentMatrix, rank_check, solver) end
66
7-
Computes the `support` field of `ν`.
8-
The `rank_check` and `dec` parameters are passed as is to the [`low_rank_ldlt`](@ref) function.
7+
Computes the `support` field of `ν` wth `solver` using a low-rank decomposition
8+
with the rank evaluated with `rank_check`.
99
"""
10-
function compute_support!(
11-
μ::MomentMatrix,
12-
rank_check::RankCheck,
13-
dec::LowRankLDLTAlgorithm,
14-
nullspace_solver = Echelon(),
15-
args...,
16-
)
17-
# Ideally, we should determine the pivots with a greedy sieve algorithm [LLR08, Algorithm 1]
18-
# so that we have more chance that low order monomials are in β and then more chance
19-
# so that the pivots form an order ideal. We just use `rref` which does not implement the sieve
20-
# v[i] * β to be in μ.x
21-
# but maybe it's sufficient due to the shift structure of the matrix.
22-
#
23-
# [LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp.
24-
# "Semidefinite characterization and computation of zero-dimensional real radical ideals."
25-
# Foundations of Computational Mathematics 8 (2008): 607-647.
26-
M = value_matrix(μ)
27-
chol = low_rank_ldlt(M, dec, rank_check)
28-
@assert size(chol.L, 1) == LinearAlgebra.checksquare(M)
29-
return μ.support = solve(
30-
MacaulayNullspace(chol.L, μ.basis, accuracy(chol)),
31-
nullspace_solver,
32-
args...,
33-
)
34-
end
35-
36-
function compute_support!::MomentMatrix, rank_check::RankCheck, args...)
37-
return compute_support!(
38-
μ::MomentMatrix,
39-
rank_check::RankCheck,
40-
SVDLDLT(),
41-
args...,
42-
)
43-
end
10+
function compute_support! end
4411

4512
# Determines weight
4613

src/null.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,59 @@ function Base.getindex(
2727
null.accuracy,
2828
)
2929
end
30+
31+
abstract type MacaulayNullspaceSolver end
32+
33+
"""
34+
struct ImageSpaceSolver{A<:LowRankLDLTAlgorithm,S<:MacaulayNullspaceSolver}
35+
ldlt::A
36+
null::S
37+
end
38+
39+
Computes the image space of the moment matrix using `ldlt` and then solve it
40+
with `null`.
41+
"""
42+
struct ImageSpaceSolver{A<:LowRankLDLTAlgorithm,S<:MacaulayNullspaceSolver}
43+
ldlt::A
44+
null::S
45+
end
46+
47+
function compute_support!(
48+
ν::MomentMatrix,
49+
rank_check::RankCheck,
50+
solver::ImageSpaceSolver,
51+
)
52+
M = value_matrix(ν)
53+
chol = low_rank_ldlt(M, solver.ldlt, rank_check)
54+
@assert size(chol.L, 1) == LinearAlgebra.checksquare(M)
55+
ν.support =
56+
solve(MacaulayNullspace(chol.L, ν.basis, accuracy(chol)), solver.null)
57+
return
58+
end
59+
60+
function compute_support!(
61+
ν::MomentMatrix,
62+
rank_check::RankCheck,
63+
ldlt::LowRankLDLTAlgorithm,
64+
null::MacaulayNullspaceSolver,
65+
)
66+
return compute_support!(ν, rank_check, ImageSpaceSolver(ldlt, null))
67+
end
68+
69+
function compute_support!(
70+
ν::MomentMatrix,
71+
rank_check::RankCheck,
72+
ldlt::LowRankLDLTAlgorithm,
73+
args...,
74+
)
75+
return compute_support!(ν, rank_check, ldlt, Echelon(args...))
76+
end
77+
78+
function compute_support!::MomentMatrix, rank_check::RankCheck, args...)
79+
return compute_support!(
80+
μ::MomentMatrix,
81+
rank_check::RankCheck,
82+
SVDLDLT(),
83+
args...,
84+
)
85+
end

src/shift.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,20 @@ function gap_zone_standard_monomials(monos, maxdegree)
7878
end
7979

8080
"""
81-
struct ShiftNullspace end
81+
struct ShiftNullspace{C<:RankCheck} <: MacaulayNullspaceSolver
82+
check::C
83+
end
8284
8385
From the [`MacaulayNullspace`](@ref), computes multiplication matrices
8486
by exploiting the shift property of the rows [DBD12].
87+
The rank check `check` is used to determine the standard monomials among
88+
the row indices of the null space.
8589
8690
[DBD12] Dreesen, Philippe, Batselier, Kim, and De Moor, Bart.
8791
*Back to the roots: Polynomial system solving, linear algebra, systems theory.*
8892
IFAC Proceedings Volumes 45.16 (2012): 1203-1208.
8993
"""
90-
struct ShiftNullspace{C<:RankCheck}
94+
struct ShiftNullspace{C<:RankCheck} <: MacaulayNullspaceSolver
9195
check::C
9296
end
9397
# Because the matrix is orthogonal, we know the SVD of the whole matrix is

test/extract.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,12 @@ end
372372
function test_extract()
373373
default_solver = SemialgebraicSets.default_algebraic_solver([1.0x - 1.0x])
374374
for solver in [
375-
SVDLDLT(),
376-
ShiftCholeskyLDLT(1e-15),
377375
FlatExtension(),
378376
FlatExtension(NewtonTypeDiagonalization()),
377+
Echelon(),
378+
ImageSpaceSolver(ShiftCholeskyLDLT(1e-15), Echelon()),
379379
ShiftNullspace(),
380+
ImageSpaceSolver(ShiftCholeskyLDLT(1e-15), ShiftNullspace()),
380381
]
381382
atoms_1(1e-10, solver)
382383
atoms_2(1e-10, solver)

0 commit comments

Comments
 (0)