clarabel_runtime.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 template<typename T1>
22  // The base QP problem (provided by CasADi)
24  // CSC representation for the quadratic cost (P)
25  const int *colindp, *rowp;
26  // CSC representation for the constraint matrix (A)
27  const int *colinda, *rowa;
28 };
29 
30 template<typename T1>
31 void casadi_clarabel_setup(casadi_clarabel_prob<T1>* p) {
32  // In this simple example the setup is trivial.
33  // (If any preprocessing is needed on the CSC arrays, do it here.)
34 }
35 
36 // The data structure that will be passed persistently during a solve.
37 template<typename T1>
39  // Pointer to the problem data
41  // The QP data (pointers to cost, bounds, etc.)
43  // A return status from Clarabel
45 };
46 
47 // Allocate and initialize memory for Clarabel
48 template<typename T1>
49 int clarabel_init_mem(casadi_clarabel_data<T1>* d) {
50  return 0;
51 }
52 
53 template<typename T1>
54 void clarabel_free_mem(casadi_clarabel_data<T1>* d) {
55 }
56 
57 // The work vector sizes are determined from the QP problem.
58 template<typename T1>
59 void casadi_clarabel_work(const casadi_clarabel_prob<T1>* p,
60  casadi_int* sz_arg,
61  casadi_int* sz_res,
62  casadi_int* sz_iw,
63  casadi_int* sz_w) {
64  casadi_qp_work(p->qp, sz_arg, sz_res, sz_iw, sz_w);
65 }
66 
67 // (Optionally, initialize pointer arrays here; we leave this empty.)
68 template<typename T1>
69 void casadi_clarabel_init(casadi_clarabel_data<T1>* d,
70  const T1*** arg,
71  T1*** res,
72  casadi_int** iw,
73  T1** w) {
74  // No special initialization needed in this example.
75 }
76 
77 // The main solve routine: builds the Clarabel problem, calls the solver,
78 // and retrieves the solution.
79 template<typename T1>
80 int casadi_clarabel_solve(casadi_clarabel_data<T1>* d,
81  const double** arg,
82  double** res,
83  casadi_int* iw,
84  double* w) {
85  /*const casadi_clarabel_prob<T1>* p = d->prob;
86  const casadi_qp_prob<T1>* p_qp = p->qp;
87  casadi_qp_data<T1>* d_qp = d->qp;
88 
89  // Build the CSC matrix for the quadratic cost P.
90  ClarabelCscMatrix P;
91  clarabel_CscMatrix_init(&P,
92  p_qp->nx, // number of rows (variables)
93  p_qp->nx, // number of columns
94  reinterpret_cast<uintptr_t*>(const_cast<int*>(p->colindp)),
95  reinterpret_cast<uintptr_t*>(const_cast<int*>(p->rowp)),
96  d_qp->h // pointer to the nonzero Hessian entries
97  );
98 
99  // Build the CSC matrix for the constraints A.
100  ClarabelCscMatrix A;
101  clarabel_CscMatrix_init(&A,
102  p_qp->na, // number of constraints (rows)
103  p_qp->nx, // number of variables (columns)
104  reinterpret_cast<uintptr_t*>(const_cast<int*>(p->colinda)),
105  reinterpret_cast<uintptr_t*>(const_cast<int*>(p->rowa)),
106  d_qp->a // pointer to the nonzero entries of A
107  );
108 
109  // For the cost, use q stored in d_qp->g.
110  const ClarabelFloat* q = d_qp->g;
111  // For the constraints, we assume that the right-hand side is stored in d_qp->b.
112  const ClarabelFloat* b = d_qp->b;
113 
114  // For the cones, we simply assume that all constraints are equalities.
115  // (Clarabel represents an equality as a zero cone.)
116  ClarabelSupportedConeT cones[1];
117  cones[0] = ClarabelZeroConeT(p_qp->na);
118 
119  // Get default settings for Clarabel.
120  ClarabelDefaultSettings settings = clarabel_DefaultSettings_default();
121 
122  // Create a Clarabel solver instance with the problem data.
123  ClarabelDefaultSolver* solver = clarabel_DefaultSolver_new(&P, q, &A, b, 1, cones, &settings);
124 
125  // Solve the problem.
126  clarabel_DefaultSolver_solve(solver);
127 
128  // Retrieve the solution.
129  ClarabelDefaultSolution solution = clarabel_DefaultSolver_solution(solver);
130  for (int i = 0; i < p_qp->nx; ++i) {
131  d_qp->x[i] = solution.x[i];
132  }
133  if (d_qp->f) {
134  *d_qp->f = solution.obj_val;
135  }
136  d_qp->success = (solution.status == ClarabelSolved);
137  d->return_status = solution.status;
138 
139  clarabel_DefaultSolver_free(solver);*/
140 
141 // QP Example
142 
143  /* From dense matrix:
144  * [[6., 0.],
145  * [0., 4.]]
146  */
147  ClarabelCscMatrix P;
148 
149  uintptr_t colptr[3] = { 0, 1, 2 };
150  uintptr_t rowval[2] = { 0, 1 };
151  ClarabelFloat nzval[2] = { 6., 4. };
152  clarabel_CscMatrix_init(
153  &P,
154  2, // row
155  2, // col
156  colptr, // colptr
157  rowval, // rowval
158  nzval// nzval
159  );
160 
161  ClarabelFloat q[2] = { -1., -4. };
162 
163  /* From dense matrix:
164  * [[ 1., -2.], // <-- LHS of equality constraint (lower bound)
165  * [ 1., 0.], // <-- LHS of inequality constraint (upper bound)
166  * [ 0., 1.], // <-- LHS of inequality constraint (upper bound)
167  * [-1., 0.], // <-- LHS of inequality constraint (lower bound)
168  * [ 0., -1.]] // <-- LHS of inequality constraint (lower bound)
169  */
170  ClarabelCscMatrix A;
171 
172  uintptr_t colptr_A[3] = { 0, 2, 5 };
173  uintptr_t rowval_A[5] = { 0, 1, 0, 2, 3 };
174  ClarabelFloat nzval_A[5] = { 1., 1., -2., 1., -1. };
175  clarabel_CscMatrix_init(
176  &A,
177  5, // row
178  2, // col
179  colptr_A, // colptr
180  rowval_A, // rowval
181  nzval_A // nzval
182  );
183 
184  ClarabelFloat b[5] = { 0., 1., 1., 1., 1. };
185 
186  ClarabelSupportedConeT cones[2];
187 
188  cones[0].tag = ClarabelZeroConeT_Tag;
189  cones[0].zero_cone_t = 1;
190  cones[1].tag = ClarabelNonnegativeConeT_Tag;
191  cones[1].nonnegative_cone_t = 4;
192 
193  // Settings
194  ClarabelDefaultSettings settings = clarabel_DefaultSettings_default();
195 
196  // Build solver
197  ClarabelDefaultSolver *solver = clarabel_DefaultSolver_new(
198  &P, // P
199  q, // q
200  &A, // A
201  b, // b
202  2, // n_cones
203  cones, &settings
204  );
205 
206  // Solve
207  clarabel_DefaultSolver_solve(solver);
208 
209  // Get solution
210  ClarabelDefaultSolution solution = clarabel_DefaultSolver_solution(solver);
211  printf("sol.x[0]: %e", solution.x[0]);
212 
213  // Free the matrices and the solver
214  clarabel_DefaultSolver_free(solver);
215 
216  casadi_qp_data<T1>* d_qp = d->qp;
217 
218  d_qp->success = true;
219 
220  return 0;
221 }
const casadi_clarabel_prob< T1 > * prob
casadi_qp_data< T1 > * qp
const casadi_qp_prob< T1 > * qp