28 void casadi_dense_lsqr_sym_ortho(T1 a, T1 b, T1* cs, T1* sn, T1* rho) {
38 }
else if (fabs(b)>fabs(a)) {
40 *sn = sign(b)/sqrt(1+tau*tau);
45 *cs = sign(a)/sqrt(1+tau*tau);
73 int casadi_dense_lsqr_single_solve(
const T1* A, T1* x, casadi_int tr,
const casadi_int ncol,
74 const casadi_int nrow, T1* w) {
76 T1 damp, atol, btol, conlim, ctol, anorm, acond, dampsq, ddnorm, res2, xnorm, xxnorm, z;
77 T1 cs2, sn2, alpha, beta, rhobar, phibar, bnorm, rnorm, arnorm, rhobar1, cs1, sn1, psi;
78 T1 cs, sn, rho, theta, phi, tau, t1, t2, n2dk, delta, gambar, rhs, zbar, gamma, res1;
79 T1 r1sq, r1norm, test1, test2, test3, rtol;
80 casadi_int iter_lim, itn, istop;
81 T1 *u, *v, *xx, *ww, *dk;
96 if (conlim > 0) ctol = 1/conlim;
108 u = w; w+= m; casadi_copy(x, m, u);
109 v = w; w+= n; casadi_clear(v, n);
110 xx = w; w+= n; casadi_clear(xx, n);
111 ww = w; w+= n; casadi_clear(v, n);
115 beta = casadi_norm_2(m, u);
118 for (i=0;i<m;++i) u[i]*=1/beta;
119 casadi_mv_dense(A, nrow, ncol, u, v, !tr);
121 alpha = casadi_norm_2(n, v);
125 for (i=0;i<n;++i) v[i]*=1/alpha;
126 casadi_copy(v, n, ww);
133 arnorm = alpha * beta;
135 while (itn<iter_lim) {
137 for (i=0;i<m;++i) u[i]*=-alpha;
139 casadi_mv_dense(A, nrow, ncol, u, v, !tr);
140 beta = casadi_norm_2(m, u);
143 for (i=0;i<m;++i) u[i]*=1/beta;
144 anorm = sqrt(anorm*anorm + alpha*alpha+beta*beta+damp*damp);
145 for (i=0;i<n;++i) v[i]*=-beta;
147 casadi_mv_dense(A, nrow, ncol, u, v, !tr);
148 alpha = casadi_norm_2(n, v);
149 if (alpha>0)
for (i=0;i<n;++i) v[i]*=1/alpha;
152 rhobar1 = sqrt(rhobar*rhobar+damp*damp);
154 cs1 = rhobar / rhobar1;
155 sn1 = damp / rhobar1;
159 casadi_dense_lsqr_sym_ortho(rhobar1, beta, &cs, &sn, &rho);
162 rhobar = -cs * alpha;
170 for (i=0;i<n;++i) dk[i]=ww[i]/rho;
172 for (i=0; i<n; ++i) xx[i] += t1*ww[i];
173 for (i=0; i<n; ++i) ww[i] = v[i] + t2*ww[i];
175 n2dk = casadi_norm_2(n, dk);
180 rhs = phi - delta * z;
182 xnorm = sqrt(xxnorm + zbar*zbar);
183 gamma = sqrt(gambar*gambar + theta*theta);
184 cs2 = gambar / gamma;
189 acond = anorm * sqrt(ddnorm);
190 res1 = phibar*phibar;
192 rnorm = sqrt(res1+res2);
193 arnorm = alpha*fabs(tau);
195 r1sq = rnorm*rnorm - dampsq * xxnorm;
196 r1norm = sqrt(fabs(r1sq));
197 if (r1sq < 0) r1norm = -r1norm;
199 test1 = rnorm / bnorm;
200 test2 = arnorm / (anorm * rnorm);
202 t1 = test1 / (1 + anorm * xnorm / bnorm);
203 rtol = btol + atol * anorm * xnorm / bnorm;
205 if (itn >= iter_lim) istop = 7;
206 if (1 + test3 <= 1) istop = 6;
207 if (1 + test2 <= 1) istop = 5;
208 if (1 + t1 <= 1) istop = 4;
210 if (test3 <= ctol) istop = 3;
211 if (test2 <= atol) istop = 2;
212 if (test1 <= rtol) istop = 1;
214 if (istop != 0)
break;
217 casadi_copy(xx, m, x);
241 template<
typename T1>
242 int casadi_dense_lsqr_solve(
const T1* A, T1* x, casadi_int nrhs, casadi_int tr,
243 const casadi_int ncol,
const casadi_int nrow, T1* w) {
245 for (i=0; i<nrhs;++i) {
247 if (casadi_dense_lsqr_single_solve(A, x+i*nrow, tr, ncol, nrow, w))
return 1;