Implement SubBasis#61
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #61 +/- ##
==========================================
+ Coverage 83.90% 84.42% +0.51%
==========================================
Files 15 15
Lines 845 873 +28
==========================================
+ Hits 709 737 +28
Misses 136 136 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| k = findfirst(==(x), supp(b)) | ||
| isnothing(k) && throw("x=$x is not supported on SubBasis") | ||
| @info T I | ||
| return convert(I, k) |
There was a problem hiding this comment.
This should be convert(I, b.parent_basis[b.supporting_elts[x]]) because we store the indices
| Base.IteratorSize(::Type{<:FixedBasis}) = Base.HasLength() | ||
| Base.length(b::FixedBasis) = length(b.elts) | ||
| struct SubBasis{T,I,V,B<:AbstractBasis{T,I}} <: FiniteSupportBasis{T,I} | ||
| supporting_elts::V |
There was a problem hiding this comment.
This should be the list of indices of the parent_basis. For DiracBasis, since indices are the same as elements, it works as well
|
@blegat I was pondering this topic over and over; At the moment what we have is
We need to add/multiply
It seems that all of this can be achieved on the level of coefficients. |
|
Good question. I definitely need an |
|
@blegat, I'm not sure what do you mean by
Nowhere there do we form a product Here's some newly updated code that make use of import StarAlgebras as SA
let X = .... # AlgebraElement for a StarAlgebra of FPMonoid (infinite dimensional, DiracBasis)
A = parent(elts)
unit = one(A)
# compute somehow a set of elements from `basis(A)` where dual sos-problem for X makes sense.
linsupp, sizes = linear_supp(X, unit)
B = SA.FixedBasis(linsupp, SA.mstructure(SA.basis(A)))
# length(word(x)) corresponds to degree of polynomials
N = maximum(x -> sizes[length(FPMonoids.word(x))÷2], linsupp)
mt = let psd_basis = @view linsupp[1:N] # linsupp is ordered by word-length
# here we use DiracMStructure of `B` and `mt` is `Matrix{<:Integer}`
mt = [B[star(x)*y] for x in psd_basis, y in psd_basis]
end
model = JuMP.Model()
# y is a vector of variables in basis `B`!
y = @variable model y[1:length(B)]
@objective model Max dot(coeffs(X, B), y) # max dot(X, y)
@constraint model dot(coeffs(unit, B), y) == 1 # given a normalized `y`
let P = @view y[mt]
@constraint model P in PSDCone() # and mt defines a psd matrix
end
return model
endsee also https://github.com/kalmarek/QuantumStuff.jl/blob/mk/new_fpmonoids/src/psd_problems.jl |
|
Thanks, I'll play around with while trying to update jump-dev/SumOfSquares.jl#375 |
|
Meeting notes: zero_basis -> Any SA.ExplicitBasis coeffs(zero_basis, q) == coeffs(zero_basis, gram_basis' * Q * gram_basis)How to compute function quadratic_form(Q, basis)
p = zero(implicit_basis(zero_basis))
MA.operate!(..., p, gram_basis' * Q * gram_basis)
return p
end
coeffs(zero_basis, quadratic_form(gram_matrix.Q, gram_matrix.basis))Symmetry case: MA.operate!(..., p, gram_basis' * Q * gram_basis)
for row, col
MA.operate!(...,
p::AlgebraElement{FullBasis{B}},
1 * star(gram_basis[row])::SymmetryAdapted{B},
Q[row, col] * gram_basis[col]::SymmetryAdapted{B},
)
end
MA.operate!(..., p::AlgebraElement{FullBasis{B}}, ::AlgebraElement{FullBasis{B}})from SOS function MA.operate!(
op::SA.UnsafeAddMul{typeof(*)},
p::SA.AlgebraElement,
g::GramMatrix,
args::Vararg{Any,N},
) where {N}
for row in eachindex(g.basis)
row_star = SA.star(g.basis[row])
for col in eachindex(g.basis)
MA.operate!(
op,
p,
MB.term_element(g.Q[row, col], identity(algebra(p))),
MB.convert_basis(row_star, SA.algebra(p)),
MB.convert_basis(g.basis[col], SA.algebra(p)),
args...,
)
end
end
return p
endConclusion, we should have something like this in |
struct QuadraticForm{T}
Q::T
end
basis(Q::QuadraticForm) = basis(Q.Q) # ExplicitBasis
Base.getindex(Q, i::T, j::T) where {T} = Q[basis(Q)[i], basis(Q)[j]]
function Base.getindex(Q, i::Integer, j::Integer)
# returns the q_ij
return Q[i, j]
end
function MA.operate!(
op::UnsafeAddMul,
p::T, # implicit basis
Q::QuadraticForm,
)
for b1 in basis(Q)
b1′ = star(b1)
for b2 in basis(Q)
MA.operate!(op, p, (1, b1′), (Q[i, j], b2))
end
end
return p
end |
But this makes the abstraction useless...
| # This file is a part of StarAlgebras.jl. License is MIT: https://github.com/JuliaAlgebra/StarAlgebras.jl/blob/main/LICENSE | ||
| # Copyright (c) 2021-2025: Marek Kaluba, Benoît Legat | ||
|
|
||
| abstract type FiniteSupportBasis{T,I} <: ExplicitBasis{T,I} end |
There was a problem hiding this comment.
@kalmarek What would be the difference between a FiniteSupportBasis and an ExplicitBasis ? I thought that an ExplicitBasis was a basis with a finite number of elements ^^
|
@kalmarek It's now ready for your review |
| Implicit bases are not stored in memory and can be potentially infinite. | ||
| abstract type ImplicitBasis{T,I} <: AbstractBasis{T,I} end | ||
|
|
||
| Implicit bases are bases that contains the product of all its elements. |
There was a problem hiding this comment.
hmm. in principle this is not guaranteed, but we could make this assumption
There was a problem hiding this comment.
I notice that it didn't have trait in the description that all instances would have which kind of means that this abstract type isn't useful. The way we use it is when multiplying AlgebraElement so this description is kind of the assumption we have. We could say that if the user violates the assumption then it will be fine but AlgebraElement might throw in the multiplication
There was a problem hiding this comment.
I'm planning to make a PR that tries to bring the concept of implicit_basis corresponding to an explicit one because I need it for SOS
Co-authored-by: Marek Kaluba <kalmar@mailbox.org>
|
@blegat If your're fine with this feel free to squash and merge. |
|
(and give yourself a positive review :D) |
|
Yes, we're getting close but we are not ready to release yet |
@blegat