Skip to content

Commit 669bc84

Browse files
feat: add safe_HomotopyContinuationProblem
1 parent 2401aa2 commit 669bc84

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

ext/MTKHomotopyContinuationExt.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,22 @@ All other keyword arguments are forwarded to `HomotopyContinuation.solver_starts
9696
"""
9797
function MTK.HomotopyContinuationProblem(
9898
sys::NonlinearSystem, u0map, parammap = nothing; kwargs...)
99+
prob = MTK._safe_HomotopyContinuationProblem(sys, u0map, parammap; kwargs...)
100+
prob isa MTK.HomotopyContinuationProblem || throw(prob)
101+
return prob
102+
end
103+
104+
function MTK._safe_HomotopyContinuationProblem(sys, u0map, parammap = nothing; kwargs...)
99105
if !iscomplete(sys)
100106
error("A completed `NonlinearSystem` is required. Call `complete` or `structural_simplify` on the system before creating a `HomotopyContinuationProblem`")
101107
end
102108
transformation = MTK.PolynomialTransformation(sys)
103109
if transformation isa MTK.NotPolynomialError
104-
throw(transformation)
110+
return transformation
105111
end
106112
result = MTK.transform_system(sys, transformation)
107113
if result isa MTK.NotPolynomialError
108-
throw(result)
114+
return result
109115
end
110116
MTK.HomotopyContinuationProblem(sys, transformation, result, u0map, parammap; kwargs...)
111117
end

src/systems/nonlinear/homotopy_continuation.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ function HomotopyContinuationProblem(::AbstractSystem, _u0, _p; kwargs...)
4848
error("HomotopyContinuation.jl is required to create and solve `HomotopyContinuationProblem`s. Please run `Pkg.add(\"HomotopyContinuation\")` to continue.")
4949
end
5050

51+
"""
52+
$(TYPEDSIGNATURES)
53+
54+
Utility function for `safe_HomotopyContinuationProblem`, implemented in the extension.
55+
"""
56+
function _safe_HomotopyContinuationProblem end
57+
58+
"""
59+
$(TYPEDSIGNATURES)
60+
61+
Return a `HomotopyContinuationProblem` if the extension is loaded and the system is
62+
polynomial. If the extension is not loaded, return `nothing`. If the system is not
63+
polynomial, return the appropriate `NotPolynomialError`.
64+
"""
65+
function safe_HomotopyContinuationProblem(sys::NonlinearSystem, args...; kwargs...)
66+
if Base.get_extension(ModelingToolkit, :MTKHomotopyContinuationExt) === nothing
67+
return nothing
68+
end
69+
return _safe_HomotopyContinuationProblem(sys, args...; kwargs...)
70+
end
71+
5172
SymbolicIndexingInterface.symbolic_container(p::HomotopyContinuationProblem) = p.sys
5273
SymbolicIndexingInterface.state_values(p::HomotopyContinuationProblem) = p.u0
5374
function SymbolicIndexingInterface.set_state!(p::HomotopyContinuationProblem, args...)

test/extensions/homotopy_continuation.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
using ModelingToolkit, NonlinearSolve, SymbolicIndexingInterface
2+
import ModelingToolkit as MTK
23
using LinearAlgebra
34
using Test
5+
6+
@testset "Safe HCProblem" begin
7+
@variables x y z
8+
eqs = [0 ~ x^2 + y^2 + 2x * y
9+
0 ~ x^2 + 4x + 4
10+
0 ~ y * z + 4x^2]
11+
@mtkbuild sys = NonlinearSystem(eqs)
12+
prob = MTK.safe_HomotopyContinuationProblem(sys, [x => 1.0, y => 1.0, z => 1.0], [])
13+
@test prob === nothing
14+
end
15+
16+
417
import HomotopyContinuation
518

619
@testset "No parameters" begin
@@ -78,30 +91,37 @@ end
7891
@test_throws ["Cannot convert", "Unable", "symbolically solve",
7992
"Exponent", "not an integer", "not a polynomial"] HomotopyContinuationProblem(
8093
sys, [])
94+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
8195
@mtkbuild sys = NonlinearSystem([x^x - x ~ 0])
8296
@test_throws ["Cannot convert", "Unable", "symbolically solve",
8397
"Exponent", "unknowns", "not a polynomial"] HomotopyContinuationProblem(
8498
sys, [])
99+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
85100
@mtkbuild sys = NonlinearSystem([((x^2) / sin(x))^2 + x ~ 0])
86101
@test_throws ["Cannot convert", "both polynomial", "non-polynomial",
87102
"recognized", "sin", "not a polynomial"] HomotopyContinuationProblem(
88103
sys, [])
104+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
89105

90106
@variables y = 2.0
91107
@mtkbuild sys = NonlinearSystem([x^2 + y^2 + 2 ~ 0, y ~ sin(x)])
92108
@test_throws ["Cannot convert", "recognized", "sin", "not a polynomial"] HomotopyContinuationProblem(
93109
sys, [])
110+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
94111

95112
@mtkbuild sys = NonlinearSystem([x^2 + y^2 - 2 ~ 0, sin(x + y) ~ 0])
96113
@test_throws ["Cannot convert", "function of multiple unknowns"] HomotopyContinuationProblem(
97114
sys, [])
115+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
98116

99117
@mtkbuild sys = NonlinearSystem([sin(x)^2 + 1 ~ 0, cos(y) - cos(x) - 1 ~ 0])
100118
@test_throws ["Cannot convert", "multiple non-polynomial terms", "same unknown"] HomotopyContinuationProblem(
101119
sys, [])
120+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
102121

103122
@mtkbuild sys = NonlinearSystem([sin(x^2)^2 + sin(x^2) - 1 ~ 0])
104123
@test_throws ["import Nemo"] HomotopyContinuationProblem(sys, [])
124+
@test MTK.safe_HomotopyContinuationProblem(sys, []) isa MTK.NotPolynomialError
105125
end
106126

107127
import Nemo

0 commit comments

Comments
 (0)