casadi 3.6.7__cp27-none-manylinux2010_x86_64.whl → 3.7.0__cp27-none-manylinux2010_x86_64.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.
Files changed (211) hide show
  1. casadi/_casadi.so +0 -0
  2. casadi/casadi-cli +0 -0
  3. casadi/casadi.py +6068 -3036
  4. casadi/cbc +0 -0
  5. casadi/clp +0 -0
  6. casadi/cmake/casadi-config-version.cmake +1 -1
  7. casadi/cmake/casadi-targets-release.cmake +5 -5
  8. casadi/cmake/casadi-targets.cmake +5 -5
  9. casadi/{lib64/cmake/tinyxml2/tinyxml2-config-version.cmake → cmake/libzip/libzip-config-version.cmake} +4 -18
  10. casadi/cmake/libzip/libzip-config.cmake +69 -0
  11. casadi/cmake/libzip/libzip-targets-release.cmake +19 -0
  12. casadi/{lib64/cmake/tinyxml2/tinyxml2-static-targets.cmake → cmake/libzip/libzip-targets.cmake} +11 -7
  13. casadi/cmake/libzip/modules/FindMbedTLS.cmake +141 -0
  14. casadi/cmake/libzip/modules/FindNettle.cmake +141 -0
  15. casadi/cmake/libzip/modules/Findzstd.cmake +186 -0
  16. casadi/include/casadi/casadi.i +194 -44
  17. casadi/include/casadi/config.h +11 -11
  18. casadi/include/casadi/core/archiver.hpp +58 -0
  19. casadi/include/casadi/core/blazing_spline.hpp +47 -0
  20. casadi/include/casadi/core/calculus.hpp +57 -2
  21. casadi/include/casadi/core/casadi_common.hpp +37 -0
  22. casadi/include/casadi/core/casadi_meta.hpp +15 -0
  23. casadi/include/casadi/core/casadi_misc.hpp +7 -0
  24. casadi/include/casadi/core/code_generator.hpp +95 -17
  25. casadi/include/casadi/core/core.hpp +5 -0
  26. casadi/include/casadi/core/dae_builder.hpp +283 -141
  27. casadi/include/casadi/core/dm.hpp +3 -0
  28. casadi/include/casadi/core/filesystem.hpp +58 -0
  29. casadi/include/casadi/core/fmu.hpp +51 -16
  30. casadi/include/casadi/core/function.hpp +19 -0
  31. casadi/include/casadi/core/generic_matrix.hpp +214 -7
  32. casadi/include/casadi/core/generic_shared.hpp +318 -0
  33. casadi/include/casadi/core/generic_shared_impl.hpp +214 -0
  34. casadi/include/casadi/core/generic_shared_internal.hpp +215 -0
  35. casadi/include/casadi/core/generic_type.hpp +3 -0
  36. casadi/include/casadi/core/global_options.hpp +10 -0
  37. casadi/include/casadi/core/integrator.hpp +41 -7
  38. casadi/include/casadi/core/matrix_decl.hpp +67 -0
  39. casadi/include/casadi/core/mx.hpp +63 -2
  40. casadi/include/casadi/core/options.hpp +6 -3
  41. casadi/include/casadi/core/optistack.hpp +43 -9
  42. casadi/include/casadi/core/printable.hpp +8 -0
  43. casadi/include/casadi/core/resource.hpp +107 -0
  44. casadi/include/casadi/core/runtime/casadi_blazing_1d_boor_eval.hpp +112 -0
  45. casadi/include/casadi/core/runtime/casadi_blazing_2d_boor_eval.hpp +311 -0
  46. casadi/include/casadi/core/runtime/casadi_blazing_3d_boor_eval.hpp +645 -0
  47. casadi/include/casadi/core/runtime/casadi_blazing_de_boor.hpp +101 -0
  48. casadi/include/casadi/core/runtime/casadi_nlp.hpp +8 -2
  49. casadi/include/casadi/core/runtime/casadi_printme.hpp +25 -0
  50. casadi/include/casadi/core/serializer.hpp +12 -4
  51. casadi/include/casadi/core/serializing_stream.hpp +3 -0
  52. casadi/include/casadi/core/shared_object.hpp +73 -161
  53. casadi/include/casadi/core/sparsity.hpp +13 -1
  54. casadi/include/casadi/core/sparsity_interface.hpp +19 -1
  55. casadi/include/casadi/core/sx.hpp +41 -0
  56. casadi/include/casadi/core/sx_elem.hpp +25 -0
  57. casadi/include/casadi/core/xml_node.hpp +5 -0
  58. casadi/include/casadi/doc.i +9703 -6539
  59. casadi/include/casadi/doc_merged.i +6483 -4447
  60. casadi/include/casadi/valgrind-casadi.supp +138 -0
  61. casadi/include/casadi/valgrind-python.supp +2470 -0
  62. casadi/include/licenses/libz-external/LICENSE +22 -0
  63. casadi/include/licenses/libz-external/contrib/dotzlib/LICENSE_1_0.txt +23 -0
  64. casadi/include/licenses/libzip-external/LICENSE +31 -0
  65. casadi/include/zconf.h +545 -0
  66. casadi/include/zip.h +528 -0
  67. casadi/include/zipconf.h +48 -0
  68. casadi/include/zlib.h +1938 -0
  69. casadi/libCbcSolver.so +0 -0
  70. casadi/libCbcSolver.so.3 +0 -0
  71. casadi/libCbcSolver.so.3.10.11 +0 -0
  72. casadi/libClpSolver.so +0 -0
  73. casadi/libClpSolver.so.1 +0 -0
  74. casadi/libClpSolver.so.1.14.9 +0 -0
  75. casadi/libbonmin.so +0 -0
  76. casadi/libbonmin.so.4 +0 -0
  77. casadi/libbonmin.so.4.8.9 +0 -0
  78. casadi/libcasadi.so +0 -0
  79. casadi/libcasadi.so.3.7 +0 -0
  80. casadi/libcasadi_archiver_libzip.so +0 -0
  81. casadi/libcasadi_archiver_libzip.so.3.7 +0 -0
  82. casadi/libcasadi_conic_cbc.so +0 -0
  83. casadi/libcasadi_conic_cbc.so.3.7 +0 -0
  84. casadi/libcasadi_conic_clp.so +0 -0
  85. casadi/libcasadi_conic_clp.so.3.7 +0 -0
  86. casadi/libcasadi_conic_cplex.so +0 -0
  87. casadi/libcasadi_conic_cplex.so.3.7 +0 -0
  88. casadi/libcasadi_conic_daqp.so +0 -0
  89. casadi/libcasadi_conic_daqp.so.3.7 +0 -0
  90. casadi/libcasadi_conic_gurobi.so +0 -0
  91. casadi/libcasadi_conic_gurobi.so.3.7 +0 -0
  92. casadi/libcasadi_conic_hpipm.so +0 -0
  93. casadi/libcasadi_conic_hpipm.so.3.7 +0 -0
  94. casadi/libcasadi_conic_ipqp.so +0 -0
  95. casadi/libcasadi_conic_ipqp.so.3.7 +0 -0
  96. casadi/libcasadi_conic_nlpsol.so +0 -0
  97. casadi/libcasadi_conic_nlpsol.so.3.7 +0 -0
  98. casadi/libcasadi_conic_osqp.so +0 -0
  99. casadi/libcasadi_conic_osqp.so.3.7 +0 -0
  100. casadi/libcasadi_conic_qpoases.so +0 -0
  101. casadi/libcasadi_conic_qpoases.so.3.7 +0 -0
  102. casadi/libcasadi_conic_qrqp.so +0 -0
  103. casadi/libcasadi_conic_qrqp.so.3.7 +0 -0
  104. casadi/libcasadi_conic_superscs.so +0 -0
  105. casadi/libcasadi_conic_superscs.so.3.7 +0 -0
  106. casadi/libcasadi_importer_shell.so +0 -0
  107. casadi/libcasadi_importer_shell.so.3.7 +0 -0
  108. casadi/libcasadi_integrator_collocation.so +0 -0
  109. casadi/libcasadi_integrator_collocation.so.3.7 +0 -0
  110. casadi/libcasadi_integrator_cvodes.so +0 -0
  111. casadi/libcasadi_integrator_cvodes.so.3.7 +0 -0
  112. casadi/libcasadi_integrator_idas.so +0 -0
  113. casadi/libcasadi_integrator_idas.so.3.7 +0 -0
  114. casadi/libcasadi_integrator_rk.so +0 -0
  115. casadi/libcasadi_integrator_rk.so.3.7 +0 -0
  116. casadi/libcasadi_interpolant_bspline.so +0 -0
  117. casadi/libcasadi_interpolant_bspline.so.3.7 +0 -0
  118. casadi/libcasadi_interpolant_linear.so +0 -0
  119. casadi/libcasadi_interpolant_linear.so.3.7 +0 -0
  120. casadi/libcasadi_linsol_csparse.so +0 -0
  121. casadi/libcasadi_linsol_csparse.so.3.7 +0 -0
  122. casadi/libcasadi_linsol_csparsecholesky.so +0 -0
  123. casadi/libcasadi_linsol_csparsecholesky.so.3.7 +0 -0
  124. casadi/libcasadi_linsol_lapacklu.so +0 -0
  125. casadi/libcasadi_linsol_lapacklu.so.3.7 +0 -0
  126. casadi/libcasadi_linsol_lapackqr.so +0 -0
  127. casadi/libcasadi_linsol_lapackqr.so.3.7 +0 -0
  128. casadi/libcasadi_linsol_ldl.so +0 -0
  129. casadi/libcasadi_linsol_ldl.so.3.7 +0 -0
  130. casadi/libcasadi_linsol_lsqr.so +0 -0
  131. casadi/libcasadi_linsol_lsqr.so.3.7 +0 -0
  132. casadi/libcasadi_linsol_ma27.so +0 -0
  133. casadi/libcasadi_linsol_ma27.so.3.7 +0 -0
  134. casadi/libcasadi_linsol_mumps.so +0 -0
  135. casadi/libcasadi_linsol_mumps.so.3.7 +0 -0
  136. casadi/libcasadi_linsol_qr.so +0 -0
  137. casadi/libcasadi_linsol_qr.so.3.7 +0 -0
  138. casadi/libcasadi_linsol_symbolicqr.so +0 -0
  139. casadi/libcasadi_linsol_symbolicqr.so.3.7 +0 -0
  140. casadi/libcasadi_linsol_tridiag.so +0 -0
  141. casadi/libcasadi_linsol_tridiag.so.3.7 +0 -0
  142. casadi/libcasadi_nlpsol_ampl.so +0 -0
  143. casadi/libcasadi_nlpsol_ampl.so.3.7 +0 -0
  144. casadi/libcasadi_nlpsol_blocksqp.so +0 -0
  145. casadi/libcasadi_nlpsol_blocksqp.so.3.7 +0 -0
  146. casadi/libcasadi_nlpsol_bonmin.so +0 -0
  147. casadi/libcasadi_nlpsol_bonmin.so.3.7 +0 -0
  148. casadi/libcasadi_nlpsol_feasiblesqpmethod.so +0 -0
  149. casadi/libcasadi_nlpsol_feasiblesqpmethod.so.3.7 +0 -0
  150. casadi/libcasadi_nlpsol_ipopt.so +0 -0
  151. casadi/libcasadi_nlpsol_ipopt.so.3.7 +0 -0
  152. casadi/libcasadi_nlpsol_knitro.so +0 -0
  153. casadi/libcasadi_nlpsol_knitro.so.3.7 +0 -0
  154. casadi/libcasadi_nlpsol_madnlp.so +0 -0
  155. casadi/libcasadi_nlpsol_madnlp.so.3.7 +0 -0
  156. casadi/libcasadi_nlpsol_qrsqp.so +0 -0
  157. casadi/libcasadi_nlpsol_qrsqp.so.3.7 +0 -0
  158. casadi/libcasadi_nlpsol_scpgen.so +0 -0
  159. casadi/libcasadi_nlpsol_scpgen.so.3.7 +0 -0
  160. casadi/libcasadi_nlpsol_snopt.so +0 -0
  161. casadi/libcasadi_nlpsol_snopt.so.3.7 +0 -0
  162. casadi/libcasadi_nlpsol_sqpmethod.so +0 -0
  163. casadi/libcasadi_nlpsol_sqpmethod.so.3.7 +0 -0
  164. casadi/libcasadi_nlpsol_worhp.so +0 -0
  165. casadi/libcasadi_nlpsol_worhp.so.3.7 +0 -0
  166. casadi/libcasadi_rootfinder_fast_newton.so +0 -0
  167. casadi/libcasadi_rootfinder_fast_newton.so.3.7 +0 -0
  168. casadi/libcasadi_rootfinder_kinsol.so +0 -0
  169. casadi/libcasadi_rootfinder_kinsol.so.3.7 +0 -0
  170. casadi/libcasadi_rootfinder_newton.so +0 -0
  171. casadi/libcasadi_rootfinder_newton.so.3.7 +0 -0
  172. casadi/libcasadi_rootfinder_nlpsol.so +0 -0
  173. casadi/libcasadi_rootfinder_nlpsol.so.3.7 +0 -0
  174. casadi/libcasadi_sundials_common.so +0 -0
  175. casadi/libcasadi_sundials_common.so.3.7 +0 -0
  176. casadi/libcasadi_xmlfile_tinyxml.so +0 -0
  177. casadi/libcasadi_xmlfile_tinyxml.so.3.7 +0 -0
  178. casadi/libcoinmumps.so +0 -0
  179. casadi/libcoinmumps.so.3 +0 -0
  180. casadi/libcoinmumps.so.3.0.1 +0 -0
  181. casadi/libdaqpstat.a +0 -0
  182. casadi/libindirect.a +0 -0
  183. casadi/libipopt.so +0 -0
  184. casadi/libipopt.so.3 +0 -0
  185. casadi/libipopt.so.3.14.11 +0 -0
  186. casadi/liblinsys.a +0 -0
  187. casadi/libosqp.a +0 -0
  188. casadi/libqdldl.a +0 -0
  189. casadi/libsipopt.so +0 -0
  190. casadi/libsipopt.so.3 +0 -0
  191. casadi/libsipopt.so.3.14.11 +0 -0
  192. casadi/libsuperscs.a +0 -0
  193. casadi/libz.a +0 -0
  194. casadi/libz.so +0 -0
  195. casadi/libz.so.1 +0 -0
  196. casadi/libz.so.1.3.1 +0 -0
  197. casadi/libzip.a +0 -0
  198. casadi/pkgconfig/casadi.pc +1 -1
  199. casadi/pkgconfig/libzip.pc +14 -0
  200. casadi/tools/__init__.py +3 -1
  201. casadi/tools/graph/graph.py +1 -1
  202. casadi/tools/structure.py +2 -2
  203. {casadi-3.6.7.dist-info → casadi-3.7.0.dist-info}/METADATA +1 -1
  204. {casadi-3.6.7.dist-info → casadi-3.7.0.dist-info}/RECORD +204 -178
  205. casadi/include/tinyxml2.h +0 -2380
  206. casadi/lib64/cmake/tinyxml2/tinyxml2-config.cmake +0 -57
  207. casadi/lib64/cmake/tinyxml2/tinyxml2-static-targets-release.cmake +0 -19
  208. casadi/lib64/libtinyxml2.a +0 -0
  209. casadi/lib64/pkgconfig/tinyxml2.pc +0 -10
  210. casadi/tools/structure3.py +0 -1441
  211. {casadi-3.6.7.dist-info → casadi-3.7.0.dist-info}/WHEEL +0 -0
@@ -1,1441 +0,0 @@
1
- #
2
- # This file is part of CasADi.
3
- #
4
- # CasADi -- A symbolic framework for dynamic optimization.
5
- # Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6
- # KU Leuven. All rights reserved.
7
- # Copyright (C) 2011-2014 Greg Horn
8
- #
9
- # CasADi is free software; you can redistribute it and/or
10
- # modify it under the terms of the GNU Lesser General Public
11
- # License as published by the Free Software Foundation; either
12
- # version 3 of the License, or (at your option) any later version.
13
- #
14
- # CasADi is distributed in the hope that it will be useful,
15
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
- # Lesser General Public License for more details.
18
- #
19
- # You should have received a copy of the GNU Lesser General Public
20
- # License along with CasADi; if not, write to the Free Software
21
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
- #
23
- #
24
- from casadi import *
25
-
26
-
27
- import numpy as np
28
- import operator
29
- import sys
30
-
31
- if sys.version_info >= (3, 0):
32
- import builtins
33
- else:
34
- import __builtin__
35
- builtins = __builtin__
36
- import collections
37
-
38
- try:
39
- callable = collections.Callable
40
- except:
41
- callable = collections.abc.Callable
42
-
43
- def is_integer(a):
44
- return isinstance(a,int) or isinstance(a,np.integer)
45
-
46
- def is_string(a):
47
- return isinstance(a,str)
48
-
49
- def isIterable(a):
50
- return isinstance(a,list) or isinstance(a,tuple)
51
-
52
- # StructIndex :tuple/list of strings
53
- # canonicalIndex : tuple/list of string or numbers
54
- # powerIndex: tuple/list of string, numbers, lists, slices, dicts
55
-
56
- # flatIndex
57
-
58
- # Primitive helpers
59
- def lpack(L): return [[x] for x in L]
60
-
61
- def combine(*args):
62
- if len(args)==0:
63
- return [[]]
64
- else:
65
- return [a + b for a in args[0] for b in combine(*args[1:])]
66
-
67
- def listindices(dims,nest=False):
68
- if len(dims)==0:
69
- if nest:
70
- return [[[]]]
71
- else:
72
- return [[]]
73
- else:
74
- tail = listindices(dims[1:])
75
- if nest:
76
- return [combine([[i]],tail) for i in range(dims[0])]
77
- else:
78
- return combine(lpack(list(range(dims[0]))),tail)
79
-
80
- def intersperseIt(*args):
81
- iterators = list(map(iter,args))
82
- active = [True]*len(args)
83
- i = 0
84
- while any(active):
85
- try:
86
- yield next(iterators[i])
87
- except:
88
- active[i] = False
89
- i = (i + 1) % len(args)
90
-
91
- def intersperse(*args):
92
- return list(intersperseIt(*args))
93
-
94
- def canonicalIndexAncestors(ind):
95
- if len(ind)==0: return []
96
- return [ind] + canonicalIndexAncestors(ind[:-(list(map(is_string,ind[::-1])).index(True)+1)])
97
-
98
- def canonical(ind,s):
99
- if ind < 0:
100
- return ind + s
101
- else:
102
- return ind
103
-
104
- def vec(e):
105
- if any(isinstance(i,list) for i in e):
106
- return sum(list(map(vec,e)),[])
107
- else:
108
- return e
109
-
110
-
111
- def correct_vector_indexing(x, i):
112
- return casadi.reshape(x[i], i.shape)
113
-
114
- # Decoraters
115
-
116
- def properGetitem(f):
117
- """
118
- This decorator modifies a __getitem__/__setitem__ method such that it will always receive a tuple
119
- """
120
- def proper(self,mbt,*args):
121
- if not isinstance(mbt,tuple):
122
- mbt = (mbt,)
123
- return f(self,mbt,*args)
124
- return proper
125
-
126
- # Enhanced standard classes
127
- class SafeDict(dict):
128
- def __getitem__(self,k):
129
- if k not in self:
130
- raise Exception("Unknown keyword '%s'. Available entries: %s" % (k,str(list(self.keys()))))
131
- return dict.__getitem__(self,k)
132
-
133
- # Placeholder classes and instances
134
- class Repeater:
135
- def __init__(self,e): self.e = e
136
-
137
- def repeated(e):
138
- """
139
- From the arguemnt, constructs something that acts like a 'list' with the argument repeated the 'correct' number of times
140
-
141
- s = struct_symSX([entry("x",repeat=6)])
142
- s["x"] = repeated(12)
143
-
144
- """
145
- return Repeater(e)
146
-
147
- class NestedDictLiteral:
148
- """
149
- NestedDictLiteral will cause all dictionaries to become explicit recursively
150
- """
151
-
152
- nesteddict = NestedDictLiteral()
153
-
154
- # Casadi-independent Structure framework
155
-
156
- def payloadUnpack(payload,i):
157
- if is_string(i):
158
- raise Exception("Got string %s where number expected."% i)
159
- if isIterable(payload):
160
- if i>=len(payload):
161
- raise Exception("Rhs out of range. Got list index %s but rhs list is only of length %s." % (i,len(payload)))
162
- return payload[i]
163
- elif isinstance(payload,Repeater):
164
- return payload.e
165
- else:
166
- return payload
167
-
168
- class StructEntry:
169
- def __init__(self,name,struct=None,data=None,dims=[]):
170
- self.name = name
171
- self.dims = dims
172
- self.struct = struct
173
-
174
- def __str__(self,compact=False):
175
- s=''
176
- if len(self.dims)>=1:
177
- s+= "repeated(%s): " % str(self.dims)
178
- if self.isPrimitive():
179
- s+=self.primitiveString()
180
- else:
181
- s+=self.struct.__str__(compact=True)
182
- return s
183
-
184
- __repr__ = __str__
185
-
186
- def primitiveString(self):
187
- return "*"
188
-
189
- def isPrimitive(self):
190
- return self.struct is None
191
-
192
- def traverseCanonicalIndex(self,nest=False,limit=1000):
193
- children = [[]] if (self.struct is None or limit==0) else self.struct.traverseCanonicalIndex(limit=limit-1)
194
- li = listindices(self.dims,nest)
195
- n = [[self.name]]
196
- if nest:
197
- return [combine(n,i,children) for i in li]
198
- else:
199
- return combine(n,li,children)
200
-
201
- def getStructEntryByStructIndex(self,structIndex):
202
- return self.struct.getStructEntryByStructIndex(structIndex)
203
-
204
- def traverseByPowerIndex(self,powerIndex,dims=None,canonicalIndex=(),dispatcher=None,payload=None):
205
- try:
206
- if dims is None: dims = self.dims
207
- # At the end of powerIndex, pending : are added automatically if dims is not exhausted
208
- if len(powerIndex)==0:
209
- if len(dims)>0:
210
- return self.traverseByPowerIndex(
211
- [slice(None) for i in dims],
212
- dims=dims,
213
- canonicalIndex=canonicalIndex,
214
- dispatcher=dispatcher,
215
- payload=payload
216
- )
217
- else:
218
- return dispatcher(payload,canonicalIndex,entry=self)
219
-
220
- if len(dims)==0:
221
- if self.isPrimitive(): # Pass on remainder of powerIndex to dispatcher
222
- return dispatcher(payload,canonicalIndex,extraIndex=tuple(powerIndex),entry=self)
223
- else:
224
- return self.struct.traverseByPowerIndex(
225
- powerIndex,
226
- canonicalIndex=canonicalIndex,
227
- dispatcher=dispatcher,
228
- payload=payload
229
- )
230
- else:
231
- p = powerIndex[0]
232
- s = dims[0]
233
- if isinstance(p,slice): # Expand slice
234
- p = list(range(*p.indices(s)))
235
- if is_integer(p):
236
- return self.traverseByPowerIndex(
237
- powerIndex[1:],
238
- dims=dims[1:],
239
- canonicalIndex=canonicalIndex+(canonical(p,s),),
240
- dispatcher=dispatcher,
241
- payload=payload
242
- )
243
- elif isinstance(p,list):
244
- return [
245
- self.traverseByPowerIndex(
246
- powerIndex[1:],
247
- dims=dims[1:],
248
- canonicalIndex=canonicalIndex+(canonical(i,s),),
249
- dispatcher=dispatcher,
250
- payload = payloadUnpack(payload,i)
251
- )
252
- for i in p]
253
- elif isinstance(p,dict):
254
- raise Exception("powerIndex entry {} cannot be used in list context.")
255
- elif isinstance(p,set):
256
- raise Exception("""powerIndex entry {"foo","bar"} cannot be used in list context.""")
257
- elif isinstance(p,NestedDictLiteral):
258
- return [
259
- self.traverseByPowerIndex(
260
- [p],
261
- dims=dims[1:],
262
- canonicalIndex=canonicalIndex+(canonical(i,s),),
263
- dispatcher=dispatcher,
264
- payload = payloadUnpack(payload,i)
265
- )
266
- for i in range(s)]
267
- elif isinstance(p, callable):
268
- r = p(self.traverseByPowerIndex(
269
- powerIndex[1:],
270
- dims=dims,
271
- canonicalIndex=canonicalIndex,
272
- dispatcher=dispatcher.callableInner(),
273
- payload=payload
274
- ))
275
- return dispatcher.callableOuter(payload,canonicalIndex,extraIndex=None,entry=None,inner=r)
276
- else:
277
- raise Exception("I don't know what to do with this: %s" % str(p))
278
- except Exception as e:
279
- raise Exception("Error occured in entry context with powerIndex %s, at canonicalIndex %s" % (str(powerIndex),str(canonicalIndex))) from e
280
-
281
- class Structure(object):
282
- def __init__(self,entries,order=None):
283
- self.entries = entries
284
-
285
- self.order = [e.name for e in self.entries] if order is None else order
286
- self.keyslist = sum([ list(i) if isinstance(i,tuple) else list([i]) for i in self.order],[])
287
-
288
- self.dict = SafeDict([(e.name,e) for e in self.entries])
289
-
290
- for e in self.order:
291
- if is_string(e):
292
- if e not in self.dict:
293
- raise Exception("Order '%s' is invalid." % e)
294
- elif isinstance(e,tuple):
295
- for ee in e:
296
- if ee not in self.dict:
297
- raise Exception("Order '%s' is invalid." % ee)
298
-
299
- def keys(self):
300
- return self.keyslist
301
-
302
- def __str__(self,compact=False):
303
- s=''
304
- if compact:
305
- s+= "{" + ",".join(k + ": " + v.__str__(compact=True) for k,v in list(self.dict.items())) + "}"
306
- else:
307
- s+= "Structure holding %d entries.\n" % len(self.dict)
308
- s+=" Order: %s\n" % str(self.order)
309
- for k,v in list(self.dict.items()):
310
- s+= " " + k + " = " + v.__str__(compact=True) + "\n"
311
- return s
312
-
313
- __repr__ = __str__
314
-
315
- def traverseCanonicalIndex(self,limit=1000):
316
- ret = []
317
- for d in self.order:
318
- if isinstance(d,tuple):
319
- for v in intersperse(*[self.dict[de].traverseCanonicalIndex(True,limit=limit-1) for de in d]):
320
- ret += v
321
- else:
322
- ret += self.dict[d].traverseCanonicalIndex(limit=limit-1)
323
- return ret
324
-
325
- def getStructEntryByStructIndex(self,structIndex):
326
- e = self.dict[structIndex[0]]
327
- if len(structIndex)>1:
328
- return e.getStructEntryByStructIndex(structIndex[1:])
329
- else:
330
- return e
331
-
332
- def getStructEntryByCanonicalIndex(self,indices):
333
- return self.getStructEntryByStructIndex([x for x in indices if is_string(x)])
334
-
335
- def getStruct(self,name):
336
- if name not in self.struct.dict:
337
- raise Exception("Cannot find entry with key '%s'. Candidates: " % (str(name),str(list(name.keys()))))
338
- ret = self.struct.dict[name].struct
339
- if ret is None:
340
- raise Exception("Entry '%s' has no structure." % (name))
341
- else:
342
- return ret
343
-
344
- def traverseByPowerIndex(self,powerIndex,canonicalIndex=(),dispatcher=None,payload=None):
345
- try:
346
- if len(powerIndex)==0: return dispatcher(payload,canonicalIndex)
347
- p = powerIndex[0]
348
- if is_string(p):
349
- return self.dict[p].traverseByPowerIndex(
350
- powerIndex[1:],
351
- canonicalIndex=canonicalIndex+(p,),
352
- dispatcher=dispatcher,
353
- payload=payload
354
- )
355
- elif isinstance(p,slice):
356
- raise Exception("slice not allowed here, did you mean '...' ?")
357
- elif isinstance(p,type(Ellipsis)):
358
- """
359
- Why ellipsis? Because it's all or nothing
360
- """
361
- return [
362
- self.dict[k].traverseByPowerIndex(
363
- powerIndex[1:],
364
- canonicalIndex=canonicalIndex+(k,),
365
- dispatcher=dispatcher,
366
- payload=payloadUnpack(payload,i)
367
- )
368
- for i,k in enumerate(self.keys())]
369
- elif isinstance(p,dict) or isinstance(p,NestedDictLiteral):
370
- if isinstance(payload,dict):
371
- return dict([
372
- ( k,
373
- self.dict[k].traverseByPowerIndex(
374
- powerIndex[1:] if isinstance(p,dict) else [p],
375
- canonicalIndex=canonicalIndex+(k,),
376
- dispatcher=dispatcher,
377
- payload=v
378
- )
379
- ) for k,v in payload.items()
380
- ])
381
- else:
382
- return dict([
383
- ( k,
384
- v.traverseByPowerIndex(
385
- powerIndex[1:] if isinstance(p,dict) else [p],
386
- canonicalIndex=canonicalIndex+(k,),
387
- dispatcher=dispatcher,
388
- payload=payload
389
- )
390
- ) for k,v in self.dict.items()
391
- ])
392
- elif isinstance(p,set):
393
- if isinstance(payload,dict):
394
- return dict([
395
- ( k,
396
- self.dict[k].traverseByPowerIndex(
397
- powerIndex[1:],
398
- canonicalIndex=canonicalIndex+(k,),
399
- dispatcher=dispatcher,
400
- payload=v
401
- )
402
- ) for k,v in payload.items() if k in p
403
- ])
404
- else:
405
- return dict([
406
- ( k,
407
- self.dict[k].traverseByPowerIndex(
408
- powerIndex[1:],
409
- canonicalIndex=canonicalIndex+(k,),
410
- dispatcher=dispatcher,
411
- payload=payload
412
- )
413
- ) for k in p
414
- ])
415
- elif isinstance(p,list):
416
- return [
417
- self.traverseByPowerIndex(
418
- powerIndex[1:],
419
- canonicalIndex=canonicalIndex+(s,),
420
- dispatcher=dispatcher,
421
- payload=payloadUnpack(payload,i)
422
- )
423
- for i,s in enumerate(p)]
424
- elif isinstance(p, callable):
425
- r = p(self.traverseByPowerIndex(
426
- powerIndex[1:],
427
- canonicalIndex=canonicalIndex,
428
- dispatcher=dispatcher.callableInner(),
429
- payload=payload
430
- ))
431
- return dispatcher.callableOuter(payload,canonicalIndex,extraIndex=None,entry=None,inner=r)
432
- else:
433
- raise Exception("I don't know what to do with this: %s" % str(p))
434
- except Exception as e:
435
- raise Exception("Error occured in struct context with powerIndex %s, at canonicalIndex %s" % (str(powerIndex),str(canonicalIndex))) from e
436
- # Casadi-dependent Structure framework
437
-
438
- class Dispatcher:
439
- def __init__(self,**args):
440
- for k,v in list(args.items()):
441
- setattr(self,k,v)
442
-
443
- def callableInner(self):
444
- return self
445
-
446
- def callableOuter(self,payload,canonicalIndex,extraIndex=None,entry=None,inner=None):
447
- return inner
448
-
449
-
450
- #Mixins
451
- class CasadiStructureDerivable:
452
-
453
- def argtype(self,arg):
454
- mtype = None
455
- if isinstance(arg,DM):
456
- a = arg
457
- mtype = DM
458
- elif not isinstance(arg,MX) and not isinstance(arg,SX):
459
- try:
460
- a = DM(arg)
461
- mtype = DM
462
- except:
463
- pass
464
-
465
- if mtype is None:
466
- if isinstance(arg,MX):
467
- a = arg
468
- mtype = MX
469
- else:
470
- try:
471
- a = MX(arg)
472
- mtype = MX
473
- except:
474
- pass
475
-
476
- if mtype is None:
477
- if isinstance(arg,SX):
478
- a = arg
479
- mtype = SX
480
- else:
481
- try:
482
- a = SX(arg)
483
- mtype = SX
484
- except:
485
- raise Exception("Call to Structure has weird argument: expecting DM-like or MX-like or SXMatrix-like")
486
-
487
- return (a,mtype)
488
-
489
- def __call__(self,arg=0):
490
- (a,mtype) = self.argtype(arg)
491
-
492
- if isinstance(a,DM):
493
- if a.shape[0] == 1 and a.shape[1] == 1 and self.size!=1:
494
- a = DM.ones(self.size,1)*a
495
- return DMStruct(self,data=a)
496
-
497
- if isinstance(a,MX):
498
- return MXStruct(self,data=a)
499
-
500
- if isinstance(a,SX):
501
- return SXStruct(self,data=a)
502
-
503
- def repeated(self,arg=0):
504
- (a,mtype) = self.argtype(arg)
505
-
506
- if not(a.shape[0] == self.size):
507
- raise Exception("Expecting %d x n DM. Got %s" % (self.size,a.dim()))
508
- s = struct([entry("t",struct=self,repeat=a.shape[1])])
509
-
510
- for (t,c) in [(DM,DMStruct), (MX, MXStruct), (SX, SXStruct)]:
511
- if isinstance(a,t):
512
- numbers = c(s,data=DataReferenceRepeated(a,a.shape[1]))
513
-
514
- p = numbers.prefix["t"]
515
- p.castmaster = True
516
- return p
517
-
518
- def squared(self,arg=0):
519
- (a,mtype) = self.argtype(arg)
520
-
521
- if a.shape[0] == 1 and a.shape[1] == 1 and self.size!=1:
522
- a = DM.ones(self.size,self.size)*a
523
- if not(a.shape[1] == a.shape[0] and a.shape[0]==self.size):
524
- raise Exception("Expecting square DM of size %s. Got %s" % (self.size,a.dim()))
525
- s = struct([entry("t",shapestruct=(self,self))])
526
- for (t,c) in [(DM,DMStruct), (MX, MXStruct), (SX, SXStruct)]:
527
- if isinstance(a,t):
528
- numbers = c(s,data=DataReferenceSquared(a,a.shape[0]))
529
- p = numbers.prefix["t"]
530
- p.castmaster = True
531
- return p
532
-
533
- def product(self,otherstruct,arg=0):
534
- (a,mtype) = self.argtype(arg)
535
-
536
- if a.shape[0] == 1 and a.shape[1] == 1 and self.size!=1:
537
- a = DM.ones(self.size,otherstruct.size)*a
538
- if not(a.shape[1]==otherstruct.size and a.shape[0]==self.size):
539
- raise Exception("Expecting DM of shape (%s,%s). Got %s" % (self.size,otherstruct.size,a.dim()))
540
- s = struct([entry("t",shapestruct=(self,otherstruct))])
541
- for (t,c) in [(DM,DMStruct), (MX, MXStruct), (SX, SXStruct)]:
542
- if isinstance(a,t):
543
- numbers = c(s,data=DataReferenceProduct(a,a.shape[0],a.shape[1]))
544
- p = numbers.prefix["t"]
545
- p.castmaster = True
546
- return p
547
-
548
- def squared_repeated(self,arg=0):
549
- (a,mtype) = self.argtype(arg)
550
-
551
- if not(a.shape[0]==self.size and a.shape[1] % self.size == 0):
552
- raise Exception("Expecting square (%d) DM by N. Got %s" % (self.size,a.dim()))
553
- s = struct([entry("t",shapestruct=(self,self),repeat=int(a.shape[1] / self.size))])
554
-
555
- for (t,c) in [(DM,DMStruct), (MX, MXStruct), (SX, SXStruct)]:
556
- if isinstance(a,t):
557
- numbers = c(s,data=DataReferenceSquaredRepeated(a,self.size,int(a.shape[1] / self.size)))
558
-
559
- p = numbers.prefix["t"]
560
- p.castmaster = True
561
- return p
562
-
563
- class GetterDispatcher(Dispatcher):
564
- def __call__(self,payload,canonicalIndex,extraIndex=None,entry=None):
565
- type = None if entry is None else entry.type
566
- if canonicalIndex in self.struct.map:
567
-
568
- if canonicalIndex in self.priority_object_map and (extraIndex is None or len(extraIndex)==0):
569
- r = self.priority_object_map[canonicalIndex]
570
- if type is None:
571
- return r
572
- elif type=="symm":
573
- return triu2symm(r)
574
- else:
575
- raise Exception("Cannot handle type '%s'." % entry.type)
576
-
577
- i = performExtraIndex(self.struct.map[canonicalIndex],extraIndex=extraIndex,entry=entry)
578
-
579
- try:
580
- if type is None:
581
- return correct_vector_indexing(self.master, i)
582
- elif type=="symm":
583
- return triu2symm(self.master[i])
584
- else:
585
- raise Exception("Cannot handle type '%s'." % entry.type)
586
- except Exception as e:
587
- raise Exception("Error in powerIndex slicing for canonicalIndex %s" % (str(canonicalIndex))) from e
588
- else:
589
- raise Exception("Canonical index %s does not exist." % str(canonicalIndex))
590
-
591
- class SetterDispatcher(Dispatcher):
592
- def __call__(self,payload,canonicalIndex,extraIndex=None,entry=None):
593
- payload_ = self.mtype(payload)
594
- type = None if entry is None else entry.type
595
- if canonicalIndex in self.struct.map:
596
- i = performExtraIndex(self.struct.map[canonicalIndex],extraIndex=extraIndex,entry=entry)
597
- try:
598
- if type is None:
599
- self.master[i] = payload_
600
- elif type=="symm":
601
- iflip = performExtraIndex(self.struct.map[canonicalIndex],extraIndex=extraIndex,entry=entry,flip=True)
602
- if payload_.is_scalar():
603
- self.master[i] = payload_
604
- self.master[iflip] = payload_
605
- else:
606
- oi = performExtraIndex(DM.ones(entry.originalsparsity),extraIndex=extraIndex,entry=entry)
607
- if oi.sparsity()!=payload_.sparsity():
608
- raise Exception("Payload sparsity " + payload_.dim() + " does not match lhs sparisty " + oi.dim() + "." )
609
- self.master[iflip] = payload_.T[iflip.sparsity()]
610
- self.master[i] = payload_[i.sparsity()]
611
- else:
612
- raise Exception("Cannot handle type '%s'." % entry.type)
613
- except NotImplementedError as e:
614
- raise CompatibilityException("Error in canonicalIndex slicing for %s: Incompatible types in a[i]=b with a %s (%s) and b %s (%s) and i %s (%s). Error: %s" % (str(canonicalIndex),str(self.master),str(builtins.type(self.master)),str(payload),str(builtins.type(payload)),str(i),str(builtins.type(i)),str(e)))
615
- except Exception as e:
616
- raise Exception("Error in powerIndex slicing for canonicalIndex %s" % (str(canonicalIndex))) from e
617
- else:
618
- raise Exception("Canonical index %s does not exist." % str(canonicalIndex))
619
-
620
- def callableInner(self):
621
- return CasadiStructure.IMDispatcher(struct=self.struct)
622
-
623
- def callableOuter(self,payload,canonicalIndex,extraIndex=None,entry=None,inner=None):
624
- try:
625
- self.master[inner] = payload
626
- except NotImplementedError:
627
- raise CompatibilityException("Error in canonicalIndex slicing for %s: Incompatible types in a[i]=b with a %s and b %s." % (str(canonicalIndex),str(self.master),str(payload)))
628
- except Exception as e:
629
- raise Exception("Error in powerIndex slicing for canonicalIndex %s" % (str(canonicalIndex))) from e
630
-
631
- class MasterGettable:
632
- @properGetitem
633
- def __getitem__(self,powerIndex):
634
- return self.struct.traverseByPowerIndex(powerIndex,dispatcher=GetterDispatcher(struct=self.struct,master=self.master,priority_object_map=self.priority_object_map))
635
-
636
- class MasterSettable:
637
- @properGetitem
638
- def __setitem__(self,powerIndex,value):
639
- return self.struct.traverseByPowerIndex(powerIndex,dispatcher=
640
- SetterDispatcher(struct=self.struct,master=self.master,mtype=self.mtype),payload=value)
641
-
642
- def delegation(extraIndex,entry,i):
643
- if is_string(extraIndex) or (isinstance(extraIndex,list) and len(extraIndex)>0 and all([is_string(e) for e in extraIndex])):
644
- extraIndex = FlatIndexDelegater(extraIndex)
645
- if isinstance(extraIndex,Delegater):
646
- if entry is None: raise Exception("Cannot use delayed index without supplied entry.")
647
- if entry.shapestruct is None: raise Exception("Cannot use delayed index without supplied shapestruct.")
648
- if not(isinstance(entry.shapestruct[i],Structure)) : raise Exception("Cannot use delayed index with a integer shapestruct argument.")
649
- return extraIndex(entry.shapestruct[i])
650
- else:
651
- return extraIndex
652
-
653
- def performExtraIndex(i,extraIndex=None,entry=None,flip=False):
654
- if extraIndex is None or len(extraIndex)==0:
655
- return i
656
- if isinstance(extraIndex[0], callable) and not isinstance(extraIndex[0],Delegater):
657
- return extraIndex[0](performExtraIndex(i,extraIndex=extraIndex[1:],entry=entry,flip=flip))
658
- if not(isinstance(extraIndex[0],NestedDictLiteral)):
659
- if len(extraIndex)>2 or len(extraIndex)==0:
660
- raise Exception("Powerindex exhausted. Remaining %s is interpreted as extraIndex, but length must be 1 or 2." % str(extraIndex))
661
- try:
662
- if len(extraIndex)==1:
663
- a = extraIndex[0]
664
- a = delegation(a,entry,0)
665
- return i.__getitem__(a)
666
- else:
667
- a,b = extraIndex
668
- a = delegation(a,entry,0)
669
- b = delegation(b,entry,1)
670
- return i.__getitem__((b,a) if flip else (a,b))
671
- except NotImplementedError:
672
- raise Exception("Powerindex exhausted. Passing on %s to %s, but it doesn't know what to do with it" % (str(extraIndex),str(type(i))))
673
- else:
674
- return i
675
-
676
-
677
- class Prefixer:
678
- def __init__(self,struct,prefix,castmaster=False):
679
- self.struct = struct
680
- self.prefix = prefix
681
- self.castmaster = castmaster
682
-
683
- methods = [ "__DM__", "__SX__","__MX__"]
684
- for m in methods:
685
- if hasattr(self.struct,m):
686
- setattr(self,m,self.cast)
687
-
688
- def __setstate__(self,state):
689
- self.__init__(state["struct"],state["prefix"],state["castmaster"])
690
-
691
- def __getstate__(self):
692
- return {"struct": self.struct, "prefix": self.prefix,"castmaster": self.castmaster}
693
-
694
- def __getattr__(self,name):
695
- # When attributes are not found, delegate to self()
696
- # This allows for e.g. sin(x) and x+1 to work
697
- if isinstance(self.struct.master,DataReference):
698
- t = self.struct.master.a
699
- else:
700
- t = self.struct.master
701
- if not(isinstance(t,list) or isinstance(t,dict) or isinstance(t,tuple)):
702
- return getattr(t,name)
703
-
704
- def cast(self):
705
- if self.castmaster:
706
- if isinstance(self.struct.master,DataReference):
707
- return self.struct.master.a
708
- else:
709
- return self.struct.master
710
- else:
711
- return self()
712
-
713
- def __str__(self):
714
- return "prefix( " + str(self.prefix) + "," + self.struct.__str__(compact=True) + ")"
715
-
716
- __repr__ = __str__
717
-
718
- def __call__(self):
719
- return self.struct.__getitem__(self.prefix)
720
-
721
- @properGetitem
722
- def __getitem__(self,powerIndex):
723
- return self.struct.__getitem__(self.prefix + powerIndex)
724
-
725
- @properGetitem
726
- def __setitem__(self,powerIndex,data):
727
- return self.struct.__setitem__(self.prefix + powerIndex,data)
728
-
729
- class PrefixConstructor:
730
-
731
- def __str__(self):
732
- return "prefixConstructor(" + self.struct.__str__(compact=True) + ")"
733
-
734
- __repr__ = __str__
735
-
736
- def __init__(self,struct,castmaster=False):
737
- self.struct = struct
738
- self.castmaster=castmaster
739
-
740
- @properGetitem
741
- def __getitem__(self,prefix):
742
- return Prefixer(self.struct,prefix,castmaster=self.castmaster)
743
-
744
- class CasadiStructure(Structure,CasadiStructureDerivable):
745
- """
746
- size
747
- map
748
- """
749
-
750
- def save(self,filename):
751
- import pickle
752
- pickle.dump(self,file(filename,"wb"),2)
753
-
754
- class FlatIndexDispatcher(Dispatcher):
755
- def __call__(self,payload,canonicalIndex,extraIndex=None,entry=None):
756
- if canonicalIndex in self.struct.map:
757
- res = performExtraIndex(self.struct.map[canonicalIndex],extraIndex=extraIndex,entry=entry)
758
- if isinstance(res,DM):
759
- assert res.is_dense()
760
- return list(map(int,list(res.nonzeros())))
761
- return list(res)
762
- else:
763
- raise Exception("Canonical index %s not found." % str(canonicalIndex))
764
-
765
- class IMDispatcher(Dispatcher):
766
- def __call__(self,payload,canonicalIndex,extraIndex=None,entry=None):
767
- if canonicalIndex in self.struct.map:
768
- return performExtraIndex(self.struct.map[canonicalIndex],extraIndex=extraIndex,entry=entry)
769
- else:
770
- raise Exception("Canonical index %s not found." % str(canonicalIndex))
771
-
772
- def __setstate__(self,state):
773
- self.__init__(*state["args"],**state["kwargs"])
774
-
775
- def __getstate__(self):
776
- return self.initializer
777
-
778
- def __init__(self,*args,**kwargs):
779
- self.initializer = {"args": args, "kwargs": kwargs}
780
- Structure.__init__(self,*args,**kwargs)
781
-
782
- self.map = {}
783
- self.lookuptable = []
784
-
785
- hmap = {}
786
- k = 0 # Global index counter
787
- for i in self.traverseCanonicalIndex():
788
- e = self.getStructEntryByCanonicalIndex(i)
789
- sp = Sparsity.dense(1,1) if e.sparsity is None else e.sparsity
790
- m = DM(sp,list(range(k,k+sp.nnz())))
791
- k += sp.nnz()
792
- it = tuple(i)
793
- self.map[it] = m
794
- self.lookuptable+=[(it,kk,p) for kk,p in enumerate(zip(sp.get_col(),sp.row()))]
795
- for a in canonicalIndexAncestors(it)[1:]:
796
- if a in hmap:
797
- hmap[a].append(m)
798
- else:
799
- hmap[a] = [m]
800
- self.size = k
801
- for k,v in hmap.items():
802
- hmap[k] = vertcat(*[i.nz[:] for i in v])
803
- self.map.update(hmap)
804
-
805
- class StructureGetter:
806
- def __init__(self,struct):
807
- self.struct = struct
808
-
809
- class IMGetter(StructureGetter):
810
- @properGetitem
811
- def __getitem__(self,powerIndex):
812
- return self.struct.traverseByPowerIndex(powerIndex,dispatcher=CasadiStructure.IMDispatcher(struct=self.struct))
813
-
814
- class FlatIndexGetter(StructureGetter):
815
- @properGetitem
816
- def __getitem__(self,powerIndex):
817
- return vec(self.struct.traverseByPowerIndex(powerIndex,dispatcher=CasadiStructure.FlatIndexDispatcher(struct=self.struct)))
818
-
819
- self.i = IMGetter(self)
820
- self.f = FlatIndexGetter(self)
821
- self.struct = self
822
-
823
- def __str__(self,compact=False):
824
- return ("" if compact else "Structure with total size %d.\n" % self.size)+ Structure.__str__(self,compact=compact)
825
-
826
- def getCanonicalIndex(self,i,extraMode=1):
827
- """
828
- Returns the canonicalIndex of the entry with a given flatIndex
829
- extraMode influences wether nothing (0), [i] (1) or [i,j] (2) will be returned as extra index
830
- """
831
- if i<0 or i>=self.size:
832
- raise Exception("Lookup index out of range. Got %d, but structure is of size %d" % (i,self.size))
833
- can,k,p = self.lookuptable[i]
834
- if extraMode==0:
835
- return can
836
- elif extraMode==1:
837
- return can+(k,)
838
- else:
839
- return can+p
840
-
841
- def canonicalIndices(self,extraMode=1):
842
- return [self.getCanonicalIndex(i,extraMode=extraMode) for i in range(self.size)]
843
-
844
- def getLabel(self,i,extraMode=1):
845
- t = self.getCanonicalIndex(i,extraMode=extraMode)
846
- return "["+ ",".join(map(str,t)) + "]"
847
-
848
- def labels(self,extraMode=1):
849
- return [self.getLabel(i,extraMode=extraMode) for i in range(self.size)]
850
-
851
- class Structured(object):
852
- description = "Generic Structured object"
853
-
854
- def __init__(self,structure):
855
- self.struct = structure.struct
856
- self.i = self.struct.i
857
- self.f = self.struct.f
858
- self.getStruct = self.struct.getStruct
859
- self.prefix = PrefixConstructor(self)
860
-
861
- @property
862
- def size(self):
863
- return self.struct.size
864
-
865
- @property
866
- def cat(self):
867
- if isinstance(self.master,DataReference):
868
- return self.master.a
869
- else:
870
- return self.master
871
-
872
- def __str__(self,compact=False):
873
- if compact is False:
874
- return self.description + " with following structure:\n" + self.struct.__str__()
875
- else:
876
- return self.description + " (" + self.struct.__str__(compact=True) + ")"
877
-
878
- def keys(self):
879
- return list(self.struct.keys())
880
-
881
- class CasadiStructured(Structured,CasadiStructureDerivable):
882
- description = "Generic Structured object"
883
-
884
- def __setstate__(self,state):
885
- cs = CasadiStructure.__new__(CasadiStructure)
886
- cs.__setstate__({"args": state["args"],"kwargs": state["kwargs"]})
887
- self.__init__(cs,order=state["order"])
888
-
889
- def __getstate__(self):
890
- d = self.struct.__getstate__()
891
- d["order"] = self.order
892
- return d
893
-
894
- def __init__(self,struct,order=None):
895
- self.order = order
896
- if hasattr(struct,"struct"):
897
- Structured.__init__(self,struct.struct)
898
- self.entries = []
899
- else:
900
- entrylist = EntryList(struct,order=order)
901
- self.entries = entrylist.entries
902
- Structured.__init__(self,CasadiStructure(self.entries, order=entrylist.order))
903
-
904
- self.getCanonicalIndex = self.struct.getCanonicalIndex
905
- self.canonicalIndices = self.struct.canonicalIndices
906
- self.getLabel = self.struct.getLabel
907
- self.labels = self.struct.labels
908
- self.priority_object_map = {}
909
-
910
- @property
911
- def shape(self):
912
- return (self.size,1)
913
-
914
- def sparsity(self):
915
- return Sparsity.dense(self.size,1)
916
-
917
- def getCanonicalIndex(self,*args,**kwargs):
918
- return self.struct.lookup(*args,**kwargs)
919
-
920
- class CompatibilityException(Exception):
921
- pass
922
-
923
- class ssymStruct(CasadiStructured,MasterGettable):
924
- description = "symbolic SX"
925
- def __init__(self,struct,order=None):
926
- CasadiStructured.__init__(self,struct,order=order)
927
-
928
- if any(e.expr is not None for e in self.entries):
929
- raise Exception("struct_symSX does not accept entries with an 'expr' argument, because such an element is not purely symbolic.")
930
-
931
- s = []
932
- for i in self.struct.traverseCanonicalIndex():
933
- e = self.struct.getStructEntryByCanonicalIndex(i)
934
- s.append(SX.sym("_".join(map(str,i)),e.sparsity.nnz()))
935
-
936
- self.master = vertcat(*[i.nz[:] for i in s])
937
-
938
- for e in self.entries:
939
- if e.sym is not None:
940
- self.master[self.i[e.name]] = e.sym
941
-
942
- def __SX__(self):
943
- return self.cat
944
-
945
- class VertsplitStructure:
946
- def buildMap(self,struct=None,parentIndex = (),parent=None):
947
- if struct is None: struct = self.struct
948
- if parent is None: parent = self.master
949
-
950
- if isinstance(parent,DataReference):
951
- parent = parent.a
952
-
953
- ks = []
954
- its = []
955
- sps = []
956
- es = []
957
- k = 0 # Global index counter
958
- for i in struct.traverseCanonicalIndex(limit=1):
959
- e = struct.getStructEntryByCanonicalIndex(i)
960
- sp = None
961
- if e.isPrimitive():
962
- sp = Sparsity.dense(1,1) if e.sparsity is None else e.sparsity
963
- else:
964
- sp = Sparsity.dense(e.struct.size,1)
965
- ks.append(k)
966
- it = tuple(i)
967
- es.append(e)
968
- its.append(it)
969
- sps.append(sp)
970
- k += sp.nnz()
971
- ks.append(parent.size1())
972
-
973
- for it, k, sp,e in zip(its,vertsplit(parent,ks),sps,es):
974
- if not(e.isPrimitive()):
975
- self.buildMap(struct=e.struct,parentIndex = parentIndex + it,parent=k)
976
- self.priority_object_map[parentIndex+it] = k if k.sparsity()==sp else MX(sp,k) #[IM(sp,range(sp.nnz()))]
977
-
978
- class msymStruct(CasadiStructured,MasterGettable,VertsplitStructure):
979
- description = "MX.sym"
980
- def __init__(self,struct,order=None):
981
- CasadiStructured.__init__(self,struct,order=order)
982
-
983
- if any(e.expr is not None for e in self.entries):
984
- raise Exception("struct_symMX does not accept entries with an 'expr' argument, because such an element is not purely symbolic.")
985
- if any(e.sym is not None for e in self.entries):
986
- raise Exception("struct_symMX does not accept entries with an 'sym' argument.")
987
-
988
- self.master = MX.sym("V",self.size,1)
989
-
990
- self.buildMap()
991
-
992
- def __MX__(self):
993
- return self.cat
994
-
995
-
996
-
997
-
998
- class MatrixStruct(CasadiStructured,MasterGettable,MasterSettable):
999
-
1000
- @property
1001
- def description(self):
1002
- return "Mutable " + self.mtype.__name__
1003
-
1004
- def __init__(self,struct,mtype,data=None,order=None):
1005
- CasadiStructured.__init__(self,struct,order=None)
1006
- if any(e.expr is None for e in self.entries):
1007
- raise Exception("struct_SX does only accept entries with an 'expr' argument.")
1008
-
1009
- self.mtype = mtype
1010
- if isinstance(data,mtype) or isinstance(data,DataReference):
1011
- self.master = data
1012
- elif data is None:
1013
- self.master = mtype.nan(self.size,1)
1014
- else:
1015
- self.master = mtype(data)
1016
-
1017
- if self.master.shape[0]!=self.size:
1018
- raise Exception("MatrixStruct: dimension error. Expecting %d-by-1, but got %s" % (self.size,self.master.dim()))
1019
- if self.master.shape[1]!=1 and self.master.shape[0]>0:
1020
- raise Exception("MatrixStruct: dimension error. Expecting %d-by-1, but got %s" % (self.size,self.master.dim()))
1021
-
1022
- for e in self.entries:
1023
- self[e.name] = e.expr
1024
-
1025
- class DMStruct(MatrixStruct):
1026
-
1027
- def save(self,filename):
1028
- import pickle
1029
- pickle.dump(self,file(filename,"wb"),2)
1030
-
1031
- def __setstate__(self,state):
1032
- cs = CasadiStructure.__new__(CasadiStructure)
1033
- cs.__setstate__({"args": state["args"],"kwargs": state["kwargs"]})
1034
- self.__init__(cs,data=state["master"])
1035
-
1036
- def __getstate__(self):
1037
- d = self.struct.__getstate__()
1038
- d["master"] = self.master
1039
- return d
1040
-
1041
- def __init__(self,struct,data=None):
1042
- MatrixStruct.__init__(self,struct,DM,data=data)
1043
-
1044
- def __DM__(self):
1045
- return self.cat
1046
-
1047
- class SXStruct(MatrixStruct):
1048
- def __init__(self,struct,data=None):
1049
- MatrixStruct.__init__(self,struct,SX,data=data)
1050
-
1051
- def __SX__(self):
1052
- return self.cat
1053
-
1054
- class MXStruct(MatrixStruct,VertsplitStructure):
1055
- def __init__(self,struct,data=None):
1056
- MatrixStruct.__init__(self,struct,MX,data=data)
1057
-
1058
- self.buildMap()
1059
-
1060
- def __MX__(self):
1061
- return self.cat
1062
-
1063
- class MXVeccatStruct(CasadiStructured,MasterGettable):
1064
- description = "Partially mutable MX"
1065
- def __init__(self,arg,order=None):
1066
- CasadiStructured.__init__(self,arg,order=order)
1067
- if any(e.expr is None for e in self.entries):
1068
- raise Exception("struct_MX does only accept entries with an 'expr' argument.")
1069
-
1070
- self.storage = []
1071
- self.mapping = {}
1072
- for k,i in enumerate(self.struct.traverseCanonicalIndex(limit=1)):
1073
- self.storage.append(None)
1074
- self.mapping[tuple(i)] = k
1075
-
1076
- for e in self.entries:
1077
- self[e.name] = e.expr
1078
-
1079
- self.dirty = True
1080
-
1081
- def __setitem__(self,powerIndex,value):
1082
- if not isinstance(powerIndex,tuple):
1083
- powerIndex = (powerIndex,)
1084
-
1085
- def inject(payload,canonicalIndex,extraIndex=None,entry=None):
1086
- if extraIndex is not None:
1087
- raise Exception("An MX veccat structure does not accept indexing on MX level for __setitem__.")
1088
- if not hasattr(self,"sparsity"):
1089
- raise Exception("An MX veccat structure __setitem__ accepts only objects that have sparsity.")
1090
-
1091
- if canonicalIndex in self.mapping:
1092
- if self.struct.map[canonicalIndex].sparsity()!=payload.sparsity():
1093
- raise Exception("Error in powerIndex slicing %s for canonicalIndex %s: Shape mismatch. lhs is %s, rhs is %s." % (str(powerIndex),str(canonicalIndex),self.struct.map[canonicalIndex].sparsity().dim(),payload.sparsity().dim()))
1094
- self.storage[self.mapping[canonicalIndex]] = payload
1095
- else:
1096
- raise Exception("Not found: %s " % str(canonicalIndex))
1097
- self.dirty = True
1098
- return self.struct.traverseByPowerIndex(powerIndex,dispatcher=inject,payload=value)
1099
-
1100
- def __MX__(self):
1101
- return self.cat
1102
-
1103
- @property
1104
- def master(self):
1105
- if any(e is None for e in self.storage):
1106
- missing = [k for k in list(self.mapping.keys()) if self.storage[self.mapping[k]] is None]
1107
- raise Exception("Problem in MX vecNZcat structure cat: missing expressions. The following entries are missing: %s" % str(missing))
1108
-
1109
- if self.dirty:
1110
- self.master_cached = vertcat(*[casadi.vec(i if i.is_dense() else i.nz[:]) for i in self.storage])
1111
-
1112
- return self.master_cached
1113
-
1114
-
1115
- struct_symSX = ssymStruct
1116
- struct_symMX = msymStruct
1117
- struct_SX = SXStruct
1118
- struct_MX_mutable = MXStruct
1119
- struct_MX = MXVeccatStruct
1120
- struct = CasadiStructured
1121
-
1122
-
1123
-
1124
- entry = StructEntry
1125
-
1126
- class CasadiStructEntry(StructEntry):
1127
- def __init__(self,*args,**kwargs):
1128
- if len(args)==0:
1129
- raise Exception("Missing name argument (first argument of Entry)")
1130
- else:
1131
- self.name = args[0]
1132
- self.dict = kwargs
1133
-
1134
- if len(args)>1:
1135
- raise Exception("Don't know what to do with unnamed arguments %s" % str(args[1:]))
1136
-
1137
-
1138
-
1139
- kw = list(kwargs.keys())
1140
- kws = ['repeat','shape','sym','expr','struct','shapestruct','type']
1141
- for k in kw:
1142
- if k not in kws:
1143
- raise Exception("Unknown keyword argument '%s'. Please use one of %s." % (k,str(kws)))
1144
-
1145
-
1146
-
1147
- for kc, fk in [
1148
- ('shape',['struct']),
1149
- ('struct',['shape','shapestruct']),
1150
- ('shapestruct',['struct']), # You might have a sparse matrix with shapestruct
1151
- ('sym',['shape','repeat','expr']),
1152
- ('expr',['shape','repeat','sym'])
1153
- ]:
1154
- if kc in kwargs:
1155
- for fki in fk:
1156
- if fki in kwargs:
1157
- raise Exception("You supplied keyword argument '%s', but it cannot be combined with keyword argument '%s'." % (kc,fki))
1158
-
1159
- # repeat argument
1160
- self.repeat = []
1161
-
1162
- if 'repeat' in kwargs:
1163
- self.repeat = kwargs["repeat"] if isinstance(kwargs["repeat"],list) else [kwargs["repeat"]]
1164
-
1165
- if not all([is_integer(x) for x in self.repeat]):
1166
- raise Exception("The 'repeat' argument, if present, must be a list of integers, but got %s" % str(self.repeat))
1167
-
1168
-
1169
- self.struct = None
1170
- # struct argument
1171
- if 'struct' in kwargs:
1172
- struct = kwargs["struct"]
1173
- if isinstance(struct,Structure):
1174
- self.struct = struct
1175
- elif isinstance(struct,Structured):
1176
- self.struct = struct.struct
1177
-
1178
-
1179
- self.sparsity = None
1180
- # shape argument
1181
- if 'shape' in kwargs:
1182
- shape = kwargs["shape"]
1183
- if is_integer(shape) :
1184
- self.sparsity = Sparsity.dense(shape,1)
1185
- elif isinstance(shape,list) or isinstance(shape,tuple):
1186
- if len(shape)==0 or len(shape)>2:
1187
- raise Exception("The 'shape' argument, if present, must be an integer, a tuple of 1 or 2 integers, a sparsity pattern.")
1188
- else:
1189
- self.sparsity = Sparsity.dense(*shape)
1190
- elif isinstance(shape,Sparsity):
1191
- self.sparsity = shape
1192
- else:
1193
- raise Exception("The 'shape' argument, if present, must be an integer, a tuple of 1 or 2 integers, or a sparsity pattern. Got %s " % str(shape))
1194
- else:
1195
- self.sparsity = Sparsity.dense(1,1)
1196
-
1197
- self.shapestruct = None
1198
- # shapestruct argument
1199
- if 'shapestruct' in kwargs:
1200
- shapestruct = kwargs["shapestruct"]
1201
- if isinstance(shapestruct,Structured) or isinstance(shapestruct,Structure):
1202
- self.shapestruct = (shapestruct.struct,1)
1203
- elif isinstance(shapestruct,tuple):
1204
- if not(all([isinstance(e,Structured) or isinstance(e,Structure) or is_integer(e) for e in shapestruct])) or len(shapestruct)==0 or len(shapestruct)>2:
1205
- raise Exception("The 'shapestruct' argument, if present, must be a structure or a tuple of structures or numbers")
1206
- self.shapestruct = tuple([e if is_integer(e) else e.struct for e in shapestruct])
1207
- else:
1208
- raise Exception("The 'shapestruct' argument, if present, must be a structure or a tuple of at most structures")
1209
-
1210
- if 'shape' not in kwargs:
1211
- self.sparsity = Sparsity.dense(*[e if is_integer(e) else e.size for e in self.shapestruct])
1212
-
1213
- # sym argument
1214
- self.sym = None
1215
- if 'sym' in kwargs:
1216
- sym = kwargs["sym"]
1217
- if isinstance(sym,SX) and sym.is_valid_input():
1218
- self.sym = sym
1219
- elif isinstance(sym,Structured):
1220
- self.struct = sym.struct
1221
- self.sym = sym.cat
1222
- else:
1223
- raise Exception("The 'sym' argument must be a purely symbolic SX or a structured symbolic. Got %s instead." % str(self.sym))
1224
- self.sparsity = self.sym.sparsity()
1225
-
1226
- # expr argument
1227
- self.expr = None
1228
- if 'expr' in kwargs:
1229
- self.expr = kwargs["expr"]
1230
-
1231
- def getPrimitive(e,repeat=[]):
1232
- if isinstance(e,list):
1233
- if len(e)==0:
1234
- return None,repeat+[0]
1235
- else:
1236
- return getPrimitive(e[0],repeat=repeat+[len(e)])
1237
- else:
1238
- return e,repeat
1239
-
1240
-
1241
- p,r = getPrimitive(self.expr)
1242
-
1243
- if p is None:
1244
- self.repeat = [0]
1245
- self.sparsity = Sparsity.dense(0,0)
1246
- else:
1247
- self.repeat = r
1248
-
1249
- if hasattr(p,"sparsity"):
1250
- self.sparsity = p.sparsity()
1251
- else:
1252
- raise Exception("The 'expr' argument must be a matrix expression or nested list of matrix expressions. Got %s instead." % str(p))
1253
-
1254
- self.type = None
1255
- # class argument
1256
- if 'type' in kwargs:
1257
- self.type= kwargs["type"]
1258
- allowedclass = ['symm']
1259
- if self.type not in allowedclass:
1260
- raise Exception("You supplied a type argument '%s' but it is not recognised. Use one of %s" % (str(self.type,str(allowedclass))))
1261
- if self.type=="symm":
1262
- if self.sparsity.size1() != self.sparsity.size2():
1263
- raise Exception("You supplied a type 'symm', but matrix is not square. Got " % self.sparsity.dim() + ".")
1264
- self.originalsparsity = self.sparsity
1265
- self.sparsity = self.sparsity*Sparsity.upper(self.sparsity.size1())
1266
-
1267
-
1268
-
1269
- StructEntry.__init__(self,self.name,struct=self.struct,dims=self.repeat,data=self.sparsity)
1270
-
1271
- def primitiveString(self):
1272
- if self.type is None:
1273
- return self.sparsity.dim()
1274
- elif self.type=="symm":
1275
- return "symm(" + self.sparsity.dim() + ")"
1276
-
1277
- def __getstate__(self):
1278
- return dict((k,getattr(self,k)) for k in ["name", "struct", "sparsity","type","repeat","shapestruct","dims"])
1279
-
1280
-
1281
- def entry(*args,**kwargs):
1282
- if len(args)==1 and isinstance(args[0],CasadiStructEntry):
1283
- return args[0]
1284
- return CasadiStructEntry(*args,**kwargs)
1285
-
1286
- class EntryList:
1287
- def __init__(self,arg,order = None):
1288
- self.entries = []
1289
- self.order = []
1290
-
1291
- if not isinstance(arg,list):
1292
- raise Exception("Expecting list of entries, with possible tuples for grouping, but got %s" % str(arg))
1293
-
1294
- for e in arg:
1295
- if isinstance(e,tuple):
1296
- entries = list(map(entry,e))
1297
- self.order.append(tuple(x.name for x in entries))
1298
- self.entries+=entries
1299
- else:
1300
- ee = entry(e)
1301
- self.order.append(ee.name)
1302
- self.entries.append(ee)
1303
-
1304
- # Override order
1305
- if order is not None:
1306
- if any(isinstance(e,tuple) for e in self.order):
1307
- raise Exception("You supplied an order by using tuple syntax on entries %s, but you overwrite it with the 'order' keyword. Use one or the other, not both.")
1308
- self.order = order
1309
- self.names = [x.name for x in self.entries]
1310
- if len(self.names)!=len(set(self.names)):
1311
- duplicates = []
1312
- for i,e in enumerate(self.names):
1313
- if e in self.names[:i] or e in self.names[i+1:]:
1314
- duplicates.append(e)
1315
- raise Exception("Your list of entries contains duplicates: %s" % str(list(set(duplicates))))
1316
-
1317
-
1318
- class Delegater:
1319
- def __init__(self,arg):
1320
- self.arg = arg
1321
-
1322
- def __str__(self):
1323
- return "%s[%s]" % (self.__class__.__name__,str(self.arg))
1324
-
1325
- __repr__ = __str__
1326
-
1327
-
1328
- class IndexDelegater(Delegater):
1329
- def __call__(self,struct):
1330
- return struct.i.__getitem__(self.arg)
1331
-
1332
- class FlatIndexDelegater(Delegater):
1333
- def __call__(self,struct):
1334
- return struct.f.__getitem__(self.arg)
1335
-
1336
-
1337
- class DelegaterConstructor:
1338
- """
1339
- Creates an object that delegates a slicing operation.
1340
-
1341
- Example usage:
1342
- s = struct_symSX([])
1343
- x = struct_symSX(entry("x",Sparsity.diag(4)))
1344
- x["x",0,index[:]]
1345
-
1346
- """
1347
- def __init__(self,delegater,prepend=()):
1348
- self.prepend = prepend
1349
- self.delegater = delegater
1350
-
1351
- @properGetitem
1352
- def __getitem__(self,arg):
1353
- return self.delegater(self.prepend + arg)
1354
-
1355
- index = DelegaterConstructor(IndexDelegater)
1356
- indexf = DelegaterConstructor(FlatIndexDelegater)
1357
-
1358
- class DataReference:
1359
- @property
1360
- def shape(self):
1361
- return self.v.shape
1362
-
1363
- def dim(self):
1364
- return self.v.dim()
1365
-
1366
-
1367
- class DataReferenceRepeated(DataReference):
1368
- def __init__(self,a,n):
1369
- assert(a.is_dense())
1370
- self.a = a
1371
- self.n = n
1372
- self.v = a.reshape((n*a.size1(),1))
1373
-
1374
- def __setitem__(self,a,b):
1375
- self.v.nz[a] = b
1376
- I = self.a.sparsity().find()
1377
- self.a.nz[I] = self.v.nz[I]
1378
-
1379
- def __getitem__(self,a):
1380
- return self.v.nz[a]
1381
-
1382
- class DataReferenceSquared(DataReference):
1383
- def __init__(self,a,n):
1384
- assert(a.is_dense())
1385
- self.a = a
1386
- self.v = a
1387
- self.n = n
1388
-
1389
- def __setitem__(self,a,b):
1390
- self.a.nz[a] = b
1391
-
1392
- def __getitem__(self,a):
1393
- return self.a.nz[a]
1394
-
1395
- @property
1396
- def shape(self):
1397
- return (self.n*self.n,1)
1398
-
1399
- class DataReferenceProduct(DataReference):
1400
- def __init__(self,a,n,m):
1401
- assert(a.is_dense())
1402
- self.a = a
1403
- self.v = a
1404
- self.n = n
1405
- self.m = m
1406
-
1407
- def __setitem__(self,a,b):
1408
- self.a.nz[a] = b
1409
-
1410
- def __getitem__(self,a):
1411
- return self.a.nz[a]
1412
-
1413
- @property
1414
- def shape(self):
1415
- return (self.n*self.m,1)
1416
-
1417
- def size1(self):
1418
- return self.n
1419
-
1420
- def size2(self):
1421
- return self.m
1422
-
1423
- class DataReferenceSquaredRepeated(DataReference):
1424
- def __init__(self,a,n,N):
1425
- assert(a.is_dense())
1426
- self.a = a
1427
- self.n = n
1428
- self.N = N
1429
- self.v = a.reshape((n*n*N,1))
1430
-
1431
- def __setitem__(self,a,b):
1432
- self.v.nz[a] = b
1433
- I = self.a.sparsity().find()
1434
- self.a.nz[I] = self.v.nz[I]
1435
-
1436
- def __getitem__(self,a):
1437
- return self.v.nz[a]
1438
-
1439
- def struct_load(filename):
1440
- import pickle
1441
- return pickle.load(file(filename,"rb"))