comparison liboctave/array/fMatrix.cc @ 21136:7cac4e7458f2

maint: clean up code around calls to current_liboctave_error_handler. Remove statements after call to handler that are no longer reachable. Place input validation first and immediately call handler if necessary. Change if/error_handler/else to if/error_handler and re-indent code. * Array-util.cc, Array.cc, CColVector.cc, CDiagMatrix.cc, CMatrix.cc, CNDArray.cc, CRowVector.cc, CSparse.cc, DiagArray2.cc, MArray.cc, PermMatrix.cc, Sparse.cc, Sparse.h, chMatrix.cc, chNDArray.cc, dColVector.cc, dDiagMatrix.cc, dMatrix.cc, dNDArray.cc, dRowVector.cc, dSparse.cc, fCColVector.cc, fCDiagMatrix.cc, fCMatrix.cc, fCNDArray.cc, fCRowVector.cc, fColVector.cc, fDiagMatrix.cc, fMatrix.cc, fNDArray.cc, fRowVector.cc, idx-vector.cc, CmplxAEPBAL.cc, CmplxCHOL.cc, CmplxGEPBAL.cc, CmplxHESS.cc, CmplxLU.cc, CmplxQR.cc, CmplxSCHUR.cc, CmplxSVD.cc, DASPK.cc, EIG.cc, LSODE.cc, Quad.cc, SparseCmplxCHOL.cc, SparseCmplxLU.cc, SparseCmplxQR.cc, SparseQR.cc, SparsedbleCHOL.cc, SparsedbleLU.cc, base-lu.cc, bsxfun-defs.cc, dbleAEPBAL.cc, dbleCHOL.cc, dbleGEPBAL.cc, dbleHESS.cc, dbleLU.cc, dbleQR.cc, dbleSCHUR.cc, dbleSVD.cc, eigs-base.cc, fCmplxAEPBAL.cc, fCmplxCHOL.cc, fCmplxLU.cc, fCmplxQR.cc, fCmplxSCHUR.cc, fEIG.cc, floatAEPBAL.cc, floatCHOL.cc, floatGEPBAL.cc, floatHESS.cc, floatLU.cc, floatQR.cc, floatSCHUR.cc, floatSVD.cc, lo-specfun.cc, oct-fftw.cc, oct-rand.cc, oct-spparms.cc, sparse-base-chol.cc, sparse-dmsolve.cc, file-ops.cc, lo-sysdep.cc, mach-info.cc, oct-env.cc, oct-syscalls.cc, cmd-edit.cc, cmd-hist.cc, data-conv.cc, lo-ieee.cc, lo-regexp.cc, oct-base64.cc, oct-shlib.cc, pathsearch.cc, singleton-cleanup.cc, sparse-util.cc, unwind-prot.cc: Remove statements after call to handler that are no longer reachable. Place input validation first and immediately call handler if necessary. Change if/error_handler/else to if/error_handler and re-indent code.
author Rik <rik@octave.org>
date Sat, 23 Jan 2016 13:52:03 -0800
parents 228b65504557
children 40051830f89b
comparison
equal deleted inserted replaced
21135:95da3bc8a281 21136:7cac4e7458f2
347 octave_idx_type r, octave_idx_type c) 347 octave_idx_type r, octave_idx_type c)
348 { 348 {
349 octave_idx_type a_len = a.numel (); 349 octave_idx_type a_len = a.numel ();
350 350
351 if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ()) 351 if (r < 0 || r >= rows () || c < 0 || c + a_len > cols ())
352 { 352 (*current_liboctave_error_handler) ("range error for insert");
353 (*current_liboctave_error_handler) ("range error for insert");
354 return *this;
355 }
356 353
357 if (a_len > 0) 354 if (a_len > 0)
358 { 355 {
359 make_unique (); 356 make_unique ();
360 357
370 octave_idx_type r, octave_idx_type c) 367 octave_idx_type r, octave_idx_type c)
371 { 368 {
372 octave_idx_type a_len = a.numel (); 369 octave_idx_type a_len = a.numel ();
373 370
374 if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ()) 371 if (r < 0 || r + a_len > rows () || c < 0 || c >= cols ())
375 { 372 (*current_liboctave_error_handler) ("range error for insert");
376 (*current_liboctave_error_handler) ("range error for insert");
377 return *this;
378 }
379 373
380 if (a_len > 0) 374 if (a_len > 0)
381 { 375 {
382 make_unique (); 376 make_unique ();
383 377
394 { 388 {
395 octave_idx_type a_nr = a.rows (); 389 octave_idx_type a_nr = a.rows ();
396 octave_idx_type a_nc = a.cols (); 390 octave_idx_type a_nc = a.cols ();
397 391
398 if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ()) 392 if (r < 0 || r + a_nr > rows () || c < 0 || c + a_nc > cols ())
399 { 393 (*current_liboctave_error_handler) ("range error for insert");
400 (*current_liboctave_error_handler) ("range error for insert");
401 return *this;
402 }
403 394
404 fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1); 395 fill (0.0, r, c, r + a_nr - 1, c + a_nc - 1);
405 396
406 octave_idx_type a_len = a.length (); 397 octave_idx_type a_len = a.length ();
407 398
441 octave_idx_type nr = rows (); 432 octave_idx_type nr = rows ();
442 octave_idx_type nc = cols (); 433 octave_idx_type nc = cols ();
443 434
444 if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0 435 if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
445 || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc) 436 || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
446 { 437 (*current_liboctave_error_handler) ("range error for fill");
447 (*current_liboctave_error_handler) ("range error for fill");
448 return *this;
449 }
450 438
451 if (r1 > r2) { std::swap (r1, r2); } 439 if (r1 > r2) { std::swap (r1, r2); }
452 if (c1 > c2) { std::swap (c1, c2); } 440 if (c1 > c2) { std::swap (c1, c2); }
453 441
454 if (r2 >= r1 && c2 >= c1) 442 if (r2 >= r1 && c2 >= c1)
467 FloatMatrix::append (const FloatMatrix& a) const 455 FloatMatrix::append (const FloatMatrix& a) const
468 { 456 {
469 octave_idx_type nr = rows (); 457 octave_idx_type nr = rows ();
470 octave_idx_type nc = cols (); 458 octave_idx_type nc = cols ();
471 if (nr != a.rows ()) 459 if (nr != a.rows ())
472 { 460 (*current_liboctave_error_handler) ("row dimension mismatch for append");
473 (*current_liboctave_error_handler) ("row dimension mismatch for append");
474 return FloatMatrix ();
475 }
476 461
477 octave_idx_type nc_insert = nc; 462 octave_idx_type nc_insert = nc;
478 FloatMatrix retval (nr, nc + a.cols ()); 463 FloatMatrix retval (nr, nc + a.cols ());
479 retval.insert (*this, 0, 0); 464 retval.insert (*this, 0, 0);
480 retval.insert (a, 0, nc_insert); 465 retval.insert (a, 0, nc_insert);
485 FloatMatrix::append (const FloatRowVector& a) const 470 FloatMatrix::append (const FloatRowVector& a) const
486 { 471 {
487 octave_idx_type nr = rows (); 472 octave_idx_type nr = rows ();
488 octave_idx_type nc = cols (); 473 octave_idx_type nc = cols ();
489 if (nr != 1) 474 if (nr != 1)
490 { 475 (*current_liboctave_error_handler) ("row dimension mismatch for append");
491 (*current_liboctave_error_handler) ("row dimension mismatch for append");
492 return FloatMatrix ();
493 }
494 476
495 octave_idx_type nc_insert = nc; 477 octave_idx_type nc_insert = nc;
496 FloatMatrix retval (nr, nc + a.numel ()); 478 FloatMatrix retval (nr, nc + a.numel ());
497 retval.insert (*this, 0, 0); 479 retval.insert (*this, 0, 0);
498 retval.insert (a, 0, nc_insert); 480 retval.insert (a, 0, nc_insert);
503 FloatMatrix::append (const FloatColumnVector& a) const 485 FloatMatrix::append (const FloatColumnVector& a) const
504 { 486 {
505 octave_idx_type nr = rows (); 487 octave_idx_type nr = rows ();
506 octave_idx_type nc = cols (); 488 octave_idx_type nc = cols ();
507 if (nr != a.numel ()) 489 if (nr != a.numel ())
508 { 490 (*current_liboctave_error_handler) ("row dimension mismatch for append");
509 (*current_liboctave_error_handler) ("row dimension mismatch for append");
510 return FloatMatrix ();
511 }
512 491
513 octave_idx_type nc_insert = nc; 492 octave_idx_type nc_insert = nc;
514 FloatMatrix retval (nr, nc + 1); 493 FloatMatrix retval (nr, nc + 1);
515 retval.insert (*this, 0, 0); 494 retval.insert (*this, 0, 0);
516 retval.insert (a, 0, nc_insert); 495 retval.insert (a, 0, nc_insert);
521 FloatMatrix::append (const FloatDiagMatrix& a) const 500 FloatMatrix::append (const FloatDiagMatrix& a) const
522 { 501 {
523 octave_idx_type nr = rows (); 502 octave_idx_type nr = rows ();
524 octave_idx_type nc = cols (); 503 octave_idx_type nc = cols ();
525 if (nr != a.rows ()) 504 if (nr != a.rows ())
526 { 505 (*current_liboctave_error_handler) ("row dimension mismatch for append");
527 (*current_liboctave_error_handler) ("row dimension mismatch for append");
528 return *this;
529 }
530 506
531 octave_idx_type nc_insert = nc; 507 octave_idx_type nc_insert = nc;
532 FloatMatrix retval (nr, nc + a.cols ()); 508 FloatMatrix retval (nr, nc + a.cols ());
533 retval.insert (*this, 0, 0); 509 retval.insert (*this, 0, 0);
534 retval.insert (a, 0, nc_insert); 510 retval.insert (a, 0, nc_insert);
539 FloatMatrix::stack (const FloatMatrix& a) const 515 FloatMatrix::stack (const FloatMatrix& a) const
540 { 516 {
541 octave_idx_type nr = rows (); 517 octave_idx_type nr = rows ();
542 octave_idx_type nc = cols (); 518 octave_idx_type nc = cols ();
543 if (nc != a.cols ()) 519 if (nc != a.cols ())
544 { 520 (*current_liboctave_error_handler) ("column dimension mismatch for stack");
545 (*current_liboctave_error_handler)
546 ("column dimension mismatch for stack");
547 return FloatMatrix ();
548 }
549 521
550 octave_idx_type nr_insert = nr; 522 octave_idx_type nr_insert = nr;
551 FloatMatrix retval (nr + a.rows (), nc); 523 FloatMatrix retval (nr + a.rows (), nc);
552 retval.insert (*this, 0, 0); 524 retval.insert (*this, 0, 0);
553 retval.insert (a, nr_insert, 0); 525 retval.insert (a, nr_insert, 0);
558 FloatMatrix::stack (const FloatRowVector& a) const 530 FloatMatrix::stack (const FloatRowVector& a) const
559 { 531 {
560 octave_idx_type nr = rows (); 532 octave_idx_type nr = rows ();
561 octave_idx_type nc = cols (); 533 octave_idx_type nc = cols ();
562 if (nc != a.numel ()) 534 if (nc != a.numel ())
563 { 535 (*current_liboctave_error_handler) ("column dimension mismatch for stack");
564 (*current_liboctave_error_handler)
565 ("column dimension mismatch for stack");
566 return FloatMatrix ();
567 }
568 536
569 octave_idx_type nr_insert = nr; 537 octave_idx_type nr_insert = nr;
570 FloatMatrix retval (nr + 1, nc); 538 FloatMatrix retval (nr + 1, nc);
571 retval.insert (*this, 0, 0); 539 retval.insert (*this, 0, 0);
572 retval.insert (a, nr_insert, 0); 540 retval.insert (a, nr_insert, 0);
577 FloatMatrix::stack (const FloatColumnVector& a) const 545 FloatMatrix::stack (const FloatColumnVector& a) const
578 { 546 {
579 octave_idx_type nr = rows (); 547 octave_idx_type nr = rows ();
580 octave_idx_type nc = cols (); 548 octave_idx_type nc = cols ();
581 if (nc != 1) 549 if (nc != 1)
582 { 550 (*current_liboctave_error_handler) ("column dimension mismatch for stack");
583 (*current_liboctave_error_handler)
584 ("column dimension mismatch for stack");
585 return FloatMatrix ();
586 }
587 551
588 octave_idx_type nr_insert = nr; 552 octave_idx_type nr_insert = nr;
589 FloatMatrix retval (nr + a.numel (), nc); 553 FloatMatrix retval (nr + a.numel (), nc);
590 retval.insert (*this, 0, 0); 554 retval.insert (*this, 0, 0);
591 retval.insert (a, nr_insert, 0); 555 retval.insert (a, nr_insert, 0);
596 FloatMatrix::stack (const FloatDiagMatrix& a) const 560 FloatMatrix::stack (const FloatDiagMatrix& a) const
597 { 561 {
598 octave_idx_type nr = rows (); 562 octave_idx_type nr = rows ();
599 octave_idx_type nc = cols (); 563 octave_idx_type nc = cols ();
600 if (nc != a.cols ()) 564 if (nc != a.cols ())
601 { 565 (*current_liboctave_error_handler) ("column dimension mismatch for stack");
602 (*current_liboctave_error_handler)
603 ("column dimension mismatch for stack");
604 return FloatMatrix ();
605 }
606 566
607 octave_idx_type nr_insert = nr; 567 octave_idx_type nr_insert = nr;
608 FloatMatrix retval (nr + a.rows (), nc); 568 FloatMatrix retval (nr + a.rows (), nc);
609 retval.insert (*this, 0, 0); 569 retval.insert (*this, 0, 0);
610 retval.insert (a, nr_insert, 0); 570 retval.insert (a, nr_insert, 0);
703 octave_idx_type nr = rows (); 663 octave_idx_type nr = rows ();
704 octave_idx_type nc = cols (); 664 octave_idx_type nc = cols ();
705 665
706 if (nr != nc || nr == 0 || nc == 0) 666 if (nr != nc || nr == 0 || nc == 0)
707 (*current_liboctave_error_handler) ("inverse requires square matrix"); 667 (*current_liboctave_error_handler) ("inverse requires square matrix");
708 else 668
709 { 669 int typ = mattype.type ();
710 int typ = mattype.type (); 670 char uplo = (typ == MatrixType::Lower ? 'L' : 'U');
711 char uplo = (typ == MatrixType::Lower ? 'L' : 'U'); 671 char udiag = 'N';
712 char udiag = 'N'; 672 retval = *this;
713 retval = *this; 673 float *tmp_data = retval.fortran_vec ();
714 float *tmp_data = retval.fortran_vec (); 674
715 675 F77_XFCN (strtri, STRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1),
716 F77_XFCN (strtri, STRTRI, (F77_CONST_CHAR_ARG2 (&uplo, 1), 676 F77_CONST_CHAR_ARG2 (&udiag, 1),
677 nr, tmp_data, nr, info
678 F77_CHAR_ARG_LEN (1)
679 F77_CHAR_ARG_LEN (1)));
680
681 // Throw-away extra info LAPACK gives so as to not change output.
682 rcon = 0.0;
683 if (info != 0)
684 info = -1;
685 else if (calc_cond)
686 {
687 octave_idx_type dtrcon_info = 0;
688 char job = '1';
689
690 OCTAVE_LOCAL_BUFFER (float, work, 3 * nr);
691 OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, nr);
692
693 F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
694 F77_CONST_CHAR_ARG2 (&uplo, 1),
717 F77_CONST_CHAR_ARG2 (&udiag, 1), 695 F77_CONST_CHAR_ARG2 (&udiag, 1),
718 nr, tmp_data, nr, info 696 nr, tmp_data, nr, rcon,
697 work, iwork, dtrcon_info
698 F77_CHAR_ARG_LEN (1)
719 F77_CHAR_ARG_LEN (1) 699 F77_CHAR_ARG_LEN (1)
720 F77_CHAR_ARG_LEN (1))); 700 F77_CHAR_ARG_LEN (1)));
721 701
722 // Throw-away extra info LAPACK gives so as to not change output. 702 if (dtrcon_info != 0)
723 rcon = 0.0;
724 if (info != 0)
725 info = -1; 703 info = -1;
726 else if (calc_cond) 704 }
727 { 705
728 octave_idx_type dtrcon_info = 0; 706 if (info == -1 && ! force)
729 char job = '1'; 707 retval = *this; // Restore matrix contents.
730
731 OCTAVE_LOCAL_BUFFER (float, work, 3 * nr);
732 OCTAVE_LOCAL_BUFFER (octave_idx_type, iwork, nr);
733
734 F77_XFCN (strcon, STRCON, (F77_CONST_CHAR_ARG2 (&job, 1),
735 F77_CONST_CHAR_ARG2 (&uplo, 1),
736 F77_CONST_CHAR_ARG2 (&udiag, 1),
737 nr, tmp_data, nr, rcon,
738 work, iwork, dtrcon_info
739 F77_CHAR_ARG_LEN (1)
740 F77_CHAR_ARG_LEN (1)
741 F77_CHAR_ARG_LEN (1)));
742
743 if (dtrcon_info != 0)
744 info = -1;
745 }
746
747 if (info == -1 && ! force)
748 retval = *this; // Restore matrix contents.
749 }
750 708
751 return retval; 709 return retval;
752 } 710 }
753 711
754 712
761 octave_idx_type nr = rows (); 719 octave_idx_type nr = rows ();
762 octave_idx_type nc = cols (); 720 octave_idx_type nc = cols ();
763 721
764 if (nr != nc || nr == 0 || nc == 0) 722 if (nr != nc || nr == 0 || nc == 0)
765 (*current_liboctave_error_handler) ("inverse requires square matrix"); 723 (*current_liboctave_error_handler) ("inverse requires square matrix");
724
725 Array<octave_idx_type> ipvt (dim_vector (nr, 1));
726 octave_idx_type *pipvt = ipvt.fortran_vec ();
727
728 retval = *this;
729 float *tmp_data = retval.fortran_vec ();
730
731 Array<float> z(dim_vector (1, 1));
732 octave_idx_type lwork = -1;
733
734 // Query the optimum work array size.
735 F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt,
736 z.fortran_vec (), lwork, info));
737
738 lwork = static_cast<octave_idx_type> (z(0));
739 lwork = (lwork < 2 *nc ? 2*nc : lwork);
740 z.resize (dim_vector (lwork, 1));
741 float *pz = z.fortran_vec ();
742
743 info = 0;
744
745 // Calculate the norm of the matrix, for later use.
746 float anorm = 0;
747 if (calc_cond)
748 anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0))
749 .max ();
750
751 F77_XFCN (sgetrf, SGETRF, (nc, nc, tmp_data, nr, pipvt, info));
752
753 // Throw-away extra info LAPACK gives so as to not change output.
754 rcon = 0.0;
755 if (info != 0)
756 info = -1;
757 else if (calc_cond)
758 {
759 octave_idx_type dgecon_info = 0;
760
761 // Now calculate the condition number for non-singular matrix.
762 char job = '1';
763 Array<octave_idx_type> iz (dim_vector (nc, 1));
764 octave_idx_type *piz = iz.fortran_vec ();
765 F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
766 nc, tmp_data, nr, anorm,
767 rcon, pz, piz, dgecon_info
768 F77_CHAR_ARG_LEN (1)));
769
770 if (dgecon_info != 0)
771 info = -1;
772 }
773
774 if (info == -1 && ! force)
775 retval = *this; // Restore matrix contents.
766 else 776 else
767 { 777 {
768 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); 778 octave_idx_type dgetri_info = 0;
769 octave_idx_type *pipvt = ipvt.fortran_vec (); 779
770
771 retval = *this;
772 float *tmp_data = retval.fortran_vec ();
773
774 Array<float> z(dim_vector (1, 1));
775 octave_idx_type lwork = -1;
776
777 // Query the optimum work array size.
778 F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt, 780 F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt,
779 z.fortran_vec (), lwork, info)); 781 pz, lwork, dgetri_info));
780 782
781 lwork = static_cast<octave_idx_type> (z(0)); 783 if (dgetri_info != 0)
782 lwork = (lwork < 2 *nc ? 2*nc : lwork);
783 z.resize (dim_vector (lwork, 1));
784 float *pz = z.fortran_vec ();
785
786 info = 0;
787
788 // Calculate the norm of the matrix, for later use.
789 float anorm = 0;
790 if (calc_cond)
791 anorm = retval.abs ().sum ().row (static_cast<octave_idx_type>(0))
792 .max ();
793
794 F77_XFCN (sgetrf, SGETRF, (nc, nc, tmp_data, nr, pipvt, info));
795
796 // Throw-away extra info LAPACK gives so as to not change output.
797 rcon = 0.0;
798 if (info != 0)
799 info = -1; 784 info = -1;
800 else if (calc_cond) 785 }
801 { 786
802 octave_idx_type dgecon_info = 0; 787 if (info != 0)
803 788 mattype.mark_as_rectangular ();
804 // Now calculate the condition number for non-singular matrix.
805 char job = '1';
806 Array<octave_idx_type> iz (dim_vector (nc, 1));
807 octave_idx_type *piz = iz.fortran_vec ();
808 F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
809 nc, tmp_data, nr, anorm,
810 rcon, pz, piz, dgecon_info
811 F77_CHAR_ARG_LEN (1)));
812
813 if (dgecon_info != 0)
814 info = -1;
815 }
816
817 if (info == -1 && ! force)
818 retval = *this; // Restore matrix contents.
819 else
820 {
821 octave_idx_type dgetri_info = 0;
822
823 F77_XFCN (sgetri, SGETRI, (nc, tmp_data, nr, pipvt,
824 pz, lwork, dgetri_info));
825
826 if (dgetri_info != 0)
827 info = -1;
828 }
829
830 if (info != 0)
831 mattype.mark_as_rectangular ();
832 }
833 789
834 return retval; 790 return retval;
835 } 791 }
836 792
837 FloatMatrix 793 FloatMatrix
1275 octave_idx_type nr = rows (); 1231 octave_idx_type nr = rows ();
1276 octave_idx_type nc = cols (); 1232 octave_idx_type nc = cols ();
1277 1233
1278 if (nr != nc) 1234 if (nr != nc)
1279 (*current_liboctave_error_handler) ("matrix must be square"); 1235 (*current_liboctave_error_handler) ("matrix must be square");
1280 else 1236
1281 { 1237 volatile int typ = mattype.type ();
1282 volatile int typ = mattype.type (); 1238
1283 1239 // Even though the matrix is marked as singular (Rectangular), we may
1284 // Even though the matrix is marked as singular (Rectangular), we may 1240 // still get a useful number from the LU factorization, because it always
1285 // still get a useful number from the LU factorization, because it always 1241 // completes.
1286 // completes. 1242
1287 1243 if (typ == MatrixType::Unknown)
1288 if (typ == MatrixType::Unknown) 1244 typ = mattype.type (*this);
1289 typ = mattype.type (*this); 1245 else if (typ == MatrixType::Rectangular)
1290 else if (typ == MatrixType::Rectangular) 1246 typ = MatrixType::Full;
1291 typ = MatrixType::Full; 1247
1292 1248 if (typ == MatrixType::Lower || typ == MatrixType::Upper)
1293 if (typ == MatrixType::Lower || typ == MatrixType::Upper) 1249 {
1250 for (octave_idx_type i = 0; i < nc; i++)
1251 retval *= elem (i,i);
1252 }
1253 else if (typ == MatrixType::Hermitian)
1254 {
1255 FloatMatrix atmp = *this;
1256 float *tmp_data = atmp.fortran_vec ();
1257
1258 float anorm = 0;
1259 if (calc_cond) anorm = xnorm (*this, 1);
1260
1261
1262 char job = 'L';
1263 F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr,
1264 tmp_data, nr, info
1265 F77_CHAR_ARG_LEN (1)));
1266
1267 if (info != 0)
1294 { 1268 {
1269 rcon = 0.0;
1270 mattype.mark_as_unsymmetric ();
1271 typ = MatrixType::Full;
1272 }
1273 else
1274 {
1275 Array<float> z (dim_vector (3 * nc, 1));
1276 float *pz = z.fortran_vec ();
1277 Array<octave_idx_type> iz (dim_vector (nc, 1));
1278 octave_idx_type *piz = iz.fortran_vec ();
1279
1280 F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 (&job, 1),
1281 nr, tmp_data, nr, anorm,
1282 rcon, pz, piz, info
1283 F77_CHAR_ARG_LEN (1)));
1284
1285 if (info != 0)
1286 rcon = 0.0;
1287
1295 for (octave_idx_type i = 0; i < nc; i++) 1288 for (octave_idx_type i = 0; i < nc; i++)
1296 retval *= elem (i,i); 1289 retval *= atmp (i,i);
1290
1291 retval = retval.square ();
1297 } 1292 }
1298 else if (typ == MatrixType::Hermitian) 1293 }
1294 else if (typ != MatrixType::Full)
1295 (*current_liboctave_error_handler) ("det: invalid dense matrix type");
1296
1297 if (typ == MatrixType::Full)
1298 {
1299 Array<octave_idx_type> ipvt (dim_vector (nr, 1));
1300 octave_idx_type *pipvt = ipvt.fortran_vec ();
1301
1302 FloatMatrix atmp = *this;
1303 float *tmp_data = atmp.fortran_vec ();
1304
1305 info = 0;
1306
1307 // Calculate the norm of the matrix, for later use.
1308 float anorm = 0;
1309 if (calc_cond) anorm = xnorm (*this, 1);
1310
1311 F77_XFCN (sgetrf, SGETRF, (nr, nr, tmp_data, nr, pipvt, info));
1312
1313 // Throw-away extra info LAPACK gives so as to not change output.
1314 rcon = 0.0;
1315 if (info != 0)
1299 { 1316 {
1300 FloatMatrix atmp = *this; 1317 info = -1;
1301 float *tmp_data = atmp.fortran_vec (); 1318 retval = FloatDET ();
1302 1319 }
1303 float anorm = 0; 1320 else
1304 if (calc_cond) anorm = xnorm (*this, 1); 1321 {
1305 1322 if (calc_cond)
1306
1307 char job = 'L';
1308 F77_XFCN (spotrf, SPOTRF, (F77_CONST_CHAR_ARG2 (&job, 1), nr,
1309 tmp_data, nr, info
1310 F77_CHAR_ARG_LEN (1)));
1311
1312 if (info != 0)
1313 { 1323 {
1314 rcon = 0.0; 1324 // Now calc the condition number for non-singular matrix.
1315 mattype.mark_as_unsymmetric (); 1325 char job = '1';
1316 typ = MatrixType::Full; 1326 Array<float> z (dim_vector (4 * nc, 1));
1317 }
1318 else
1319 {
1320 Array<float> z (dim_vector (3 * nc, 1));
1321 float *pz = z.fortran_vec (); 1327 float *pz = z.fortran_vec ();
1322 Array<octave_idx_type> iz (dim_vector (nc, 1)); 1328 Array<octave_idx_type> iz (dim_vector (nc, 1));
1323 octave_idx_type *piz = iz.fortran_vec (); 1329 octave_idx_type *piz = iz.fortran_vec ();
1324 1330
1325 F77_XFCN (spocon, SPOCON, (F77_CONST_CHAR_ARG2 (&job, 1), 1331 F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
1326 nr, tmp_data, nr, anorm, 1332 nc, tmp_data, nr, anorm,
1327 rcon, pz, piz, info 1333 rcon, pz, piz, info
1328 F77_CHAR_ARG_LEN (1))); 1334 F77_CHAR_ARG_LEN (1)));
1329
1330 if (info != 0)
1331 rcon = 0.0;
1332
1333 for (octave_idx_type i = 0; i < nc; i++)
1334 retval *= atmp (i,i);
1335
1336 retval = retval.square ();
1337 } 1335 }
1338 } 1336
1339 else if (typ != MatrixType::Full)
1340 (*current_liboctave_error_handler) ("det: invalid dense matrix type");
1341
1342 if (typ == MatrixType::Full)
1343 {
1344 Array<octave_idx_type> ipvt (dim_vector (nr, 1));
1345 octave_idx_type *pipvt = ipvt.fortran_vec ();
1346
1347 FloatMatrix atmp = *this;
1348 float *tmp_data = atmp.fortran_vec ();
1349
1350 info = 0;
1351
1352 // Calculate the norm of the matrix, for later use.
1353 float anorm = 0;
1354 if (calc_cond) anorm = xnorm (*this, 1);
1355
1356 F77_XFCN (sgetrf, SGETRF, (nr, nr, tmp_data, nr, pipvt, info));
1357
1358 // Throw-away extra info LAPACK gives so as to not change output.
1359 rcon = 0.0;
1360 if (info != 0) 1337 if (info != 0)
1361 { 1338 {
1362 info = -1; 1339 info = -1;
1363 retval = FloatDET (); 1340 retval = FloatDET ();
1364 } 1341 }
1365 else 1342 else
1366 { 1343 {
1367 if (calc_cond) 1344 for (octave_idx_type i = 0; i < nc; i++)
1368 { 1345 {
1369 // Now calc the condition number for non-singular matrix. 1346 float c = atmp(i,i);
1370 char job = '1'; 1347 retval *= (ipvt(i) != (i+1)) ? -c : c;
1371 Array<float> z (dim_vector (4 * nc, 1));
1372 float *pz = z.fortran_vec ();
1373 Array<octave_idx_type> iz (dim_vector (nc, 1));
1374 octave_idx_type *piz = iz.fortran_vec ();
1375
1376 F77_XFCN (sgecon, SGECON, (F77_CONST_CHAR_ARG2 (&job, 1),
1377 nc, tmp_data, nr, anorm,
1378 rcon, pz, piz, info
1379 F77_CHAR_ARG_LEN (1)));
1380 }
1381
1382 if (info != 0)
1383 {
1384 info = -1;
1385 retval = FloatDET ();
1386 }
1387 else
1388 {
1389 for (octave_idx_type i = 0; i < nc; i++)
1390 {
1391 float c = atmp(i,i);
1392 retval *= (ipvt(i) != (i+1)) ? -c : c;
1393 }
1394 } 1348 }
1395 } 1349 }
1396 } 1350 }
1397 } 1351 }
1398 1352
1413 octave_idx_type nr = rows (); 1367 octave_idx_type nr = rows ();
1414 octave_idx_type nc = cols (); 1368 octave_idx_type nc = cols ();
1415 1369
1416 if (nr != nc) 1370 if (nr != nc)
1417 (*current_liboctave_error_handler) ("matrix must be square"); 1371 (*current_liboctave_error_handler) ("matrix must be square");
1418 else if (nr == 0 || nc == 0) 1372
1373 if (nr == 0 || nc == 0)
1419 rcon = octave_Inf; 1374 rcon = octave_Inf;
1420 else 1375 else
1421 { 1376 {
1422 volatile int typ = mattype.type (); 1377 volatile int typ = mattype.type ();
1423 1378
1448 F77_CHAR_ARG_LEN (1))); 1403 F77_CHAR_ARG_LEN (1)));
1449 1404
1450 if (info != 0) 1405 if (info != 0)
1451 rcon = 0.0; 1406 rcon = 0.0;
1452 } 1407 }
1453 else if (typ == MatrixType::Permuted_Upper) 1408 else if (typ == MatrixType::Permuted_Upper)
1454 (*current_liboctave_error_handler) 1409 (*current_liboctave_error_handler)
1455 ("permuted triangular matrix not implemented"); 1410 ("permuted triangular matrix not implemented");
1456 else if (typ == MatrixType::Lower) 1411 else if (typ == MatrixType::Lower)
1457 { 1412 {
1458 const float *tmp_data = fortran_vec (); 1413 const float *tmp_data = fortran_vec ();
1581 octave_idx_type nc = cols (); 1536 octave_idx_type nc = cols ();
1582 1537
1583 if (nr != b.rows ()) 1538 if (nr != b.rows ())
1584 (*current_liboctave_error_handler) 1539 (*current_liboctave_error_handler)
1585 ("matrix dimension mismatch solution of linear equations"); 1540 ("matrix dimension mismatch solution of linear equations");
1586 else if (nr == 0 || nc == 0 || b.cols () == 0) 1541
1542 if (nr == 0 || nc == 0 || b.cols () == 0)
1587 retval = FloatMatrix (nc, b.cols (), 0.0); 1543 retval = FloatMatrix (nc, b.cols (), 0.0);
1588 else 1544 else
1589 { 1545 {
1590 volatile int typ = mattype.type (); 1546 volatile int typ = mattype.type ();
1591 1547
1594 octave_idx_type b_nc = b.cols (); 1550 octave_idx_type b_nc = b.cols ();
1595 rcon = 1.; 1551 rcon = 1.;
1596 info = 0; 1552 info = 0;
1597 1553
1598 if (typ == MatrixType::Permuted_Upper) 1554 if (typ == MatrixType::Permuted_Upper)
1599 { 1555 (*current_liboctave_error_handler)
1600 (*current_liboctave_error_handler) 1556 ("permuted triangular matrix not implemented");
1601 ("permuted triangular matrix not implemented");
1602 }
1603 else 1557 else
1604 { 1558 {
1605 const float *tmp_data = fortran_vec (); 1559 const float *tmp_data = fortran_vec ();
1606 1560
1607 retval = b; 1561 retval = b;
1677 octave_idx_type nc = cols (); 1631 octave_idx_type nc = cols ();
1678 1632
1679 if (nr != b.rows ()) 1633 if (nr != b.rows ())
1680 (*current_liboctave_error_handler) 1634 (*current_liboctave_error_handler)
1681 ("matrix dimension mismatch solution of linear equations"); 1635 ("matrix dimension mismatch solution of linear equations");
1682 else if (nr == 0 || nc == 0 || b.cols () == 0) 1636
1637 if (nr == 0 || nc == 0 || b.cols () == 0)
1683 retval = FloatMatrix (nc, b.cols (), 0.0); 1638 retval = FloatMatrix (nc, b.cols (), 0.0);
1684 else 1639 else
1685 { 1640 {
1686 volatile int typ = mattype.type (); 1641 volatile int typ = mattype.type ();
1687 1642
1690 octave_idx_type b_nc = b.cols (); 1645 octave_idx_type b_nc = b.cols ();
1691 rcon = 1.; 1646 rcon = 1.;
1692 info = 0; 1647 info = 0;
1693 1648
1694 if (typ == MatrixType::Permuted_Lower) 1649 if (typ == MatrixType::Permuted_Lower)
1695 { 1650 (*current_liboctave_error_handler)
1696 (*current_liboctave_error_handler) 1651 ("permuted triangular matrix not implemented");
1697 ("permuted triangular matrix not implemented");
1698 }
1699 else 1652 else
1700 { 1653 {
1701 const float *tmp_data = fortran_vec (); 1654 const float *tmp_data = fortran_vec ();
1702 1655
1703 retval = b; 1656 retval = b;
1772 octave_idx_type nc = cols (); 1725 octave_idx_type nc = cols ();
1773 1726
1774 if (nr != nc || nr != b.rows ()) 1727 if (nr != nc || nr != b.rows ())
1775 (*current_liboctave_error_handler) 1728 (*current_liboctave_error_handler)
1776 ("matrix dimension mismatch solution of linear equations"); 1729 ("matrix dimension mismatch solution of linear equations");
1777 else if (nr == 0 || b.cols () == 0) 1730
1731 if (nr == 0 || b.cols () == 0)
1778 retval = FloatMatrix (nc, b.cols (), 0.0); 1732 retval = FloatMatrix (nc, b.cols (), 0.0);
1779 else 1733 else
1780 { 1734 {
1781 volatile int typ = mattype.type (); 1735 volatile int typ = mattype.type ();
1782 1736
1985 return transpose ().solve (mattype, b, info, rcon, sing_handler, 1939 return transpose ().solve (mattype, b, info, rcon, sing_handler,
1986 singular_fallback); 1940 singular_fallback);
1987 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) 1941 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian)
1988 retval = fsolve (mattype, b, info, rcon, sing_handler, true); 1942 retval = fsolve (mattype, b, info, rcon, sing_handler, true);
1989 else if (typ != MatrixType::Rectangular) 1943 else if (typ != MatrixType::Rectangular)
1990 { 1944 (*current_liboctave_error_handler) ("unknown matrix type");
1991 (*current_liboctave_error_handler) ("unknown matrix type");
1992 return FloatMatrix ();
1993 }
1994 1945
1995 // Rectangular or one of the above solvers flags a singular matrix 1946 // Rectangular or one of the above solvers flags a singular matrix
1996 if (singular_fallback && mattype.type () == MatrixType::Rectangular) 1947 if (singular_fallback && mattype.type () == MatrixType::Rectangular)
1997 { 1948 {
1998 octave_idx_type rank; 1949 octave_idx_type rank;
2297 octave_idx_type n = cols (); 2248 octave_idx_type n = cols ();
2298 2249
2299 if (m != b.rows ()) 2250 if (m != b.rows ())
2300 (*current_liboctave_error_handler) 2251 (*current_liboctave_error_handler)
2301 ("matrix dimension mismatch solution of linear equations"); 2252 ("matrix dimension mismatch solution of linear equations");
2302 else if (m == 0 || n == 0 || b.cols () == 0) 2253
2254 if (m == 0 || n == 0 || b.cols () == 0)
2303 retval = FloatMatrix (n, b.cols (), 0.0); 2255 retval = FloatMatrix (n, b.cols (), 0.0);
2304 else 2256 else
2305 { 2257 {
2306 volatile octave_idx_type minmn = (m < n ? m : n); 2258 volatile octave_idx_type minmn = (m < n ? m : n);
2307 octave_idx_type maxmn = m > n ? m : n; 2259 octave_idx_type maxmn = m > n ? m : n;
2492 octave_idx_type n = cols (); 2444 octave_idx_type n = cols ();
2493 2445
2494 if (m != b.numel ()) 2446 if (m != b.numel ())
2495 (*current_liboctave_error_handler) 2447 (*current_liboctave_error_handler)
2496 ("matrix dimension mismatch solution of linear equations"); 2448 ("matrix dimension mismatch solution of linear equations");
2497 else if (m == 0 || n == 0) 2449
2450 if (m == 0 || n == 0)
2498 retval = FloatColumnVector (n, 0.0); 2451 retval = FloatColumnVector (n, 0.0);
2499 else 2452 else
2500 { 2453 {
2501 volatile octave_idx_type minmn = (m < n ? m : n); 2454 volatile octave_idx_type minmn = (m < n ? m : n);
2502 octave_idx_type maxmn = m > n ? m : n; 2455 octave_idx_type maxmn = m > n ? m : n;
2726 octave_idx_type nc = cols (); 2679 octave_idx_type nc = cols ();
2727 2680
2728 if (nr == 1 || nc == 1) 2681 if (nr == 1 || nc == 1)
2729 retval = FloatDiagMatrix (*this, m, n); 2682 retval = FloatDiagMatrix (*this, m, n);
2730 else 2683 else
2731 (*current_liboctave_error_handler) 2684 (*current_liboctave_error_handler) ("diag: expecting vector argument");
2732 ("diag: expecting vector argument");
2733 2685
2734 return retval; 2686 return retval;
2735 } 2687 }
2736 2688
2737 FloatColumnVector 2689 FloatColumnVector
3233 { 3185 {
3234 octave_idx_type nr = a.rows (); 3186 octave_idx_type nr = a.rows ();
3235 octave_idx_type nc = a.columns (); 3187 octave_idx_type nc = a.columns ();
3236 3188
3237 if (nr != b.rows () || nc != b.columns ()) 3189 if (nr != b.rows () || nc != b.columns ())
3238 { 3190 (*current_liboctave_error_handler)
3239 (*current_liboctave_error_handler) 3191 ("two-arg min requires same size arguments");
3240 ("two-arg min requires same size arguments");
3241 return FloatMatrix ();
3242 }
3243 3192
3244 EMPTY_RETURN_CHECK (FloatMatrix); 3193 EMPTY_RETURN_CHECK (FloatMatrix);
3245 3194
3246 FloatMatrix result (nr, nc); 3195 FloatMatrix result (nr, nc);
3247 3196
3300 { 3249 {
3301 octave_idx_type nr = a.rows (); 3250 octave_idx_type nr = a.rows ();
3302 octave_idx_type nc = a.columns (); 3251 octave_idx_type nc = a.columns ();
3303 3252
3304 if (nr != b.rows () || nc != b.columns ()) 3253 if (nr != b.rows () || nc != b.columns ())
3305 { 3254 (*current_liboctave_error_handler)
3306 (*current_liboctave_error_handler) 3255 ("two-arg max requires same size arguments");
3307 ("two-arg max requires same size arguments");
3308 return FloatMatrix ();
3309 }
3310 3256
3311 EMPTY_RETURN_CHECK (FloatMatrix); 3257 EMPTY_RETURN_CHECK (FloatMatrix);
3312 3258
3313 FloatMatrix result (nr, nc); 3259 FloatMatrix result (nr, nc);
3314 3260