32 T1 casadi_cvx_house(T1* v, T1* beta, casadi_int nv) {
39 for (i=1; i<nv; ++i) sigma += v[i]*v[i];
40 s = sqrt(v0*v0 + sigma);
54 *beta = 2*v02/(sigma+v02);
56 for (i=1;i<nv;++i) v[i] /= v0;
77 void casadi_cvx_house_apply_symm(casadi_int n, casadi_int k, T1* A, T1* p, T1* v, T1 beta) {
78 casadi_int i, j, stride, N;
90 p[i] += beta*(*a++)*v[i];
93 p[j] += beta*(*a)*v[i];
94 p[i] += beta*(*a++)*v[j];
100 casadi_axpy(N, -beta*casadi_dot(N, p, v)/2, v, p);
108 for (j=i+1;j<N;++j) {
109 *a++ -= v[i]*p[j]+v[j]*p[i];
126 template<
typename T1>
127 void casadi_cvx_tri(T1* A, casadi_int n, T1* p) {
129 T1 *A_base, *v, beta;
130 for (k=0;k<n-2;++k) {
137 casadi_copy(A_base, N, v);
140 *A_base = casadi_cvx_house(v, &beta, N);
142 casadi_cvx_house_apply_symm(n, k, A, p, v, beta);
149 template<
typename T1>
150 T1 casadi_cvx_beta(
const T1* v, casadi_int nv) {
151 return v[0]==0 ? 0 : 2/casadi_dot(nv, v, v);
157 template<
typename T1>
158 void casadi_cvx_givens(T1 a, T1 b, T1* c, T1* s) {
164 if (fabs(b)>fabs(a)) {
185 template<
typename T1>
186 void casadi_cvx_implicit_qr(casadi_int n, T1* t_diag, T1* t_off, T1* cs) {
187 T1 d, mu, to2, x, z, c, s, t1, t2, d0, d1, o0, o1, sd;
189 d = 0.5*(t_diag[n-2]-t_diag[n-1]);
190 to2 = t_off[n-2]*t_off[n-2];
193 mu = t_diag[n-1]-to2/(d+sd*sqrt(d*d+to2));
196 for (i=0;i<n-1;++i) {
198 casadi_cvx_givens(x, z, &c, &s);
206 t_diag[i] = c*t1-s*t2;
207 t_off[i] = s*t1+c*t2;
208 t_diag[i+1] = d0*s*s+2*s*o0*c+d1*c*c;
211 t_off[i-1] = t_off[i-1]*c-z*s;
237 template<
typename T1>
238 int casadi_cvx_symm_schur(casadi_int n, T1* t_diag, T1* t_off, T1 tol, casadi_int max_iter,
239 casadi_int* trace_meta, T1* trace) {
240 casadi_int i, p, q, sp, sq, trace_offset, nn;
242 n_iter = trace_meta++;
249 if (*n_iter==max_iter)
return 1;
251 for (i=0;i<n-1;++i) {
252 if (fabs(t_off[i])<=tol*(fabs(t_diag[i])+fabs(t_diag[i+1]))) {
262 for (i=0;i<n-1;++i) {
263 if (t_off[n-i-2]==0 && sq==0) {
268 if (t_off[i]==0 && sp==0) {
281 casadi_cvx_implicit_qr(nn, t_diag+p, t_off+p, trace ? trace+trace_offset :
nullptr);
282 trace_offset += 2*(nn-1);
287 *trace_meta++ = trace_offset;
298 template<
typename T1>
299 void casadi_cvx_givens_apply(casadi_int n, T1* q, T1 c, T1 s, casadi_int p) {
300 T1 t1, t2, t3, t4, a,
b;
314 t2 = c*m[1]+s*m[n+1];
316 t4 = c*m[n+1]-s*m[1];
322 for (i=0;i<n-p-2;++i) {
345 template<
typename T1>
346 void casadi_cvx_house_apply(casadi_int n, casadi_int m, casadi_int s, T1* A,
347 T1* p,
const T1* v, T1 beta) {
360 p[i] += beta*a[j]*v[j];
378 template<
typename T1>
379 T1 casadi_cvx_scalar(T1 epsilon, casadi_int reflect, T1 eig) {
380 return fmax(epsilon, reflect ? fabs(eig) : eig);
393 template<
typename T1>
394 int casadi_cvx(casadi_int n, T1 *A, T1 epsilon, T1 tol, casadi_int reflect, casadi_int max_iter,
395 T1* w, casadi_int* iw) {
396 casadi_int i, j, k, n_iter, nn, p, trace_offset;
398 T1 c, s, t_off0, beta;
399 T1 *cs, *t_diag, *t_off;
406 A[0] = casadi_cvx_scalar(epsilon, reflect, A[0]);
410 casadi_cvx_tri(A, n, w);
425 t_diag[i] = A[i+n*i];
428 for (i=1;i<n-1;++i) {
429 t_off[i] = A[i+1+n*i];
433 if (casadi_cvx_symm_schur(n, t_diag, t_off, tol, max_iter, iw, w))
return 1;
437 A[i+n*i] = casadi_cvx_scalar(epsilon, reflect, t_diag[i]);
442 for (j=i+1;j<n;++j) A[j+i*n] = 0;
447 t_meta = iw+3*(n_iter-1)+1;
449 for (i=0;i<n_iter;++i) {
452 trace_offset = *t_meta++;
455 for (j=0;j<nn-1;j++) {
458 casadi_cvx_givens_apply(n, A, c, s, p+nn-j-2);
463 for (k = n-3; k>=0; --k) {
464 casadi_int N = n-k-1;
466 beta = casadi_cvx_beta(v, N);
467 casadi_cvx_house_apply_symm(n, k, A, w, v, beta);
468 casadi_cvx_house_apply(k+1, N, n, A+k+1, w, v, beta);