|
2 | 2 | Julia package for computing multivariate singular integrals
|
3 | 3 |
|
4 | 4 |
|
5 |
| -The function `newtoniansquare([x,y], n)` computes a matrix of Newtonian potentials of Legendre polynomials on the unit square $Ω := [-1,1]^2$. That is it computes |
| 5 | +The function `newtoniansquare([x,y], p)` computes a matrix of Newtonian potentials of Legendre polynomials on the unit square $Ω := [-1,1]^2$. That is it computes |
6 | 6 | ```math
|
7 | 7 | \begin{pmatrix}
|
8 |
| -L_{00}(𝐱) & \cdots & L_{0,p-1}(𝐱) & L_{0p}(𝐱) \\ |
9 |
| -L_{10}(𝐱) & \cdots & L_{1,p-1}(𝐱) \\ |
| 8 | +L_{11}(𝐱) & \cdots & L_{1,p-1}(𝐱) & L_{1p}(𝐱) \\ |
| 9 | +L_{21}(𝐱) & \cdots & L_{2,p-1}(𝐱) \\ |
10 | 10 | \vdots & \iddots \\
|
11 |
| -L_{p0}(𝐱) |
| 11 | +L_{p1}(𝐱) |
12 | 12 | \end{pmatrix}
|
13 | 13 | ```
|
14 | 14 | where $𝐱 = [x,y]$ is any point in $ℝ²$ (including on or near the unit square $Ω$) and
|
15 | 15 | ```math
|
16 |
| -L_{k,j}(𝐱) := ∬_Ω P_k(s) P_j(t) \log(\| [s,t] - [x,y] \|) \, ds \, dt |
| 16 | +L_{k,j}(𝐱) := ∬_Ω P_{k-1}(s) P_{j-1}(t) \log(\| [s,t] - [x,y] \|) \, ds \, dt |
17 | 17 | ```
|
18 | 18 | where $P_k$ and $P_j$ are the Legendre polynomials of degree $k$ and $j$, respectively.
|
| 19 | + |
| 20 | + |
| 21 | +Here we show an example of how to use the package for computing the Newtonian potential for $f(x,y) = \cos(x*\exp(y))$, |
| 22 | +which is faster than QuadGK.jl: |
| 23 | +```julia |
| 24 | +julia> using MultivariateSingularIntegrals, ClassicalOrthogonalPolynomials, LinearAlgebra, QuadGK |
| 25 | + |
| 26 | +julia> f = (x,y) -> cos(x * exp(y)); |
| 27 | + |
| 28 | +julia> 𝐱 = [0.1, 1.1]; # point near the unit square |
| 29 | + |
| 30 | +julia> @time qgk_approx = quadgk(s -> quadgk(t -> f(s, t) * log(norm(𝐱 - [s,t])), -1, 1)[1], -1, 1)[1]; # compute the integral using quadgk |
| 31 | + 0.388834 seconds (804.74 k allocations: 35.045 MiB, 3.99% gc time, 98.86% compilation time) |
| 32 | + |
| 33 | +julia> P = Legendre(); # Legendre polynomials |
| 34 | + |
| 35 | +julia> p = 40; # degree of the Legendre polynomials |
| 36 | + |
| 37 | +julia> x = ClassicalOrthogonalPolynomials.grid(P, p); # grid of points |
| 38 | + |
| 39 | +julia> F = f.(x, x') # evaluate f on the grid; |
| 40 | + |
| 41 | +julia> @time C = plan_transform(P, (p, p)) * F; # 2D Legendre coefficients |
| 42 | + 0.002116 seconds (2.87 k allocations: 3.594 MiB) |
| 43 | + |
| 44 | +julia> @time N = Float64.(newtoniansquare(big.(𝐱), p)); # compute the Newtonian potential of Legendre polynomials, using BigFloat to avoid numerical issues |
| 45 | + 0.003480 seconds (80.94 k allocations: 4.119 MiB) |
| 46 | + |
| 47 | +julia> @test dot(N, C) ≈ qgk_approx |
| 48 | +Test Passed |
| 49 | +``` |
| 50 | +The package continues to work inside the unit square: |
| 51 | +```julia |
| 52 | +julia> 𝐱 = [0.1, 0.2]; |
| 53 | + |
| 54 | +julia> @time N = Float64.(newtoniansquare(big.(𝐱), p)); |
| 55 | + 0.005985 seconds (165.52 k allocations: 8.324 MiB) |
| 56 | + |
| 57 | +julia> dot(N, C) |
| 58 | +-1.2555132824835833 |
| 59 | +``` |
| 60 | + |
| 61 | +The package also supports complex logarithmic integrals with kernel $\log(z-(s+{\rm i}t))$ via `logkernelsquare` |
| 62 | +and Stieltjes integrals with kernel $1/(z-(s+{\rm i}t))$ via `stieltjessquare`. The real and imaginary parts of Stieltjes integrals containing the gradient of the Newtonian potential. |
0 commit comments