Skip to content

Commit 55de24c

Browse files
sparse.jl added
1 parent 63dfad9 commit 55de24c

File tree

2 files changed

+2
-159
lines changed

2 files changed

+2
-159
lines changed

src/SymbolicNumericIntegration.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include("candidates.jl")
1717
include("homotopy.jl")
1818

1919
include("numeric_utils.jl")
20+
include("sparse.jl")
2021
include("integral.jl")
2122

2223
export integrate, generate_basis

src/integral.jl

Lines changed: 1 addition & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -234,165 +234,7 @@ end
234234
integral, error
235235
"""
236236
function try_integrate(T, eq, x, basis, radius; kwargs...)
237-
args = Dict(kwargs)
238-
abstol, opt, complex_plane, verbose = args[:abstol], args[:opt], args[:complex_plane],
239-
args[:verbose]
240-
241237
basis = basis[2:end] # remove 1 from the beginning
242-
n = length(basis)
243-
244-
# A is an nxn matrix holding the values of the fragments at n random points
245-
A = zeros(Complex{T}, (n, n))
246-
X = zeros(Complex{T}, n)
247-
248-
init_basis_matrix!(T, A, X, x, eq, basis, radius, complex_plane; abstol)
249-
250-
y₁, ϵ₁ = sparse_fit(T, A, x, basis, opt; abstol)
251-
if ϵ₁ < abstol
252-
return y₁, ϵ₁
253-
end
254-
255-
y₂, ϵ₂ = find_singlet(T, A, basis; abstol)
256-
if ϵ₂ < abstol
257-
return y₂, ϵ₂
258-
end
259-
260-
if n < 8 # here, 8 is arbitrary and signifies a small basis
261-
y₃, ϵ₃ = find_dense(T, A, basis; abstol)
262-
if ϵ₃ < abstol
263-
return y₃, ϵ₃
264-
end
265-
end
266-
267-
# moving toward the poles
268-
modify_basis_matrix!(T, A, X, x, eq, basis, radius; abstol)
269-
y₄, ϵ₄ = sparse_fit(T, A, x, basis, opt; abstol)
270-
271-
if ϵ₄ < abstol || ϵ₄ < ϵ₁
272-
return y₄, ϵ₄
273-
else
274-
return y₁, ϵ₁
275-
end
238+
return solve_sparse(T, eq, x, basis, radius; kwargs...)
276239
end
277240

278-
function init_basis_matrix!(T, A, X, x, eq, basis, radius, complex_plane; abstol = 1e-6)
279-
n = size(A, 1)
280-
k = 1
281-
i = 1
282-
283-
eq_fun = fun!(eq, x)
284-
Δbasis_fun = deriv_fun!.(basis, x)
285-
286-
while k <= n
287-
try
288-
x₀ = test_point(complex_plane, radius)
289-
X[k] = x₀ # move_toward_roots_poles(x₀, x, eq)
290-
b₀ = eq_fun(X[k])
291-
292-
if is_proper(b₀)
293-
for j in 1:n
294-
A[k, j] = Δbasis_fun[j](X[k]) / b₀
295-
end
296-
if all(is_proper, A[k, :])
297-
k += 1
298-
end
299-
end
300-
catch e
301-
println("Error from init_basis_matrix!: ", e)
302-
end
303-
end
304-
end
305-
306-
function move_toward_roots_poles(z, x, eq; n = 1, max_r = 100.0)
307-
eq_fun = fun!(eq, x)
308-
Δeq_fun = deriv_fun!(eq, x)
309-
is_root = rand() < 0.5
310-
z₀ = z
311-
for i in 1:n
312-
dz = eq_fun(z) / Δeq_fun(z)
313-
if is_root
314-
z -= dz
315-
else
316-
z += dz
317-
end
318-
if abs(z) > max_r
319-
return z₀
320-
end
321-
end
322-
return z
323-
end
324-
325-
function modify_basis_matrix!(T, A, X, x, eq, basis, radius; abstol = 1e-6)
326-
n = size(A, 1)
327-
eq_fun = fun!(eq, x)
328-
Δeq_fun = deriv_fun!(eq, x)
329-
Δbasis_fun = deriv_fun!.(basis, x)
330-
331-
for k in 1:n
332-
# One Newton iteration toward the poles
333-
# note the + sign instead of the usual - in Newton-Raphson's method. This is
334-
# because we are moving toward the poles and not zeros.
335-
336-
X[k] += eq_fun(X[k]) / Δeq_fun(X[k])
337-
b₀ = eq_fun(X[k])
338-
for j in 1:n
339-
A[k, j] = Δbasis_fun[j](X[k]) / b₀
340-
end
341-
end
342-
end
343-
344-
function sparse_fit(T, A, x, basis, opt; abstol = 1e-6)
345-
n = length(basis)
346-
# find a linearly independent subset of the basis
347-
l = find_independent_subset(A; abstol)
348-
A, basis, n = A[l, l], basis[l], sum(l)
349-
350-
try
351-
b = ones(n)
352-
# q₀ = A \ b
353-
q₀ = DataDrivenDiffEq.init(opt, A, b)
354-
@views sparse_regression!(q₀, A, permutedims(b)', opt, maxiter = 1000)
355-
ϵ = rms(A * q₀ - b)
356-
q = nice_parameter.(q₀)
357-
if sum(iscomplex.(q)) > 2
358-
return nothing, Inf
359-
end # eliminating complex coefficients
360-
return sum(q[i] * expr(basis[i]) for i in 1:length(basis) if q[i] != 0;
361-
init = zero(x)),
362-
abs(ϵ)
363-
catch e
364-
println("Error from sparse_fit", e)
365-
return nothing, Inf
366-
end
367-
end
368-
369-
function find_singlet(T, A, basis; abstol)
370-
σ = vec(std(A; dims = 1))
371-
μ = vec(mean(A; dims = 1))
372-
l =.< abstol) .* (abs.(μ) .> abstol)
373-
if sum(l) == 1
374-
k = findfirst(l)
375-
return nice_parameter(1 / μ[k]) * expr(basis[k]), σ[k]
376-
else
377-
return nothing, Inf
378-
end
379-
end
380-
381-
function find_dense(T, A, basis; abstol = 1e-6)
382-
n = size(A, 1)
383-
b = ones(T, n)
384-
385-
try
386-
q = A \ b
387-
if minimum(abs.(q)) > abstol
388-
ϵ = maximum(abs.(A * q .- b))
389-
if ϵ < abstol
390-
y = sum(nice_parameter.(q) .* expr.(basis))
391-
return y, ϵ
392-
end
393-
end
394-
catch e
395-
#
396-
end
397-
return nothing, Inf
398-
end

0 commit comments

Comments
 (0)