Skip to content

Commit 5d0d0f9

Browse files
authored
Add plotgrid and fix grid (#38)
* Add plotgrid and fix grid * Fix grammatrix for ContinuousPolynomial{0} * fix test * Update test_dirichlet.jl * Update test_dirichlet.jl * update transform * Update arrowhead.jl * Support singularities * Update Project.toml * Update Project.toml * simplify arrowhead show * InfiniteLinearAlgebra v0.7 * Update continuouspolynomial.jl * Update Project.toml * add tests * Update test_piecewisepolynomial.jl * DirichletPolynomial can preserve vanishing
1 parent f394e8f commit 5d0d0f9

11 files changed

+340
-190
lines changed

Project.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PiecewiseOrthogonalPolynomials"
22
uuid = "4461d12d-4663-4550-8580-cb764c85e20f"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.2.0"
4+
version = "0.2.1"
55

66
[deps]
77
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -25,12 +25,12 @@ BandedMatrices = "0.17.33"
2525
BlockArrays = "0.16.25"
2626
BlockBandedMatrices = "0.12.2"
2727
ClassicalOrthogonalPolynomials = "0.11"
28-
ContinuumArrays = "0.14"
28+
ContinuumArrays = "0.15"
2929
FillArrays = "1.0"
3030
InfiniteArrays = "0.12.6, 0.13"
31-
InfiniteLinearAlgebra = "0.6.16"
31+
InfiniteLinearAlgebra = "0.6.16, 0.7"
3232
LazyArrays = "1.0"
33-
LazyBandedMatrices = "0.8.15"
33+
LazyBandedMatrices = "0.9.1"
3434
MatrixFactorizations = "2.0"
3535
QuasiArrays = "0.11"
3636
julia = "1.9"

examples/coulomb.jl

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,83 @@
1-
using PiecewiseOrthogonalPolynomials, Plots
1+
using PiecewiseOrthogonalPolynomials, ClassicalOrthogonalPolynomials, BandedMatrices, Plots
2+
using Base: oneto
23

3-
p = reverse(2.0 .^ (-(0:10)))
4+
let M = 20, R = 100
5+
global r = reverse(2.0 .^ (-(0:M))); r = R*[-reverse(r); 0; r]
6+
global V = x -> max(-1/abs(x), -2.0 ^(M)/R)
7+
end
48

5-
C = ContinuousPolynomial{1}(p)
6-
x = axes(C,1)
7-
a = C / C \ log.(x)
9+
Q = DirichletPolynomial(r)
10+
P = ContinuousPolynomial{0}(Q)
811

12+
a = expand(P, V)
13+
14+
15+
16+
p = 20; KR = Block.(oneto(p))
17+
Δ = (diff(Q)'diff(Q))[KR,KR];
18+
M = grammatrix(Q)[KR,KR];
19+
20+
R = P\Q
21+
@time A = (R'* P' * (a .* P) *R)[KR,KR];
22+
23+
24+
λ,V = eigen((Matrix(Δ) + 10A), (Matrix(M)))
25+
26+
27+
28+
g = range(-100,100; length=10000)
29+
p = plot(g, 10a[g]; legend=false, ylims=(-150,5), linestyle=:dash, linewidth=2)
30+
scatter!(r, 10a[r])
31+
savefig("coulombpotential.pdf")
32+
33+
p = plot(g, 10a[g]; legend=false, ylims=(-30,5), linestyle=:dash, linewidth=2)
34+
Pl = Q[g,KR];
35+
for j = 1:100; plot!(g, Pl * real(V[:,j]) .+ λ[j], linewidth=2) end
36+
p
37+
38+
savefig("coulomb.pdf")
39+
40+
g = range(-5,5; length=1000)
41+
p = plot(g, 10a[g]; legend=false, ylims=(-40,0), linestyle=:dash, linewidth=2)
42+
Pl = Q[g,KR];
43+
for j = 1:10; plot!(g, Pl * real(V[:,j]) .+ λ[j], linewidth=2) end
44+
p
45+
46+
savefig("coulomb.pdf")
47+
48+
p2 = plot(g, 10a[g]; legend=false, ylims=(-2800,-2700), linestyle=:dash, linewidth=2)
49+
50+
nanabs = x -> iszero(x) ? NaN : abs(x)
51+
scatter(nanabs.(10coefficients(a)[1:size(V,1)]); yscale=:log10, legend=false)
52+
53+
KR = Block.(oneto(30)); scatter(10nanabs.(coefficients(expand(P[:,KR], V))[KR]); yscale=:log10, legend=false, yticks=10.0 .^(-20:5:5))
54+
savefig("coulombcoeffs.pdf")
55+
scatter!(nanabs.(V[:,2]); yscale=:log10)
56+
57+
58+
a = expand(P, x -> x^2)
59+
Δ = -weaklaplacian(Q)[KR,KR]
60+
M = grammatrix(Q)[KR,KR]
61+
62+
R = P\Q
63+
@time A = (R'* P' * (a .* P) *R)[KR,KR];
64+
λ,V = eigen((Matrix(Δ) + 1000A), (Matrix(M)))
65+
66+
67+
plot(Q[:,KR] * ((Δ + 1000A) \ [1; zeros(size(Δ,1)-1)]))
68+
p
69+
70+
71+
r = range(-1,1; length=10)
72+
Q = DirichletPolynomial(r)
73+
λ,V = eigen(Matrix((-weaklaplacian(Q))[KR,KR]), Matrix(grammatrix(Q)[KR,KR]))
74+
75+
plot(Q[:,KR] * V[:,4])
76+
77+
78+
79+
80+
81+
ContinuousPolynomial{0}(r) \ ContinuousPolynomial{1}(r)
982

10-
a = C[:,1]
1183

12-
C \ (a .* C[:,1])

src/PiecewiseOrthogonalPolynomials.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import ArrayLayouts: sublayout, sub_materialize, symmetriclayout, transposelayou
55
import BandedMatrices: _BandedMatrix
66
import BlockArrays: BlockSlice, block, blockindex, blockvec
77
import BlockBandedMatrices: _BandedBlockBandedMatrix, AbstractBandedBlockBandedMatrix, subblockbandwidths, blockbandwidths, AbstractBandedBlockBandedLayout, layout_replace_in_print_matrix
8-
import ClassicalOrthogonalPolynomials: grid, ldiv, pad, adaptivetransform_ldiv, grammatrix
8+
import ClassicalOrthogonalPolynomials: grid, plotgrid, ldiv, pad, adaptivetransform_ldiv, grammatrix, Plan, singularities, basis_singularities, singularitiesbroadcast
99
import ContinuumArrays: @simplify, factorize, TransformFactorization, AbstractBasisLayout, MemoryLayout, layout_broadcasted, ExpansionLayout, basis, plan_grid_transform, grammatrix
1010
import LazyArrays: paddeddata
1111
import LazyBandedMatrices: BlockBroadcastMatrix, BlockVec, BandedLazyLayouts, AbstractLazyBandedBlockBandedLayout, UpperOrLowerTriangular
12-
import Base: axes, getindex, +, -, *, /, ==, \, OneTo, oneto, replace_in_print_matrix, copy, diff, getproperty, adjoint, transpose, tail
12+
import Base: axes, getindex, +, -, *, /, ==, \, OneTo, oneto, replace_in_print_matrix, copy, diff, getproperty, adjoint, transpose, tail, _sum
1313
import LinearAlgebra: BlasInt
1414
import MatrixFactorizations: reversecholcopy
1515

src/arrowhead.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const ArrowheadMatrices = Union{ArrowheadMatrix,Symmetric{<:Any,<:ArrowheadMatri
2525

2626
subblockbandwidths(A::ArrowheadMatrices) = (1,1)
2727

28+
BlockArrays._show_typeof(io::IO, B::ArrowheadMatrix{T}) where T = print(io, "ArrowheadMatrix{$T}")
29+
2830
function blockbandwidths(A::ArrowheadMatrix)
2931
l,u = bandwidths(A.D[1])
3032
max(l,length(A.C)),max(u,length(A.B))
@@ -193,10 +195,10 @@ function materialize!(M::MatMulMatAdd{<:ArrowheadLayouts,<:AbstractColumnMajor,<
193195
_fill_lmul!(β, Y)
194196
for J = blockaxes(X,2)
195197
mul!(view(Y, Block(1), J), A.A, view(X, Block(1), J), α, one(α))
196-
for k = 1:length(A.B)
198+
for k = 1:min(length(A.B), blocksize(X,1)-1)
197199
mul!(view(Y, Block(1), J), A.B[k], view(X, Block(k+1), J), α, one(α))
198200
end
199-
for k = 1:length(A.C)
201+
for k = 1:min(length(A.C), blocksize(Y,1)-1)
200202
mul!(view(Y, Block(k+1), J), A.C[k], view(X, Block(1), J), α, one(α))
201203
end
202204
end

src/continuouspolynomial.jl

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ContinuousPolynomial{o}(pts) where {o} = ContinuousPolynomial{o,Float64}(pts)
88
ContinuousPolynomial{o,T}(P::ContinuousPolynomial) where {o,T} = ContinuousPolynomial{o,T}(P.points)
99
ContinuousPolynomial{o}(P::ContinuousPolynomial) where {o} = ContinuousPolynomial{o,eltype(P)}(P)
1010

11-
PiecewisePolynomial(P::ContinuousPolynomial{0,T}) where {T} = PiecewisePolynomial(Legendre{T}(), P.points)
11+
PiecewisePolynomial(P::ContinuousPolynomial{o,T}) where {o,T} = PiecewisePolynomial(Legendre{T}(), P.points)
1212

1313
axes(B::ContinuousPolynomial{0}) = axes(PiecewisePolynomial(B))
1414
axes(B::ContinuousPolynomial{1}) =
@@ -44,10 +44,12 @@ end
4444

4545
factorize(V::SubQuasiArray{T,N,<:ContinuousPolynomial{0},<:Tuple{Inclusion,BlockSlice}}, dims...) where {T,N} =
4646
factorize(view(PiecewisePolynomial(parent(V)), parentindices(V)...), dims...)
47-
grid(V::SubQuasiArray{T,N,<:ContinuousPolynomial{0},<:Tuple{Inclusion,Any}}) where {T,N} =
48-
grid(view(PiecewisePolynomial(parent(V)), parentindices(V)...))
49-
grid(V::SubQuasiArray{T,N,<:ContinuousPolynomial,<:Tuple{Inclusion,Any}}) where {T,N} =
50-
grid(view(ContinuousPolynomial{0,T}(parent(V)), parentindices(V)...))
47+
48+
plan_grid_transform(P::ContinuousPolynomial{0}, args...) = plan_grid_transform(PiecewisePolynomial(P), args...)
49+
50+
for grd in (:grid, :plotgrid)
51+
@eval $grd(C::ContinuousPolynomial, n...) = $grd(PiecewisePolynomial(C), n...)
52+
end
5153

5254
function adaptivetransform_ldiv(Q::ContinuousPolynomial{1,V}, f::AbstractQuasiVector) where V
5355
T = promote_type(V, eltype(f))
@@ -94,23 +96,6 @@ end
9496
#######
9597

9698
function \(P::ContinuousPolynomial{0}, C::ContinuousPolynomial{1})
97-
T = promote_type(eltype(P), eltype(C))
98-
# diag blocks based on
99-
# L = Legendre{T}() \ Weighted(Jacobi{T}(1,1))
100-
@assert P.points == C.points
101-
N = length(P.points)
102-
v = mortar(Fill.((convert(T, 2):2:∞) ./ (3:2:∞), N - 1))
103-
z = Zeros{T}(axes(v))
104-
H1 = BlockBroadcastArray(hcat, z, v)
105-
M1 = BlockVcat(Zeros{T}(N, 2), H1)
106-
M2 = BlockVcat(Ones{T}(N, 2) / 2, Zeros{T}((axes(v, 1), Base.OneTo(2))))
107-
H3 = BlockBroadcastArray(hcat, z, -v)
108-
M3 = BlockVcat(Hcat(Ones{T}(N) / 2, -Ones{T}(N) / 2), H3)
109-
dat = BlockHcat(M1, M2, M3)'
110-
_BandedBlockBandedMatrix(dat, axes(P, 2), (1, 1), (0, 1))
111-
end
112-
113-
function \(P::ContinuousPolynomial{0, <:Any, <:AbstractRange}, C::ContinuousPolynomial{1, <:Any, <:AbstractRange})
11499
T = promote_type(eltype(P), eltype(C))
115100
@assert P.points == C.points
116101
v = (convert(T, 2):2:∞) ./ (3:2:∞)
@@ -132,7 +117,7 @@ function grammatrix(A::ContinuousPolynomial{0,T}) where T
132117
N = length(r) - 1
133118
hs = diff(r)
134119
M = grammatrix(Legendre{T}())
135-
ArrowheadMatrix{T}(Diagonal(Fill(hs[1], N)), (), (), [Diagonal(M.diag[2:end] * h/2) for h in hs])
120+
ArrowheadMatrix{T}(Diagonal(hs), (), (), [Diagonal(M.diag[2:end] * h/2) for h in hs])
136121
end
137122

138123
function grammatrix(A::ContinuousPolynomial{0,T, <:AbstractRange}) where T
@@ -196,7 +181,7 @@ function diff(C::ContinuousPolynomial{1,T}; dims=1) where T
196181
H = BlockBroadcastArray(hcat, z, v)
197182
M = BlockVcat(Hcat(Ones{T}(N) .* [zero(T); s] , -Ones{T}(N) .* [s; zero(T)] ), H)
198183
P = ContinuousPolynomial{0}(C)
199-
ApplyQuasiMatrix(*, P, _BandedBlockBandedMatrix(M', (axes(P, 2), axes(C, 2)), (0, 0), (0, 1)))
184+
ApplyQuasiMatrix(*, P, _BandedBlockBandedMatrix(M', axes(P, 2), (0, 0), (0, 1)))
200185
end
201186

202187
function weaklaplacian(C::ContinuousPolynomial{1,T,<:AbstractRange}) where T
@@ -210,3 +195,12 @@ function weaklaplacian(C::ContinuousPolynomial{1,T,<:AbstractRange}) where T
210195
Fill(Diagonal(convert(T, -16) .* (1:∞) .^ 2 ./ (s .* ((2:2:∞) .+ 1))), N-1)))
211196
end
212197

198+
199+
200+
###
201+
# singularities
202+
###
203+
204+
singularities(C::ContinuousPolynomial{λ}) where λ = C
205+
basis_singularities(C::ContinuousPolynomial) = C
206+
singularitiesbroadcast(_, C::ContinuousPolynomial) = C # Assume we stay smooth

src/dirichlet.jl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ function \(Q::DirichletPolynomial, C::ContinuousPolynomial{1})
4343
ArrowheadMatrix(layout_getindex(Eye{T}(m), 2:m-1, :), (), (), Fill(Eye{T}(∞), m-1))
4444
end
4545

46+
function \(P::ContinuousPolynomial, Q::DirichletPolynomial)
47+
C = ContinuousPolynomial{1}(Q)
48+
(P \ C) * (C \ Q)
49+
end
50+
4651

4752
function adaptivetransform_ldiv(Q::DirichletPolynomial{V}, f::AbstractQuasiVector) where V
4853
C = ContinuousPolynomial{1}(Q)
@@ -78,6 +83,12 @@ function grammatrix(Q::DirichletPolynomial{T, <:AbstractRange}) where T
7883
(h*b/2)'), ∞, 0, 2), N)))
7984
end
8085

86+
function grammatrix(Q::DirichletPolynomial)
87+
C = ContinuousPolynomial{1}(Q)
88+
R = C \ Q
89+
R' * grammatrix(C) * R
90+
end
91+
8192
@simplify function *(Ac::QuasiAdjoint{<:Any,<:DirichletPolynomial}, B::ContinuousPolynomial)
8293
A = Ac'
8394
C = ContinuousPolynomial{1}(A)
@@ -87,4 +98,17 @@ end
8798
function diff(Q::DirichletPolynomial{T}; dims=1) where T
8899
C = ContinuousPolynomial{1}(Q)
89100
diff(C; dims=dims) * (C \ Q)
90-
end
101+
end
102+
103+
for grd in (:grid, :plotgrid)
104+
@eval $grd(C::DirichletPolynomial, n...) = $grd(PiecewisePolynomial(C), n...)
105+
end
106+
107+
###
108+
# singularities
109+
###
110+
111+
singularities(C::DirichletPolynomial) = C
112+
basis_singularities(C::DirichletPolynomial) = C
113+
singularitiesbroadcast(_, Q::DirichletPolynomial) = ContinuousPolynomial{1}(Q) # Assume we stay smooth but might not vanish
114+
singularitiesbroadcast(::typeof(sin), Q::DirichletPolynomial) = Q # Smooth functions such that f(0) == 0 preserve behaviour

src/piecewisepolynomial.jl

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,31 @@ function repeatgrid(ax, g, pts)
2525
ret
2626
end
2727

28-
function grid(V::SubQuasiArray{T,2,<:PiecewisePolynomial,<:Tuple{Inclusion,BlockSlice}}) where {T}
29-
P = parent(V)
30-
_, JR = parentindices(V)
31-
N = Int(last(JR))
32-
g = grid(P.basis[:, OneTo(N)])
28+
29+
function grid(P::PiecewisePolynomial, N::Block{1})
30+
g = grid(P.basis, Int(N))
3331
repeatgrid(axes(P.basis, 1), g, P.points)
3432
end
3533

36-
function grid(V::SubQuasiArray{T,N,<:PiecewisePolynomial,<:Tuple{Inclusion,Any}}) where {T,N}
37-
P = parent(V)
38-
kr,jr = parentindices(V)
39-
J = findblock(axes(P,2), last(jr))
40-
grid(view(P, kr, Block(1):J))
34+
function plotgrid(P::PiecewisePolynomial, N::Block{1})
35+
g = plotgrid(P.basis, Int(N))
36+
vec(repeatgrid(axes(P.basis, 1), g, P.points)[end:-1:1,:]) # sort
4137
end
4238

4339

44-
struct ApplyFactorization{T, FF, FAC<:Factorization{T}} <: Factorization{T}
40+
41+
grid(P::PiecewisePolynomial, n::Int) = grid(P, findblock(axes(P,2),n))
42+
plotgrid(P::PiecewisePolynomial, n::Int) = plotgrid(P, findblock(axes(P,2),n))
43+
44+
45+
46+
47+
struct ApplyPlan{T, FF, FAC<:Plan{T}} <: Plan{T}
4548
f::FF
4649
F::FAC
4750
end
4851

49-
\(P::ApplyFactorization, f) = P.f(P.F \ f)
52+
*(P::ApplyPlan, f::AbstractArray) = P.f(P.F * f)
5053

5154

5255
_perm_blockvec(X::AbstractMatrix) = BlockVec(transpose(X))
@@ -60,12 +63,15 @@ function _perm_blockvec(X::AbstractArray{T,3}) where T
6063
ret
6164
end
6265

66+
function plan_grid_transform(P::PiecewisePolynomial, N::Block{1}, dims...)
67+
x,F = plan_grid_transform(P.basis, (Int(N), length(P.points)-1, dims...), 1)
68+
repeatgrid(axes(P.basis, 1), x, P.points), ApplyPlan(_perm_blockvec, F)
69+
end
70+
6371
function factorize(V::SubQuasiArray{<:Any,2,<:PiecewisePolynomial,<:Tuple{Inclusion,BlockSlice}}, dims...)
6472
P = parent(V)
6573
_,JR = parentindices(V)
66-
N = Int(last(JR.block))
67-
x,F = plan_grid_transform(P.basis, Array{eltype(P)}(undef, N, length(P.points)-1, dims...), 1)
68-
ApplyFactorization(_perm_blockvec, TransformFactorization(repeatgrid(axes(P.basis, 1), x, P.points), F))
74+
TransformFactorization(plan_grid_transform(P, last(JR.block), dims...)...)
6975
end
7076

7177

@@ -105,3 +111,12 @@ function layout_broadcasted(::Tuple{ExpansionLayout{PiecewisePolynomialLayout{0}
105111
P = ContinuousPolynomial{0}(C)
106112
(a .* P) * (P \ C)
107113
end
114+
115+
116+
###
117+
# singularities
118+
###
119+
120+
singularities(C::PiecewisePolynomial) = C
121+
basis_singularities(C::PiecewisePolynomial) = C
122+
singularitiesbroadcast(_, C::PiecewisePolynomial) = C # Assume we stay piecewise smooth

test/test_arrowhead.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ import Base: oneto, OneTo
103103
@test blockbandwidths(L) == (1,1)
104104
@test subblockbandwidths(L) == (1,1)
105105

106-
@test stringmime("text/plain", L[Block.(OneTo(3)), Block.(OneTo(3))]) == "3×3-blocked 9×10 ArrowheadMatrix{Float64, BandedMatrix{Float64, Fill{Float64, 2, Tuple{OneTo{$Int}, OneTo{$Int}}}, OneTo{$Int}}, Tuple{BandedMatrix{Float64, Fill{Float64, 2, Tuple{OneTo{$Int}, OneTo{$Int}}}, OneTo{$Int}}}, Tuple{BandedMatrix{Float64, LazyArrays.ApplyArray{Float64, 2, typeof(vcat), Tuple{Fill{Float64, 2, Tuple{OneTo{$Int}, OneTo{$Int}}}, Fill{Float64, 2, Tuple{OneTo{$Int}, OneTo{$Int}}}}}, OneTo{$Int}}}, Vector{BandedMatrix{Float64, Matrix{Float64}, OneTo{$Int}}}}:\n 0.5 0.5 ⋅ ⋅ │ 0.666667 ⋅ ⋅ │ ⋅ ⋅ ⋅ \n ⋅ 0.5 0.5 ⋅ │ ⋅ 0.666667 ⋅ │ ⋅ ⋅ ⋅ \n ⋅ ⋅ 0.5 0.5 │ ⋅ ⋅ 0.666667 │ ⋅ ⋅ ⋅ \n ───────────────────────┼───────────────────────────────────┼───────────────\n -0.5 0.5 ⋅ ⋅ │ 0.0 ⋅ ⋅ │ 0.8 ⋅ ⋅ \n ⋅ -0.5 0.5 ⋅ │ ⋅ 0.0 ⋅ │ ⋅ 0.8 ⋅ \n ⋅ ⋅ -0.5 0.5 │ ⋅ ⋅ 0.0 │ ⋅ ⋅ 0.8\n ───────────────────────┼───────────────────────────────────┼───────────────\n ⋅ ⋅ ⋅ ⋅ │ -0.666667 ⋅ ⋅ │ 0.0 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ │ ⋅ -0.666667 ⋅ │ ⋅ 0.0 ⋅ \n ⋅ ⋅ ⋅ ⋅ │ ⋅ ⋅ -0.666667 │ ⋅ ⋅ 0.0"
106+
@test stringmime("text/plain", L[Block.(OneTo(3)), Block.(OneTo(3))]) == "3×3-blocked 9×10 ArrowheadMatrix{Float64}:\n 0.5 0.5 ⋅ ⋅ │ 0.666667 ⋅ ⋅ │ ⋅ ⋅ ⋅ \n ⋅ 0.5 0.5 ⋅ │ ⋅ 0.666667 ⋅ │ ⋅ ⋅ ⋅ \n ⋅ ⋅ 0.5 0.5 │ ⋅ ⋅ 0.666667 │ ⋅ ⋅ ⋅ \n ───────────────────────┼───────────────────────────────────┼───────────────\n -0.5 0.5 ⋅ ⋅ │ 0.0 ⋅ ⋅ │ 0.8 ⋅ ⋅ \n ⋅ -0.5 0.5 ⋅ │ ⋅ 0.0 ⋅ │ ⋅ 0.8 ⋅ \n ⋅ ⋅ -0.5 0.5 │ ⋅ ⋅ 0.0 │ ⋅ ⋅ 0.8\n ───────────────────────┼───────────────────────────────────┼───────────────\n ⋅ ⋅ ⋅ ⋅ │ -0.666667 ⋅ ⋅ │ 0.0 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ │ ⋅ -0.666667 ⋅ │ ⋅ 0.0 ⋅ \n ⋅ ⋅ ⋅ ⋅ │ ⋅ ⋅ -0.666667 │ ⋅ ⋅ 0.0"
107107
end
108108

109109
@testset "Helmholtz solve" begin

0 commit comments

Comments
 (0)