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