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);
53 *beta = 2*v02/(sigma+v02);
55 for (i=1;i<nv;++i) v[i] /= v0;
76 void casadi_cvx_house_apply_symm(casadi_int n, casadi_int k, T1* A, T1* p, T1* v, T1 beta) {
77 casadi_int i, j, stride, N;
89 p[i] += beta*(*a++)*v[i];
92 p[j] += beta*(*a)*v[i];
93 p[i] += beta*(*a++)*v[j];
99 casadi_axpy(N, -beta*casadi_dot(N, p, v)/2, v, p);
107 for (j=i+1;j<N;++j) {
108 *a++ -= v[i]*p[j]+v[j]*p[i];
125 template<
typename T1>
126 void casadi_cvx_tri(T1* A, casadi_int n, T1* beta, T1* p) {
130 for (k=0;k<n-2;++k) {
137 casadi_copy(A_base, N, v);
140 *A_base = casadi_cvx_house(v, &beta[k], N);
142 casadi_cvx_house_apply_symm(n, k, A, pp, v, beta[k]);
150 template<
typename T1>
151 void casadi_cvx_givens(T1 a, T1 b, T1* c, T1* s) {
157 if (fabs(b)>fabs(a)) {
178 template<
typename T1>
179 void casadi_cvx_implicit_qr(casadi_int n, T1* t_diag, T1* t_off, T1* cs) {
180 T1 d, mu, to2, x, z, c, s, t1, t2, d0, d1, o0, o1, sd;
182 d = 0.5*(t_diag[n-2]-t_diag[n-1]);
183 to2 = t_off[n-2]*t_off[n-2];
186 mu = t_diag[n-1]-to2/(d+sd*sqrt(d*d+to2));
189 for (i=0;i<n-1;++i) {
191 casadi_cvx_givens(x, z, &c, &s);
199 t_diag[i] = c*t1-s*t2;
200 t_off[i] = s*t1+c*t2;
201 t_diag[i+1] = d0*s*s+2*s*o0*c+d1*c*c;
204 t_off[i-1] = t_off[i-1]*c-z*s;
230 template<
typename T1>
231 int casadi_cvx_symm_schur(casadi_int n, T1* t_diag, T1* t_off, T1 tol, casadi_int max_iter,
232 casadi_int* trace_meta, T1* trace) {
233 casadi_int i, p, q, sp, sq, trace_offset, nn;
235 n_iter = trace_meta++;
242 if (*n_iter==max_iter)
return 1;
244 for (i=0;i<n-1;++i) {
245 if (fabs(t_off[i])<=tol*(fabs(t_diag[i])+fabs(t_diag[i+1]))) {
255 for (i=0;i<n-1;++i) {
256 if (t_off[n-i-2]==0 && sq==0) {
261 if (t_off[i]==0 && sp==0) {
274 casadi_cvx_implicit_qr(nn, t_diag+p, t_off+p, trace ? trace+trace_offset :
nullptr);
275 trace_offset += 2*(nn-1);
280 *trace_meta++ = trace_offset;
291 template<
typename T1>
292 void casadi_cvx_givens_apply(casadi_int n, T1* q, T1 c, T1 s, casadi_int p) {
293 T1 t1, t2, t3, t4, a, b;
307 t2 = c*m[1]+s*m[n+1];
309 t4 = c*m[n+1]-s*m[1];
315 for (i=0;i<n-p-2;++i) {
338 template<
typename T1>
339 void casadi_cvx_house_apply(casadi_int n, casadi_int m, casadi_int s, T1* A,
340 T1* p,
const T1* v, T1 beta) {
353 p[i] += beta*a[j]*v[j];
371 template<
typename T1>
372 T1 casadi_cvx_scalar(T1 epsilon, casadi_int reflect, T1 eig) {
373 return fmax(epsilon, reflect ? fabs(eig) : eig);
386 template<
typename T1>
387 int casadi_cvx(casadi_int n, T1 *A, T1 epsilon, T1 tol, casadi_int reflect, casadi_int max_iter,
388 T1* w, casadi_int* iw) {
389 casadi_int i, j, k, n_iter, nn, p, trace_offset;
392 T1 *cs, *t_diag, *t_off;
400 A[0] = casadi_cvx_scalar(epsilon, reflect, A[0]);
404 casadi_cvx_tri(A, n, beta, w);
419 t_diag[i] = A[i+n*i];
422 for (i=1;i<n-1;++i) {
423 t_off[i] = A[i+1+n*i];
427 if (casadi_cvx_symm_schur(n, t_diag, t_off, tol, max_iter, iw, w))
return 1;
431 A[i+n*i] = casadi_cvx_scalar(epsilon, reflect, t_diag[i]);
436 for (j=i+1;j<n;++j) A[j+i*n] = 0;
441 t_meta = iw+3*(n_iter-1)+1;
443 for (i=0;i<n_iter;++i) {
446 trace_offset = *t_meta++;
449 for (j=0;j<nn-1;j++) {
452 casadi_cvx_givens_apply(n, A, c, s, p+nn-j-2);
457 for (k = n-3; k>=0; --k) {
458 casadi_int N = n-k-1;
460 casadi_cvx_house_apply_symm(n, k, A, w, v, beta[k]);
461 casadi_cvx_house_apply(k+1, N, n, A+k+1, w, v, beta[k]);