Mercurial > hg > octave-lyh
comparison liboctave/SparseQR.cc @ 10314:07ebe522dac2
untabify liboctave C++ sources
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 11 Feb 2010 12:23:32 -0500 |
parents | 4c0cdbe0acca |
children | 12884915a8e4 |
comparison
equal
deleted
inserted
replaced
10313:f3b65e1ae355 | 10314:07ebe522dac2 |
---|---|
183 ret = Matrix (nc, b_nc, 0.0); | 183 ret = Matrix (nc, b_nc, 0.0); |
184 else | 184 else |
185 { | 185 { |
186 OCTAVE_LOCAL_BUFFER (double, buf, S->m2); | 186 OCTAVE_LOCAL_BUFFER (double, buf, S->m2); |
187 for (volatile octave_idx_type j = 0, idx = 0; j < b_nc; j++, idx+=b_nr) | 187 for (volatile octave_idx_type j = 0, idx = 0; j < b_nc; j++, idx+=b_nr) |
188 { | 188 { |
189 octave_quit (); | 189 octave_quit (); |
190 for (octave_idx_type i = nr; i < S->m2; i++) | 190 for (octave_idx_type i = nr; i < S->m2; i++) |
191 buf[i] = 0.; | 191 buf[i] = 0.; |
192 volatile octave_idx_type nm = (nr < nc ? nr : nc); | 192 volatile octave_idx_type nm = (nr < nc ? nr : nc); |
193 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 193 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
194 #if defined(CS_VER) && (CS_VER >= 2) | 194 #if defined(CS_VER) && (CS_VER >= 2) |
195 CXSPARSE_DNAME (_ipvec) (S->pinv, bvec + idx, buf, b_nr); | 195 CXSPARSE_DNAME (_ipvec) (S->pinv, bvec + idx, buf, b_nr); |
196 #else | 196 #else |
197 CXSPARSE_DNAME (_ipvec) (b_nr, S->Pinv, bvec + idx, buf); | 197 CXSPARSE_DNAME (_ipvec) (b_nr, S->Pinv, bvec + idx, buf); |
198 #endif | 198 #endif |
199 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 199 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
200 | 200 |
201 for (volatile octave_idx_type i = 0; i < nm; i++) | 201 for (volatile octave_idx_type i = 0; i < nm; i++) |
202 { | 202 { |
203 octave_quit (); | 203 octave_quit (); |
204 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 204 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
205 CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf); | 205 CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf); |
206 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 206 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
207 } | 207 } |
208 for (octave_idx_type i = 0; i < b_nr; i++) | 208 for (octave_idx_type i = 0; i < b_nr; i++) |
209 vec[i+idx] = buf[i]; | 209 vec[i+idx] = buf[i]; |
210 } | 210 } |
211 } | 211 } |
212 return ret; | 212 return ret; |
213 #else | 213 #else |
214 return Matrix (); | 214 return Matrix (); |
215 #endif | 215 #endif |
229 ret = Matrix (nc, nr, 0.0); | 229 ret = Matrix (nc, nr, 0.0); |
230 else | 230 else |
231 { | 231 { |
232 OCTAVE_LOCAL_BUFFER (double, bvec, nr + 1); | 232 OCTAVE_LOCAL_BUFFER (double, bvec, nr + 1); |
233 for (octave_idx_type i = 0; i < nr; i++) | 233 for (octave_idx_type i = 0; i < nr; i++) |
234 bvec[i] = 0.; | 234 bvec[i] = 0.; |
235 OCTAVE_LOCAL_BUFFER (double, buf, S->m2); | 235 OCTAVE_LOCAL_BUFFER (double, buf, S->m2); |
236 for (volatile octave_idx_type j = 0, idx = 0; j < nr; j++, idx+=nr) | 236 for (volatile octave_idx_type j = 0, idx = 0; j < nr; j++, idx+=nr) |
237 { | 237 { |
238 octave_quit (); | 238 octave_quit (); |
239 bvec[j] = 1.0; | 239 bvec[j] = 1.0; |
240 for (octave_idx_type i = nr; i < S->m2; i++) | 240 for (octave_idx_type i = nr; i < S->m2; i++) |
241 buf[i] = 0.; | 241 buf[i] = 0.; |
242 volatile octave_idx_type nm = (nr < nc ? nr : nc); | 242 volatile octave_idx_type nm = (nr < nc ? nr : nc); |
243 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 243 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
244 #if defined(CS_VER) && (CS_VER >= 2) | 244 #if defined(CS_VER) && (CS_VER >= 2) |
245 CXSPARSE_DNAME (_ipvec) (S->pinv, bvec, buf, nr); | 245 CXSPARSE_DNAME (_ipvec) (S->pinv, bvec, buf, nr); |
246 #else | 246 #else |
247 CXSPARSE_DNAME (_ipvec) (nr, S->Pinv, bvec, buf); | 247 CXSPARSE_DNAME (_ipvec) (nr, S->Pinv, bvec, buf); |
248 #endif | 248 #endif |
249 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 249 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
250 | 250 |
251 for (volatile octave_idx_type i = 0; i < nm; i++) | 251 for (volatile octave_idx_type i = 0; i < nm; i++) |
252 { | 252 { |
253 octave_quit (); | 253 octave_quit (); |
254 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 254 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
255 CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf); | 255 CXSPARSE_DNAME (_happly) (N->L, i, N->B[i], buf); |
256 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 256 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
257 } | 257 } |
258 for (octave_idx_type i = 0; i < nr; i++) | 258 for (octave_idx_type i = 0; i < nr; i++) |
259 vec[i+idx] = buf[i]; | 259 vec[i+idx] = buf[i]; |
260 bvec[j] = 0.0; | 260 bvec[j] = 0.0; |
261 } | 261 } |
262 } | 262 } |
263 return ret.transpose (); | 263 return ret.transpose (); |
264 #else | 264 #else |
265 return Matrix (); | 265 return Matrix (); |
266 #endif | 266 #endif |
285 x = Matrix (nc, b_nc, 0.0); | 285 x = Matrix (nc, b_nc, 0.0); |
286 else if (nr >= nc) | 286 else if (nr >= nc) |
287 { | 287 { |
288 SparseQR q (a, 3); | 288 SparseQR q (a, 3); |
289 if (! q.ok ()) | 289 if (! q.ok ()) |
290 return Matrix(); | 290 return Matrix(); |
291 x.resize(nc, b_nc); | 291 x.resize(nc, b_nc); |
292 double *vec = x.fortran_vec(); | 292 double *vec = x.fortran_vec(); |
293 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); | 293 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); |
294 for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; | 294 for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; |
295 i++, idx+=nc, bidx+=b_nr) | 295 i++, idx+=nc, bidx+=b_nr) |
296 { | 296 { |
297 octave_quit (); | 297 octave_quit (); |
298 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 298 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
299 buf[j] = 0.; | 299 buf[j] = 0.; |
300 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 300 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
301 #if defined(CS_VER) && (CS_VER >= 2) | 301 #if defined(CS_VER) && (CS_VER >= 2) |
302 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, bvec + bidx, buf, nr); | 302 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, bvec + bidx, buf, nr); |
303 #else | 303 #else |
304 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, bvec + bidx, buf); | 304 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, bvec + bidx, buf); |
305 #endif | 305 #endif |
306 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 306 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
307 for (volatile octave_idx_type j = 0; j < nc; j++) | 307 for (volatile octave_idx_type j = 0; j < nc; j++) |
308 { | 308 { |
309 octave_quit (); | 309 octave_quit (); |
310 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 310 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
311 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 311 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
312 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 312 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
313 } | 313 } |
314 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 314 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
315 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 315 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
316 #if defined(CS_VER) && (CS_VER >= 2) | 316 #if defined(CS_VER) && (CS_VER >= 2) |
317 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, vec + idx, nc); | 317 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, vec + idx, nc); |
318 #else | 318 #else |
319 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, vec + idx); | 319 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, vec + idx); |
320 #endif | 320 #endif |
321 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 321 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
322 } | 322 } |
323 info = 0; | 323 info = 0; |
324 } | 324 } |
325 else | 325 else |
326 { | 326 { |
327 SparseMatrix at = a.hermitian(); | 327 SparseMatrix at = a.hermitian(); |
328 SparseQR q (at, 3); | 328 SparseQR q (at, 3); |
329 if (! q.ok ()) | 329 if (! q.ok ()) |
330 return Matrix(); | 330 return Matrix(); |
331 x.resize(nc, b_nc); | 331 x.resize(nc, b_nc); |
332 double *vec = x.fortran_vec(); | 332 double *vec = x.fortran_vec(); |
333 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); | 333 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); |
334 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); | 334 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); |
335 for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; | 335 for (volatile octave_idx_type i = 0, idx = 0, bidx = 0; i < b_nc; |
336 i++, idx+=nc, bidx+=b_nr) | 336 i++, idx+=nc, bidx+=b_nr) |
337 { | 337 { |
338 octave_quit (); | 338 octave_quit (); |
339 for (octave_idx_type j = nr; j < nbuf; j++) | 339 for (octave_idx_type j = nr; j < nbuf; j++) |
340 buf[j] = 0.; | 340 buf[j] = 0.; |
341 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 341 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
342 #if defined(CS_VER) && (CS_VER >= 2) | 342 #if defined(CS_VER) && (CS_VER >= 2) |
343 CXSPARSE_DNAME (_pvec) (q.S()->q, bvec + bidx, buf, nr); | 343 CXSPARSE_DNAME (_pvec) (q.S()->q, bvec + bidx, buf, nr); |
344 #else | 344 #else |
345 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, bvec + bidx, buf); | 345 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, bvec + bidx, buf); |
346 #endif | 346 #endif |
347 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 347 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
348 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 348 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
349 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 349 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
350 { | 350 { |
351 octave_quit (); | 351 octave_quit (); |
352 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 352 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
353 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 353 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
354 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 354 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
355 } | 355 } |
356 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 356 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
357 #if defined(CS_VER) && (CS_VER >= 2) | 357 #if defined(CS_VER) && (CS_VER >= 2) |
358 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, vec + idx, nc); | 358 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, vec + idx, nc); |
359 #else | 359 #else |
360 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, vec + idx); | 360 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, vec + idx); |
361 #endif | 361 #endif |
362 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 362 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
363 } | 363 } |
364 info = 0; | 364 info = 0; |
365 } | 365 } |
366 | 366 |
367 return x; | 367 return x; |
368 #else | 368 #else |
389 x = SparseMatrix (nc, b_nc); | 389 x = SparseMatrix (nc, b_nc); |
390 else if (nr >= nc) | 390 else if (nr >= nc) |
391 { | 391 { |
392 SparseQR q (a, 3); | 392 SparseQR q (a, 3); |
393 if (! q.ok ()) | 393 if (! q.ok ()) |
394 return SparseMatrix(); | 394 return SparseMatrix(); |
395 x = SparseMatrix (nc, b_nc, b.nzmax()); | 395 x = SparseMatrix (nc, b_nc, b.nzmax()); |
396 x.xcidx(0) = 0; | 396 x.xcidx(0) = 0; |
397 x_nz = b.nzmax(); | 397 x_nz = b.nzmax(); |
398 ii = 0; | 398 ii = 0; |
399 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 399 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
400 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); | 400 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); |
401 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 401 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
402 { | 402 { |
403 octave_quit (); | 403 octave_quit (); |
404 for (octave_idx_type j = 0; j < b_nr; j++) | 404 for (octave_idx_type j = 0; j < b_nr; j++) |
405 Xx[j] = b.xelem(j,i); | 405 Xx[j] = b.xelem(j,i); |
406 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 406 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
407 buf[j] = 0.; | 407 buf[j] = 0.; |
408 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 408 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
409 #if defined(CS_VER) && (CS_VER >= 2) | 409 #if defined(CS_VER) && (CS_VER >= 2) |
410 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); | 410 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); |
411 #else | 411 #else |
412 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); | 412 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); |
413 #endif | 413 #endif |
414 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 414 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
415 for (volatile octave_idx_type j = 0; j < nc; j++) | 415 for (volatile octave_idx_type j = 0; j < nc; j++) |
416 { | 416 { |
417 octave_quit (); | 417 octave_quit (); |
418 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 418 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
419 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 419 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
420 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 420 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
421 } | 421 } |
422 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 422 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
423 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 423 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
424 #if defined(CS_VER) && (CS_VER >= 2) | 424 #if defined(CS_VER) && (CS_VER >= 2) |
425 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); | 425 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); |
426 #else | 426 #else |
427 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); | 427 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); |
428 #endif | 428 #endif |
429 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 429 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
430 | 430 |
431 for (octave_idx_type j = 0; j < nc; j++) | 431 for (octave_idx_type j = 0; j < nc; j++) |
432 { | 432 { |
433 double tmp = Xx[j]; | 433 double tmp = Xx[j]; |
434 if (tmp != 0.0) | 434 if (tmp != 0.0) |
435 { | 435 { |
436 if (ii == x_nz) | 436 if (ii == x_nz) |
437 { | 437 { |
438 // Resize the sparse matrix | 438 // Resize the sparse matrix |
439 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; | 439 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; |
440 sz = (sz > 10 ? sz : 10) + x_nz; | 440 sz = (sz > 10 ? sz : 10) + x_nz; |
441 x.change_capacity (sz); | 441 x.change_capacity (sz); |
442 x_nz = sz; | 442 x_nz = sz; |
443 } | 443 } |
444 x.xdata(ii) = tmp; | 444 x.xdata(ii) = tmp; |
445 x.xridx(ii++) = j; | 445 x.xridx(ii++) = j; |
446 } | 446 } |
447 } | 447 } |
448 x.xcidx(i+1) = ii; | 448 x.xcidx(i+1) = ii; |
449 } | 449 } |
450 info = 0; | 450 info = 0; |
451 } | 451 } |
452 else | 452 else |
453 { | 453 { |
454 SparseMatrix at = a.hermitian(); | 454 SparseMatrix at = a.hermitian(); |
455 SparseQR q (at, 3); | 455 SparseQR q (at, 3); |
456 if (! q.ok ()) | 456 if (! q.ok ()) |
457 return SparseMatrix(); | 457 return SparseMatrix(); |
458 x = SparseMatrix (nc, b_nc, b.nzmax()); | 458 x = SparseMatrix (nc, b_nc, b.nzmax()); |
459 x.xcidx(0) = 0; | 459 x.xcidx(0) = 0; |
460 x_nz = b.nzmax(); | 460 x_nz = b.nzmax(); |
461 ii = 0; | 461 ii = 0; |
462 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); | 462 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); |
463 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 463 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
464 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); | 464 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); |
465 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 465 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
466 { | 466 { |
467 octave_quit (); | 467 octave_quit (); |
468 for (octave_idx_type j = 0; j < b_nr; j++) | 468 for (octave_idx_type j = 0; j < b_nr; j++) |
469 Xx[j] = b.xelem(j,i); | 469 Xx[j] = b.xelem(j,i); |
470 for (octave_idx_type j = nr; j < nbuf; j++) | 470 for (octave_idx_type j = nr; j < nbuf; j++) |
471 buf[j] = 0.; | 471 buf[j] = 0.; |
472 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 472 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
473 #if defined(CS_VER) && (CS_VER >= 2) | 473 #if defined(CS_VER) && (CS_VER >= 2) |
474 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); | 474 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); |
475 #else | 475 #else |
476 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); | 476 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); |
477 #endif | 477 #endif |
478 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 478 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
479 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 479 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
480 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 480 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
481 { | 481 { |
482 octave_quit (); | 482 octave_quit (); |
483 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 483 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
484 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 484 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
485 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 485 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
486 } | 486 } |
487 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 487 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
488 #if defined(CS_VER) && (CS_VER >= 2) | 488 #if defined(CS_VER) && (CS_VER >= 2) |
489 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); | 489 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); |
490 #else | 490 #else |
491 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); | 491 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); |
492 #endif | 492 #endif |
493 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 493 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
494 | 494 |
495 for (octave_idx_type j = 0; j < nc; j++) | 495 for (octave_idx_type j = 0; j < nc; j++) |
496 { | 496 { |
497 double tmp = Xx[j]; | 497 double tmp = Xx[j]; |
498 if (tmp != 0.0) | 498 if (tmp != 0.0) |
499 { | 499 { |
500 if (ii == x_nz) | 500 if (ii == x_nz) |
501 { | 501 { |
502 // Resize the sparse matrix | 502 // Resize the sparse matrix |
503 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; | 503 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; |
504 sz = (sz > 10 ? sz : 10) + x_nz; | 504 sz = (sz > 10 ? sz : 10) + x_nz; |
505 x.change_capacity (sz); | 505 x.change_capacity (sz); |
506 x_nz = sz; | 506 x_nz = sz; |
507 } | 507 } |
508 x.xdata(ii) = tmp; | 508 x.xdata(ii) = tmp; |
509 x.xridx(ii++) = j; | 509 x.xridx(ii++) = j; |
510 } | 510 } |
511 } | 511 } |
512 x.xcidx(i+1) = ii; | 512 x.xcidx(i+1) = ii; |
513 } | 513 } |
514 info = 0; | 514 info = 0; |
515 } | 515 } |
516 | 516 |
517 x.maybe_compress (); | 517 x.maybe_compress (); |
518 return x; | 518 return x; |
539 x = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0)); | 539 x = ComplexMatrix (nc, b_nc, Complex (0.0, 0.0)); |
540 else if (nr >= nc) | 540 else if (nr >= nc) |
541 { | 541 { |
542 SparseQR q (a, 3); | 542 SparseQR q (a, 3); |
543 if (! q.ok ()) | 543 if (! q.ok ()) |
544 return ComplexMatrix(); | 544 return ComplexMatrix(); |
545 x.resize(nc, b_nc); | 545 x.resize(nc, b_nc); |
546 Complex *vec = x.fortran_vec(); | 546 Complex *vec = x.fortran_vec(); |
547 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 547 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
548 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); | 548 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); |
549 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); | 549 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); |
550 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 550 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
551 { | 551 { |
552 octave_quit (); | 552 octave_quit (); |
553 for (octave_idx_type j = 0; j < b_nr; j++) | 553 for (octave_idx_type j = 0; j < b_nr; j++) |
554 { | 554 { |
555 Complex c = b.xelem (j,i); | 555 Complex c = b.xelem (j,i); |
556 Xx[j] = std::real (c); | 556 Xx[j] = std::real (c); |
557 Xz[j] = std::imag (c); | 557 Xz[j] = std::imag (c); |
558 } | 558 } |
559 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 559 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
560 buf[j] = 0.; | 560 buf[j] = 0.; |
561 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 561 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
562 #if defined(CS_VER) && (CS_VER >= 2) | 562 #if defined(CS_VER) && (CS_VER >= 2) |
563 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); | 563 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); |
564 #else | 564 #else |
565 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); | 565 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); |
566 #endif | 566 #endif |
567 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 567 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
568 for (volatile octave_idx_type j = 0; j < nc; j++) | 568 for (volatile octave_idx_type j = 0; j < nc; j++) |
569 { | 569 { |
570 octave_quit (); | 570 octave_quit (); |
571 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 571 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
572 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 572 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
573 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 573 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
574 } | 574 } |
575 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 575 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
576 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 576 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
577 #if defined(CS_VER) && (CS_VER >= 2) | 577 #if defined(CS_VER) && (CS_VER >= 2) |
578 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); | 578 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); |
579 #else | 579 #else |
580 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); | 580 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); |
581 #endif | 581 #endif |
582 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 582 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
583 buf[j] = 0.; | 583 buf[j] = 0.; |
584 #if defined(CS_VER) && (CS_VER >= 2) | 584 #if defined(CS_VER) && (CS_VER >= 2) |
585 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr); | 585 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr); |
586 #else | 586 #else |
587 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf); | 587 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf); |
588 #endif | 588 #endif |
589 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 589 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
590 for (volatile octave_idx_type j = 0; j < nc; j++) | 590 for (volatile octave_idx_type j = 0; j < nc; j++) |
591 { | 591 { |
592 octave_quit (); | 592 octave_quit (); |
593 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 593 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
594 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 594 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
595 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 595 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
596 } | 596 } |
597 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 597 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
598 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 598 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
599 #if defined(CS_VER) && (CS_VER >= 2) | 599 #if defined(CS_VER) && (CS_VER >= 2) |
600 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc); | 600 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc); |
601 #else | 601 #else |
602 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz); | 602 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz); |
603 #endif | 603 #endif |
604 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 604 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
605 for (octave_idx_type j = 0; j < nc; j++) | 605 for (octave_idx_type j = 0; j < nc; j++) |
606 vec[j+idx] = Complex (Xx[j], Xz[j]); | 606 vec[j+idx] = Complex (Xx[j], Xz[j]); |
607 } | 607 } |
608 info = 0; | 608 info = 0; |
609 } | 609 } |
610 else | 610 else |
611 { | 611 { |
612 SparseMatrix at = a.hermitian(); | 612 SparseMatrix at = a.hermitian(); |
613 SparseQR q (at, 3); | 613 SparseQR q (at, 3); |
614 if (! q.ok ()) | 614 if (! q.ok ()) |
615 return ComplexMatrix(); | 615 return ComplexMatrix(); |
616 x.resize(nc, b_nc); | 616 x.resize(nc, b_nc); |
617 Complex *vec = x.fortran_vec(); | 617 Complex *vec = x.fortran_vec(); |
618 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); | 618 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); |
619 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 619 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
620 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); | 620 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); |
621 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); | 621 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); |
622 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 622 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
623 { | 623 { |
624 octave_quit (); | 624 octave_quit (); |
625 for (octave_idx_type j = 0; j < b_nr; j++) | 625 for (octave_idx_type j = 0; j < b_nr; j++) |
626 { | 626 { |
627 Complex c = b.xelem (j,i); | 627 Complex c = b.xelem (j,i); |
628 Xx[j] = std::real (c); | 628 Xx[j] = std::real (c); |
629 Xz[j] = std::imag (c); | 629 Xz[j] = std::imag (c); |
630 } | 630 } |
631 for (octave_idx_type j = nr; j < nbuf; j++) | 631 for (octave_idx_type j = nr; j < nbuf; j++) |
632 buf[j] = 0.; | 632 buf[j] = 0.; |
633 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 633 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
634 #if defined(CS_VER) && (CS_VER >= 2) | 634 #if defined(CS_VER) && (CS_VER >= 2) |
635 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); | 635 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); |
636 #else | 636 #else |
637 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); | 637 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); |
638 #endif | 638 #endif |
639 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 639 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
640 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 640 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
641 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 641 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
642 { | 642 { |
643 octave_quit (); | 643 octave_quit (); |
644 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 644 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
645 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 645 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
646 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 646 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
647 } | 647 } |
648 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 648 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
649 #if defined(CS_VER) && (CS_VER >= 2) | 649 #if defined(CS_VER) && (CS_VER >= 2) |
650 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); | 650 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); |
651 #else | 651 #else |
652 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); | 652 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); |
653 #endif | 653 #endif |
654 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 654 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
655 for (octave_idx_type j = nr; j < nbuf; j++) | 655 for (octave_idx_type j = nr; j < nbuf; j++) |
656 buf[j] = 0.; | 656 buf[j] = 0.; |
657 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 657 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
658 #if defined(CS_VER) && (CS_VER >= 2) | 658 #if defined(CS_VER) && (CS_VER >= 2) |
659 CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr); | 659 CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr); |
660 #else | 660 #else |
661 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf); | 661 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf); |
662 #endif | 662 #endif |
663 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 663 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
664 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 664 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
665 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 665 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
666 { | 666 { |
667 octave_quit (); | 667 octave_quit (); |
668 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 668 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
669 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 669 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
670 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 670 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
671 } | 671 } |
672 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 672 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
673 #if defined(CS_VER) && (CS_VER >= 2) | 673 #if defined(CS_VER) && (CS_VER >= 2) |
674 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc); | 674 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc); |
675 #else | 675 #else |
676 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz); | 676 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz); |
677 #endif | 677 #endif |
678 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 678 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
679 for (octave_idx_type j = 0; j < nc; j++) | 679 for (octave_idx_type j = 0; j < nc; j++) |
680 vec[j+idx] = Complex (Xx[j], Xz[j]); | 680 vec[j+idx] = Complex (Xx[j], Xz[j]); |
681 } | 681 } |
682 info = 0; | 682 info = 0; |
683 } | 683 } |
684 | 684 |
685 return x; | 685 return x; |
686 #else | 686 #else |
707 x = SparseComplexMatrix (nc, b_nc); | 707 x = SparseComplexMatrix (nc, b_nc); |
708 else if (nr >= nc) | 708 else if (nr >= nc) |
709 { | 709 { |
710 SparseQR q (a, 3); | 710 SparseQR q (a, 3); |
711 if (! q.ok ()) | 711 if (! q.ok ()) |
712 return SparseComplexMatrix(); | 712 return SparseComplexMatrix(); |
713 x = SparseComplexMatrix (nc, b_nc, b.nzmax()); | 713 x = SparseComplexMatrix (nc, b_nc, b.nzmax()); |
714 x.xcidx(0) = 0; | 714 x.xcidx(0) = 0; |
715 x_nz = b.nzmax(); | 715 x_nz = b.nzmax(); |
716 ii = 0; | 716 ii = 0; |
717 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 717 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
718 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); | 718 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); |
719 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); | 719 OCTAVE_LOCAL_BUFFER (double, buf, q.S()->m2); |
720 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 720 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
721 { | 721 { |
722 octave_quit (); | 722 octave_quit (); |
723 for (octave_idx_type j = 0; j < b_nr; j++) | 723 for (octave_idx_type j = 0; j < b_nr; j++) |
724 { | 724 { |
725 Complex c = b.xelem (j,i); | 725 Complex c = b.xelem (j,i); |
726 Xx[j] = std::real (c); | 726 Xx[j] = std::real (c); |
727 Xz[j] = std::imag (c); | 727 Xz[j] = std::imag (c); |
728 } | 728 } |
729 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 729 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
730 buf[j] = 0.; | 730 buf[j] = 0.; |
731 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 731 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
732 #if defined(CS_VER) && (CS_VER >= 2) | 732 #if defined(CS_VER) && (CS_VER >= 2) |
733 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); | 733 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xx, buf, nr); |
734 #else | 734 #else |
735 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); | 735 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xx, buf); |
736 #endif | 736 #endif |
737 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 737 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
738 for (volatile octave_idx_type j = 0; j < nc; j++) | 738 for (volatile octave_idx_type j = 0; j < nc; j++) |
739 { | 739 { |
740 octave_quit (); | 740 octave_quit (); |
741 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 741 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
742 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 742 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
743 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 743 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
744 } | 744 } |
745 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 745 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
746 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 746 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
747 #if defined(CS_VER) && (CS_VER >= 2) | 747 #if defined(CS_VER) && (CS_VER >= 2) |
748 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); | 748 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xx, nc); |
749 #else | 749 #else |
750 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); | 750 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xx); |
751 #endif | 751 #endif |
752 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 752 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
753 for (octave_idx_type j = nr; j < q.S()->m2; j++) | 753 for (octave_idx_type j = nr; j < q.S()->m2; j++) |
754 buf[j] = 0.; | 754 buf[j] = 0.; |
755 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 755 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
756 #if defined(CS_VER) && (CS_VER >= 2) | 756 #if defined(CS_VER) && (CS_VER >= 2) |
757 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr); | 757 CXSPARSE_DNAME (_ipvec) (q.S()->pinv, Xz, buf, nr); |
758 #else | 758 #else |
759 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf); | 759 CXSPARSE_DNAME (_ipvec) (nr, q.S()->Pinv, Xz, buf); |
760 #endif | 760 #endif |
761 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 761 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
762 for (volatile octave_idx_type j = 0; j < nc; j++) | 762 for (volatile octave_idx_type j = 0; j < nc; j++) |
763 { | 763 { |
764 octave_quit (); | 764 octave_quit (); |
765 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 765 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
766 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 766 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
767 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 767 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
768 } | 768 } |
769 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 769 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
770 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); | 770 CXSPARSE_DNAME (_usolve) (q.N()->U, buf); |
771 #if defined(CS_VER) && (CS_VER >= 2) | 771 #if defined(CS_VER) && (CS_VER >= 2) |
772 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc); | 772 CXSPARSE_DNAME (_ipvec) (q.S()->q, buf, Xz, nc); |
773 #else | 773 #else |
774 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz); | 774 CXSPARSE_DNAME (_ipvec) (nc, q.S()->Q, buf, Xz); |
775 #endif | 775 #endif |
776 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 776 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
777 | 777 |
778 for (octave_idx_type j = 0; j < nc; j++) | 778 for (octave_idx_type j = 0; j < nc; j++) |
779 { | 779 { |
780 Complex tmp = Complex (Xx[j], Xz[j]); | 780 Complex tmp = Complex (Xx[j], Xz[j]); |
781 if (tmp != 0.0) | 781 if (tmp != 0.0) |
782 { | 782 { |
783 if (ii == x_nz) | 783 if (ii == x_nz) |
784 { | 784 { |
785 // Resize the sparse matrix | 785 // Resize the sparse matrix |
786 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; | 786 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; |
787 sz = (sz > 10 ? sz : 10) + x_nz; | 787 sz = (sz > 10 ? sz : 10) + x_nz; |
788 x.change_capacity (sz); | 788 x.change_capacity (sz); |
789 x_nz = sz; | 789 x_nz = sz; |
790 } | 790 } |
791 x.xdata(ii) = tmp; | 791 x.xdata(ii) = tmp; |
792 x.xridx(ii++) = j; | 792 x.xridx(ii++) = j; |
793 } | 793 } |
794 } | 794 } |
795 x.xcidx(i+1) = ii; | 795 x.xcidx(i+1) = ii; |
796 } | 796 } |
797 info = 0; | 797 info = 0; |
798 } | 798 } |
799 else | 799 else |
800 { | 800 { |
801 SparseMatrix at = a.hermitian(); | 801 SparseMatrix at = a.hermitian(); |
802 SparseQR q (at, 3); | 802 SparseQR q (at, 3); |
803 if (! q.ok ()) | 803 if (! q.ok ()) |
804 return SparseComplexMatrix(); | 804 return SparseComplexMatrix(); |
805 x = SparseComplexMatrix (nc, b_nc, b.nzmax()); | 805 x = SparseComplexMatrix (nc, b_nc, b.nzmax()); |
806 x.xcidx(0) = 0; | 806 x.xcidx(0) = 0; |
807 x_nz = b.nzmax(); | 807 x_nz = b.nzmax(); |
808 ii = 0; | 808 ii = 0; |
809 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); | 809 volatile octave_idx_type nbuf = (nc > q.S()->m2 ? nc : q.S()->m2); |
810 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); | 810 OCTAVE_LOCAL_BUFFER (double, Xx, (b_nr > nc ? b_nr : nc)); |
811 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); | 811 OCTAVE_LOCAL_BUFFER (double, Xz, (b_nr > nc ? b_nr : nc)); |
812 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); | 812 OCTAVE_LOCAL_BUFFER (double, buf, nbuf); |
813 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) | 813 for (volatile octave_idx_type i = 0, idx = 0; i < b_nc; i++, idx+=nc) |
814 { | 814 { |
815 octave_quit (); | 815 octave_quit (); |
816 for (octave_idx_type j = 0; j < b_nr; j++) | 816 for (octave_idx_type j = 0; j < b_nr; j++) |
817 { | 817 { |
818 Complex c = b.xelem (j,i); | 818 Complex c = b.xelem (j,i); |
819 Xx[j] = std::real (c); | 819 Xx[j] = std::real (c); |
820 Xz[j] = std::imag (c); | 820 Xz[j] = std::imag (c); |
821 } | 821 } |
822 for (octave_idx_type j = nr; j < nbuf; j++) | 822 for (octave_idx_type j = nr; j < nbuf; j++) |
823 buf[j] = 0.; | 823 buf[j] = 0.; |
824 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 824 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
825 #if defined(CS_VER) && (CS_VER >= 2) | 825 #if defined(CS_VER) && (CS_VER >= 2) |
826 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); | 826 CXSPARSE_DNAME (_pvec) (q.S()->q, Xx, buf, nr); |
827 #else | 827 #else |
828 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); | 828 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xx, buf); |
829 #endif | 829 #endif |
830 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 830 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
831 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 831 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
832 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 832 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
833 { | 833 { |
834 octave_quit (); | 834 octave_quit (); |
835 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 835 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
836 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 836 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
837 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 837 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
838 } | 838 } |
839 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 839 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
840 #if defined(CS_VER) && (CS_VER >= 2) | 840 #if defined(CS_VER) && (CS_VER >= 2) |
841 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); | 841 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xx, nc); |
842 #else | 842 #else |
843 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); | 843 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xx); |
844 #endif | 844 #endif |
845 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 845 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
846 for (octave_idx_type j = nr; j < nbuf; j++) | 846 for (octave_idx_type j = nr; j < nbuf; j++) |
847 buf[j] = 0.; | 847 buf[j] = 0.; |
848 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 848 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
849 #if defined(CS_VER) && (CS_VER >= 2) | 849 #if defined(CS_VER) && (CS_VER >= 2) |
850 CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr); | 850 CXSPARSE_DNAME (_pvec) (q.S()->q, Xz, buf, nr); |
851 #else | 851 #else |
852 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf); | 852 CXSPARSE_DNAME (_pvec) (nr, q.S()->Q, Xz, buf); |
853 #endif | 853 #endif |
854 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); | 854 CXSPARSE_DNAME (_utsolve) (q.N()->U, buf); |
855 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 855 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
856 for (volatile octave_idx_type j = nr-1; j >= 0; j--) | 856 for (volatile octave_idx_type j = nr-1; j >= 0; j--) |
857 { | 857 { |
858 octave_quit (); | 858 octave_quit (); |
859 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 859 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
860 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); | 860 CXSPARSE_DNAME (_happly) (q.N()->L, j, q.N()->B[j], buf); |
861 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 861 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
862 } | 862 } |
863 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 863 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
864 #if defined(CS_VER) && (CS_VER >= 2) | 864 #if defined(CS_VER) && (CS_VER >= 2) |
865 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc); | 865 CXSPARSE_DNAME (_pvec) (q.S()->pinv, buf, Xz, nc); |
866 #else | 866 #else |
867 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz); | 867 CXSPARSE_DNAME (_pvec) (nc, q.S()->Pinv, buf, Xz); |
868 #endif | 868 #endif |
869 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 869 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
870 | 870 |
871 for (octave_idx_type j = 0; j < nc; j++) | 871 for (octave_idx_type j = 0; j < nc; j++) |
872 { | 872 { |
873 Complex tmp = Complex (Xx[j], Xz[j]); | 873 Complex tmp = Complex (Xx[j], Xz[j]); |
874 if (tmp != 0.0) | 874 if (tmp != 0.0) |
875 { | 875 { |
876 if (ii == x_nz) | 876 if (ii == x_nz) |
877 { | 877 { |
878 // Resize the sparse matrix | 878 // Resize the sparse matrix |
879 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; | 879 octave_idx_type sz = x_nz * (b_nc - i) / b_nc; |
880 sz = (sz > 10 ? sz : 10) + x_nz; | 880 sz = (sz > 10 ? sz : 10) + x_nz; |
881 x.change_capacity (sz); | 881 x.change_capacity (sz); |
882 x_nz = sz; | 882 x_nz = sz; |
883 } | 883 } |
884 x.xdata(ii) = tmp; | 884 x.xdata(ii) = tmp; |
885 x.xridx(ii++) = j; | 885 x.xridx(ii++) = j; |
886 } | 886 } |
887 } | 887 } |
888 x.xcidx(i+1) = ii; | 888 x.xcidx(i+1) = ii; |
889 } | 889 } |
890 info = 0; | 890 info = 0; |
891 } | 891 } |
892 | 892 |
893 x.maybe_compress (); | 893 x.maybe_compress (); |
894 return x; | 894 return x; |
897 #endif | 897 #endif |
898 } | 898 } |
899 | 899 |
900 Matrix | 900 Matrix |
901 qrsolve(const SparseMatrix &a, const MArray2<double> &b, | 901 qrsolve(const SparseMatrix &a, const MArray2<double> &b, |
902 octave_idx_type &info) | 902 octave_idx_type &info) |
903 { | 903 { |
904 return qrsolve (a, Matrix (b), info); | 904 return qrsolve (a, Matrix (b), info); |
905 } | 905 } |
906 | 906 |
907 ComplexMatrix | 907 ComplexMatrix |
908 qrsolve(const SparseMatrix &a, const MArray2<Complex> &b, | 908 qrsolve(const SparseMatrix &a, const MArray2<Complex> &b, |
909 octave_idx_type &info) | 909 octave_idx_type &info) |
910 { | 910 { |
911 return qrsolve (a, ComplexMatrix (b), info); | 911 return qrsolve (a, ComplexMatrix (b), info); |
912 } | 912 } |