Skip to content

Commit db1da9c

Browse files
committed
inplace versions
1 parent c339e2b commit db1da9c

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

src/MultivariateSingularIntegrals.jl

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,10 @@ end
6868

6969

7070

71-
function rec_rhs_1(z, m, n)
71+
function rec_rhs_1!(F::AbstractMatrix{T}, z) where T
72+
m,n = size(F)
7273
x,y = reim(z)
73-
T= complex(float(typeof(z)))
7474
πT = convert(T, π)
75-
F = zeros(T,m,n)
7675
if x < -1 && -1 < y < 1
7776
C_y = Ultraspherical{T}(-1/2)[y,2:n+1]
7877
F[1,:] .-= (4im*πT * x) .* C_y
@@ -97,9 +96,9 @@ end
9796

9897

9998

100-
function rec_rhs_2(z, m, n)
99+
function rec_rhs_2!(F::AbstractMatrix{T}, z) where T
100+
m,n = size(F)
101101
x,y = reim(z)
102-
T= T= complex(float(typeof(z)))
103102
πT = convert(T, π)
104103
if -1 < x < 1 && -1 y < 1
105104
C_x = Ultraspherical{T}(-3/2)[x,3:m+2]
@@ -154,17 +153,26 @@ The bottom right of the returned matrix is zero. For a square truncation compute
154153
"""
155154

156155
function logkernelsquare(z, n)
157-
F_1 = rec_rhs_1(z, n, n)
158-
F_2 = rec_rhs_2(z, n, n)
159-
A = zeros(complex(float(eltype(z))),n,n)
156+
T = complex(float(eltype(z)))
157+
logkernelsquare!(zeros(T,n,n), z, zeros(T,n,n), zeros(T,n,n))
158+
end
159+
160+
161+
function logkernelsquare!(A::AbstractMatrix{T}, z, F_1, F_2) where T
162+
m,n = size(A)
163+
@assert m == n
164+
rec_rhs_1!(F_1, z)
165+
rec_rhs_2!(F_2, z)
160166
A[1,1] = L₀₀(z)
161167
logkernelsquare_populatefirstcolumn!(A, z, F_1, F_2)
162168
logkernelsquare_populatefirstrow!(A, z, F_1, F_2)
163-
F = F_2 - F_1
169+
170+
F = F_1 # reuse the memory
171+
F .= F_2 .- F_1
164172

165173
# 2nd row/column
166174

167-
for k = 1:n-2
175+
for k = 1:m-2
168176
A[k+1,2] = im*(F[k+1,1] + (A[k,1] - A[k+2,1])/(2k+1))
169177
end
170178

test/runtests.jl

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
using MultivariateSingularIntegrals, QuadGK, ClassicalOrthogonalPolynomials, Test
22

3+
@testset "accurate for low order" begin
4+
Z = (2, 2im, 2+2im, 2-2im, -2 - 2im, -1.001-1.5im, -0.999-1.5im, -0.5-2im, -1-1.5im, -2+2im, -2, 0.1+0.2im, 0.1+im, 0.1-im, 1+0.1im, -1+0.1im, 1+im, -1+im, -1-im, 1-im)
5+
n = 6
6+
for z in Z
7+
L = logkernelsquare(z,n)
8+
for j = 0:n-1, k=0:n-j-1
9+
q = quadgk(s -> quadgk(t -> iszero(s+im*t) ? 0.0+0.0im : log(z-(s+im*t)) * legendrep(k,s) * legendrep(j,t), -1, 1, atol=1E-12)[1], -1, 1, atol=1E-12)[1]
10+
@test q L[k+1,j+1] atol=1E-10
11+
end
12+
end
13+
end
314

4-
Z = (2, 2im, 2+2im, 2-2im, -2 - 2im, -1.001-1.5im, -0.999-1.5im, -0.5-2im, -1-1.5im, -2+2im, -2, 0.1+0.2im, 0.1+im, 0.1-im, 1+0.1im, -1+0.1im, 1+im, -1+im, -1-im, 1-im)
5-
n = 6
6-
for z in Z
7-
L = logkernelsquare(z,n)
8-
for j = 0:n-1, k=0:n-j-1
9-
q = quadgk(s -> quadgk(t -> iszero(s+im*t) ? 0.0+0.0im : log(z-(s+im*t)) * legendrep(k,s) * legendrep(j,t), -1, 1, atol=1E-12)[1], -1, 1, atol=1E-12)[1]
10-
@test q L[k+1,j+1] atol=1E-10
15+
@testset "BigFloat" begin
16+
setprecision(2000) do
17+
for z in (big(2.0), big(2.0im), big(2.0+2im), big(2.0-2im), big(-2.0 - 2im))
18+
P = Legendre{BigFloat}()
19+
n = 100
20+
M = Diagonal((P'P)[1:n,1:n])
21+
@test P[big(0.), 1:n]' * inv(M) * logkernelsquare(z, n) * inv(M) * P[big(0.), 1:n] log(z) atol=1E-40
22+
end
1123
end
1224
end
1325

26+
n = 4000
27+
z = 2.0
28+
@profview logkernelsquare(z, n)
29+
30+
x = range(-1,1,n); @time log.(abs.(x .+ im .* x'));

0 commit comments

Comments
 (0)