codac 2.0.0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codac/__init__.py +5 -0
- codac/_core.cp314-win_amd64.pyd +0 -0
- codac/_graphics.cp314-win_amd64.pyd +0 -0
- codac/_unsupported.cp314-win_amd64.pyd +0 -0
- codac/core/__init__.py +459 -0
- codac/graphics/__init__.py +1 -0
- codac/sympy/__init__.py +2 -0
- codac/tests/__init__.py +1 -0
- codac/tests/codac2_tests_predefined_tubes.py +193 -0
- codac/tests/test_AnalyticFunction.py +442 -0
- codac/tests/test_AnalyticTraj.py +62 -0
- codac/tests/test_Approx.py +27 -0
- codac/tests/test_BoolInterval.py +96 -0
- codac/tests/test_Color.py +77 -0
- codac/tests/test_ConvexPolygon.py +300 -0
- codac/tests/test_CtcAction.py +30 -0
- codac/tests/test_CtcCartProd.py +39 -0
- codac/tests/test_CtcCtcBoundary.py +48 -0
- codac/tests/test_CtcDeriv.py +434 -0
- codac/tests/test_CtcEval.py +214 -0
- codac/tests/test_CtcFixpoint.py +65 -0
- codac/tests/test_CtcInter.py +39 -0
- codac/tests/test_CtcInverse.py +213 -0
- codac/tests/test_CtcInverseNotIn.py +129 -0
- codac/tests/test_CtcLazy.py +50 -0
- codac/tests/test_CtcLohner.py +156 -0
- codac/tests/test_CtcPolygon.py +91 -0
- codac/tests/test_CtcSegment.py +104 -0
- codac/tests/test_CtcVisible.py +65 -0
- codac/tests/test_Ellipsoid.py +20 -0
- codac/tests/test_GaussJordan.py +34 -0
- codac/tests/test_IntFullPivLU.py +84 -0
- codac/tests/test_Interval.py +254 -0
- codac/tests/test_IntervalMatrix.py +664 -0
- codac/tests/test_IntervalVector.py +657 -0
- codac/tests/test_Interval_operations.py +293 -0
- codac/tests/test_Matrix.py +80 -0
- codac/tests/test_OctaSym.py +41 -0
- codac/tests/test_Parallelepiped.py +35 -0
- codac/tests/test_Parallelepiped_eval.py +62 -0
- codac/tests/test_Polygon.py +120 -0
- codac/tests/test_SampledTraj.py +135 -0
- codac/tests/test_Segment.py +138 -0
- codac/tests/test_SepCartProd.py +34 -0
- codac/tests/test_SepCtcBoundary.py +52 -0
- codac/tests/test_SepInverse.py +104 -0
- codac/tests/test_SepPolygon.py +102 -0
- codac/tests/test_SepProj.py +39 -0
- codac/tests/test_SepTransform.py +41 -0
- codac/tests/test_SepVisible.py +34 -0
- codac/tests/test_Slice.py +78 -0
- codac/tests/test_Slice_polygon.py +208 -0
- codac/tests/test_SlicedTube.py +562 -0
- codac/tests/test_SlicedTube_integral.py +380 -0
- codac/tests/test_TDomain.py +115 -0
- codac/tests/test_Vector.py +41 -0
- codac/tests/test_arithmetic_add.py +54 -0
- codac/tests/test_arithmetic_div.py +46 -0
- codac/tests/test_arithmetic_mul.py +114 -0
- codac/tests/test_arithmetic_sub.py +54 -0
- codac/tests/test_capd.py +19 -0
- codac/tests/test_cart_prod.py +38 -0
- codac/tests/test_eigen.py +19 -0
- codac/tests/test_geometry.py +136 -0
- codac/tests/test_hull.py +35 -0
- codac/tests/test_ibex.py +19 -0
- codac/tests/test_inversion.py +57 -0
- codac/tests/test_linear_ctc.py +77 -0
- codac/tests/test_operators.py +414 -0
- codac/tests/test_peibos.py +83 -0
- codac/tests/test_peibos_capd.py +19 -0
- codac/tests/test_predefined_tubes.py +193 -0
- codac/tests/test_serialization.py +30 -0
- codac/tests/test_sympy.py +234 -0
- codac/tests/test_transformations.py +61 -0
- codac/tests/test_trunc.py +95 -0
- codac/unsupported/__init__.py +1 -0
- codac/version.py +1 -0
- codac-2.0.0.dist-info/METADATA +23 -0
- codac-2.0.0.dist-info/RECORD +82 -0
- codac-2.0.0.dist-info/WHEEL +5 -0
- codac-2.0.0.dist-info/top_level.txt +1 -0
codac/__init__.py
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
codac/core/__init__.py
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# Codac Python binding - main file
|
|
2
|
+
# ----------------------------------------------------------------------------
|
|
3
|
+
# \date 2026
|
|
4
|
+
# \author Simon Rohou
|
|
5
|
+
# \copyright Copyright 2026 Codac Team
|
|
6
|
+
# \license GNU Lesser General Public License (LGPL)
|
|
7
|
+
|
|
8
|
+
from codac._core import *
|
|
9
|
+
import sys
|
|
10
|
+
import warnings
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import numpy as _np
|
|
14
|
+
except ImportError:
|
|
15
|
+
_np = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def codac_error(message):
|
|
19
|
+
print(f'''
|
|
20
|
+
=============================================================================
|
|
21
|
+
The following Codac assertion failed:
|
|
22
|
+
|
|
23
|
+
{message}
|
|
24
|
+
|
|
25
|
+
You need help? Submit an issue on: https://github.com/codac-team/codac/issues
|
|
26
|
+
=============================================================================
|
|
27
|
+
''')
|
|
28
|
+
raise ValueError("")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
_ANALYTIC_FUNCTION_TYPES = (
|
|
32
|
+
AnalyticFunction_Scalar,
|
|
33
|
+
AnalyticFunction_Vector,
|
|
34
|
+
AnalyticFunction_Matrix,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
_SLICEDTUBE_TYPES = (
|
|
38
|
+
SlicedTube_Interval,
|
|
39
|
+
SlicedTube_IntervalVector,
|
|
40
|
+
SlicedTube_IntervalMatrix,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
_ANALYTIC_TRAJ_TYPES = (
|
|
44
|
+
AnalyticTraj_Scalar,
|
|
45
|
+
AnalyticTraj_Vector,
|
|
46
|
+
AnalyticTraj_Matrix,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
_SAMPLED_TRAJ_TYPES = (
|
|
50
|
+
SampledTraj_Scalar,
|
|
51
|
+
SampledTraj_Vector,
|
|
52
|
+
SampledTraj_Matrix,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def _is_scalar_expr_like(x):
|
|
56
|
+
return isinstance(x, (int, float, Interval, ScalarVar, ScalarExpr))
|
|
57
|
+
|
|
58
|
+
def _is_vector_expr_like(x):
|
|
59
|
+
return isinstance(x, (Vector, IntervalVector, VectorVar, VectorExpr))
|
|
60
|
+
|
|
61
|
+
def _is_matrix_expr_like(x):
|
|
62
|
+
return isinstance(x, (Matrix, IntervalMatrix, MatrixVar, MatrixExpr))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _to_function_argument_expr(x):
|
|
66
|
+
if _is_scalar_expr_like(x):
|
|
67
|
+
return ScalarExpr(x)
|
|
68
|
+
if _is_vector_expr_like(x):
|
|
69
|
+
return VectorExpr(x)
|
|
70
|
+
if _is_matrix_expr_like(x):
|
|
71
|
+
return MatrixExpr(x)
|
|
72
|
+
codac_error("AnalyticFunction: invalid input arguments")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def AnalyticFunction(args, e=None):
|
|
76
|
+
if e is None:
|
|
77
|
+
if isinstance(args, _ANALYTIC_FUNCTION_TYPES):
|
|
78
|
+
return args
|
|
79
|
+
codac_error("AnalyticFunction: invalid function argument")
|
|
80
|
+
|
|
81
|
+
if _is_scalar_expr_like(e):
|
|
82
|
+
return AnalyticFunction_Scalar(args, ScalarExpr(e))
|
|
83
|
+
|
|
84
|
+
if _is_vector_expr_like(e):
|
|
85
|
+
return AnalyticFunction_Vector(args, VectorExpr(e))
|
|
86
|
+
|
|
87
|
+
if _is_matrix_expr_like(e):
|
|
88
|
+
return AnalyticFunction_Matrix(args, MatrixExpr(e))
|
|
89
|
+
|
|
90
|
+
if isinstance(e, list):
|
|
91
|
+
lst = []
|
|
92
|
+
for e_i in e:
|
|
93
|
+
if _is_scalar_expr_like(e_i):
|
|
94
|
+
lst.append(ScalarExpr(e_i))
|
|
95
|
+
else:
|
|
96
|
+
codac_error("AnalyticFunction: invalid vectorial expression")
|
|
97
|
+
return AnalyticFunction_Vector(args, lst)
|
|
98
|
+
|
|
99
|
+
codac_error("AnalyticFunction: can only build functions from scalar or vector expressions")
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _make_variadic_analytic_function_call(cpp_call):
|
|
103
|
+
def _call(self, *args):
|
|
104
|
+
if len(args) == 1 and isinstance(args[0], list):
|
|
105
|
+
args = tuple(args[0])
|
|
106
|
+
|
|
107
|
+
lst = []
|
|
108
|
+
for arg in args:
|
|
109
|
+
lst.append(_to_function_argument_expr(arg))
|
|
110
|
+
return cpp_call(self, lst)
|
|
111
|
+
|
|
112
|
+
return _call
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
for _cls in _ANALYTIC_FUNCTION_TYPES:
|
|
116
|
+
_cls._codac_python_cpp_call = _cls.__call__
|
|
117
|
+
_cls.__call__ = _make_variadic_analytic_function_call(_cls._codac_python_cpp_call)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Ctc_IntervalVector(Ctc_IntervalVector_):
|
|
121
|
+
|
|
122
|
+
def __init__(self, n):
|
|
123
|
+
Ctc_IntervalVector_.__init__(self, n)
|
|
124
|
+
|
|
125
|
+
def copy(self):
|
|
126
|
+
return super().copy()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class Sep(SepBase):
|
|
130
|
+
|
|
131
|
+
def copy(self):
|
|
132
|
+
return super().copy()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def CtcInverse(f, y, with_centered_form=True):
|
|
136
|
+
f = AnalyticFunction(f)
|
|
137
|
+
|
|
138
|
+
if isinstance(f, AnalyticFunction_Scalar):
|
|
139
|
+
return CtcInverse_Interval(f, y, with_centered_form)
|
|
140
|
+
|
|
141
|
+
if isinstance(f, AnalyticFunction_Vector):
|
|
142
|
+
return CtcInverse_IntervalVector(f, y, with_centered_form)
|
|
143
|
+
|
|
144
|
+
codac_error("CtcInverse: can only build CtcInverse from scalar or vector functions")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def CtcInverseNotIn(f, y, with_centered_form=True):
|
|
148
|
+
f = AnalyticFunction(f)
|
|
149
|
+
|
|
150
|
+
if isinstance(f, AnalyticFunction_Scalar):
|
|
151
|
+
return CtcInverseNotIn_Interval(f, y, with_centered_form)
|
|
152
|
+
|
|
153
|
+
if isinstance(f, AnalyticFunction_Vector):
|
|
154
|
+
return CtcInverseNotIn_IntervalVector(f, y, with_centered_form)
|
|
155
|
+
|
|
156
|
+
codac_error("CtcInverseNotIn: can only build CtcInverseNotIn from scalar or vector functions")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def Approx(x, eps=sys.float_info.epsilon*10):
|
|
160
|
+
if isinstance(x, (int, float)):
|
|
161
|
+
return Approx_double(x, eps)
|
|
162
|
+
elif isinstance(x, Interval):
|
|
163
|
+
return Approx_Interval(x, eps)
|
|
164
|
+
elif isinstance(x, Vector):
|
|
165
|
+
return Approx_Vector(x, eps)
|
|
166
|
+
elif isinstance(x, IntervalVector):
|
|
167
|
+
return Approx_IntervalVector(x, eps)
|
|
168
|
+
elif isinstance(x, Matrix):
|
|
169
|
+
return Approx_Matrix(x, eps)
|
|
170
|
+
elif isinstance(x, IntervalMatrix):
|
|
171
|
+
return Approx_IntervalMatrix(x, eps)
|
|
172
|
+
elif isinstance(x, Segment):
|
|
173
|
+
return Approx_Segment(x, eps)
|
|
174
|
+
elif isinstance(x, (Polygon, ConvexPolygon)):
|
|
175
|
+
return Approx_Polygon(x, eps)
|
|
176
|
+
elif isinstance(x, tuple) and len(x) == 2 and isinstance(x[0], Interval) and isinstance(x[1], Interval):
|
|
177
|
+
return Approx_pair_Interval(x, eps)
|
|
178
|
+
else:
|
|
179
|
+
codac_error("Approx: invalid input")
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def hull(*args):
|
|
183
|
+
# -1: to be defined, 0: IntervalVector, 1: IntervalMatrix
|
|
184
|
+
lst = []
|
|
185
|
+
mode = -1
|
|
186
|
+
|
|
187
|
+
for arg in args:
|
|
188
|
+
if isinstance(arg, (Vector)):
|
|
189
|
+
mode = 0
|
|
190
|
+
lst.append(IntervalVector(arg))
|
|
191
|
+
elif isinstance(arg, (IntervalVector)):
|
|
192
|
+
mode = 0
|
|
193
|
+
lst.append(arg)
|
|
194
|
+
elif isinstance(arg, (Matrix)):
|
|
195
|
+
mode = 1
|
|
196
|
+
lst.append(IntervalMatrix(arg))
|
|
197
|
+
elif isinstance(arg, (IntervalMatrix)):
|
|
198
|
+
mode = 1
|
|
199
|
+
lst.append(arg)
|
|
200
|
+
elif isinstance(arg, (list)):
|
|
201
|
+
if isinstance(arg[0], (IntervalVector)):
|
|
202
|
+
return hull_intervalvector(arg)
|
|
203
|
+
elif isinstance(arg[0], (IntervalMatrix)):
|
|
204
|
+
return hull_intervalmatrix(arg)
|
|
205
|
+
else:
|
|
206
|
+
codac_error("hull: invalid input arguments")
|
|
207
|
+
else:
|
|
208
|
+
codac_error("hull: invalid input arguments")
|
|
209
|
+
|
|
210
|
+
if mode == 0:
|
|
211
|
+
return hull_intervalvector(lst)
|
|
212
|
+
return hull_intervalmatrix(lst)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def cart_prod(*args):
|
|
216
|
+
# -1: to be defined, 0: vector, 1: intervalvector, 2: ctc, 3: sep
|
|
217
|
+
lst = []
|
|
218
|
+
mode = -1
|
|
219
|
+
|
|
220
|
+
for arg in args:
|
|
221
|
+
|
|
222
|
+
if isinstance(arg, (int, float, Vector)):
|
|
223
|
+
if mode == -1:
|
|
224
|
+
mode = 0
|
|
225
|
+
|
|
226
|
+
elif isinstance(arg, (list, Interval, IntervalVector)):
|
|
227
|
+
if mode != 2 and mode != 3:
|
|
228
|
+
mode = 1
|
|
229
|
+
|
|
230
|
+
elif isinstance(arg, (Ctc_IntervalVector, Ctc_IntervalVector_)):
|
|
231
|
+
mode = 2
|
|
232
|
+
|
|
233
|
+
elif isinstance(arg, (Sep, SepBase)):
|
|
234
|
+
mode = 3
|
|
235
|
+
|
|
236
|
+
else:
|
|
237
|
+
codac_error("cart_prod: invalid input arguments (a/" + str(mode) + ", " + str(arg) + ")")
|
|
238
|
+
|
|
239
|
+
for arg in args:
|
|
240
|
+
|
|
241
|
+
if isinstance(arg, (int, float)):
|
|
242
|
+
if mode == 0:
|
|
243
|
+
lst.append(Vector([arg]))
|
|
244
|
+
elif mode == 1:
|
|
245
|
+
lst.append(IntervalVector(Vector([arg])))
|
|
246
|
+
elif mode == 2:
|
|
247
|
+
lst.append(CtcWrapper(IntervalVector([arg])))
|
|
248
|
+
elif mode == 3:
|
|
249
|
+
lst.append(SepWrapper(IntervalVector([arg])))
|
|
250
|
+
else:
|
|
251
|
+
codac_error("cart_prod: invalid input arguments (b/" + str(mode) + ")")
|
|
252
|
+
|
|
253
|
+
elif isinstance(arg, (Vector)):
|
|
254
|
+
if mode == 0:
|
|
255
|
+
lst.append(arg)
|
|
256
|
+
elif mode == 1:
|
|
257
|
+
lst.append(IntervalVector(arg))
|
|
258
|
+
elif mode == 2:
|
|
259
|
+
lst.append(CtcWrapper(IntervalVector(arg)))
|
|
260
|
+
elif mode == 3:
|
|
261
|
+
lst.append(SepWrapper(IntervalVector(arg)))
|
|
262
|
+
else:
|
|
263
|
+
codac_error("cart_prod: invalid input arguments (c/" + str(mode) + ")")
|
|
264
|
+
|
|
265
|
+
elif isinstance(arg, (Interval)) or (isinstance(arg, list) and not isinstance(arg[0], list)):
|
|
266
|
+
if mode == 1:
|
|
267
|
+
lst.append(IntervalVector([arg]))
|
|
268
|
+
elif mode == 2:
|
|
269
|
+
lst.append(CtcWrapper(IntervalVector([arg])))
|
|
270
|
+
elif mode == 3:
|
|
271
|
+
lst.append(SepWrapper(IntervalVector([arg])))
|
|
272
|
+
else:
|
|
273
|
+
codac_error("cart_prod: invalid input arguments (d/" + str(mode) + ")")
|
|
274
|
+
|
|
275
|
+
elif isinstance(arg, (list, IntervalVector)) or (isinstance(arg, list) and isinstance(arg[0], list)):
|
|
276
|
+
if mode == 1:
|
|
277
|
+
lst.append(IntervalVector(arg))
|
|
278
|
+
elif mode == 2:
|
|
279
|
+
lst.append(CtcWrapper(IntervalVector(arg)))
|
|
280
|
+
elif mode == 3:
|
|
281
|
+
lst.append(SepWrapper(IntervalVector(arg)))
|
|
282
|
+
else:
|
|
283
|
+
codac_error("cart_prod: invalid input arguments (e/" + str(mode) + ")")
|
|
284
|
+
|
|
285
|
+
elif isinstance(arg, (Ctc_IntervalVector, Ctc_IntervalVector_)):
|
|
286
|
+
if mode != 2:
|
|
287
|
+
codac_error("cart_prod: invalid input arguments (f/" + str(mode) + ")")
|
|
288
|
+
lst.append(arg)
|
|
289
|
+
|
|
290
|
+
elif isinstance(arg, (Sep, SepBase)):
|
|
291
|
+
if mode != 3:
|
|
292
|
+
codac_error("cart_prod: invalid input arguments (g/" + str(mode) + ")")
|
|
293
|
+
lst.append(arg)
|
|
294
|
+
|
|
295
|
+
else:
|
|
296
|
+
mode = -2 # will generate an error
|
|
297
|
+
|
|
298
|
+
if mode == 0:
|
|
299
|
+
return cart_prod_vector(lst)
|
|
300
|
+
if mode == 1:
|
|
301
|
+
return cart_prod_intervalvector(lst)
|
|
302
|
+
if mode == 2:
|
|
303
|
+
return cart_prod_ctc(lst)
|
|
304
|
+
if mode == 3:
|
|
305
|
+
return cart_prod_sep(lst)
|
|
306
|
+
codac_error("cart_prod: invalid input arguments (h/" + str(mode) + ")")
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def tube_cart_prod(*x):
|
|
310
|
+
if not isinstance(x, tuple):
|
|
311
|
+
return tube_cart_prod_list([x])
|
|
312
|
+
return tube_cart_prod_list([*x])
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def traj_cart_prod(*x):
|
|
316
|
+
if not isinstance(x, tuple):
|
|
317
|
+
return traj_cart_prod_list([x])
|
|
318
|
+
return traj_cart_prod_list([*x])
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _sampled_traj_type_and_value(x):
|
|
322
|
+
if isinstance(x, (int, float)):
|
|
323
|
+
return SampledTraj_Scalar, float
|
|
324
|
+
|
|
325
|
+
if isinstance(x, Vector) \
|
|
326
|
+
or (_np is not None and isinstance(x, _np.ndarray) and x.ndim == 1) \
|
|
327
|
+
or (isinstance(x, (list, tuple)) and (len(x) == 0 or not isinstance(x[0], (list, tuple)))):
|
|
328
|
+
return SampledTraj_Vector, lambda y: y if isinstance(y, Vector) else Vector(y)
|
|
329
|
+
|
|
330
|
+
if isinstance(x, Matrix) \
|
|
331
|
+
or (_np is not None and isinstance(x, _np.ndarray) and x.ndim == 2) \
|
|
332
|
+
or (isinstance(x, (list, tuple)) and len(x) > 0 and isinstance(x[0], (list, tuple))):
|
|
333
|
+
return SampledTraj_Matrix, lambda y: y if isinstance(y, Matrix) else Matrix(y)
|
|
334
|
+
|
|
335
|
+
return None, None
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def SampledTraj(x=None, y=None):
|
|
339
|
+
if y is None:
|
|
340
|
+
if x is None:
|
|
341
|
+
codac_error("SampledTraj: unable to deduce the trajectory type from an empty constructor")
|
|
342
|
+
|
|
343
|
+
for cls in _SAMPLED_TRAJ_TYPES:
|
|
344
|
+
if isinstance(x, cls):
|
|
345
|
+
return cls(dict(x))
|
|
346
|
+
|
|
347
|
+
if isinstance(x, dict):
|
|
348
|
+
if not x:
|
|
349
|
+
codac_error("SampledTraj: unable to deduce the trajectory type from an empty map")
|
|
350
|
+
cls, cast = _sampled_traj_type_and_value(next(iter(x.values())))
|
|
351
|
+
if cls is None:
|
|
352
|
+
codac_error("SampledTraj: wrong constructor argument")
|
|
353
|
+
return cls({float(t): cast(v) for t, v in x.items()})
|
|
354
|
+
|
|
355
|
+
codac_error("SampledTraj: wrong constructor argument")
|
|
356
|
+
|
|
357
|
+
if len(y) == 0:
|
|
358
|
+
codac_error("SampledTraj: unable to deduce the trajectory type from empty samples")
|
|
359
|
+
|
|
360
|
+
cls, cast = _sampled_traj_type_and_value(y[0])
|
|
361
|
+
if cls is None:
|
|
362
|
+
codac_error("SampledTraj: unable to deduce the trajectory type from the provided samples")
|
|
363
|
+
|
|
364
|
+
if cls is SampledTraj_Scalar:
|
|
365
|
+
return cls(list(x), [float(v) for v in y])
|
|
366
|
+
|
|
367
|
+
if cls is SampledTraj_Vector and _np is not None and isinstance(x, _np.ndarray) and isinstance(y, _np.ndarray):
|
|
368
|
+
return cls(x, y)
|
|
369
|
+
|
|
370
|
+
return cls({float(t): cast(v) for t, v in zip(x, y)})
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def AnalyticTraj(t,f):
|
|
374
|
+
|
|
375
|
+
if isinstance(t, _ANALYTIC_FUNCTION_TYPES) and not isinstance(f, _ANALYTIC_FUNCTION_TYPES):
|
|
376
|
+
warnings.warn(
|
|
377
|
+
"AnalyticTraj(f,t) is deprecated; use AnalyticTraj(t,f) instead.",
|
|
378
|
+
FutureWarning,
|
|
379
|
+
stacklevel=2
|
|
380
|
+
)
|
|
381
|
+
t,f = f,t
|
|
382
|
+
|
|
383
|
+
f = AnalyticFunction(f)
|
|
384
|
+
|
|
385
|
+
if isinstance(f, AnalyticFunction_Scalar):
|
|
386
|
+
return AnalyticTraj_Scalar(t,f)
|
|
387
|
+
|
|
388
|
+
if isinstance(f, AnalyticFunction_Vector):
|
|
389
|
+
return AnalyticTraj_Vector(t,f)
|
|
390
|
+
|
|
391
|
+
if isinstance(f, AnalyticFunction_Matrix):
|
|
392
|
+
return AnalyticTraj_Matrix(t,f)
|
|
393
|
+
|
|
394
|
+
codac_error("AnalyticTraj: can only build this trajectory from an AnalyticFunction_[Scalar/Vector/Matrix]")
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def SlicedTube(x, y=None):
|
|
398
|
+
|
|
399
|
+
if y is None:
|
|
400
|
+
if isinstance(x, SlicedTube_Interval):
|
|
401
|
+
return SlicedTube_Interval(x)
|
|
402
|
+
if isinstance(x, SlicedTube_IntervalVector):
|
|
403
|
+
return SlicedTube_IntervalVector(x)
|
|
404
|
+
if isinstance(x, SlicedTube_IntervalMatrix):
|
|
405
|
+
return SlicedTube_IntervalMatrix(x)
|
|
406
|
+
codac_error("SlicedTube: unable to copy this tube from another one")
|
|
407
|
+
|
|
408
|
+
y = AnalyticFunction(y) if isinstance(y, _ANALYTIC_FUNCTION_TYPES) else y
|
|
409
|
+
|
|
410
|
+
if isinstance(y, (Interval, AnalyticFunction_Scalar, AnalyticTraj_Scalar, SampledTraj_Scalar)):
|
|
411
|
+
return SlicedTube_Interval(x, y)
|
|
412
|
+
|
|
413
|
+
if isinstance(y, (IntervalVector, AnalyticFunction_Vector, AnalyticTraj_Vector, SampledTraj_Vector)):
|
|
414
|
+
return SlicedTube_IntervalVector(x, y)
|
|
415
|
+
|
|
416
|
+
if isinstance(y, (IntervalMatrix, AnalyticFunction_Matrix, AnalyticTraj_Matrix, SampledTraj_Matrix)):
|
|
417
|
+
return SlicedTube_IntervalMatrix(x, y)
|
|
418
|
+
|
|
419
|
+
codac_error("SlicedTube: wrong constructor argument")
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def fixpoint(contract, *x):
|
|
423
|
+
vol = -1.0
|
|
424
|
+
prev_vol = None
|
|
425
|
+
|
|
426
|
+
while vol != prev_vol:
|
|
427
|
+
|
|
428
|
+
prev_vol = vol
|
|
429
|
+
if type(x) is tuple:
|
|
430
|
+
x = contract(*x)
|
|
431
|
+
else: # prevent from unpacking
|
|
432
|
+
x = contract(x)
|
|
433
|
+
|
|
434
|
+
# For computing the volume:
|
|
435
|
+
# only a real Python tuple is considered as a collection of objects.
|
|
436
|
+
# Otherwise, any iterable object (tube, boxes, etc.) will be divided in the for loop.
|
|
437
|
+
items = x if type(x) is tuple else (x,)
|
|
438
|
+
|
|
439
|
+
vol = 0.0
|
|
440
|
+
for xi in items:
|
|
441
|
+
if xi.is_empty():
|
|
442
|
+
return x
|
|
443
|
+
w = xi.volume()
|
|
444
|
+
# As infinity is absorbent, this would not
|
|
445
|
+
# allow us to identify a contraction, so we
|
|
446
|
+
# exclude these cases:
|
|
447
|
+
if w != oo:
|
|
448
|
+
vol += w
|
|
449
|
+
|
|
450
|
+
return x
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
# Deprecated function draw_while_paving(..)
|
|
454
|
+
draw_while_paving = lambda *args, **kwargs: (_ for _ in ()).throw(
|
|
455
|
+
NotImplementedError(
|
|
456
|
+
"draw_while_paving(..) is deprecated,\n "
|
|
457
|
+
" please replace by DefaultFigure.pave(..) (or any Figure2D object)"
|
|
458
|
+
)
|
|
459
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from codac._graphics import *
|
codac/sympy/__init__.py
ADDED
codac/tests/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Codac tests are placed in this folder (see python/CMakeLists.txt)
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
from codac import *
|
|
2
|
+
|
|
3
|
+
def tube_test_1():
|
|
4
|
+
|
|
5
|
+
x = SlicedTube(create_tdomain([0.,46.], 1., False), Interval())
|
|
6
|
+
x.set_ith_slice([4,8], 0)
|
|
7
|
+
x.set_ith_slice([2,7], 1)
|
|
8
|
+
x.set_ith_slice([1,6], 2)
|
|
9
|
+
x.set_ith_slice([-4,4], 3)
|
|
10
|
+
x.set_ith_slice([-7,-1], 4)
|
|
11
|
+
x.set_ith_slice([-9,-5], 5)
|
|
12
|
+
x.set_ith_slice([-10,-6], 6)
|
|
13
|
+
x.set_ith_slice([-11,-7], 7)
|
|
14
|
+
x.set_ith_slice([-10,-6], 8)
|
|
15
|
+
x.set_ith_slice([-9,-4], 9)
|
|
16
|
+
x.set_ith_slice([-8,-5], 10)
|
|
17
|
+
x.set_ith_slice([-7,-4], 11)
|
|
18
|
+
x.set_ith_slice([-6,-2], 12)
|
|
19
|
+
x.set_ith_slice([-5,-1], 13)
|
|
20
|
+
x.set_ith_slice([-5,3], 14) # to be updated
|
|
21
|
+
x.set_ith_slice([-2,4], 15)
|
|
22
|
+
x.set_ith_slice([0,6], 16)
|
|
23
|
+
x.set_ith_slice([2,7], 17)
|
|
24
|
+
x.set_ith_slice([4,8], 18)
|
|
25
|
+
x.set_ith_slice([6,9], 19)
|
|
26
|
+
x.set_ith_slice([7,10], 20)
|
|
27
|
+
x.set_ith_slice([8,11], 21)
|
|
28
|
+
x.set_ith_slice([9,12], 22)
|
|
29
|
+
x.set_ith_slice([8,13], 23)
|
|
30
|
+
x.set_ith_slice([7,12], 24)
|
|
31
|
+
x.set_ith_slice([5,11], 25)
|
|
32
|
+
x.set_ith_slice([3,10], 26)
|
|
33
|
+
x.set_ith_slice([4,9], 27)
|
|
34
|
+
x.set_ith_slice([5,8], 28)
|
|
35
|
+
x.set_ith_slice([4,7], 29)
|
|
36
|
+
x.set_ith_slice([3,6], 30)
|
|
37
|
+
x.set_ith_slice([3,5], 31)
|
|
38
|
+
x.set_ith_slice([2,5], 32)
|
|
39
|
+
x.set_ith_slice([2,5], 33)
|
|
40
|
+
x.set_ith_slice([1,5], 34)
|
|
41
|
+
x.set_ith_slice([2,4], 35)
|
|
42
|
+
x.set_ith_slice([1,4], 36)
|
|
43
|
+
x.set_ith_slice([0,4], 37)
|
|
44
|
+
x.set_ith_slice([-1,3], 38)
|
|
45
|
+
x.set_ith_slice([-1,3], 39)
|
|
46
|
+
x.set_ith_slice([-1,4], 40)
|
|
47
|
+
x.set_ith_slice([0,5], 41)
|
|
48
|
+
x.set_ith_slice([1,6], 42)
|
|
49
|
+
x.set_ith_slice([0,5], 43)
|
|
50
|
+
x.set_ith_slice([-1,4], 44)
|
|
51
|
+
x.set_ith_slice([-1,3], 45)
|
|
52
|
+
return x
|
|
53
|
+
|
|
54
|
+
def tube_test_1_01():
|
|
55
|
+
|
|
56
|
+
x = SlicedTube(create_tdomain([0.,46.], 0.5, False), Interval())
|
|
57
|
+
|
|
58
|
+
x.set([4,8], [0,1])
|
|
59
|
+
x.set([2,7], [1,2])
|
|
60
|
+
x.set([1,6], [2,3])
|
|
61
|
+
x.set([-4,4], [3,4])
|
|
62
|
+
x.set([-7,-1], [4,5])
|
|
63
|
+
x.set([-9,-5], [5,6])
|
|
64
|
+
x.set([-10,-6], [6,7])
|
|
65
|
+
x.set([-11,-7], [7,8])
|
|
66
|
+
x.set([-10,-6], [8,9])
|
|
67
|
+
x.set([-9,-4], [9,10])
|
|
68
|
+
x.set([-8,-5], [10,11])
|
|
69
|
+
x.set([-7,-4], [11,12])
|
|
70
|
+
x.set([-6,-2], [12,13])
|
|
71
|
+
x.set([-5,-1], [13,14])
|
|
72
|
+
x.set([-4,2], [14,15])
|
|
73
|
+
x.set([-2,4], [15,16])
|
|
74
|
+
x.set([0,6], [16,17])
|
|
75
|
+
x.set([2,7], [17,18])
|
|
76
|
+
x.set([4,8], [18,19])
|
|
77
|
+
x.set([6,9], [19,20])
|
|
78
|
+
x.set([7,10], [20,21])
|
|
79
|
+
x.set([8,11], [21,22])
|
|
80
|
+
x.set([9,12], [22,23])
|
|
81
|
+
x.set([8,13], [23,24])
|
|
82
|
+
x.set([7,12], [24,25])
|
|
83
|
+
x.set([5,11], [25,26])
|
|
84
|
+
x.set([3,10], [26,27])
|
|
85
|
+
x.set([4,9], [27,28])
|
|
86
|
+
x.set([5,8], [28,29])
|
|
87
|
+
x.set([4,7], [29,30])
|
|
88
|
+
x.set([3,6], [30,31])
|
|
89
|
+
x.set([3,5], [31,32])
|
|
90
|
+
x.set([2,5], [32,33])
|
|
91
|
+
x.set([2,5], [33,34])
|
|
92
|
+
x.set([1,5], [34,35])
|
|
93
|
+
x.set([2,4], [35,36])
|
|
94
|
+
x.set([1,4], [36,37])
|
|
95
|
+
x.set([0,4], [37,38])
|
|
96
|
+
x.set([-1,3], [38,39])
|
|
97
|
+
x.set([-1,3], [39,40])
|
|
98
|
+
x.set([-1,4], [40,41])
|
|
99
|
+
x.set([0,5], [41,42])
|
|
100
|
+
x.set([1,6], [42,43])
|
|
101
|
+
x.set([0,5], [43,44])
|
|
102
|
+
x.set([-1,4], [44,45])
|
|
103
|
+
x.set([-1,3], [45,46])
|
|
104
|
+
return x
|
|
105
|
+
|
|
106
|
+
def tube_test2():
|
|
107
|
+
|
|
108
|
+
x = SlicedTube(create_tdomain([0.,46.], 1., False), Interval())
|
|
109
|
+
|
|
110
|
+
x.set_ith_slice([-2,0], 0)
|
|
111
|
+
x.set_ith_slice([-3,1], 1)
|
|
112
|
+
x.set_ith_slice([-1,3], 2)
|
|
113
|
+
x.set_ith_slice([2,4], 3)
|
|
114
|
+
x.set_ith_slice([3,5], 4)
|
|
115
|
+
x.set_ith_slice([2,6], 5)
|
|
116
|
+
x.set_ith_slice([2,5], 6)
|
|
117
|
+
x.set_ith_slice([1,4], 7)
|
|
118
|
+
x.set_ith_slice([1,3], 8)
|
|
119
|
+
x.set_ith_slice([2,3], 9)
|
|
120
|
+
x.set_ith_slice([2,4], 10)
|
|
121
|
+
x.set_ith_slice([1,3], 11)
|
|
122
|
+
x.set_ith_slice([0,2], 12)
|
|
123
|
+
x.set_ith_slice([-1,2], 13)
|
|
124
|
+
x.set_ith_slice([-2,1], 14)
|
|
125
|
+
x.set_ith_slice([-3,0], 15)
|
|
126
|
+
x.set_ith_slice([-2,0], 16)
|
|
127
|
+
x.set_ith_slice([-1,1], 17)
|
|
128
|
+
x.set_ith_slice([0,2], 18)
|
|
129
|
+
x.set_ith_slice([1,3], 19)
|
|
130
|
+
x.set_ith_slice([1,4], 20)
|
|
131
|
+
x.set_ith_slice([2,5], 21)
|
|
132
|
+
x.set_ith_slice([2,4], 22)
|
|
133
|
+
x.set_ith_slice([1,3], 23)
|
|
134
|
+
x.set_ith_slice([0,2], 24)
|
|
135
|
+
x.set_ith_slice([0,2], 25)
|
|
136
|
+
x.set_ith_slice([0,2], 26)
|
|
137
|
+
x.set_ith_slice([1,2], 27)
|
|
138
|
+
x.set_ith_slice([1,3], 28)
|
|
139
|
+
x.set_ith_slice([0,3], 29)
|
|
140
|
+
x.set_ith_slice([-1,2], 30)
|
|
141
|
+
x.set_ith_slice([-2,1], 31)
|
|
142
|
+
x.set_ith_slice([-3,0], 32)
|
|
143
|
+
x.set_ith_slice([-4,-1], 33)
|
|
144
|
+
x.set_ith_slice([-4,-2], 34)
|
|
145
|
+
x.set_ith_slice([-3,-1], 35)
|
|
146
|
+
x.set_ith_slice([-4,-2], 36)
|
|
147
|
+
x.set_ith_slice([-4,-2], 37)
|
|
148
|
+
x.set_ith_slice([-4,-2], 38)
|
|
149
|
+
x.set_ith_slice([-3,-1], 39)
|
|
150
|
+
x.set_ith_slice([-3,-1], 40)
|
|
151
|
+
x.set_ith_slice([-2,-1], 41)
|
|
152
|
+
x.set_ith_slice([-1,1], 42)
|
|
153
|
+
x.set_ith_slice([-1,1], 43)
|
|
154
|
+
x.set_ith_slice([0,2], 44)
|
|
155
|
+
x.set_ith_slice([1,3], 45)
|
|
156
|
+
return x
|
|
157
|
+
|
|
158
|
+
def tube_test3():
|
|
159
|
+
|
|
160
|
+
x = SlicedTube(create_tdomain([0.,5.], 1., False), Interval())
|
|
161
|
+
|
|
162
|
+
x.set_ith_slice([1,3], 0)
|
|
163
|
+
x.set_ith_slice([0,2], 1)
|
|
164
|
+
x.set_ith_slice([-1,1], 2)
|
|
165
|
+
x.set_ith_slice([-2,0], 3)
|
|
166
|
+
x.set_ith_slice([-3,-1], 4)
|
|
167
|
+
return x
|
|
168
|
+
|
|
169
|
+
def tube_test4():
|
|
170
|
+
|
|
171
|
+
x = SlicedTube(create_tdomain([0.,21.], 1., False), Interval())
|
|
172
|
+
|
|
173
|
+
x.set([1,2], [0,9])
|
|
174
|
+
x.set([0.5,1.5], [9,11])
|
|
175
|
+
x.set([-1,1], [10.2]) # degenerate time interval
|
|
176
|
+
x.set([-1.5,-0.5], [11,12])
|
|
177
|
+
x.set([-1,1], [12,13])
|
|
178
|
+
x.set([0.5,1.5], [13,14])
|
|
179
|
+
x.set([1,2], [14,21])
|
|
180
|
+
return x
|
|
181
|
+
|
|
182
|
+
def tube_test4_05():
|
|
183
|
+
|
|
184
|
+
x = SlicedTube(create_tdomain([0.,21.], 0.5, False), Interval())
|
|
185
|
+
|
|
186
|
+
x.set([1,2], [0,9])
|
|
187
|
+
x.set([0.5,1.5], [9,10])
|
|
188
|
+
x.set([-1,1], [10,11])
|
|
189
|
+
x.set([-1.5,-0.5], [11,12])
|
|
190
|
+
x.set([-1,1], [12,13])
|
|
191
|
+
x.set([0.5,1.5], [13,14])
|
|
192
|
+
x.set([1,2], [14,21])
|
|
193
|
+
return x
|