Mercurial > octave
comparison libinterp/dldfcn/qr.cc @ 22206:21684fa513ce
Return C = Q'*B not Q when qr has two arguments (bug #41567, bug #46912)
* qr.cc (Fqr): For full case, explicitly calculate Q. Add 8 tests.
author | mfasi <mogrob.sanit@gmail.com> |
---|---|
date | Thu, 18 Feb 2016 11:57:12 +1100 |
parents | 278fc29b69ca |
children | 99454a60bf5e |
comparison
equal
deleted
inserted
replaced
22205:8a456af24e6b | 22206:21684fa513ce |
---|---|
212 int arg_is_empty = empty_arg ("qr", arg.rows (), arg.columns ()); | 212 int arg_is_empty = empty_arg ("qr", arg.rows (), arg.columns ()); |
213 | 213 |
214 if (arg_is_empty < 0) | 214 if (arg_is_empty < 0) |
215 return retval; | 215 return retval; |
216 | 216 |
217 bool economy = false; | |
218 bool is_cmplx = false; | |
219 bool b_mat = false; | |
220 int have_b = 0; | |
221 | |
222 if (arg.is_complex_type ()) | |
223 is_cmplx = true; | |
224 if (nargin > 1) | |
225 { | |
226 have_b = 1; | |
227 if (args(nargin-1).is_scalar_type ()) | |
228 { | |
229 int val = args(nargin-1).int_value (); | |
230 if (val == 0) | |
231 { | |
232 economy = true; | |
233 have_b = (nargin > 2 ? 2 : 0); | |
234 } | |
235 } | |
236 else if (args(nargin-1).is_matrix_type ()) | |
237 b_mat = true; | |
238 if (have_b > 0 && args(have_b).is_complex_type ()) | |
239 is_cmplx = true; | |
240 } | |
241 | |
217 if (arg.is_sparse_type ()) | 242 if (arg.is_sparse_type ()) |
218 { | 243 { |
219 bool economy = false; | |
220 bool is_cmplx = false; | |
221 int have_b = 0; | |
222 | |
223 if (arg.is_complex_type ()) | |
224 is_cmplx = true; | |
225 if (nargin > 1) | |
226 { | |
227 have_b = 1; | |
228 if (args(nargin-1).is_scalar_type ()) | |
229 { | |
230 int val = args(nargin-1).int_value (); | |
231 if (val == 0) | |
232 { | |
233 economy = true; | |
234 have_b = (nargin > 2 ? 2 : 0); | |
235 } | |
236 } | |
237 if (have_b > 0 && args(have_b).is_complex_type ()) | |
238 is_cmplx = true; | |
239 } | |
240 | 244 |
241 if (is_cmplx) | 245 if (is_cmplx) |
242 { | 246 { |
243 sparse_qr<SparseComplexMatrix> q (arg.sparse_complex_matrix_value ()); | 247 sparse_qr<SparseComplexMatrix> q (arg.sparse_complex_matrix_value ()); |
244 | 248 |
293 | 297 |
294 case 2: | 298 case 2: |
295 { | 299 { |
296 qr<FloatMatrix> fact (m, type); | 300 qr<FloatMatrix> fact (m, type); |
297 retval = ovl (fact.Q (), get_qr_r (fact)); | 301 retval = ovl (fact.Q (), get_qr_r (fact)); |
302 if (b_mat) | |
303 { | |
304 if (is_cmplx) | |
305 retval(0) = fact.Q ().transpose () | |
306 * args(1).float_complex_matrix_value (); | |
307 else | |
308 retval(0) = fact.Q ().transpose () | |
309 * args(1).float_matrix_value (); | |
310 } | |
298 } | 311 } |
299 break; | 312 break; |
300 | 313 |
301 default: | 314 default: |
302 { | 315 { |
329 | 342 |
330 case 2: | 343 case 2: |
331 { | 344 { |
332 qr<FloatComplexMatrix> fact (m, type); | 345 qr<FloatComplexMatrix> fact (m, type); |
333 retval = ovl (fact.Q (), get_qr_r (fact)); | 346 retval = ovl (fact.Q (), get_qr_r (fact)); |
347 if (b_mat) | |
348 retval (0) = conj (fact.Q ().transpose ()) | |
349 * args(1).float_complex_matrix_value (); | |
334 } | 350 } |
335 break; | 351 break; |
336 | 352 |
337 default: | 353 default: |
338 { | 354 { |
366 | 382 |
367 case 2: | 383 case 2: |
368 { | 384 { |
369 qr<Matrix> fact (m, type); | 385 qr<Matrix> fact (m, type); |
370 retval = ovl (fact.Q (), get_qr_r (fact)); | 386 retval = ovl (fact.Q (), get_qr_r (fact)); |
387 if (b_mat) | |
388 { | |
389 if (is_cmplx) | |
390 retval(0) = fact.Q ().transpose () | |
391 * args(1).complex_matrix_value (); | |
392 else | |
393 retval(0) = fact.Q ().transpose () | |
394 * args(1).matrix_value (); | |
395 } | |
371 } | 396 } |
372 break; | 397 break; |
373 | 398 |
374 default: | 399 default: |
375 { | 400 { |
401 | 426 |
402 case 2: | 427 case 2: |
403 { | 428 { |
404 qr<ComplexMatrix> fact (m, type); | 429 qr<ComplexMatrix> fact (m, type); |
405 retval = ovl (fact.Q (), get_qr_r (fact)); | 430 retval = ovl (fact.Q (), get_qr_r (fact)); |
431 if (b_mat) | |
432 retval (0) = conj (fact.Q ().transpose ()) | |
433 * args(1).complex_matrix_value (); | |
406 } | 434 } |
407 break; | 435 break; |
408 | 436 |
409 default: | 437 default: |
410 { | 438 { |
436 %! assert (qe * re, a, sqrt (eps)); | 464 %! assert (qe * re, a, sqrt (eps)); |
437 | 465 |
438 %!test | 466 %!test |
439 %! a = [0, 2, 1; 2, 1, 2]; | 467 %! a = [0, 2, 1; 2, 1, 2]; |
440 %! | 468 %! |
469 %! [q, r] = qr (a); | |
470 %! [qe, re] = qr (a, 0); | |
471 %! | |
472 %! assert (q * r, a, sqrt (eps)); | |
473 %! assert (qe * re, a, sqrt (eps)); | |
474 | |
475 %!test | |
476 %! a = [0, 2, 1; 2, 1, 2]; | |
477 %! | |
441 %! [q, r, p] = qr (a); # FIXME: not giving right dimensions. | 478 %! [q, r, p] = qr (a); # FIXME: not giving right dimensions. |
442 %! [qe, re, pe] = qr (a, 0); | 479 %! [qe, re, pe] = qr (a, 0); |
443 %! | 480 %! |
444 %! assert (q * r, a * p, sqrt (eps)); | 481 %! assert (q * r, a * p, sqrt (eps)); |
445 %! assert (qe * re, a(:, pe), sqrt (eps)); | 482 %! assert (qe * re, a(:, pe), sqrt (eps)); |
459 %! [q, r, p] = qr (a); | 496 %! [q, r, p] = qr (a); |
460 %! [qe, re, pe] = qr (a, 0); | 497 %! [qe, re, pe] = qr (a, 0); |
461 %! | 498 %! |
462 %! assert (q * r, a * p, sqrt (eps)); | 499 %! assert (q * r, a * p, sqrt (eps)); |
463 %! assert (qe * re, a(:, pe), sqrt (eps)); | 500 %! assert (qe * re, a(:, pe), sqrt (eps)); |
501 | |
502 %!test | |
503 %! a = [0, 2, 1; 2, 1, 2; 3, 1, 2]; | |
504 %! b = [1, 3, 2; 1, 1, 0; 3, 0, 2]; | |
505 %! | |
506 %! [q, r] = qr (a); | |
507 %! [c, re] = qr (a, b); | |
508 %! | |
509 %! assert (r, re, sqrt (eps)); | |
510 %! assert (q'*b, c, sqrt (eps)); | |
511 | |
512 %!test | |
513 %! a = [0, 2, i; 2, 1, 2; 3, 1, 2]; | |
514 %! b = [1, 3, 2; 1, i, 0; 3, 0, 2]; | |
515 %! | |
516 %! [q, r] = qr (a); | |
517 %! [c, re] = qr (a, b); | |
518 %! | |
519 %! assert (r, re, sqrt (eps)); | |
520 %! assert (q'*b, c, sqrt (eps)); | |
521 | |
522 %!test | |
523 %! a = [0, 2, i; 2, 1, 2; 3, 1, 2]; | |
524 %! b = [1, 3, 2; 1, 1, 0; 3, 0, 2]; | |
525 %! | |
526 %! [q, r] = qr (a); | |
527 %! [c, re] = qr (a, b); | |
528 %! | |
529 %! assert (r, re, sqrt (eps)); | |
530 %! assert (q'*b, c, sqrt (eps)); | |
531 | |
532 %!test | |
533 %! a = [0, 2, 1; 2, 1, 2; 3, 1, 2]; | |
534 %! b = [1, 3, 2; 1, i, 0; 3, 0, 2]; | |
535 %! | |
536 %! [q, r] = qr (a); | |
537 %! [c, re] = qr (a, b); | |
538 %! | |
539 %! assert (r, re, sqrt (eps)); | |
540 %! assert (q'*b, c, sqrt (eps)); | |
464 | 541 |
465 %!error qr () | 542 %!error qr () |
466 %!error qr ([1, 2; 3, 4], 0, 2) | 543 %!error qr ([1, 2; 3, 4], 0, 2) |
467 | 544 |
468 %!function retval = __testqr (q, r, a, p) | 545 %!function retval = __testqr (q, r, a, p) |
573 %! [qe, re, pe] = qr (a, 0); | 650 %! [qe, re, pe] = qr (a, 0); |
574 %! | 651 %! |
575 %! assert (q * r, a * p, sqrt (eps ("single"))); | 652 %! assert (q * r, a * p, sqrt (eps ("single"))); |
576 %! assert (qe * re, a(:, pe), sqrt (eps ("single"))); | 653 %! assert (qe * re, a(:, pe), sqrt (eps ("single"))); |
577 | 654 |
655 %!test | |
656 %! a = single([0, 2, 1; 2, 1, 2; 3, 1, 2]); | |
657 %! b = single([1, 3, 2; 1, 1, 0; 3, 0, 2]); | |
658 %! | |
659 %! [q, r] = qr (a); | |
660 %! [c, re] = qr (a, b); | |
661 %! | |
662 %! assert (r, re, sqrt (eps ("single"))); | |
663 %! assert (q'*b, c, sqrt (eps ("single"))); | |
664 | |
665 %!test | |
666 %! a = single([0, 2, i; 2, 1, 2; 3, 1, 2]); | |
667 %! b = single([1, 3, 2; 1, i, 0; 3, 0, 2]); | |
668 %! | |
669 %! [q, r] = qr (a); | |
670 %! [c, re] = qr (a, b); | |
671 %! | |
672 %! assert (r, re, sqrt (eps ("single"))); | |
673 %! assert (q'*b, c, sqrt (eps ("single"))); | |
674 | |
675 %!test | |
676 %! a = single([0, 2, i; 2, 1, 2; 3, 1, 2]); | |
677 %! b = single([1, 3, 2; 1, 1, 0; 3, 0, 2]); | |
678 %! | |
679 %! [q, r] = qr (a); | |
680 %! [c, re] = qr (a, b); | |
681 %! | |
682 %! assert (r, re, sqrt (eps)); | |
683 %! assert (q'*b, c, sqrt (eps)); | |
684 | |
685 %!test | |
686 %! a = single([0, 2, 1; 2, 1, 2; 3, 1, 2]); | |
687 %! b = single([1, 3, 2; 1, i, 0; 3, 0, 2]); | |
688 %! | |
689 %! [q, r] = qr (a); | |
690 %! [c, re] = qr (a, b); | |
691 %! | |
692 %! assert (r, re, sqrt (eps ("single"))); | |
693 %! assert (q'*b, c, sqrt (eps ("single"))); | |
694 | |
578 %!error qr () | 695 %!error qr () |
579 %!error qr ([1, 2; 3, 4], 0, 2) | 696 %!error qr ([1, 2; 3, 4], 0, 2) |
580 | 697 |
581 %!test | 698 %!test |
582 %! t = ones (24, 1); | 699 %! t = ones (24, 1); |