diff --git a/README.md b/README.md index 48a01e4..f921067 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ This is a project for the "Laboratorio Computazionale" exam at the University of - Parallelization - Extract functions in separate modules(?) -## Example system +## Example systems + +Here's some tests on 2x2 systems, with the plotted real approximate solutions $$ \begin{align*} @@ -23,6 +25,26 @@ xy - 1 &= 0 \\ \end{align*} $$ -Plot of the approximate solutions: +![](solutions1.png) + +--- + +$$ +\begin{align*} +x^2 + y^2 - 2 &= 0 \\ +xy - 1 &= 0 \\ +\end{align*} +$$ + +![](solutions2.png) + +--- + +$$ +\begin{align*} +x^3 + 5x^2 - y - 10 &= 0 \\ +2x^2 - y - 10 &= 0 \\ +\end{align*} +$$ -![](solutions.png) +![](solutions3.png) diff --git a/hc.jl b/hc.jl index 6aa7f74..dfb0be3 100644 --- a/hc.jl +++ b/hc.jl @@ -5,12 +5,20 @@ using Plots # Define start system based on total degree function start_system(F) degrees = [maxdegree(p) for p in F] + # @polyvar h + # G = [x_i^d - h^d for (d, x_i) in zip(degrees, variables(F))] G = [x_i^d - 1 for (d, x_i) in zip(degrees, variables(F))] r = [[exp(2im*pi/d)^k for k=0:d-1] for d in degrees] - roots = collect(Iterators.product(r...)) + # roots = vec([vcat(collect(root), 1) for root in collect(Iterators.product(r...))]) + roots = vec([collect(root) for root in collect(Iterators.product(r...))]) return (G, roots) end +function homogenize(F) + @polyvar h + return [sum([h^(maxdegree(p)-maxdegree(t))*t for t in p.terms]) for p in F] +end + # Define homotopy function function homotopy(F, G) γ = cis(2π * rand()) @@ -32,7 +40,7 @@ function en_step(H, x, t, step_size) xp = x .+ Δx * step_size # Corrector step - for _ in 1:5 + for _ in 1:10 JH = [jh(vars=>xp) for jh in differentiate(H(t+step_size), vars)] Δx = JH \ -[h(vars=>xp) for h in H(t+step_size)] xp = xp .+ Δx @@ -45,11 +53,14 @@ function en_step(H, x, t, step_size) end # Adaptive step size -function adapt_step(H, x, t, step, m) - Δ = LinearAlgebra.norm([h(variables(H(t))=>x) for h in H(t)]) +function adapt_step(x, x_old, step, m) + Δ = LinearAlgebra.norm(x - x_old) +# function adapt_step(H, x, t, step, m) + # Δ = LinearAlgebra.norm([h(variables(H(t))=>x) for h in H(t)]) if Δ > 0.1 step = 0.5 * step - elseif Δ < 0.001 + m = 0 + else m+=1 if (m == 5) step = 2 * step @@ -61,20 +72,22 @@ function adapt_step(H, x, t, step, m) end # Main homotopy continuation loop -function solve(F, maxsteps=10000) - (G, roots) = start_system(F) +function solve(F, (G, roots) = start_system(F), maxsteps=10000) + # F=homogenize(F) H=homotopy(F,G) solutions = [] for r in roots t = 1.0 - step_size = 0.1 + step_size = 0.01 x0 = r m = 0 while t > 0 && maxsteps > 0 - x0 = en_step(H, x0, t, step_size) - (m, step_size) = adapt_step(H, x0, t, step_size, m) + x = en_step(H, x0, t, step_size) + (m, step_size) = adapt_step(x, x0, step_size, m) + # (m, step_size) = adapt_step(H, x, t, step_size, m) + x0 = x t -= step_size maxsteps -= 1 end @@ -84,20 +97,29 @@ function solve(F, maxsteps=10000) return solutions end -function plot_real(solutions, F) - p=plot(xlim = (-3, 3), ylim = (-3, 3), aspect_ratio = :equal) - contour!(-3:0.1:3, -3:0.1:3, (x,y)->F[1](variables(F)=>[x,y]), levels=[0], cbar=false, color=:cyan) - contour!(-3:0.1:3, -3:0.1:3, (x,y)->F[2](variables(F)=>[x,y]), levels=[0], cbar=false, color=:green) - scatter!([real(sol[1]) for sol in solutions], [real(sol[2]) for sol in solutions], color = "red", label = "Solutions") +function plot_real(solutions, F, h, v, name) + p=plot(xlim = (-h, h), ylim = (-v, v), aspect_ratio = :equal) + contour!(-h:0.1:h, -v:0.1:v, (x,y)->F[1](variables(F)=>[x,y]), levels=[0], cbar=false, color=:cyan) + contour!(-h:0.1:h, -v:0.1:v, (x,y)->F[2](variables(F)=>[x,y]), levels=[0], cbar=false, color=:green) + scatter!([real(sol[1]) for sol in solutions], [real(sol[2]) for sol in solutions], color = "red", label = "Real solutions") - png("solutions") + png("solutions" * name) end # Input polynomial system @polyvar x y F = [x*y - 1, x^2 + y^2 - 4] +T = [x*y - 1, x^2 + y^2 - 2] +C = [x^3 - y + 5x^2 - 10, 2x^2 - y - 10] +P = [x*y - 1, x*y] -sF = solve(F) +sF = filter(u -> imag(u[1]) < 0.1 && imag(u[2]) < 0.1, solve(F)) +sT = filter(u -> imag(u[1]) < 0.1 && imag(u[2]) < 0.1, solve(T)) +sC = filter(u -> imag(u[1]) < 0.1 && imag(u[2]) < 0.1, solve(C)) +# sP = filter(u -> imag(u[1]) < 0.1 && imag(u[2]) < 0.1, solve(P)) # Plotting the system and the real solutions -plot_real(sF, F) +plot_real(sF, F, 4, 4, "1") +plot_real(sT, T, 4, 4, "2") +plot_real(sC, C, 6, 12, "3") +# plot_real(sP, P, 5, 5, "4") diff --git a/solutions.png b/solutions.png deleted file mode 100644 index 98a5e8c..0000000 Binary files a/solutions.png and /dev/null differ diff --git a/solutions1.png b/solutions1.png new file mode 100644 index 0000000..17e3a36 Binary files /dev/null and b/solutions1.png differ diff --git a/solutions2.png b/solutions2.png new file mode 100644 index 0000000..54adf3a Binary files /dev/null and b/solutions2.png differ diff --git a/solutions3.png b/solutions3.png new file mode 100644 index 0000000..f5382b7 Binary files /dev/null and b/solutions3.png differ