31 T1 casadi_cvx_house(T1* v, T1* beta, casadi_int nv) {
38 for (i=1; i<nv; ++i) sigma += v[i]*v[i];
39 s = sqrt(v0*v0 + sigma);
52 *beta = 2*v02/(sigma+v02);
54 for (i=1;i<nv;++i) v[i] /= v0;
75 void casadi_cvx_house_apply_symm(casadi_int n, casadi_int k, T1* A, T1* p, T1* v, T1 beta) {
76 casadi_int i, j, stride, N;
88 p[i] += beta*(*a++)*v[i];
91 p[j] += beta*(*a)*v[i];
92 p[i] += beta*(*a++)*v[j];
98 casadi_axpy(N, -beta*casadi_dot(N, p, v)/2, v, p);
106 for (j=i+1;j<N;++j) {
107 *a++ -= v[i]*p[j]+v[j]*p[i];
124 template<
typename T1>
125 void casadi_cvx_tri(T1* A, casadi_int n, T1* beta, T1* p) {
129 for (k=0;k<n-2;++k) {
136 casadi_copy(A_base, N, v);
139 *A_base = casadi_cvx_house(v, &beta[k], N);
141 casadi_cvx_house_apply_symm(n, k, A, pp, v, beta[k]);
149 template<
typename T1>
150 void casadi_cvx_givens(T1 a, T1 b, T1* c, T1* s) {
156 if (fabs(b)>fabs(a)) {
177 template<
typename T1>
178 void casadi_cvx_implicit_qr(casadi_int n, T1* t_diag, T1* t_off, T1* cs) {
179 T1 d, mu, to2, x, z, c, s, t1, t2, d0, d1, o0, o1, sd;
181 d = 0.5*(t_diag[n-2]-t_diag[n-1]);
182 to2 = t_off[n-2]*t_off[n-2];
185 mu = t_diag[n-1]-to2/(d+sd*sqrt(d*d+to2));
188 for (i=0;i<n-1;++i) {
190 casadi_cvx_givens(x, z, &c, &s);
198 t_diag[i] = c*t1-s*t2;
199 t_off[i] = s*t1+c*t2;
200 t_diag[i+1] = d0*s*s+2*s*o0*c+d1*c*c;
203 t_off[i-1] = t_off[i-1]*c-z*s;
229 template<
typename T1>
230 int casadi_cvx_symm_schur(casadi_int n, T1* t_diag, T1* t_off, T1 tol, casadi_int max_iter,
231 casadi_int* trace_meta, T1* trace) {
232 casadi_int i, p, q, sp, sq, trace_offset, nn;
234 n_iter = trace_meta++;
241 if (*n_iter==max_iter)
return 1;
243 for (i=0;i<n-1;++i) {
244 if (fabs(t_off[i])<=tol*(fabs(t_diag[i])+fabs(t_diag[i+1]))) {
254 for (i=0;i<n-1;++i) {
255 if (t_off[n-i-2]==0 && sq==0) {
260 if (t_off[i]==0 && sp==0) {
273 casadi_cvx_implicit_qr(nn, t_diag+p, t_off+p, trace ? trace+trace_offset :
nullptr);
274 trace_offset += 2*(nn-1);
279 *trace_meta++ = trace_offset;
290 template<
typename T1>
291 void casadi_cvx_givens_apply(casadi_int n, T1* q, T1 c, T1 s, casadi_int p) {
292 T1 t1, t2, t3, t4, a, b;
306 t2 = c*m[1]+s*m[n+1];
308 t4 = c*m[n+1]-s*m[1];
314 for (i=0;i<n-p-2;++i) {
337 template<
typename T1>
338 void casadi_cvx_house_apply(casadi_int n, casadi_int m, casadi_int s, T1* A,
339 T1* p,
const T1* v, T1 beta) {
352 p[i] += beta*a[j]*v[j];
369 template<
typename T1>
370 T1 casadi_cvx_scalar(T1 epsilon, casadi_int reflect, T1 eig) {
371 return fmax(epsilon, reflect ? fabs(eig) : eig);
384 template<
typename T1>
385 int casadi_cvx(casadi_int n, T1 *A, T1 epsilon, T1 tol, casadi_int reflect, casadi_int max_iter,
386 T1* w, casadi_int* iw) {
387 casadi_int i, j, k, n_iter, nn, p, trace_offset;
390 T1 *cs, *t_diag, *t_off;
398 A[0] = casadi_cvx_scalar(epsilon, reflect, A[0]);
402 casadi_cvx_tri(A, n, beta, w);
417 t_diag[i] = A[i+n*i];
420 for (i=1;i<n-1;++i) {
421 t_off[i] = A[i+1+n*i];
425 if (casadi_cvx_symm_schur(n, t_diag, t_off, tol, max_iter, iw, w))
return 1;
429 A[i+n*i] = casadi_cvx_scalar(epsilon, reflect, t_diag[i]);
434 for (j=i+1;j<n;++j) A[j+i*n] = 0;
439 t_meta = iw+3*(n_iter-1)+1;
441 for (i=0;i<n_iter;++i) {
444 trace_offset = *t_meta++;
447 for (j=0;j<nn-1;j++) {
450 casadi_cvx_givens_apply(n, A, c, s, p+nn-j-2);
455 for (k = n-3; k>=0; --k) {
456 casadi_int N = n-k-1;
458 casadi_cvx_house_apply_symm(n, k, A, w, v, beta[k]);
459 casadi_cvx_house_apply(k+1, N, n, A+k+1, w, v, beta[k]);