24 T1 casadi_house(T1* v, T1* beta, casadi_int nv) {
27 T1 v0, sigma, s, sigma_is_zero, v0_nonpos;
31 for (i=1; i<nv; ++i) sigma += v[i]*v[i];
32 s = sqrt(v0*v0 + sigma);
34 sigma_is_zero = sigma==0;
37 v[0] = if_else(sigma_is_zero, 1,
38 if_else(v0_nonpos, v0-s, -sigma/(v0+s)));
39 *beta = if_else(sigma_is_zero, 2*v0_nonpos, -1/(s*v[0]));
53 void casadi_qr(
const casadi_int* sp_a,
const T1* nz_a, T1* x,
54 const casadi_int* sp_v, T1* nz_v,
const casadi_int* sp_r, T1* nz_r, T1* beta,
55 const casadi_int* prinv,
const casadi_int* pc) {
57 casadi_int ncol, nrow, r, c, k, k1;
59 const casadi_int *a_colind, *a_row, *v_colind, *v_row, *r_colind, *r_row;
62 a_colind=sp_a+2; a_row=sp_a+2+ncol+1;
64 v_colind=sp_v+2; v_row=sp_v+2+ncol+1;
65 r_colind=sp_r+2; r_row=sp_r+2+ncol+1;
67 for (r=0; r<nrow; ++r) x[r] = 0;
69 for (c=0; c<ncol; ++c) {
71 for (k=a_colind[pc[c]]; k<a_colind[pc[c]+1]; ++k) x[prinv[a_row[k]]] = nz_a[k];
74 for (k=r_colind[c]; k<r_colind[c+1] && (r=r_row[k])<c; ++k) {
77 for (k1=v_colind[r]; k1<v_colind[r+1]; ++k1) alpha += nz_v[k1]*x[v_row[k1]];
80 for (k1=v_colind[r]; k1<v_colind[r+1]; ++k1) x[v_row[k1]] -= alpha*nz_v[k1];
87 for (k=v_colind[c]; k<v_colind[c+1]; ++k) {
88 nz_v[k] = x[v_row[k]];
93 *nz_r++ = casadi_house(nz_v + v_colind[c], beta + c, v_colind[c+1] - v_colind[c]);
103 template<
typename T1>
104 void casadi_qr_mv(
const casadi_int* sp_v,
const T1* v,
const T1* beta, T1* x,
107 casadi_int ncol, c, c1, k;
109 const casadi_int *colind, *row;
112 colind=sp_v+2; row=sp_v+2+ncol+1;
114 for (c1=0; c1<ncol; ++c1) {
116 c = tr ? c1 : ncol-1-c1;
119 for (k=colind[c]; k<colind[c+1]; ++k) alpha += v[k]*x[row[k]];
122 for (k=colind[c]; k<colind[c+1]; ++k) x[row[k]] -= alpha*v[k];
128 template<
typename T1>
129 void casadi_qr_trs(
const casadi_int* sp_r,
const T1* nz_r, T1* x, casadi_int tr) {
131 casadi_int ncol, r, c, k;
132 const casadi_int *colind, *row;
135 colind=sp_r+2; row=sp_r+2+ncol+1;
138 for (c=0; c<ncol; ++c) {
139 for (k=colind[c]; k<colind[c+1]; ++k) {
144 x[c] -= nz_r[k]*x[r];
150 for (c=ncol-1; c>=0; --c) {
151 for (k=colind[c+1]-1; k>=colind[c]; --k) {
156 x[r] -= nz_r[k]*x[c];
166 template<
typename T1>
167 void casadi_qr_solve(T1* x, casadi_int nrhs, casadi_int tr,
168 const casadi_int* sp_v,
const T1* v,
const casadi_int* sp_r,
const T1* r,
169 const T1* beta,
const casadi_int* prinv,
const casadi_int* pc, T1* w) {
170 casadi_int k, c, nrow_ext, ncol;
171 nrow_ext = sp_v[0]; ncol = sp_v[1];
172 for (k=0; k<nrhs; ++k) {
176 for (c=0; c<ncol; ++c) w[c] = x[pc[c]];
178 casadi_qr_trs(sp_r, r, w, 1);
180 casadi_qr_mv(sp_v, v, beta, w, 0);
182 for (c=0; c<ncol; ++c) x[c] = w[prinv[c]];
186 for (c=0; c<nrow_ext; ++c) w[c] = 0;
187 for (c=0; c<ncol; ++c) w[prinv[c]] = x[c];
189 casadi_qr_mv(sp_v, v, beta, w, 1);
191 casadi_qr_trs(sp_r, r, w, 0);
193 for (c=0; c<ncol; ++c) x[pc[c]] = w[c];
201 template<
typename T1>
202 casadi_int casadi_qr_singular(T1* rmin, casadi_int* irmin,
const T1* nz_r,
203 const casadi_int* sp_r,
const casadi_int* pc, T1 eps) {
206 casadi_int ncol, c, nullity;
207 const casadi_int* r_colind;
214 for (c=0; c<ncol; ++c) {
215 rd = fabs(nz_r[r_colind[c+1]-1]);
217 if (rd<eps) nullity++;
219 if (c==0 || rd < rd_min) {
221 if (rmin) *rmin = rd;
222 if (irmin) *irmin = pc[c];
231 template<
typename T1>
232 void casadi_qr_colcomb(T1* v,
const T1* nz_r,
const casadi_int* sp_r,
233 const casadi_int* pc, T1 eps, casadi_int ind) {
235 casadi_int ncol, r, c, k;
236 const casadi_int *r_colind, *r_row;
240 r_row = r_colind + ncol + 1;
242 for (c=0; c<ncol; ++c) {
243 if (fabs(nz_r[r_colind[c+1]-1])<eps && 0==ind--) {
249 casadi_clear(v, ncol);
252 for (k=r_colind[ind]; k<r_colind[ind+1]-1; ++k) {
253 v[pc[r_row[k]]] = -nz_r[k];
256 for (c=ind-1; c>=0; --c) {
257 for (k=r_colind[c+1]-1; k>=r_colind[c]; --k) {
260 if (fabs(nz_r[k])<eps) {
266 v[pc[r]] -= nz_r[k]*v[pc[c]];
271 casadi_scal(ncol, 1./sqrt(casadi_dot(ncol, v, v)), v);