1from typing
import Tuple, Union
5from os.path
import join, basename
19 second_order: bool =
False,
20 name: str =
"alpaqa_problem",
21) -> Tuple[cs.CodeGenerator, int, int, int]:
22 """Convert the objective and constraint functions into a CasADi code
25 :param f: Objective function.
26 :param g: Constraint function.
27 :param second_order: Whether to generate functions for evaluating Hessians.
28 :param name: Optional string description of the problem (used
for filename).
30 :
return: * Code generator that generates the functions
and derivatives
32 * Dimensions of the decision variables (primal dimension).
33 * Number of nonlinear constraints (dual dimension).
34 * Number of parameters.
37 assert f.n_in()
in [1, 2]
38 assert f.n_in() == g.n_in()
39 assert f.size1_in(0) == g.size1_in(0)
41 assert f.size1_in(1) == g.size1_in(1)
46 p = f.size1_in(1)
if f.n_in() == 2
else 0
47 xp = (f.sx_in(0), f.sx_in(1))
if f.n_in() == 2
else (f.sx_in(0), )
48 xp_names = (f.name_in(0),
49 f.name_in(1))
if f.n_in() == 2
else (f.name_in(0), )
54 L =
f(*xp) + cs.dot(y,
g(*xp))
if m > 0
else f(*xp)
57 cg = cs.CodeGenerator(cgname)
69 [cs.gradient(
f(*xp), x)],
84 [cs.jtimes(
g(*xp), x, y,
True)],
93 [cs.hessian(L, x)[0]],
101 [cs.gradient(cs.jtimes(L, x, v,
False), x)],
102 [*xp_names,
"y",
"v"],
108def _load_casadi_problem(sofile, n, m, p):
110 prob = pa.load_casadi_problem_with_param(sofile, n, m, p)
112 prob = pa.load_casadi_problem(sofile, n, m)
119 second_order: bool =
False,
120 name: str =
"alpaqa_problem",
121) -> Union[pa.Problem, pa.ProblemWithParam]:
122 """Compile the objective and constraint functions into a alpaqa Problem.
124 :param f: Objective function.
125 :param g: Constraint function.
126 :param second_order: Whether to generate functions for evaluating Hessians.
127 :param name: Optional string description of the problem (used
for filename).
129 :
return: * Problem specification that can be passed to the solvers.
134 homecachedir = os.path.expanduser(
"~/.cache")
135 if os.path.isdir(homecachedir):
136 cachedir = join(homecachedir,
'alpaqa',
'cache')
138 cachedir = join(tempfile.gettempdir(),
'alpaqa',
'cache')
139 cachefile = join(cachedir,
'problems')
141 key = base64.b64encode(pickle.dumps(
142 (f, g, second_order, name))).decode(
'ascii')
144 os.makedirs(cachedir, exist_ok=
True)
145 with shelve.open(cachefile)
as cache:
147 uid, soname, dim = cache[key]
148 probdir = join(cachedir, str(uid))
149 sofile = join(probdir, soname)
151 return _load_casadi_problem(sofile, *dim)
158 projdir = join(cachedir,
"build")
159 builddir = join(projdir,
"build")
160 os.makedirs(builddir, exist_ok=
True)
161 probdir = join(cachedir, str(uid))
163 cfile = cgen.generate(join(projdir,
""))
164 with open(join(projdir,
'CMakeLists.txt'),
'w')
as f:
166 cmake_minimum_required(VERSION 3.17)
167 project(CasADi-{name} LANGUAGES C)
168 set(CMAKE_SHARED_LIBRARY_PREFIX "")
169 add_library({name} SHARED {basename(cfile)})
170 install(FILES $<TARGET_FILE:{name}>
172 install(FILES {basename(cfile)}
175 build_type = 'Release'
176 configure_cmd = [
'cmake',
'-B', builddir,
'-S', projdir]
177 if platform.system() !=
'Windows':
178 configure_cmd += [
'-G',
'Ninja Multi-Config']
179 build_cmd = [
'cmake',
'--build', builddir,
'--config', build_type]
181 'cmake',
'--install', builddir,
'--config', build_type,
'--prefix',
184 subprocess.run(configure_cmd, check=
True)
185 subprocess.run(build_cmd, check=
True)
186 subprocess.run(install_cmd, check=
True)
187 sofile = glob.glob(join(probdir,
"lib", name +
".*"))
190 f
"Unable to find compiled CasADi problem '{name}'")
191 elif len(sofile) > 1:
192 raise RuntimeWarning(
193 f
"Multiple compiled CasADi problem files were found for '{name}'"
196 soname = os.path.relpath(sofile, probdir)
197 cache[key] = uid, soname, (n, m, p)
199 return _load_casadi_problem(sofile, n, m, p)
Tuple[cs.CodeGenerator, int, int, int] generate_casadi_problem(cs.Function f, cs.Function g, bool second_order=False, str name="alpaqa_problem")
Union[pa.Problem, pa.ProblemWithParam] generate_and_compile_casadi_problem(cs.Function f, cs.Function g, bool second_order=False, str name="alpaqa_problem")
auto project(const Vec &v, const Box &box)
Project a vector onto a box.