diff --git a/src/monomial.jl b/src/monomial.jl index b9275cb..fa1fa71 100644 --- a/src/monomial.jl +++ b/src/monomial.jl @@ -202,6 +202,46 @@ function SA.coeffs( end end +function SA.adjoint_coeffs( + cfs, + source::MonomialIndexedBasis{B1}, + target::MonomialIndexedBasis{B2}, +) where {B1,B2} + source === target && return cfs + source == target && return cfs + res = SA.zero_coeffs( + _promote_coef(_promote_coef(SA.value_type(cfs), B1), B2), + source, + ) + return SA.adjoint_coeffs!(res, cfs, source, target) +end + +function SA.adjoint_coeffs!( + res, + cfs, + source::MonomialIndexedBasis{B1}, + target::MonomialIndexedBasis{B2}, +) where {B1,B2} + if B1 === B2 + return @invoke SA.adjoint_coeffs!( + res, + cfs, + source::SA.AbstractBasis, + target::SA.AbstractBasis, + ) + end + MA.operate!(zero, res) + target_full = implicit_basis(target) + for (i, src_elem) in enumerate(source) + full_col = SA.coeffs(algebra_element(src_elem), target_full) + col = SA.coeffs(full_col, target_full, target) + for (j, v) in SA.nonzero_pairs(col) + res[i] += v * cfs[j] + end + end + return res +end + # FIXME this assumes that the basis is invariant under adjoint SA.star(::SubBasis, coeffs) = SA.star.(coeffs) diff --git a/test/chebyshev.jl b/test/chebyshev.jl index 6126f58..05104f5 100644 --- a/test/chebyshev.jl +++ b/test/chebyshev.jl @@ -1,4 +1,6 @@ using Test +import LinearAlgebra +import MultivariatePolynomials as MP import StarAlgebras as SA using MultivariateBases import MultivariateBases as MB @@ -74,3 +76,19 @@ end ]), ) end + +@testset "Cross-algebra adjoint vs transformation_to" begin + @polyvar x + monos = MP.monomials(x, 0:3) + mono_sub = MB.SubBasis{MB.Monomial}(monos) + cheby_sub = MB.SubBasis{MB.Chebyshev}(monos) + A = Matrix(MB.transformation_to(cheby_sub, mono_sub)) + cfs_cheby = collect(1.0:length(cheby_sub)) + @test collect(SA.coeffs(cfs_cheby, cheby_sub, mono_sub)) ≈ A * cfs_cheby + f_mono = collect(1.0:length(mono_sub)) + @test collect(SA.adjoint_coeffs(f_mono, cheby_sub, mono_sub)) ≈ A' * f_mono + Ainv = inv(A) + g_cheby = collect(1.0:length(cheby_sub)) + @test collect(SA.adjoint_coeffs(g_cheby, mono_sub, cheby_sub)) ≈ + Ainv' * g_cheby +end