Skip to content

Commit 044d677

Browse files
committed
update symbolic derivative performance evaluation
1 parent a34a0a0 commit 044d677

File tree

5 files changed

+187
-20
lines changed

5 files changed

+187
-20
lines changed

benchmarks/benchmark_sym_derivative.py

Lines changed: 147 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,154 @@
33
from pybdr.model import tank6eq, Model
44
from pybdr.util.functional import performance_counter, performance_counter_start
55

6-
if __name__ == "__main__":
7-
m = Model(tank6eq, [6, 1])
86

9-
time_start = performance_counter_start()
10-
x, u = np.random.random(6), np.random.rand(1)
7+
def test_sym_derivative_case_00():
8+
sys_test = tank6eq
9+
dimes = [6, 1]
10+
11+
m = Model(sys_test, dimes)
12+
13+
x_np, u_np = np.random.rand(6), np.random.rand(1)
14+
15+
print()
16+
17+
time_cur = performance_counter_start()
18+
19+
# ----------------------------------------------------------------------
20+
# order 0, for variable 0
21+
22+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0) # Run 1
23+
24+
time_cur = performance_counter(time_cur, 'derivative 00 Run 1')
25+
26+
# 10 runs
27+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
28+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
29+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
30+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
31+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
32+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
33+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
34+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
35+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
36+
np_derivative_00 = m.evaluate((x_np, u_np), 'numpy', 0, 0)
37+
38+
time_cur = performance_counter(time_cur, 'derivative 00 Run 2+ AVG', 10)
39+
40+
# ----------------------------------------------------------------------
41+
# order 0, for variable 1
42+
43+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1) # Run 1
44+
45+
time_cur = performance_counter(time_cur, 'derivative 01 Run 1')
46+
47+
# 10 runs
48+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
49+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
50+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
51+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
52+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
53+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
54+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
55+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
56+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
57+
np_derivative_01 = m.evaluate((x_np, u_np), 'numpy', 0, 1)
58+
59+
time_cur = performance_counter(time_cur, 'derivative 01 Run 2+ AVG', 10)
60+
61+
# ----------------------------------------------------------------------
62+
# order 1, for variable 0
63+
64+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0) # Run 1
65+
66+
time_cur = performance_counter(time_cur, 'derivative 10 Run 1')
67+
68+
# 10 runs
69+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
70+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
71+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
72+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
73+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
74+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
75+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
76+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
77+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
78+
np_derivative_10 = m.evaluate((x_np, u_np), 'numpy', 1, 0)
79+
80+
time_cur = performance_counter(time_cur, 'derivative 10 Run 2+ AVG', 10)
1181

12-
np_derivative_0 = m.evaluate((x, u), "numpy", 3, 0)
13-
np_derivative_1 = m.evaluate((x, u), "numpy", 3, 1)
14-
np_derivative_2 = m.evaluate((x, u), "numpy", 0, 0)
82+
# ----------------------------------------------------------------------
83+
# order 1, for variable 1
1584

16-
x, u = Interval.rand(6), Interval.rand(1)
17-
int_derivative_0 = m.evaluate((x, u), "interval", 3, 0)
18-
int_derivative_1 = m.evaluate((x, u), "interval", 2, 0)
19-
int_derivative_2 = m.evaluate((x, u), "interval", 2, 0)
20-
int_derivative_3 = m.evaluate((x, u), "interval", 0, 1)
85+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1) # Run 1
2186

22-
performance_counter(time_start, "sym_derivative")
23-
87+
time_cur = performance_counter(time_cur, 'derivative 10 Run 1')
88+
89+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
90+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
91+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
92+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
93+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
94+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
95+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
96+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
97+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
98+
np_derivative_11 = m.evaluate((x_np, u_np), 'numpy', 1, 1)
99+
100+
time_cur = performance_counter(time_cur, 'derivative 11 Run 2+ AVG', 10)
101+
102+
# ----------------------------------------------------------------------
103+
# order 3, for variable 0
104+
105+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0) # Run 1
106+
107+
time_cur = performance_counter(time_cur, 'derivative 10 Run 1')
108+
109+
# 10 runs
110+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
111+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
112+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
113+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
114+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
115+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
116+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
117+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
118+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
119+
np_derivative_30 = m.evaluate((x_np, u_np), 'numpy', 3, 0)
120+
121+
time_cur = performance_counter(time_cur, 'derivative 30 Run 2+ AVG', 10)
122+
123+
# ----------------------------------------------------------------------
124+
# order 3, for variable 1
125+
126+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1) # Run 1
127+
128+
time_cur = performance_counter(time_cur, 'derivative 10 Run 1')
129+
130+
# 10 runs
131+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
132+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
133+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
134+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
135+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
136+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
137+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
138+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
139+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
140+
np_derivative_31 = m.evaluate((x_np, u_np), 'numpy', 3, 1)
141+
142+
time_cur = performance_counter(time_cur, 'derivative 31 Run 2+ AVG', 10)
143+
144+
145+
def test_sym_derivative_case_01():
146+
print("test_sym_derivative_case_01")
147+
148+
149+
def test_sym_derivative_case_02():
150+
print("test_sym_derivative_case_02")
151+
152+
153+
if __name__ == "__main__":
154+
test_sym_derivative_case_00()
155+
test_sym_derivative_case_01()
156+
test_sym_derivative_case_02()

pybdr/model/model.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,14 @@ def evaluate(self, xs: tuple, mod: str, order: int, v: int):
7777
self.__take_derivative(order, v)
7878

7979
def _eval_numpy():
80-
if mod not in self.__inr_series[order]:
80+
if mod not in self.__inr_series[order] or v not in self.__inr_series[order][mod]:
81+
self.__inr_series[order][mod] = {}
8182
d = self.__series(order, "sym", v)
8283
d = d if order == 0 else d.squeeze(axis=-1)
8384
d = ImmutableDenseNDimArray(d)
84-
self.__inr_series[order][mod] = {v: lambdify(self.__inr_x, d, "numpy")}
85+
if v not in self.__inr_series[order][mod]:
86+
self.__inr_series[order][mod][v] = lambdify(self.__inr_x, d, "numpy")
87+
# self.__inr_series[order][mod] = {v: lambdify(self.__inr_x, d, "numpy")}
8588
r = np.asarray(self.__series(order, mod, v)(*np.concatenate(xs, axis=-1)))
8689
return r.squeeze(axis=-1) if order == 0 else r
8790

pybdr/util/functional/auxiliary.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,10 @@ def performance_counter_start():
106106
return time.perf_counter_ns()
107107

108108

109-
def performance_counter(start: time.perf_counter_ns(), event: str):
109+
def performance_counter(start: time.perf_counter_ns(), event: str, runs: int = 1):
110+
assert runs >= 1
110111
end = time.perf_counter_ns()
111-
print(event + " cost: {}s".format((end - start) * 1e-9))
112+
print(event + " cost: {}s".format(((end - start) / runs) * 1e-9))
112113
return end
113114

114115

test/algorithm/test_gira2005hscc.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def test_reach_linear_zono_algo3_case_00():
3131

3232
print(len(ri))
3333

34-
# plot(ri, [0, 1])
34+
plot(ri, [0, 1])
3535

3636

3737
def test_reach_linear_zono_algo3_case_01():
@@ -146,6 +146,30 @@ def test_reach_linear_zono_algo3_parallel_case_03():
146146
plot_cmp([ri_whole, ri], [0, 1], cs=["#FF5722", "#303F9F"])
147147

148148

149+
def test_reach_linear_zono_algo3_bound_demo():
150+
xa = [[-1, -4], [4, -1]]
151+
ub = np.array([[1], [1]])
152+
153+
lin_sys = LinSys(xa, ub)
154+
opts = GIRA2005HSCC.Options()
155+
opts.t_end = 0.1
156+
opts.step = 0.1
157+
opts.eta = 4
158+
159+
x0 = Interval(580 * np.ones(2), 620 * np.ones(2))
160+
opts.u = cvt2(ub @ Interval(0.1, 0.3), Geometry.TYPE.ZONOTOPE) # u must contain origin
161+
x0_bounds = boundary(x0, 40, Geometry.TYPE.ZONOTOPE)
162+
163+
print(len(x0_bounds))
164+
165+
_, ri_whole, _, _ = GIRA2005HSCC.reach(lin_sys, opts, cvt2(x0, Geometry.TYPE.ZONOTOPE))
166+
167+
_, ri, _, _ = GIRA2005HSCC.reach_parallel(lin_sys, opts, x0_bounds)
168+
169+
plot(ri_whole, [0, 1])
170+
plot(ri, [0, 1])
171+
172+
149173
def test_reach_linear_zono_algo3_parallel_case_04():
150174
xa = np.array([[-1, -4, 0, 0, 0], [4, -1, 0, 0, 0], [0, 0, -3, 1, 0], [0, 0, -1, -3, 0], [0, 0, 0, 0, -2]])
151175
ub = np.eye(5)
@@ -170,7 +194,7 @@ def test_reach_linear_zono_algo3_parallel_case_04():
170194
# plot_cmp([])
171195

172196

173-
def test_reach_linear_zono_algo3_parallel_case_04():
197+
def test_reach_linear_zono_algo3_parallel_case_05():
174198
time_tag = performance_counter_start()
175199

176200
xa = [[-1, 0], [-1, 1]]

test/geometry/test_interval.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ def test_addition_00():
6565
print(c)
6666

6767

68+
def test_addition_01():
69+
a = Interval.rand(2, 3, 4)
70+
b = a + 1
71+
print(b)
72+
73+
6874
def test_addition_case_01():
6975
from pybdr.geometry import Zonotope
7076
a = Interval.rand(2)

0 commit comments

Comments
 (0)