Skip to content

Commit 30c046a

Browse files
authored
Merge pull request #735 from control-toolbox/ctflows
Add comprehensive CTFlows signature freezing tests
2 parents 90c7e5e + 9558441 commit 30c046a

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed

src/imports/ctflows.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# CTFlows reexports
22

3+
# Generated code
4+
@reexport import CTFlows: CTFlows # for generated code (prefix)
5+
36
# Types
4-
@reexport import CTFlows: Hamiltonian, HamiltonianLift, HamiltonianVectorField
7+
import CTFlows: Hamiltonian, HamiltonianLift, HamiltonianVectorField
58

69
# Methods
710
@reexport import CTFlows: Lift, Flow, , Lie, Poisson, @Lie, *

test/suite/reexport/test_ctflows.jl

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,159 @@ function test_ctflows()
6262
Test.@test hasmethod(Flow, Tuple{Vararg{Any}})
6363
end
6464
end
65+
66+
# ====================================================================
67+
# SIGNATURE FREEZING TESTS
68+
# ====================================================================
69+
# These tests make simple calls to exported methods to freeze their signatures.
70+
# They are not meant to verify correct functionality but to ensure the
71+
# API remains stable and catch breaking changes early.
72+
73+
Test.@testset "Signature Freezing" begin
74+
Test.@testset "Hamiltonian Types" begin
75+
# Test basic construction patterns
76+
H = OptimalControl.Hamiltonian((x, p) -> x[1]^2 + p[1]^2)
77+
Test.@test H isa OptimalControl.Hamiltonian
78+
79+
HL = OptimalControl.HamiltonianLift(x -> [x[1], x[2]])
80+
Test.@test HL isa OptimalControl.HamiltonianLift
81+
82+
HV = OptimalControl.HamiltonianVectorField((x, p) -> [p[1], -x[1]])
83+
Test.@test HV isa OptimalControl.HamiltonianVectorField
84+
end
85+
86+
Test.@testset "Lift Function" begin
87+
# Lift from VectorField
88+
X = CTFlows.VectorField(x -> [x[1]^2, x[2]^2])
89+
H = Lift(X)
90+
Test.@test H isa CTFlows.HamiltonianLift
91+
92+
# Lift from Function
93+
f = x -> [x[1]^2, x[2]^2]
94+
H2 = Lift(f)
95+
Test.@test H2 isa Function
96+
97+
# Test basic evaluation (signature verification)
98+
Test.@test H([1, 2], [3, 4]) isa Real
99+
Test.@test H2([1, 2], [3, 4]) isa Real
100+
end
101+
102+
Test.@testset "Flow Function" begin
103+
# Basic Flow call - just verify it doesn't error
104+
# The exact signature may vary, so we just test it exists
105+
Test.@test Flow isa Function
106+
end
107+
108+
Test.@testset "Operators" begin
109+
# Set up simple test objects
110+
X = CTFlows.VectorField(x -> [x[2], -x[1]])
111+
f = x -> x[1]^2 + x[2]^2
112+
113+
# Test dot operator (directional derivative)
114+
dot_result = X f
115+
Test.@test dot_result isa Function
116+
117+
# Test Lie function
118+
lie_result = Lie(X, f)
119+
Test.@test lie_result isa Function
120+
121+
# Test Poisson bracket
122+
g = (x, p) -> x[1]*p[1] + x[2]*p[2]
123+
poisson_result = Poisson(f, g)
124+
Test.@test poisson_result isa CTFlows.Hamiltonian
125+
126+
# Note: * operator is not defined for VectorField * Function combinations
127+
# This is expected behavior based on CTFlows API
128+
end
129+
130+
Test.@testset "@Lie Macro" begin
131+
# Test basic macro usage
132+
X1 = CTFlows.VectorField(x -> [x[2], -x[1]])
133+
X2 = CTFlows.VectorField(x -> [x[1], x[2]])
134+
135+
# Simple Lie bracket with macro
136+
lie_macro_result = @Lie [X1, X2]
137+
Test.@test lie_macro_result isa CTFlows.VectorField
138+
139+
# Test evaluation
140+
Test.@test lie_macro_result([1, 2]) isa Vector
141+
end
142+
143+
Test.@testset "Complex Signature Tests" begin
144+
# Test with different arities and keyword arguments
145+
146+
# Non-autonomous VectorField - needs correct signature
147+
X_nonauto = CTFlows.VectorField((t, x) -> [t + x[1], x[2]]; autonomous=false)
148+
H_nonauto = Lift(X_nonauto)
149+
Test.@test H_nonauto(1, [1, 2], [3, 4]) isa Real
150+
151+
# Variable VectorField - needs correct signature
152+
X_var = CTFlows.VectorField((x, v) -> [x[1] + v, x[2]]; variable=true)
153+
H_var = Lift(X_var)
154+
Test.@test H_var([1, 2], [3, 4], 1) isa Real
155+
156+
# Non-autonomous variable VectorField - needs correct signature
157+
X_both = CTFlows.VectorField((t, x, v) -> [t + x[1] + v, x[2]]; autonomous=false, variable=true)
158+
H_both = Lift(X_both)
159+
Test.@test H_both(1, [1, 2], [3, 4], 1) isa Real
160+
161+
# Hamiltonian with different signatures
162+
H_auto = OptimalControl.Hamiltonian((x, p) -> x[1]*p[1])
163+
Test.@test H_auto([1, 2], [3, 4]) isa Real
164+
165+
H_nonauto_ham = OptimalControl.Hamiltonian((t, x, p) -> t + x[1]*p[1]; autonomous=false)
166+
Test.@test H_nonauto_ham(1, [1, 2], [3, 4]) isa Real
167+
168+
H_var_ham = OptimalControl.Hamiltonian((x, p, v) -> v + x[1]*p[1]; variable=true)
169+
Test.@test H_var_ham([1, 2], [3, 4], 1) isa Real
170+
end
171+
172+
Test.@testset "Operator Combinations" begin
173+
# Test combinations of operators to ensure they work together
174+
X1 = CTFlows.VectorField(x -> [x[2], -x[1]])
175+
X2 = CTFlows.VectorField(x -> [x[1], x[2]])
176+
f = x -> x[1]^2 + x[2]^2
177+
g = (x, p) -> x[1]*p[1] + x[2]*p[2]
178+
179+
# Lie bracket of VectorFields
180+
lie_vf = Lie(X1, X2)
181+
Test.@test lie_vf isa CTFlows.VectorField
182+
Test.@test lie_vf([1, 2]) isa Vector
183+
184+
# Multiple operator combinations
185+
Test.@test (X1 f)([1, 2]) isa Real
186+
187+
# Test Poisson bracket with ForwardDiff-compatible functions
188+
h = (x, p) -> x[1]*p[1] + x[2]*p[2] # Simple polynomial function
189+
poisson_result = Poisson(h, g)
190+
Test.@test poisson_result isa CTFlows.Hamiltonian
191+
Test.@test poisson_result([1, 2], [3, 4]) isa Real
192+
193+
# Note: * operator is not defined for VectorField * Function
194+
# This is expected behavior based on CTFlows API
195+
end
196+
197+
Test.@testset "Macro with Different Contexts" begin
198+
# Test @Lie macro in different contexts
199+
200+
# Simple case
201+
X1 = CTFlows.VectorField(x -> [x[2], -x[1]])
202+
X2 = CTFlows.VectorField(x -> [x[1], x[2]])
203+
result1 = @Lie [X1, X2]
204+
Test.@test result1 isa CTFlows.VectorField
205+
206+
# Nested case
207+
X3 = CTFlows.VectorField(x -> [2*x[1], 3*x[2]])
208+
result2 = @Lie [[X1, X2], X3]
209+
Test.@test result2 isa CTFlows.VectorField
210+
211+
# With Hamiltonians (Poisson bracket) - returns Hamiltonian
212+
H1 = OptimalControl.Hamiltonian((x, p) -> x[1]*p[1])
213+
H2 = OptimalControl.Hamiltonian((x, p) -> x[2]*p[2])
214+
result3 = @Lie {H1, H2}
215+
Test.@test result3 isa CTFlows.Hamiltonian
216+
end
217+
end
65218
end
66219
end
67220

0 commit comments

Comments
 (0)