Mercurial > octave-nkf
comparison liboctave/dSparse.cc @ 11586:12df7854fa7c
strip trailing whitespace from source files
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 20 Jan 2011 17:24:59 -0500 |
parents | a83bad07f7e3 |
children | b646413c3d0e |
comparison
equal
deleted
inserted
replaced
11585:1473d0cf86d2 | 11586:12df7854fa7c |
---|---|
182 | 182 |
183 SparseMatrix::SparseMatrix (const PermMatrix& a) | 183 SparseMatrix::SparseMatrix (const PermMatrix& a) |
184 : MSparse<double> (a.rows (), a.cols (), a.rows ()) | 184 : MSparse<double> (a.rows (), a.cols (), a.rows ()) |
185 { | 185 { |
186 octave_idx_type n = a.rows (); | 186 octave_idx_type n = a.rows (); |
187 for (octave_idx_type i = 0; i <= n; i++) | 187 for (octave_idx_type i = 0; i <= n; i++) |
188 cidx (i) = i; | 188 cidx (i) = i; |
189 const Array<octave_idx_type> pv = a.pvec (); | 189 const Array<octave_idx_type> pv = a.pvec (); |
190 | 190 |
191 if (a.is_row_perm ()) | 191 if (a.is_row_perm ()) |
192 { | 192 { |
300 SparseMatrix result; | 300 SparseMatrix result; |
301 dim_vector dv = dims (); | 301 dim_vector dv = dims (); |
302 | 302 |
303 if (dv.numel () == 0 || dim >= dv.length ()) | 303 if (dv.numel () == 0 || dim >= dv.length ()) |
304 return result; | 304 return result; |
305 | 305 |
306 if (dim < 0) | 306 if (dim < 0) |
307 dim = dv.first_non_singleton (); | 307 dim = dv.first_non_singleton (); |
308 | 308 |
309 octave_idx_type nr = dv(0); | 309 octave_idx_type nr = dv(0); |
310 octave_idx_type nc = dv(1); | 310 octave_idx_type nc = dv(1); |
380 if (ridx(k) == i) | 380 if (ridx(k) == i) |
381 { | 381 { |
382 found = true; | 382 found = true; |
383 break; | 383 break; |
384 } | 384 } |
385 | 385 |
386 if (!found) | 386 if (!found) |
387 idx_arg.elem(i) = j; | 387 idx_arg.elem(i) = j; |
388 | 388 |
389 } | 389 } |
390 | 390 |
449 SparseMatrix result; | 449 SparseMatrix result; |
450 dim_vector dv = dims (); | 450 dim_vector dv = dims (); |
451 | 451 |
452 if (dv.numel () == 0 || dim >= dv.length ()) | 452 if (dv.numel () == 0 || dim >= dv.length ()) |
453 return result; | 453 return result; |
454 | 454 |
455 if (dim < 0) | 455 if (dim < 0) |
456 dim = dv.first_non_singleton (); | 456 dim = dv.first_non_singleton (); |
457 | 457 |
458 octave_idx_type nr = dv(0); | 458 octave_idx_type nr = dv(0); |
459 octave_idx_type nc = dv(1); | 459 octave_idx_type nc = dv(1); |
529 if (ridx(k) == i) | 529 if (ridx(k) == i) |
530 { | 530 { |
531 found = true; | 531 found = true; |
532 break; | 532 break; |
533 } | 533 } |
534 | 534 |
535 if (!found) | 535 if (!found) |
536 idx_arg.elem(i) = j; | 536 idx_arg.elem(i) = j; |
537 | 537 |
538 } | 538 } |
539 | 539 |
583 } | 583 } |
584 | 584 |
585 return result; | 585 return result; |
586 } | 586 } |
587 | 587 |
588 RowVector | 588 RowVector |
589 SparseMatrix::row (octave_idx_type i) const | 589 SparseMatrix::row (octave_idx_type i) const |
590 { | 590 { |
591 octave_idx_type nc = columns (); | 591 octave_idx_type nc = columns (); |
592 RowVector retval (nc, 0); | 592 RowVector retval (nc, 0); |
593 | 593 |
602 } | 602 } |
603 | 603 |
604 return retval; | 604 return retval; |
605 } | 605 } |
606 | 606 |
607 ColumnVector | 607 ColumnVector |
608 SparseMatrix::column (octave_idx_type i) const | 608 SparseMatrix::column (octave_idx_type i) const |
609 { | 609 { |
610 octave_idx_type nr = rows (); | 610 octave_idx_type nr = rows (); |
611 ColumnVector retval (nr); | 611 ColumnVector retval (nr); |
612 | 612 |
672 } | 672 } |
673 | 673 |
674 return r; | 674 return r; |
675 } | 675 } |
676 | 676 |
677 SparseMatrix | 677 SparseMatrix |
678 atan2 (const double& x, const SparseMatrix& y) | 678 atan2 (const double& x, const SparseMatrix& y) |
679 { | 679 { |
680 octave_idx_type nr = y.rows (); | 680 octave_idx_type nr = y.rows (); |
681 octave_idx_type nc = y.cols (); | 681 octave_idx_type nc = y.cols (); |
682 | 682 |
694 | 694 |
695 return SparseMatrix (tmp); | 695 return SparseMatrix (tmp); |
696 } | 696 } |
697 } | 697 } |
698 | 698 |
699 SparseMatrix | 699 SparseMatrix |
700 atan2 (const SparseMatrix& x, const double& y) | 700 atan2 (const SparseMatrix& x, const double& y) |
701 { | 701 { |
702 octave_idx_type nr = x.rows (); | 702 octave_idx_type nr = x.rows (); |
703 octave_idx_type nc = x.cols (); | 703 octave_idx_type nc = x.cols (); |
704 octave_idx_type nz = x.nnz (); | 704 octave_idx_type nz = x.nnz (); |
735 } | 735 } |
736 else | 736 else |
737 return retval; | 737 return retval; |
738 } | 738 } |
739 | 739 |
740 SparseMatrix | 740 SparseMatrix |
741 atan2 (const SparseMatrix& x, const SparseMatrix& y) | 741 atan2 (const SparseMatrix& x, const SparseMatrix& y) |
742 { | 742 { |
743 SparseMatrix r; | 743 SparseMatrix r; |
744 | 744 |
745 if ((x.rows() == y.rows()) && (x.cols() == y.cols())) | 745 if ((x.rows() == y.rows()) && (x.cols() == y.cols())) |
746 { | 746 { |
747 octave_idx_type x_nr = x.rows (); | 747 octave_idx_type x_nr = x.rows (); |
748 octave_idx_type x_nc = x.cols (); | 748 octave_idx_type x_nc = x.cols (); |
749 | 749 |
750 octave_idx_type y_nr = y.rows (); | 750 octave_idx_type y_nr = y.rows (); |
753 if (x_nr != y_nr || x_nc != y_nc) | 753 if (x_nr != y_nr || x_nc != y_nc) |
754 gripe_nonconformant ("atan2", x_nr, x_nc, y_nr, y_nc); | 754 gripe_nonconformant ("atan2", x_nr, x_nc, y_nr, y_nc); |
755 else | 755 else |
756 { | 756 { |
757 r = SparseMatrix (x_nr, x_nc, (x.nnz () + y.nnz ())); | 757 r = SparseMatrix (x_nr, x_nc, (x.nnz () + y.nnz ())); |
758 | 758 |
759 octave_idx_type jx = 0; | 759 octave_idx_type jx = 0; |
760 r.cidx (0) = 0; | 760 r.cidx (0) = 0; |
761 for (octave_idx_type i = 0 ; i < x_nc ; i++) | 761 for (octave_idx_type i = 0 ; i < x_nc ; i++) |
762 { | 762 { |
763 octave_idx_type ja = x.cidx(i); | 763 octave_idx_type ja = x.cidx(i); |
764 octave_idx_type ja_max = x.cidx(i+1); | 764 octave_idx_type ja_max = x.cidx(i+1); |
765 bool ja_lt_max= ja < ja_max; | 765 bool ja_lt_max= ja < ja_max; |
766 | 766 |
767 octave_idx_type jb = y.cidx(i); | 767 octave_idx_type jb = y.cidx(i); |
768 octave_idx_type jb_max = y.cidx(i+1); | 768 octave_idx_type jb_max = y.cidx(i+1); |
769 bool jb_lt_max = jb < jb_max; | 769 bool jb_lt_max = jb < jb_max; |
770 | 770 |
771 while (ja_lt_max || jb_lt_max ) | 771 while (ja_lt_max || jb_lt_max ) |
772 { | 772 { |
773 octave_quit (); | 773 octave_quit (); |
774 if ((! jb_lt_max) || | 774 if ((! jb_lt_max) || |
775 (ja_lt_max && (x.ridx(ja) < y.ridx(jb)))) | 775 (ja_lt_max && (x.ridx(ja) < y.ridx(jb)))) |
801 jb_lt_max= jb < jb_max; | 801 jb_lt_max= jb < jb_max; |
802 } | 802 } |
803 } | 803 } |
804 r.cidx(i+1) = jx; | 804 r.cidx(i+1) = jx; |
805 } | 805 } |
806 | 806 |
807 r.maybe_compress (); | 807 r.maybe_compress (); |
808 } | 808 } |
809 } | 809 } |
810 else | 810 else |
811 (*current_liboctave_error_handler) ("matrix size mismatch"); | 811 (*current_liboctave_error_handler) ("matrix size mismatch"); |
835 { | 835 { |
836 double rcond; | 836 double rcond; |
837 return inverse (mattype, info, rcond, 0, 0); | 837 return inverse (mattype, info, rcond, 0, 0); |
838 } | 838 } |
839 | 839 |
840 SparseMatrix | 840 SparseMatrix |
841 SparseMatrix::dinverse (MatrixType &mattyp, octave_idx_type& info, | 841 SparseMatrix::dinverse (MatrixType &mattyp, octave_idx_type& info, |
842 double& rcond, const bool, | 842 double& rcond, const bool, |
843 const bool calccond) const | 843 const bool calccond) const |
844 { | 844 { |
845 SparseMatrix retval; | 845 SparseMatrix retval; |
846 | 846 |
847 octave_idx_type nr = rows (); | 847 octave_idx_type nr = rows (); |
861 { | 861 { |
862 if (typ == MatrixType::Permuted_Diagonal) | 862 if (typ == MatrixType::Permuted_Diagonal) |
863 retval = transpose(); | 863 retval = transpose(); |
864 else | 864 else |
865 retval = *this; | 865 retval = *this; |
866 | 866 |
867 // Force make_unique to be called | 867 // Force make_unique to be called |
868 double *v = retval.data(); | 868 double *v = retval.data(); |
869 | 869 |
870 if (calccond) | 870 if (calccond) |
871 { | 871 { |
872 double dmax = 0., dmin = octave_Inf; | 872 double dmax = 0., dmin = octave_Inf; |
873 for (octave_idx_type i = 0; i < nr; i++) | 873 for (octave_idx_type i = 0; i < nr; i++) |
874 { | 874 { |
875 double tmp = fabs(v[i]); | 875 double tmp = fabs(v[i]); |
876 if (tmp > dmax) | 876 if (tmp > dmax) |
877 dmax = tmp; | 877 dmax = tmp; |
889 } | 889 } |
890 | 890 |
891 return retval; | 891 return retval; |
892 } | 892 } |
893 | 893 |
894 SparseMatrix | 894 SparseMatrix |
895 SparseMatrix::tinverse (MatrixType &mattyp, octave_idx_type& info, | 895 SparseMatrix::tinverse (MatrixType &mattyp, octave_idx_type& info, |
896 double& rcond, const bool, | 896 double& rcond, const bool, |
897 const bool calccond) const | 897 const bool calccond) const |
898 { | 898 { |
899 SparseMatrix retval; | 899 SparseMatrix retval; |
900 | 900 |
901 octave_idx_type nr = rows (); | 901 octave_idx_type nr = rows (); |
908 { | 908 { |
909 // Print spparms("spumoni") info if requested | 909 // Print spparms("spumoni") info if requested |
910 int typ = mattyp.type (); | 910 int typ = mattyp.type (); |
911 mattyp.info (); | 911 mattyp.info (); |
912 | 912 |
913 if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper || | 913 if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper || |
914 typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | 914 typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
915 { | 915 { |
916 double anorm = 0.; | 916 double anorm = 0.; |
917 double ainvnorm = 0.; | 917 double ainvnorm = 0.; |
918 | 918 |
939 for (octave_idx_type i = 0; i < nr; i++) | 939 for (octave_idx_type i = 0; i < nr; i++) |
940 { | 940 { |
941 octave_quit (); | 941 octave_quit (); |
942 // place the 1 in the identity position | 942 // place the 1 in the identity position |
943 octave_idx_type cx_colstart = cx; | 943 octave_idx_type cx_colstart = cx; |
944 | 944 |
945 if (cx == nz2) | 945 if (cx == nz2) |
946 { | 946 { |
947 nz2 *= 2; | 947 nz2 *= 2; |
948 retval.change_capacity (nz2); | 948 retval.change_capacity (nz2); |
949 } | 949 } |
952 retval.xridx(cx) = i; | 952 retval.xridx(cx) = i; |
953 retval.xdata(cx) = 1.0; | 953 retval.xdata(cx) = 1.0; |
954 cx++; | 954 cx++; |
955 | 955 |
956 // iterate accross columns of input matrix | 956 // iterate accross columns of input matrix |
957 for (octave_idx_type j = i+1; j < nr; j++) | 957 for (octave_idx_type j = i+1; j < nr; j++) |
958 { | 958 { |
959 double v = 0.; | 959 double v = 0.; |
960 // iterate to calculate sum | 960 // iterate to calculate sum |
961 octave_idx_type colXp = retval.xcidx(i); | 961 octave_idx_type colXp = retval.xcidx(i); |
962 octave_idx_type colUp = cidx(j); | 962 octave_idx_type colUp = cidx(j); |
963 octave_idx_type rpX, rpU; | 963 octave_idx_type rpX, rpU; |
964 | 964 |
965 if (cidx(j) == cidx(j+1)) | 965 if (cidx(j) == cidx(j+1)) |
966 { | 966 { |
967 (*current_liboctave_error_handler) | 967 (*current_liboctave_error_handler) |
968 ("division by zero"); | 968 ("division by zero"); |
969 goto inverse_singular; | 969 goto inverse_singular; |
970 } | 970 } |
971 | 971 |
972 do | 972 do |
973 { | 973 { |
974 octave_quit (); | 974 octave_quit (); |
975 rpX = retval.xridx(colXp); | 975 rpX = retval.xridx(colXp); |
976 rpU = ridx(colUp); | 976 rpU = ridx(colUp); |
977 | 977 |
978 if (rpX < rpU) | 978 if (rpX < rpU) |
979 colXp++; | 979 colXp++; |
980 else if (rpX > rpU) | 980 else if (rpX > rpU) |
981 colUp++; | 981 colUp++; |
982 else | 982 else |
983 { | 983 { |
984 v -= retval.xdata(colXp) * data(colUp); | 984 v -= retval.xdata(colXp) * data(colUp); |
985 colXp++; | 985 colXp++; |
986 colUp++; | 986 colUp++; |
987 } | 987 } |
988 } while ((rpX<j) && (rpU<j) && | 988 } while ((rpX<j) && (rpU<j) && |
989 (colXp<cx) && (colUp<nz)); | 989 (colXp<cx) && (colUp<nz)); |
990 | 990 |
991 // get A(m,m) | 991 // get A(m,m) |
992 if (typ == MatrixType::Upper) | 992 if (typ == MatrixType::Upper) |
993 colUp = cidx(j+1) - 1; | 993 colUp = cidx(j+1) - 1; |
994 else | 994 else |
995 colUp = cidx(j); | 995 colUp = cidx(j); |
996 double pivot = data(colUp); | 996 double pivot = data(colUp); |
997 if (pivot == 0. || ridx(colUp) != j) | 997 if (pivot == 0. || ridx(colUp) != j) |
998 { | 998 { |
999 (*current_liboctave_error_handler) | 999 (*current_liboctave_error_handler) |
1000 ("division by zero"); | 1000 ("division by zero"); |
1001 goto inverse_singular; | 1001 goto inverse_singular; |
1002 } | 1002 } |
1003 | 1003 |
1004 if (v != 0.) | 1004 if (v != 0.) |
1020 if (typ == MatrixType::Upper) | 1020 if (typ == MatrixType::Upper) |
1021 colUp = cidx(i+1) - 1; | 1021 colUp = cidx(i+1) - 1; |
1022 else | 1022 else |
1023 colUp = cidx(i); | 1023 colUp = cidx(i); |
1024 double pivot = data(colUp); | 1024 double pivot = data(colUp); |
1025 if (pivot == 0. || ridx(colUp) != i) | 1025 if (pivot == 0. || ridx(colUp) != i) |
1026 { | 1026 { |
1027 (*current_liboctave_error_handler) ("division by zero"); | 1027 (*current_liboctave_error_handler) ("division by zero"); |
1028 goto inverse_singular; | 1028 goto inverse_singular; |
1029 } | 1029 } |
1030 | 1030 |
1069 | 1069 |
1070 // place the 1 in the identity position | 1070 // place the 1 in the identity position |
1071 work[iidx] = 1.0; | 1071 work[iidx] = 1.0; |
1072 | 1072 |
1073 // iterate accross columns of input matrix | 1073 // iterate accross columns of input matrix |
1074 for (octave_idx_type j = iidx+1; j < nr; j++) | 1074 for (octave_idx_type j = iidx+1; j < nr; j++) |
1075 { | 1075 { |
1076 double v = 0.; | 1076 double v = 0.; |
1077 octave_idx_type jidx = perm[j]; | 1077 octave_idx_type jidx = perm[j]; |
1078 // iterate to calculate sum | 1078 // iterate to calculate sum |
1079 for (octave_idx_type k = cidx(jidx); | 1079 for (octave_idx_type k = cidx(jidx); |
1080 k < cidx(jidx+1); k++) | 1080 k < cidx(jidx+1); k++) |
1081 { | 1081 { |
1082 octave_quit (); | 1082 octave_quit (); |
1083 v -= work[ridx(k)] * data(k); | 1083 v -= work[ridx(k)] * data(k); |
1084 } | 1084 } |
1087 double pivot; | 1087 double pivot; |
1088 if (typ == MatrixType::Permuted_Upper) | 1088 if (typ == MatrixType::Permuted_Upper) |
1089 pivot = data(cidx(jidx+1) - 1); | 1089 pivot = data(cidx(jidx+1) - 1); |
1090 else | 1090 else |
1091 pivot = data(cidx(jidx)); | 1091 pivot = data(cidx(jidx)); |
1092 if (pivot == 0.) | 1092 if (pivot == 0.) |
1093 { | 1093 { |
1094 (*current_liboctave_error_handler) | 1094 (*current_liboctave_error_handler) |
1095 ("division by zero"); | 1095 ("division by zero"); |
1096 goto inverse_singular; | 1096 goto inverse_singular; |
1097 } | 1097 } |
1098 | 1098 |
1099 work[j] = v / pivot; | 1099 work[j] = v / pivot; |
1107 colUp = cidx(perm[iidx]); | 1107 colUp = cidx(perm[iidx]); |
1108 | 1108 |
1109 double pivot = data(colUp); | 1109 double pivot = data(colUp); |
1110 if (pivot == 0.) | 1110 if (pivot == 0.) |
1111 { | 1111 { |
1112 (*current_liboctave_error_handler) | 1112 (*current_liboctave_error_handler) |
1113 ("division by zero"); | 1113 ("division by zero"); |
1114 goto inverse_singular; | 1114 goto inverse_singular; |
1115 } | 1115 } |
1116 | 1116 |
1117 octave_idx_type new_cx = cx; | 1117 octave_idx_type new_cx = cx; |
1146 { | 1146 { |
1147 // Calculate the 1-norm of inverse matrix for rcond calculation | 1147 // Calculate the 1-norm of inverse matrix for rcond calculation |
1148 for (octave_idx_type j = 0; j < nr; j++) | 1148 for (octave_idx_type j = 0; j < nr; j++) |
1149 { | 1149 { |
1150 double atmp = 0.; | 1150 double atmp = 0.; |
1151 for (octave_idx_type i = retval.cidx(j); | 1151 for (octave_idx_type i = retval.cidx(j); |
1152 i < retval.cidx(j+1); i++) | 1152 i < retval.cidx(j+1); i++) |
1153 atmp += fabs(retval.data(i)); | 1153 atmp += fabs(retval.data(i)); |
1154 if (atmp > ainvnorm) | 1154 if (atmp > ainvnorm) |
1155 ainvnorm = atmp; | 1155 ainvnorm = atmp; |
1156 } | 1156 } |
1157 | 1157 |
1158 rcond = 1. / ainvnorm / anorm; | 1158 rcond = 1. / ainvnorm / anorm; |
1159 } | 1159 } |
1160 } | 1160 } |
1161 else | 1161 else |
1162 (*current_liboctave_error_handler) ("incorrect matrix type"); | 1162 (*current_liboctave_error_handler) ("incorrect matrix type"); |
1163 } | 1163 } |
1167 inverse_singular: | 1167 inverse_singular: |
1168 return SparseMatrix(); | 1168 return SparseMatrix(); |
1169 } | 1169 } |
1170 | 1170 |
1171 SparseMatrix | 1171 SparseMatrix |
1172 SparseMatrix::inverse (MatrixType &mattype, octave_idx_type& info, | 1172 SparseMatrix::inverse (MatrixType &mattype, octave_idx_type& info, |
1173 double& rcond, int, int calc_cond) const | 1173 double& rcond, int, int calc_cond) const |
1174 { | 1174 { |
1175 int typ = mattype.type (false); | 1175 int typ = mattype.type (false); |
1176 SparseMatrix ret; | 1176 SparseMatrix ret; |
1177 | 1177 |
1219 | 1219 |
1220 MatrixType tmp_typ (MatrixType::Upper); | 1220 MatrixType tmp_typ (MatrixType::Upper); |
1221 SparseLU fact (*this, Qinit, Matrix(), false, false); | 1221 SparseLU fact (*this, Qinit, Matrix(), false, false); |
1222 rcond = fact.rcond(); | 1222 rcond = fact.rcond(); |
1223 double rcond2; | 1223 double rcond2; |
1224 SparseMatrix InvL = fact.L().transpose().tinverse(tmp_typ, | 1224 SparseMatrix InvL = fact.L().transpose().tinverse(tmp_typ, |
1225 info, rcond2, true, false); | 1225 info, rcond2, true, false); |
1226 SparseMatrix InvU = fact.U().tinverse(tmp_typ, info, rcond2, | 1226 SparseMatrix InvU = fact.U().tinverse(tmp_typ, info, rcond2, |
1227 true, false).transpose(); | 1227 true, false).transpose(); |
1228 ret = fact.Pc().transpose() * InvU * InvL * fact.Pr(); | 1228 ret = fact.Pc().transpose() * InvU * InvL * fact.Pr(); |
1229 } | 1229 } |
1283 // Set whether we are allowed to modify Q or not | 1283 // Set whether we are allowed to modify Q or not |
1284 tmp = octave_sparse_params::get_key ("autoamd"); | 1284 tmp = octave_sparse_params::get_key ("autoamd"); |
1285 if (!xisnan (tmp)) | 1285 if (!xisnan (tmp)) |
1286 Control (UMFPACK_FIXQ) = tmp; | 1286 Control (UMFPACK_FIXQ) = tmp; |
1287 | 1287 |
1288 // Turn-off UMFPACK scaling for LU | 1288 // Turn-off UMFPACK scaling for LU |
1289 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; | 1289 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; |
1290 | 1290 |
1291 UMFPACK_DNAME (report_control) (control); | 1291 UMFPACK_DNAME (report_control) (control); |
1292 | 1292 |
1293 const octave_idx_type *Ap = cidx (); | 1293 const octave_idx_type *Ap = cidx (); |
1297 UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control); | 1297 UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control); |
1298 | 1298 |
1299 void *Symbolic; | 1299 void *Symbolic; |
1300 Matrix Info (1, UMFPACK_INFO); | 1300 Matrix Info (1, UMFPACK_INFO); |
1301 double *info = Info.fortran_vec (); | 1301 double *info = Info.fortran_vec (); |
1302 int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, | 1302 int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, |
1303 Ax, 0, &Symbolic, control, info); | 1303 Ax, 0, &Symbolic, control, info); |
1304 | 1304 |
1305 if (status < 0) | 1305 if (status < 0) |
1306 { | 1306 { |
1307 (*current_liboctave_error_handler) | 1307 (*current_liboctave_error_handler) |
1308 ("SparseMatrix::determinant symbolic factorization failed"); | 1308 ("SparseMatrix::determinant symbolic factorization failed"); |
1309 | 1309 |
1310 UMFPACK_DNAME (report_status) (control, status); | 1310 UMFPACK_DNAME (report_status) (control, status); |
1311 UMFPACK_DNAME (report_info) (control, info); | 1311 UMFPACK_DNAME (report_info) (control, info); |
1312 | 1312 |
1315 else | 1315 else |
1316 { | 1316 { |
1317 UMFPACK_DNAME (report_symbolic) (Symbolic, control); | 1317 UMFPACK_DNAME (report_symbolic) (Symbolic, control); |
1318 | 1318 |
1319 void *Numeric; | 1319 void *Numeric; |
1320 status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, | 1320 status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, |
1321 &Numeric, control, info) ; | 1321 &Numeric, control, info) ; |
1322 UMFPACK_DNAME (free_symbolic) (&Symbolic) ; | 1322 UMFPACK_DNAME (free_symbolic) (&Symbolic) ; |
1323 | 1323 |
1324 rcond = Info (UMFPACK_RCOND); | 1324 rcond = Info (UMFPACK_RCOND); |
1325 | 1325 |
1326 if (status < 0) | 1326 if (status < 0) |
1327 { | 1327 { |
1328 (*current_liboctave_error_handler) | 1328 (*current_liboctave_error_handler) |
1329 ("SparseMatrix::determinant numeric factorization failed"); | 1329 ("SparseMatrix::determinant numeric factorization failed"); |
1330 | 1330 |
1331 UMFPACK_DNAME (report_status) (control, status); | 1331 UMFPACK_DNAME (report_status) (control, status); |
1332 UMFPACK_DNAME (report_info) (control, info); | 1332 UMFPACK_DNAME (report_info) (control, info); |
1333 | 1333 |
1341 | 1341 |
1342 status = UMFPACK_DNAME (get_determinant) (&c10, &e10, Numeric, info); | 1342 status = UMFPACK_DNAME (get_determinant) (&c10, &e10, Numeric, info); |
1343 | 1343 |
1344 if (status < 0) | 1344 if (status < 0) |
1345 { | 1345 { |
1346 (*current_liboctave_error_handler) | 1346 (*current_liboctave_error_handler) |
1347 ("SparseMatrix::determinant error calculating determinant"); | 1347 ("SparseMatrix::determinant error calculating determinant"); |
1348 | 1348 |
1349 UMFPACK_DNAME (report_status) (control, status); | 1349 UMFPACK_DNAME (report_status) (control, status); |
1350 UMFPACK_DNAME (report_info) (control, info); | 1350 UMFPACK_DNAME (report_info) (control, info); |
1351 } | 1351 } |
1352 else | 1352 else |
1353 retval = DET (c10, e10, 10); | 1353 retval = DET (c10, e10, 10); |
1363 return retval; | 1363 return retval; |
1364 } | 1364 } |
1365 | 1365 |
1366 Matrix | 1366 Matrix |
1367 SparseMatrix::dsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& err, | 1367 SparseMatrix::dsolve (MatrixType &mattype, const Matrix& b, octave_idx_type& err, |
1368 double& rcond, solve_singularity_handler, | 1368 double& rcond, solve_singularity_handler, |
1369 bool calc_cond) const | 1369 bool calc_cond) const |
1370 { | 1370 { |
1371 Matrix retval; | 1371 Matrix retval; |
1372 | 1372 |
1373 octave_idx_type nr = rows (); | 1373 octave_idx_type nr = rows (); |
1400 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 1400 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
1401 retval(k,j) = b(ridx(i),j) / data (i); | 1401 retval(k,j) = b(ridx(i),j) / data (i); |
1402 | 1402 |
1403 if (calc_cond) | 1403 if (calc_cond) |
1404 { | 1404 { |
1405 double dmax = 0., dmin = octave_Inf; | 1405 double dmax = 0., dmin = octave_Inf; |
1406 for (octave_idx_type i = 0; i < nm; i++) | 1406 for (octave_idx_type i = 0; i < nm; i++) |
1407 { | 1407 { |
1408 double tmp = fabs(data(i)); | 1408 double tmp = fabs(data(i)); |
1409 if (tmp > dmax) | 1409 if (tmp > dmax) |
1410 dmax = tmp; | 1410 dmax = tmp; |
1422 | 1422 |
1423 return retval; | 1423 return retval; |
1424 } | 1424 } |
1425 | 1425 |
1426 SparseMatrix | 1426 SparseMatrix |
1427 SparseMatrix::dsolve (MatrixType &mattype, const SparseMatrix& b, | 1427 SparseMatrix::dsolve (MatrixType &mattype, const SparseMatrix& b, |
1428 octave_idx_type& err, double& rcond, | 1428 octave_idx_type& err, double& rcond, |
1429 solve_singularity_handler, bool calc_cond) const | 1429 solve_singularity_handler, bool calc_cond) const |
1430 { | 1430 { |
1431 SparseMatrix retval; | 1431 SparseMatrix retval; |
1432 | 1432 |
1433 octave_idx_type nr = rows (); | 1433 octave_idx_type nr = rows (); |
1490 retval.xcidx(j+1) = ii; | 1490 retval.xcidx(j+1) = ii; |
1491 } | 1491 } |
1492 | 1492 |
1493 if (calc_cond) | 1493 if (calc_cond) |
1494 { | 1494 { |
1495 double dmax = 0., dmin = octave_Inf; | 1495 double dmax = 0., dmin = octave_Inf; |
1496 for (octave_idx_type i = 0; i < nm; i++) | 1496 for (octave_idx_type i = 0; i < nm; i++) |
1497 { | 1497 { |
1498 double tmp = fabs(data(i)); | 1498 double tmp = fabs(data(i)); |
1499 if (tmp > dmax) | 1499 if (tmp > dmax) |
1500 dmax = tmp; | 1500 dmax = tmp; |
1547 else | 1547 else |
1548 for (octave_idx_type j = 0; j < b.cols(); j++) | 1548 for (octave_idx_type j = 0; j < b.cols(); j++) |
1549 for (octave_idx_type k = 0; k < nc; k++) | 1549 for (octave_idx_type k = 0; k < nc; k++) |
1550 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 1550 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
1551 retval(k,j) = b(ridx(i),j) / data (i); | 1551 retval(k,j) = b(ridx(i),j) / data (i); |
1552 | 1552 |
1553 if (calc_cond) | 1553 if (calc_cond) |
1554 { | 1554 { |
1555 double dmax = 0., dmin = octave_Inf; | 1555 double dmax = 0., dmin = octave_Inf; |
1556 for (octave_idx_type i = 0; i < nm; i++) | 1556 for (octave_idx_type i = 0; i < nm; i++) |
1557 { | 1557 { |
1558 double tmp = fabs(data(i)); | 1558 double tmp = fabs(data(i)); |
1559 if (tmp > dmax) | 1559 if (tmp > dmax) |
1560 dmax = tmp; | 1560 dmax = tmp; |
1573 return retval; | 1573 return retval; |
1574 } | 1574 } |
1575 | 1575 |
1576 SparseComplexMatrix | 1576 SparseComplexMatrix |
1577 SparseMatrix::dsolve (MatrixType &mattype, const SparseComplexMatrix& b, | 1577 SparseMatrix::dsolve (MatrixType &mattype, const SparseComplexMatrix& b, |
1578 octave_idx_type& err, double& rcond, | 1578 octave_idx_type& err, double& rcond, |
1579 solve_singularity_handler, bool calc_cond) const | 1579 solve_singularity_handler, bool calc_cond) const |
1580 { | 1580 { |
1581 SparseComplexMatrix retval; | 1581 SparseComplexMatrix retval; |
1582 | 1582 |
1583 octave_idx_type nr = rows (); | 1583 octave_idx_type nr = rows (); |
1637 retval.xdata (ii++) = b.data(k) / data (i); | 1637 retval.xdata (ii++) = b.data(k) / data (i); |
1638 } | 1638 } |
1639 } | 1639 } |
1640 retval.xcidx(j+1) = ii; | 1640 retval.xcidx(j+1) = ii; |
1641 } | 1641 } |
1642 | 1642 |
1643 if (calc_cond) | 1643 if (calc_cond) |
1644 { | 1644 { |
1645 double dmax = 0., dmin = octave_Inf; | 1645 double dmax = 0., dmin = octave_Inf; |
1646 for (octave_idx_type i = 0; i < nm; i++) | 1646 for (octave_idx_type i = 0; i < nm; i++) |
1647 { | 1647 { |
1648 double tmp = fabs(data(i)); | 1648 double tmp = fabs(data(i)); |
1649 if (tmp > dmax) | 1649 if (tmp > dmax) |
1650 dmax = tmp; | 1650 dmax = tmp; |
1664 } | 1664 } |
1665 | 1665 |
1666 Matrix | 1666 Matrix |
1667 SparseMatrix::utsolve (MatrixType &mattype, const Matrix& b, | 1667 SparseMatrix::utsolve (MatrixType &mattype, const Matrix& b, |
1668 octave_idx_type& err, double& rcond, | 1668 octave_idx_type& err, double& rcond, |
1669 solve_singularity_handler sing_handler, | 1669 solve_singularity_handler sing_handler, |
1670 bool calc_cond) const | 1670 bool calc_cond) const |
1671 { | 1671 { |
1672 Matrix retval; | 1672 Matrix retval; |
1673 | 1673 |
1674 octave_idx_type nr = rows (); | 1674 octave_idx_type nr = rows (); |
1730 if (ridx(cidx(kidx+1)-1) != k || | 1730 if (ridx(cidx(kidx+1)-1) != k || |
1731 data(cidx(kidx+1)-1) == 0.) | 1731 data(cidx(kidx+1)-1) == 0.) |
1732 { | 1732 { |
1733 err = -2; | 1733 err = -2; |
1734 goto triangular_error; | 1734 goto triangular_error; |
1735 } | 1735 } |
1736 | 1736 |
1737 double tmp = work[k] / data(cidx(kidx+1)-1); | 1737 double tmp = work[k] / data(cidx(kidx+1)-1); |
1738 work[k] = tmp; | 1738 work[k] = tmp; |
1739 for (octave_idx_type i = cidx(kidx); | 1739 for (octave_idx_type i = cidx(kidx); |
1740 i < cidx(kidx+1)-1; i++) | 1740 i < cidx(kidx+1)-1; i++) |
1741 { | 1741 { |
1742 octave_idx_type iidx = ridx(i); | 1742 octave_idx_type iidx = ridx(i); |
1743 work[iidx] = work[iidx] - tmp * data(i); | 1743 work[iidx] = work[iidx] - tmp * data(i); |
1744 } | 1744 } |
1765 | 1765 |
1766 if (work[k] != 0.) | 1766 if (work[k] != 0.) |
1767 { | 1767 { |
1768 double tmp = work[k] / data(cidx(iidx+1)-1); | 1768 double tmp = work[k] / data(cidx(iidx+1)-1); |
1769 work[k] = tmp; | 1769 work[k] = tmp; |
1770 for (octave_idx_type i = cidx(iidx); | 1770 for (octave_idx_type i = cidx(iidx); |
1771 i < cidx(iidx+1)-1; i++) | 1771 i < cidx(iidx+1)-1; i++) |
1772 { | 1772 { |
1773 octave_idx_type idx2 = ridx(i); | 1773 octave_idx_type idx2 = ridx(i); |
1774 work[idx2] = work[idx2] - tmp * data(i); | 1774 work[idx2] = work[idx2] - tmp * data(i); |
1775 } | 1775 } |
1806 if (ridx(cidx(k+1)-1) != k || | 1806 if (ridx(cidx(k+1)-1) != k || |
1807 data(cidx(k+1)-1) == 0.) | 1807 data(cidx(k+1)-1) == 0.) |
1808 { | 1808 { |
1809 err = -2; | 1809 err = -2; |
1810 goto triangular_error; | 1810 goto triangular_error; |
1811 } | 1811 } |
1812 | 1812 |
1813 double tmp = work[k] / data(cidx(k+1)-1); | 1813 double tmp = work[k] / data(cidx(k+1)-1); |
1814 work[k] = tmp; | 1814 work[k] = tmp; |
1815 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) | 1815 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
1816 { | 1816 { |
1898 return retval; | 1898 return retval; |
1899 } | 1899 } |
1900 | 1900 |
1901 SparseMatrix | 1901 SparseMatrix |
1902 SparseMatrix::utsolve (MatrixType &mattype, const SparseMatrix& b, | 1902 SparseMatrix::utsolve (MatrixType &mattype, const SparseMatrix& b, |
1903 octave_idx_type& err, double& rcond, | 1903 octave_idx_type& err, double& rcond, |
1904 solve_singularity_handler sing_handler, | 1904 solve_singularity_handler sing_handler, |
1905 bool calc_cond) const | 1905 bool calc_cond) const |
1906 { | 1906 { |
1907 SparseMatrix retval; | 1907 SparseMatrix retval; |
1908 | 1908 |
1974 if (ridx(cidx(kidx+1)-1) != k || | 1974 if (ridx(cidx(kidx+1)-1) != k || |
1975 data(cidx(kidx+1)-1) == 0.) | 1975 data(cidx(kidx+1)-1) == 0.) |
1976 { | 1976 { |
1977 err = -2; | 1977 err = -2; |
1978 goto triangular_error; | 1978 goto triangular_error; |
1979 } | 1979 } |
1980 | 1980 |
1981 double tmp = work[k] / data(cidx(kidx+1)-1); | 1981 double tmp = work[k] / data(cidx(kidx+1)-1); |
1982 work[k] = tmp; | 1982 work[k] = tmp; |
1983 for (octave_idx_type i = cidx(kidx); | 1983 for (octave_idx_type i = cidx(kidx); |
1984 i < cidx(kidx+1)-1; i++) | 1984 i < cidx(kidx+1)-1; i++) |
1985 { | 1985 { |
1986 octave_idx_type iidx = ridx(i); | 1986 octave_idx_type iidx = ridx(i); |
1987 work[iidx] = work[iidx] - tmp * data(i); | 1987 work[iidx] = work[iidx] - tmp * data(i); |
1988 } | 1988 } |
2031 | 2031 |
2032 if (work[k] != 0.) | 2032 if (work[k] != 0.) |
2033 { | 2033 { |
2034 double tmp = work[k] / data(cidx(iidx+1)-1); | 2034 double tmp = work[k] / data(cidx(iidx+1)-1); |
2035 work[k] = tmp; | 2035 work[k] = tmp; |
2036 for (octave_idx_type i = cidx(iidx); | 2036 for (octave_idx_type i = cidx(iidx); |
2037 i < cidx(iidx+1)-1; i++) | 2037 i < cidx(iidx+1)-1; i++) |
2038 { | 2038 { |
2039 octave_idx_type idx2 = ridx(i); | 2039 octave_idx_type idx2 = ridx(i); |
2040 work[idx2] = work[idx2] - tmp * data(i); | 2040 work[idx2] = work[idx2] - tmp * data(i); |
2041 } | 2041 } |
2071 if (ridx(cidx(k+1)-1) != k || | 2071 if (ridx(cidx(k+1)-1) != k || |
2072 data(cidx(k+1)-1) == 0.) | 2072 data(cidx(k+1)-1) == 0.) |
2073 { | 2073 { |
2074 err = -2; | 2074 err = -2; |
2075 goto triangular_error; | 2075 goto triangular_error; |
2076 } | 2076 } |
2077 | 2077 |
2078 double tmp = work[k] / data(cidx(k+1)-1); | 2078 double tmp = work[k] / data(cidx(k+1)-1); |
2079 work[k] = tmp; | 2079 work[k] = tmp; |
2080 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) | 2080 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
2081 { | 2081 { |
2125 { | 2125 { |
2126 if (work[k] != 0.) | 2126 if (work[k] != 0.) |
2127 { | 2127 { |
2128 double tmp = work[k] / data(cidx(k+1)-1); | 2128 double tmp = work[k] / data(cidx(k+1)-1); |
2129 work[k] = tmp; | 2129 work[k] = tmp; |
2130 for (octave_idx_type i = cidx(k); | 2130 for (octave_idx_type i = cidx(k); |
2131 i < cidx(k+1)-1; i++) | 2131 i < cidx(k+1)-1; i++) |
2132 { | 2132 { |
2133 octave_idx_type iidx = ridx(i); | 2133 octave_idx_type iidx = ridx(i); |
2134 work[iidx] = work[iidx] - tmp * data(i); | 2134 work[iidx] = work[iidx] - tmp * data(i); |
2135 } | 2135 } |
2184 } | 2184 } |
2185 return retval; | 2185 return retval; |
2186 } | 2186 } |
2187 | 2187 |
2188 ComplexMatrix | 2188 ComplexMatrix |
2189 SparseMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b, | 2189 SparseMatrix::utsolve (MatrixType &mattype, const ComplexMatrix& b, |
2190 octave_idx_type& err, double& rcond, | 2190 octave_idx_type& err, double& rcond, |
2191 solve_singularity_handler sing_handler, | 2191 solve_singularity_handler sing_handler, |
2192 bool calc_cond) const | 2192 bool calc_cond) const |
2193 { | 2193 { |
2194 ComplexMatrix retval; | 2194 ComplexMatrix retval; |
2195 | 2195 |
2206 else | 2206 else |
2207 { | 2207 { |
2208 // Print spparms("spumoni") info if requested | 2208 // Print spparms("spumoni") info if requested |
2209 int typ = mattype.type (); | 2209 int typ = mattype.type (); |
2210 mattype.info (); | 2210 mattype.info (); |
2211 | 2211 |
2212 if (typ == MatrixType::Permuted_Upper || | 2212 if (typ == MatrixType::Permuted_Upper || |
2213 typ == MatrixType::Upper) | 2213 typ == MatrixType::Upper) |
2214 { | 2214 { |
2215 double anorm = 0.; | 2215 double anorm = 0.; |
2216 double ainvnorm = 0.; | 2216 double ainvnorm = 0.; |
2252 if (ridx(cidx(kidx+1)-1) != k || | 2252 if (ridx(cidx(kidx+1)-1) != k || |
2253 data(cidx(kidx+1)-1) == 0.) | 2253 data(cidx(kidx+1)-1) == 0.) |
2254 { | 2254 { |
2255 err = -2; | 2255 err = -2; |
2256 goto triangular_error; | 2256 goto triangular_error; |
2257 } | 2257 } |
2258 | 2258 |
2259 Complex tmp = cwork[k] / data(cidx(kidx+1)-1); | 2259 Complex tmp = cwork[k] / data(cidx(kidx+1)-1); |
2260 cwork[k] = tmp; | 2260 cwork[k] = tmp; |
2261 for (octave_idx_type i = cidx(kidx); | 2261 for (octave_idx_type i = cidx(kidx); |
2262 i < cidx(kidx+1)-1; i++) | 2262 i < cidx(kidx+1)-1; i++) |
2263 { | 2263 { |
2264 octave_idx_type iidx = ridx(i); | 2264 octave_idx_type iidx = ridx(i); |
2265 cwork[iidx] = cwork[iidx] - tmp * data(i); | 2265 cwork[iidx] = cwork[iidx] - tmp * data(i); |
2266 } | 2266 } |
2288 | 2288 |
2289 if (work[k] != 0.) | 2289 if (work[k] != 0.) |
2290 { | 2290 { |
2291 double tmp = work[k] / data(cidx(iidx+1)-1); | 2291 double tmp = work[k] / data(cidx(iidx+1)-1); |
2292 work[k] = tmp; | 2292 work[k] = tmp; |
2293 for (octave_idx_type i = cidx(iidx); | 2293 for (octave_idx_type i = cidx(iidx); |
2294 i < cidx(iidx+1)-1; i++) | 2294 i < cidx(iidx+1)-1; i++) |
2295 { | 2295 { |
2296 octave_idx_type idx2 = ridx(i); | 2296 octave_idx_type idx2 = ridx(i); |
2297 work[idx2] = work[idx2] - tmp * data(i); | 2297 work[idx2] = work[idx2] - tmp * data(i); |
2298 } | 2298 } |
2329 if (ridx(cidx(k+1)-1) != k || | 2329 if (ridx(cidx(k+1)-1) != k || |
2330 data(cidx(k+1)-1) == 0.) | 2330 data(cidx(k+1)-1) == 0.) |
2331 { | 2331 { |
2332 err = -2; | 2332 err = -2; |
2333 goto triangular_error; | 2333 goto triangular_error; |
2334 } | 2334 } |
2335 | 2335 |
2336 Complex tmp = cwork[k] / data(cidx(k+1)-1); | 2336 Complex tmp = cwork[k] / data(cidx(k+1)-1); |
2337 cwork[k] = tmp; | 2337 cwork[k] = tmp; |
2338 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) | 2338 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
2339 { | 2339 { |
2362 { | 2362 { |
2363 if (work[k] != 0.) | 2363 if (work[k] != 0.) |
2364 { | 2364 { |
2365 double tmp = work[k] / data(cidx(k+1)-1); | 2365 double tmp = work[k] / data(cidx(k+1)-1); |
2366 work[k] = tmp; | 2366 work[k] = tmp; |
2367 for (octave_idx_type i = cidx(k); | 2367 for (octave_idx_type i = cidx(k); |
2368 i < cidx(k+1)-1; i++) | 2368 i < cidx(k+1)-1; i++) |
2369 { | 2369 { |
2370 octave_idx_type iidx = ridx(i); | 2370 octave_idx_type iidx = ridx(i); |
2371 work[iidx] = work[iidx] - tmp * data(i); | 2371 work[iidx] = work[iidx] - tmp * data(i); |
2372 } | 2372 } |
2423 return retval; | 2423 return retval; |
2424 } | 2424 } |
2425 | 2425 |
2426 SparseComplexMatrix | 2426 SparseComplexMatrix |
2427 SparseMatrix::utsolve (MatrixType &mattype, const SparseComplexMatrix& b, | 2427 SparseMatrix::utsolve (MatrixType &mattype, const SparseComplexMatrix& b, |
2428 octave_idx_type& err, double& rcond, | 2428 octave_idx_type& err, double& rcond, |
2429 solve_singularity_handler sing_handler, | 2429 solve_singularity_handler sing_handler, |
2430 bool calc_cond) const | 2430 bool calc_cond) const |
2431 { | 2431 { |
2432 SparseComplexMatrix retval; | 2432 SparseComplexMatrix retval; |
2433 | 2433 |
2444 else | 2444 else |
2445 { | 2445 { |
2446 // Print spparms("spumoni") info if requested | 2446 // Print spparms("spumoni") info if requested |
2447 int typ = mattype.type (); | 2447 int typ = mattype.type (); |
2448 mattype.info (); | 2448 mattype.info (); |
2449 | 2449 |
2450 if (typ == MatrixType::Permuted_Upper || | 2450 if (typ == MatrixType::Permuted_Upper || |
2451 typ == MatrixType::Upper) | 2451 typ == MatrixType::Upper) |
2452 { | 2452 { |
2453 double anorm = 0.; | 2453 double anorm = 0.; |
2454 double ainvnorm = 0.; | 2454 double ainvnorm = 0.; |
2499 if (ridx(cidx(kidx+1)-1) != k || | 2499 if (ridx(cidx(kidx+1)-1) != k || |
2500 data(cidx(kidx+1)-1) == 0.) | 2500 data(cidx(kidx+1)-1) == 0.) |
2501 { | 2501 { |
2502 err = -2; | 2502 err = -2; |
2503 goto triangular_error; | 2503 goto triangular_error; |
2504 } | 2504 } |
2505 | 2505 |
2506 Complex tmp = cwork[k] / data(cidx(kidx+1)-1); | 2506 Complex tmp = cwork[k] / data(cidx(kidx+1)-1); |
2507 cwork[k] = tmp; | 2507 cwork[k] = tmp; |
2508 for (octave_idx_type i = cidx(kidx); | 2508 for (octave_idx_type i = cidx(kidx); |
2509 i < cidx(kidx+1)-1; i++) | 2509 i < cidx(kidx+1)-1; i++) |
2510 { | 2510 { |
2511 octave_idx_type iidx = ridx(i); | 2511 octave_idx_type iidx = ridx(i); |
2512 cwork[iidx] = cwork[iidx] - tmp * data(i); | 2512 cwork[iidx] = cwork[iidx] - tmp * data(i); |
2513 } | 2513 } |
2557 | 2557 |
2558 if (work[k] != 0.) | 2558 if (work[k] != 0.) |
2559 { | 2559 { |
2560 double tmp = work[k] / data(cidx(iidx+1)-1); | 2560 double tmp = work[k] / data(cidx(iidx+1)-1); |
2561 work[k] = tmp; | 2561 work[k] = tmp; |
2562 for (octave_idx_type i = cidx(iidx); | 2562 for (octave_idx_type i = cidx(iidx); |
2563 i < cidx(iidx+1)-1; i++) | 2563 i < cidx(iidx+1)-1; i++) |
2564 { | 2564 { |
2565 octave_idx_type idx2 = ridx(i); | 2565 octave_idx_type idx2 = ridx(i); |
2566 work[idx2] = work[idx2] - tmp * data(i); | 2566 work[idx2] = work[idx2] - tmp * data(i); |
2567 } | 2567 } |
2597 if (ridx(cidx(k+1)-1) != k || | 2597 if (ridx(cidx(k+1)-1) != k || |
2598 data(cidx(k+1)-1) == 0.) | 2598 data(cidx(k+1)-1) == 0.) |
2599 { | 2599 { |
2600 err = -2; | 2600 err = -2; |
2601 goto triangular_error; | 2601 goto triangular_error; |
2602 } | 2602 } |
2603 | 2603 |
2604 Complex tmp = cwork[k] / data(cidx(k+1)-1); | 2604 Complex tmp = cwork[k] / data(cidx(k+1)-1); |
2605 cwork[k] = tmp; | 2605 cwork[k] = tmp; |
2606 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) | 2606 for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) |
2607 { | 2607 { |
2652 { | 2652 { |
2653 if (work[k] != 0.) | 2653 if (work[k] != 0.) |
2654 { | 2654 { |
2655 double tmp = work[k] / data(cidx(k+1)-1); | 2655 double tmp = work[k] / data(cidx(k+1)-1); |
2656 work[k] = tmp; | 2656 work[k] = tmp; |
2657 for (octave_idx_type i = cidx(k); | 2657 for (octave_idx_type i = cidx(k); |
2658 i < cidx(k+1)-1; i++) | 2658 i < cidx(k+1)-1; i++) |
2659 { | 2659 { |
2660 octave_idx_type iidx = ridx(i); | 2660 octave_idx_type iidx = ridx(i); |
2661 work[iidx] = work[iidx] - tmp * data(i); | 2661 work[iidx] = work[iidx] - tmp * data(i); |
2662 } | 2662 } |
2734 else | 2734 else |
2735 { | 2735 { |
2736 // Print spparms("spumoni") info if requested | 2736 // Print spparms("spumoni") info if requested |
2737 int typ = mattype.type (); | 2737 int typ = mattype.type (); |
2738 mattype.info (); | 2738 mattype.info (); |
2739 | 2739 |
2740 if (typ == MatrixType::Permuted_Lower || | 2740 if (typ == MatrixType::Permuted_Lower || |
2741 typ == MatrixType::Lower) | 2741 typ == MatrixType::Lower) |
2742 { | 2742 { |
2743 double anorm = 0.; | 2743 double anorm = 0.; |
2744 double ainvnorm = 0.; | 2744 double ainvnorm = 0.; |
2788 | 2788 |
2789 if (minr != k || data(mini) == 0) | 2789 if (minr != k || data(mini) == 0) |
2790 { | 2790 { |
2791 err = -2; | 2791 err = -2; |
2792 goto triangular_error; | 2792 goto triangular_error; |
2793 } | 2793 } |
2794 | 2794 |
2795 double tmp = work[k] / data(mini); | 2795 double tmp = work[k] / data(mini); |
2796 work[k] = tmp; | 2796 work[k] = tmp; |
2797 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 2797 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
2798 { | 2798 { |
2824 if (work[k] != 0.) | 2824 if (work[k] != 0.) |
2825 { | 2825 { |
2826 octave_idx_type minr = nr; | 2826 octave_idx_type minr = nr; |
2827 octave_idx_type mini = 0; | 2827 octave_idx_type mini = 0; |
2828 | 2828 |
2829 for (octave_idx_type i = cidx(k); | 2829 for (octave_idx_type i = cidx(k); |
2830 i < cidx(k+1); i++) | 2830 i < cidx(k+1); i++) |
2831 if (perm[ridx(i)] < minr) | 2831 if (perm[ridx(i)] < minr) |
2832 { | 2832 { |
2833 minr = perm[ridx(i)]; | 2833 minr = perm[ridx(i)]; |
2834 mini = i; | 2834 mini = i; |
2835 } | 2835 } |
2836 | 2836 |
2837 double tmp = work[k] / data(mini); | 2837 double tmp = work[k] / data(mini); |
2838 work[k] = tmp; | 2838 work[k] = tmp; |
2839 for (octave_idx_type i = cidx(k); | 2839 for (octave_idx_type i = cidx(k); |
2840 i < cidx(k+1); i++) | 2840 i < cidx(k+1); i++) |
2841 { | 2841 { |
2842 if (i == mini) | 2842 if (i == mini) |
2843 continue; | 2843 continue; |
2844 | 2844 |
2878 if (ridx(cidx(k)) != k || | 2878 if (ridx(cidx(k)) != k || |
2879 data(cidx(k)) == 0.) | 2879 data(cidx(k)) == 0.) |
2880 { | 2880 { |
2881 err = -2; | 2881 err = -2; |
2882 goto triangular_error; | 2882 goto triangular_error; |
2883 } | 2883 } |
2884 | 2884 |
2885 double tmp = work[k] / data(cidx(k)); | 2885 double tmp = work[k] / data(cidx(k)); |
2886 work[k] = tmp; | 2886 work[k] = tmp; |
2887 for (octave_idx_type i = cidx(k)+1; | 2887 for (octave_idx_type i = cidx(k)+1; |
2888 i < cidx(k+1); i++) | 2888 i < cidx(k+1); i++) |
2889 { | 2889 { |
2890 octave_idx_type iidx = ridx(i); | 2890 octave_idx_type iidx = ridx(i); |
2891 work[iidx] = work[iidx] - tmp * data(i); | 2891 work[iidx] = work[iidx] - tmp * data(i); |
2892 } | 2892 } |
2912 | 2912 |
2913 if (work[k] != 0.) | 2913 if (work[k] != 0.) |
2914 { | 2914 { |
2915 double tmp = work[k] / data(cidx(k)); | 2915 double tmp = work[k] / data(cidx(k)); |
2916 work[k] = tmp; | 2916 work[k] = tmp; |
2917 for (octave_idx_type i = cidx(k)+1; | 2917 for (octave_idx_type i = cidx(k)+1; |
2918 i < cidx(k+1); i++) | 2918 i < cidx(k+1); i++) |
2919 { | 2919 { |
2920 octave_idx_type iidx = ridx(i); | 2920 octave_idx_type iidx = ridx(i); |
2921 work[iidx] = work[iidx] - tmp * data(i); | 2921 work[iidx] = work[iidx] - tmp * data(i); |
2922 } | 2922 } |
2972 | 2972 |
2973 return retval; | 2973 return retval; |
2974 } | 2974 } |
2975 | 2975 |
2976 SparseMatrix | 2976 SparseMatrix |
2977 SparseMatrix::ltsolve (MatrixType &mattype, const SparseMatrix& b, | 2977 SparseMatrix::ltsolve (MatrixType &mattype, const SparseMatrix& b, |
2978 octave_idx_type& err, double& rcond, | 2978 octave_idx_type& err, double& rcond, |
2979 solve_singularity_handler sing_handler, | 2979 solve_singularity_handler sing_handler, |
2980 bool calc_cond) const | 2980 bool calc_cond) const |
2981 { | 2981 { |
2982 SparseMatrix retval; | 2982 SparseMatrix retval; |
2983 | 2983 |
2994 else | 2994 else |
2995 { | 2995 { |
2996 // Print spparms("spumoni") info if requested | 2996 // Print spparms("spumoni") info if requested |
2997 int typ = mattype.type (); | 2997 int typ = mattype.type (); |
2998 mattype.info (); | 2998 mattype.info (); |
2999 | 2999 |
3000 if (typ == MatrixType::Permuted_Lower || | 3000 if (typ == MatrixType::Permuted_Lower || |
3001 typ == MatrixType::Lower) | 3001 typ == MatrixType::Lower) |
3002 { | 3002 { |
3003 double anorm = 0.; | 3003 double anorm = 0.; |
3004 double ainvnorm = 0.; | 3004 double ainvnorm = 0.; |
3052 | 3052 |
3053 if (minr != k || data(mini) == 0) | 3053 if (minr != k || data(mini) == 0) |
3054 { | 3054 { |
3055 err = -2; | 3055 err = -2; |
3056 goto triangular_error; | 3056 goto triangular_error; |
3057 } | 3057 } |
3058 | 3058 |
3059 double tmp = work[k] / data(mini); | 3059 double tmp = work[k] / data(mini); |
3060 work[k] = tmp; | 3060 work[k] = tmp; |
3061 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 3061 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
3062 { | 3062 { |
3110 if (work[k] != 0.) | 3110 if (work[k] != 0.) |
3111 { | 3111 { |
3112 octave_idx_type minr = nr; | 3112 octave_idx_type minr = nr; |
3113 octave_idx_type mini = 0; | 3113 octave_idx_type mini = 0; |
3114 | 3114 |
3115 for (octave_idx_type i = cidx(k); | 3115 for (octave_idx_type i = cidx(k); |
3116 i < cidx(k+1); i++) | 3116 i < cidx(k+1); i++) |
3117 if (perm[ridx(i)] < minr) | 3117 if (perm[ridx(i)] < minr) |
3118 { | 3118 { |
3119 minr = perm[ridx(i)]; | 3119 minr = perm[ridx(i)]; |
3120 mini = i; | 3120 mini = i; |
3121 } | 3121 } |
3122 | 3122 |
3123 double tmp = work[k] / data(mini); | 3123 double tmp = work[k] / data(mini); |
3124 work[k] = tmp; | 3124 work[k] = tmp; |
3125 for (octave_idx_type i = cidx(k); | 3125 for (octave_idx_type i = cidx(k); |
3126 i < cidx(k+1); i++) | 3126 i < cidx(k+1); i++) |
3127 { | 3127 { |
3128 if (i == mini) | 3128 if (i == mini) |
3129 continue; | 3129 continue; |
3130 | 3130 |
3164 if (ridx(cidx(k)) != k || | 3164 if (ridx(cidx(k)) != k || |
3165 data(cidx(k)) == 0.) | 3165 data(cidx(k)) == 0.) |
3166 { | 3166 { |
3167 err = -2; | 3167 err = -2; |
3168 goto triangular_error; | 3168 goto triangular_error; |
3169 } | 3169 } |
3170 | 3170 |
3171 double tmp = work[k] / data(cidx(k)); | 3171 double tmp = work[k] / data(cidx(k)); |
3172 work[k] = tmp; | 3172 work[k] = tmp; |
3173 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) | 3173 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
3174 { | 3174 { |
3219 | 3219 |
3220 if (work[k] != 0.) | 3220 if (work[k] != 0.) |
3221 { | 3221 { |
3222 double tmp = work[k] / data(cidx(k)); | 3222 double tmp = work[k] / data(cidx(k)); |
3223 work[k] = tmp; | 3223 work[k] = tmp; |
3224 for (octave_idx_type i = cidx(k)+1; | 3224 for (octave_idx_type i = cidx(k)+1; |
3225 i < cidx(k+1); i++) | 3225 i < cidx(k+1); i++) |
3226 { | 3226 { |
3227 octave_idx_type iidx = ridx(i); | 3227 octave_idx_type iidx = ridx(i); |
3228 work[iidx] = work[iidx] - tmp * data(i); | 3228 work[iidx] = work[iidx] - tmp * data(i); |
3229 } | 3229 } |
3279 | 3279 |
3280 return retval; | 3280 return retval; |
3281 } | 3281 } |
3282 | 3282 |
3283 ComplexMatrix | 3283 ComplexMatrix |
3284 SparseMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b, | 3284 SparseMatrix::ltsolve (MatrixType &mattype, const ComplexMatrix& b, |
3285 octave_idx_type& err, double& rcond, | 3285 octave_idx_type& err, double& rcond, |
3286 solve_singularity_handler sing_handler, | 3286 solve_singularity_handler sing_handler, |
3287 bool calc_cond) const | 3287 bool calc_cond) const |
3288 { | 3288 { |
3289 ComplexMatrix retval; | 3289 ComplexMatrix retval; |
3290 | 3290 |
3301 else | 3301 else |
3302 { | 3302 { |
3303 // Print spparms("spumoni") info if requested | 3303 // Print spparms("spumoni") info if requested |
3304 int typ = mattype.type (); | 3304 int typ = mattype.type (); |
3305 mattype.info (); | 3305 mattype.info (); |
3306 | 3306 |
3307 if (typ == MatrixType::Permuted_Lower || | 3307 if (typ == MatrixType::Permuted_Lower || |
3308 typ == MatrixType::Lower) | 3308 typ == MatrixType::Lower) |
3309 { | 3309 { |
3310 double anorm = 0.; | 3310 double anorm = 0.; |
3311 double ainvnorm = 0.; | 3311 double ainvnorm = 0.; |
3354 | 3354 |
3355 if (minr != k || data(mini) == 0) | 3355 if (minr != k || data(mini) == 0) |
3356 { | 3356 { |
3357 err = -2; | 3357 err = -2; |
3358 goto triangular_error; | 3358 goto triangular_error; |
3359 } | 3359 } |
3360 | 3360 |
3361 Complex tmp = cwork[k] / data(mini); | 3361 Complex tmp = cwork[k] / data(mini); |
3362 cwork[k] = tmp; | 3362 cwork[k] = tmp; |
3363 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 3363 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
3364 { | 3364 { |
3391 if (work[k] != 0.) | 3391 if (work[k] != 0.) |
3392 { | 3392 { |
3393 octave_idx_type minr = nr; | 3393 octave_idx_type minr = nr; |
3394 octave_idx_type mini = 0; | 3394 octave_idx_type mini = 0; |
3395 | 3395 |
3396 for (octave_idx_type i = cidx(k); | 3396 for (octave_idx_type i = cidx(k); |
3397 i < cidx(k+1); i++) | 3397 i < cidx(k+1); i++) |
3398 if (perm[ridx(i)] < minr) | 3398 if (perm[ridx(i)] < minr) |
3399 { | 3399 { |
3400 minr = perm[ridx(i)]; | 3400 minr = perm[ridx(i)]; |
3401 mini = i; | 3401 mini = i; |
3402 } | 3402 } |
3403 | 3403 |
3404 double tmp = work[k] / data(mini); | 3404 double tmp = work[k] / data(mini); |
3405 work[k] = tmp; | 3405 work[k] = tmp; |
3406 for (octave_idx_type i = cidx(k); | 3406 for (octave_idx_type i = cidx(k); |
3407 i < cidx(k+1); i++) | 3407 i < cidx(k+1); i++) |
3408 { | 3408 { |
3409 if (i == mini) | 3409 if (i == mini) |
3410 continue; | 3410 continue; |
3411 | 3411 |
3446 if (ridx(cidx(k)) != k || | 3446 if (ridx(cidx(k)) != k || |
3447 data(cidx(k)) == 0.) | 3447 data(cidx(k)) == 0.) |
3448 { | 3448 { |
3449 err = -2; | 3449 err = -2; |
3450 goto triangular_error; | 3450 goto triangular_error; |
3451 } | 3451 } |
3452 | 3452 |
3453 Complex tmp = cwork[k] / data(cidx(k)); | 3453 Complex tmp = cwork[k] / data(cidx(k)); |
3454 cwork[k] = tmp; | 3454 cwork[k] = tmp; |
3455 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) | 3455 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
3456 { | 3456 { |
3480 | 3480 |
3481 if (work[k] != 0.) | 3481 if (work[k] != 0.) |
3482 { | 3482 { |
3483 double tmp = work[k] / data(cidx(k)); | 3483 double tmp = work[k] / data(cidx(k)); |
3484 work[k] = tmp; | 3484 work[k] = tmp; |
3485 for (octave_idx_type i = cidx(k)+1; | 3485 for (octave_idx_type i = cidx(k)+1; |
3486 i < cidx(k+1); i++) | 3486 i < cidx(k+1); i++) |
3487 { | 3487 { |
3488 octave_idx_type iidx = ridx(i); | 3488 octave_idx_type iidx = ridx(i); |
3489 work[iidx] = work[iidx] - tmp * data(i); | 3489 work[iidx] = work[iidx] - tmp * data(i); |
3490 } | 3490 } |
3541 return retval; | 3541 return retval; |
3542 } | 3542 } |
3543 | 3543 |
3544 SparseComplexMatrix | 3544 SparseComplexMatrix |
3545 SparseMatrix::ltsolve (MatrixType &mattype, const SparseComplexMatrix& b, | 3545 SparseMatrix::ltsolve (MatrixType &mattype, const SparseComplexMatrix& b, |
3546 octave_idx_type& err, double& rcond, | 3546 octave_idx_type& err, double& rcond, |
3547 solve_singularity_handler sing_handler, | 3547 solve_singularity_handler sing_handler, |
3548 bool calc_cond) const | 3548 bool calc_cond) const |
3549 { | 3549 { |
3550 SparseComplexMatrix retval; | 3550 SparseComplexMatrix retval; |
3551 | 3551 |
3562 else | 3562 else |
3563 { | 3563 { |
3564 // Print spparms("spumoni") info if requested | 3564 // Print spparms("spumoni") info if requested |
3565 int typ = mattype.type (); | 3565 int typ = mattype.type (); |
3566 mattype.info (); | 3566 mattype.info (); |
3567 | 3567 |
3568 if (typ == MatrixType::Permuted_Lower || | 3568 if (typ == MatrixType::Permuted_Lower || |
3569 typ == MatrixType::Lower) | 3569 typ == MatrixType::Lower) |
3570 { | 3570 { |
3571 double anorm = 0.; | 3571 double anorm = 0.; |
3572 double ainvnorm = 0.; | 3572 double ainvnorm = 0.; |
3620 | 3620 |
3621 if (minr != k || data(mini) == 0) | 3621 if (minr != k || data(mini) == 0) |
3622 { | 3622 { |
3623 err = -2; | 3623 err = -2; |
3624 goto triangular_error; | 3624 goto triangular_error; |
3625 } | 3625 } |
3626 | 3626 |
3627 Complex tmp = cwork[k] / data(mini); | 3627 Complex tmp = cwork[k] / data(mini); |
3628 cwork[k] = tmp; | 3628 cwork[k] = tmp; |
3629 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | 3629 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
3630 { | 3630 { |
3679 if (work[k] != 0.) | 3679 if (work[k] != 0.) |
3680 { | 3680 { |
3681 octave_idx_type minr = nr; | 3681 octave_idx_type minr = nr; |
3682 octave_idx_type mini = 0; | 3682 octave_idx_type mini = 0; |
3683 | 3683 |
3684 for (octave_idx_type i = cidx(k); | 3684 for (octave_idx_type i = cidx(k); |
3685 i < cidx(k+1); i++) | 3685 i < cidx(k+1); i++) |
3686 if (perm[ridx(i)] < minr) | 3686 if (perm[ridx(i)] < minr) |
3687 { | 3687 { |
3688 minr = perm[ridx(i)]; | 3688 minr = perm[ridx(i)]; |
3689 mini = i; | 3689 mini = i; |
3690 } | 3690 } |
3691 | 3691 |
3692 double tmp = work[k] / data(mini); | 3692 double tmp = work[k] / data(mini); |
3693 work[k] = tmp; | 3693 work[k] = tmp; |
3694 for (octave_idx_type i = cidx(k); | 3694 for (octave_idx_type i = cidx(k); |
3695 i < cidx(k+1); i++) | 3695 i < cidx(k+1); i++) |
3696 { | 3696 { |
3697 if (i == mini) | 3697 if (i == mini) |
3698 continue; | 3698 continue; |
3699 | 3699 |
3733 if (ridx(cidx(k)) != k || | 3733 if (ridx(cidx(k)) != k || |
3734 data(cidx(k)) == 0.) | 3734 data(cidx(k)) == 0.) |
3735 { | 3735 { |
3736 err = -2; | 3736 err = -2; |
3737 goto triangular_error; | 3737 goto triangular_error; |
3738 } | 3738 } |
3739 | 3739 |
3740 Complex tmp = cwork[k] / data(cidx(k)); | 3740 Complex tmp = cwork[k] / data(cidx(k)); |
3741 cwork[k] = tmp; | 3741 cwork[k] = tmp; |
3742 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) | 3742 for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) |
3743 { | 3743 { |
3789 | 3789 |
3790 if (work[k] != 0.) | 3790 if (work[k] != 0.) |
3791 { | 3791 { |
3792 double tmp = work[k] / data(cidx(k)); | 3792 double tmp = work[k] / data(cidx(k)); |
3793 work[k] = tmp; | 3793 work[k] = tmp; |
3794 for (octave_idx_type i = cidx(k)+1; | 3794 for (octave_idx_type i = cidx(k)+1; |
3795 i < cidx(k+1); i++) | 3795 i < cidx(k+1); i++) |
3796 { | 3796 { |
3797 octave_idx_type iidx = ridx(i); | 3797 octave_idx_type iidx = ridx(i); |
3798 work[iidx] = work[iidx] - tmp * data(i); | 3798 work[iidx] = work[iidx] - tmp * data(i); |
3799 } | 3799 } |
3866 (*current_liboctave_error_handler) | 3866 (*current_liboctave_error_handler) |
3867 ("matrix dimension mismatch solution of linear equations"); | 3867 ("matrix dimension mismatch solution of linear equations"); |
3868 else if (nr == 0 || b.cols () == 0) | 3868 else if (nr == 0 || b.cols () == 0) |
3869 retval = Matrix (nc, b.cols (), 0.0); | 3869 retval = Matrix (nc, b.cols (), 0.0); |
3870 else if (calc_cond) | 3870 else if (calc_cond) |
3871 (*current_liboctave_error_handler) | 3871 (*current_liboctave_error_handler) |
3872 ("calculation of condition number not implemented"); | 3872 ("calculation of condition number not implemented"); |
3873 else | 3873 else |
3874 { | 3874 { |
3875 // Print spparms("spumoni") info if requested | 3875 // Print spparms("spumoni") info if requested |
3876 volatile int typ = mattype.type (); | 3876 volatile int typ = mattype.type (); |
3877 mattype.info (); | 3877 mattype.info (); |
3878 | 3878 |
3879 if (typ == MatrixType::Tridiagonal_Hermitian) | 3879 if (typ == MatrixType::Tridiagonal_Hermitian) |
3880 { | 3880 { |
3881 OCTAVE_LOCAL_BUFFER (double, D, nr); | 3881 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3882 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); | 3882 OCTAVE_LOCAL_BUFFER (double, DL, nr - 1); |
3883 | 3883 |
3909 D[j] = data(i); | 3909 D[j] = data(i); |
3910 else if (ridx(i) == j + 1) | 3910 else if (ridx(i) == j + 1) |
3911 DL[j] = data(i); | 3911 DL[j] = data(i); |
3912 } | 3912 } |
3913 } | 3913 } |
3914 | 3914 |
3915 octave_idx_type b_nc = b.cols(); | 3915 octave_idx_type b_nc = b.cols(); |
3916 retval = b; | 3916 retval = b; |
3917 double *result = retval.fortran_vec (); | 3917 double *result = retval.fortran_vec (); |
3918 | 3918 |
3919 F77_XFCN (dptsv, DPTSV, (nr, b_nc, D, DL, result, | 3919 F77_XFCN (dptsv, DPTSV, (nr, b_nc, D, DL, result, |
3920 b.rows(), err)); | 3920 b.rows(), err)); |
3921 | 3921 |
3922 if (err != 0) | 3922 if (err != 0) |
3923 { | 3923 { |
3924 err = 0; | 3924 err = 0; |
3925 mattype.mark_as_unsymmetric (); | 3925 mattype.mark_as_unsymmetric (); |
3926 typ = MatrixType::Tridiagonal; | 3926 typ = MatrixType::Tridiagonal; |
3927 } | 3927 } |
3928 else | 3928 else |
3929 rcond = 1.; | 3929 rcond = 1.; |
3930 } | 3930 } |
3931 | 3931 |
3932 if (typ == MatrixType::Tridiagonal) | 3932 if (typ == MatrixType::Tridiagonal) |
3933 { | 3933 { |
3971 | 3971 |
3972 octave_idx_type b_nc = b.cols(); | 3972 octave_idx_type b_nc = b.cols(); |
3973 retval = b; | 3973 retval = b; |
3974 double *result = retval.fortran_vec (); | 3974 double *result = retval.fortran_vec (); |
3975 | 3975 |
3976 F77_XFCN (dgtsv, DGTSV, (nr, b_nc, DL, D, DU, result, | 3976 F77_XFCN (dgtsv, DGTSV, (nr, b_nc, DL, D, DU, result, |
3977 b.rows(), err)); | 3977 b.rows(), err)); |
3978 | 3978 |
3979 if (err != 0) | 3979 if (err != 0) |
3980 { | 3980 { |
3981 rcond = 0.; | 3981 rcond = 0.; |
3988 } | 3988 } |
3989 else | 3989 else |
3990 (*current_liboctave_error_handler) | 3990 (*current_liboctave_error_handler) |
3991 ("matrix singular to machine precision"); | 3991 ("matrix singular to machine precision"); |
3992 | 3992 |
3993 } | 3993 } |
3994 else | 3994 else |
3995 rcond = 1.; | 3995 rcond = 1.; |
3996 } | 3996 } |
3997 else if (typ != MatrixType::Tridiagonal_Hermitian) | 3997 else if (typ != MatrixType::Tridiagonal_Hermitian) |
3998 (*current_liboctave_error_handler) ("incorrect matrix type"); | 3998 (*current_liboctave_error_handler) ("incorrect matrix type"); |
3999 } | 3999 } |
4000 | 4000 |
4001 return retval; | 4001 return retval; |
4002 } | 4002 } |
4003 | 4003 |
4004 SparseMatrix | 4004 SparseMatrix |
4005 SparseMatrix::trisolve (MatrixType &mattype, const SparseMatrix& b, | 4005 SparseMatrix::trisolve (MatrixType &mattype, const SparseMatrix& b, |
4006 octave_idx_type& err, double& rcond, | 4006 octave_idx_type& err, double& rcond, |
4007 solve_singularity_handler sing_handler, | 4007 solve_singularity_handler sing_handler, |
4008 bool calc_cond) const | 4008 bool calc_cond) const |
4009 { | 4009 { |
4010 SparseMatrix retval; | 4010 SparseMatrix retval; |
4011 | 4011 |
4017 (*current_liboctave_error_handler) | 4017 (*current_liboctave_error_handler) |
4018 ("matrix dimension mismatch solution of linear equations"); | 4018 ("matrix dimension mismatch solution of linear equations"); |
4019 else if (nr == 0 || b.cols () == 0) | 4019 else if (nr == 0 || b.cols () == 0) |
4020 retval = SparseMatrix (nc, b.cols ()); | 4020 retval = SparseMatrix (nc, b.cols ()); |
4021 else if (calc_cond) | 4021 else if (calc_cond) |
4022 (*current_liboctave_error_handler) | 4022 (*current_liboctave_error_handler) |
4023 ("calculation of condition number not implemented"); | 4023 ("calculation of condition number not implemented"); |
4024 else | 4024 else |
4025 { | 4025 { |
4026 // Print spparms("spumoni") info if requested | 4026 // Print spparms("spumoni") info if requested |
4027 int typ = mattype.type (); | 4027 int typ = mattype.type (); |
4028 mattype.info (); | 4028 mattype.info (); |
4029 | 4029 |
4030 // Note can't treat symmetric case as there is no dpttrf function | 4030 // Note can't treat symmetric case as there is no dpttrf function |
4031 if (typ == MatrixType::Tridiagonal || | 4031 if (typ == MatrixType::Tridiagonal || |
4032 typ == MatrixType::Tridiagonal_Hermitian) | 4032 typ == MatrixType::Tridiagonal_Hermitian) |
4033 { | 4033 { |
4034 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); | 4034 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); |
4072 } | 4072 } |
4073 } | 4073 } |
4074 | 4074 |
4075 F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); | 4075 F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); |
4076 | 4076 |
4077 if (err != 0) | 4077 if (err != 0) |
4078 { | 4078 { |
4079 rcond = 0.0; | 4079 rcond = 0.0; |
4080 err = -2; | 4080 err = -2; |
4081 | 4081 |
4082 if (sing_handler) | 4082 if (sing_handler) |
4086 } | 4086 } |
4087 else | 4087 else |
4088 (*current_liboctave_error_handler) | 4088 (*current_liboctave_error_handler) |
4089 ("matrix singular to machine precision"); | 4089 ("matrix singular to machine precision"); |
4090 | 4090 |
4091 } | 4091 } |
4092 else | 4092 else |
4093 { | 4093 { |
4094 rcond = 1.0; | 4094 rcond = 1.0; |
4095 char job = 'N'; | 4095 char job = 'N'; |
4096 volatile octave_idx_type x_nz = b.nnz (); | 4096 volatile octave_idx_type x_nz = b.nnz (); |
4097 octave_idx_type b_nc = b.cols (); | 4097 octave_idx_type b_nc = b.cols (); |
4106 for (octave_idx_type i = 0; i < nr; i++) | 4106 for (octave_idx_type i = 0; i < nr; i++) |
4107 work[i] = 0.; | 4107 work[i] = 0.; |
4108 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) | 4108 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
4109 work[b.ridx(i)] = b.data(i); | 4109 work[b.ridx(i)] = b.data(i); |
4110 | 4110 |
4111 F77_XFCN (dgttrs, DGTTRS, | 4111 F77_XFCN (dgttrs, DGTTRS, |
4112 (F77_CONST_CHAR_ARG2 (&job, 1), | 4112 (F77_CONST_CHAR_ARG2 (&job, 1), |
4113 nr, 1, DL, D, DU, DU2, pipvt, | 4113 nr, 1, DL, D, DU, DU2, pipvt, |
4114 work, b.rows (), err | 4114 work, b.rows (), err |
4115 F77_CHAR_ARG_LEN (1))); | 4115 F77_CHAR_ARG_LEN (1))); |
4116 | 4116 |
4117 // Count non-zeros in work vector and adjust | 4117 // Count non-zeros in work vector and adjust |
4118 // space in retval if needed | 4118 // space in retval if needed |
4119 octave_idx_type new_nnz = 0; | 4119 octave_idx_type new_nnz = 0; |
4120 for (octave_idx_type i = 0; i < nr; i++) | 4120 for (octave_idx_type i = 0; i < nr; i++) |
4121 if (work[i] != 0.) | 4121 if (work[i] != 0.) |
4122 new_nnz++; | 4122 new_nnz++; |
4147 | 4147 |
4148 return retval; | 4148 return retval; |
4149 } | 4149 } |
4150 | 4150 |
4151 ComplexMatrix | 4151 ComplexMatrix |
4152 SparseMatrix::trisolve (MatrixType &mattype, const ComplexMatrix& b, | 4152 SparseMatrix::trisolve (MatrixType &mattype, const ComplexMatrix& b, |
4153 octave_idx_type& err, double& rcond, | 4153 octave_idx_type& err, double& rcond, |
4154 solve_singularity_handler sing_handler, | 4154 solve_singularity_handler sing_handler, |
4155 bool calc_cond) const | 4155 bool calc_cond) const |
4156 { | 4156 { |
4157 ComplexMatrix retval; | 4157 ComplexMatrix retval; |
4158 | 4158 |
4164 (*current_liboctave_error_handler) | 4164 (*current_liboctave_error_handler) |
4165 ("matrix dimension mismatch solution of linear equations"); | 4165 ("matrix dimension mismatch solution of linear equations"); |
4166 else if (nr == 0 || b.cols () == 0) | 4166 else if (nr == 0 || b.cols () == 0) |
4167 retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0)); | 4167 retval = ComplexMatrix (nc, b.cols (), Complex (0.0, 0.0)); |
4168 else if (calc_cond) | 4168 else if (calc_cond) |
4169 (*current_liboctave_error_handler) | 4169 (*current_liboctave_error_handler) |
4170 ("calculation of condition number not implemented"); | 4170 ("calculation of condition number not implemented"); |
4171 else | 4171 else |
4172 { | 4172 { |
4173 // Print spparms("spumoni") info if requested | 4173 // Print spparms("spumoni") info if requested |
4174 volatile int typ = mattype.type (); | 4174 volatile int typ = mattype.type (); |
4175 mattype.info (); | 4175 mattype.info (); |
4176 | 4176 |
4177 if (typ == MatrixType::Tridiagonal_Hermitian) | 4177 if (typ == MatrixType::Tridiagonal_Hermitian) |
4178 { | 4178 { |
4179 OCTAVE_LOCAL_BUFFER (double, D, nr); | 4179 OCTAVE_LOCAL_BUFFER (double, D, nr); |
4180 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); | 4180 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); |
4181 | 4181 |
4214 octave_idx_type b_nc = b.cols(); | 4214 octave_idx_type b_nc = b.cols(); |
4215 rcond = 1.; | 4215 rcond = 1.; |
4216 | 4216 |
4217 retval = b; | 4217 retval = b; |
4218 Complex *result = retval.fortran_vec (); | 4218 Complex *result = retval.fortran_vec (); |
4219 | 4219 |
4220 F77_XFCN (zptsv, ZPTSV, (nr, b_nc, D, DL, result, | 4220 F77_XFCN (zptsv, ZPTSV, (nr, b_nc, D, DL, result, |
4221 b_nr, err)); | 4221 b_nr, err)); |
4222 | 4222 |
4223 if (err != 0) | 4223 if (err != 0) |
4224 { | 4224 { |
4225 err = 0; | 4225 err = 0; |
4272 octave_idx_type b_nc = b.cols(); | 4272 octave_idx_type b_nc = b.cols(); |
4273 rcond = 1.; | 4273 rcond = 1.; |
4274 | 4274 |
4275 retval = b; | 4275 retval = b; |
4276 Complex *result = retval.fortran_vec (); | 4276 Complex *result = retval.fortran_vec (); |
4277 | 4277 |
4278 F77_XFCN (zgtsv, ZGTSV, (nr, b_nc, DL, D, DU, result, | 4278 F77_XFCN (zgtsv, ZGTSV, (nr, b_nc, DL, D, DU, result, |
4279 b_nr, err)); | 4279 b_nr, err)); |
4280 | 4280 |
4281 if (err != 0) | 4281 if (err != 0) |
4282 { | 4282 { |
4283 rcond = 0.; | 4283 rcond = 0.; |
4284 err = -2; | 4284 err = -2; |
4285 | 4285 |
4286 if (sing_handler) | 4286 if (sing_handler) |
4287 { | 4287 { |
4288 sing_handler (rcond); | 4288 sing_handler (rcond); |
4289 mattype.mark_as_rectangular (); | 4289 mattype.mark_as_rectangular (); |
4290 } | 4290 } |
4300 return retval; | 4300 return retval; |
4301 } | 4301 } |
4302 | 4302 |
4303 SparseComplexMatrix | 4303 SparseComplexMatrix |
4304 SparseMatrix::trisolve (MatrixType &mattype, const SparseComplexMatrix& b, | 4304 SparseMatrix::trisolve (MatrixType &mattype, const SparseComplexMatrix& b, |
4305 octave_idx_type& err, double& rcond, | 4305 octave_idx_type& err, double& rcond, |
4306 solve_singularity_handler sing_handler, | 4306 solve_singularity_handler sing_handler, |
4307 bool calc_cond) const | 4307 bool calc_cond) const |
4308 { | 4308 { |
4309 SparseComplexMatrix retval; | 4309 SparseComplexMatrix retval; |
4310 | 4310 |
4316 (*current_liboctave_error_handler) | 4316 (*current_liboctave_error_handler) |
4317 ("matrix dimension mismatch solution of linear equations"); | 4317 ("matrix dimension mismatch solution of linear equations"); |
4318 else if (nr == 0 || b.cols () == 0) | 4318 else if (nr == 0 || b.cols () == 0) |
4319 retval = SparseComplexMatrix (nc, b.cols ()); | 4319 retval = SparseComplexMatrix (nc, b.cols ()); |
4320 else if (calc_cond) | 4320 else if (calc_cond) |
4321 (*current_liboctave_error_handler) | 4321 (*current_liboctave_error_handler) |
4322 ("calculation of condition number not implemented"); | 4322 ("calculation of condition number not implemented"); |
4323 else | 4323 else |
4324 { | 4324 { |
4325 // Print spparms("spumoni") info if requested | 4325 // Print spparms("spumoni") info if requested |
4326 int typ = mattype.type (); | 4326 int typ = mattype.type (); |
4327 mattype.info (); | 4327 mattype.info (); |
4328 | 4328 |
4329 // Note can't treat symmetric case as there is no dpttrf function | 4329 // Note can't treat symmetric case as there is no dpttrf function |
4330 if (typ == MatrixType::Tridiagonal || | 4330 if (typ == MatrixType::Tridiagonal || |
4331 typ == MatrixType::Tridiagonal_Hermitian) | 4331 typ == MatrixType::Tridiagonal_Hermitian) |
4332 { | 4332 { |
4333 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); | 4333 OCTAVE_LOCAL_BUFFER (double, DU2, nr - 2); |
4371 } | 4371 } |
4372 } | 4372 } |
4373 | 4373 |
4374 F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); | 4374 F77_XFCN (dgttrf, DGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); |
4375 | 4375 |
4376 if (err != 0) | 4376 if (err != 0) |
4377 { | 4377 { |
4378 rcond = 0.0; | 4378 rcond = 0.0; |
4379 err = -2; | 4379 err = -2; |
4380 | 4380 |
4381 if (sing_handler) | 4381 if (sing_handler) |
4384 mattype.mark_as_rectangular (); | 4384 mattype.mark_as_rectangular (); |
4385 } | 4385 } |
4386 else | 4386 else |
4387 (*current_liboctave_error_handler) | 4387 (*current_liboctave_error_handler) |
4388 ("matrix singular to machine precision"); | 4388 ("matrix singular to machine precision"); |
4389 } | 4389 } |
4390 else | 4390 else |
4391 { | 4391 { |
4392 rcond = 1.; | 4392 rcond = 1.; |
4393 char job = 'N'; | 4393 char job = 'N'; |
4394 octave_idx_type b_nr = b.rows (); | 4394 octave_idx_type b_nr = b.rows (); |
4395 octave_idx_type b_nc = b.cols (); | 4395 octave_idx_type b_nc = b.cols (); |
4396 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); | 4396 OCTAVE_LOCAL_BUFFER (double, Bx, b_nr); |
4411 Complex c = b (i,j); | 4411 Complex c = b (i,j); |
4412 Bx[i] = std::real (c); | 4412 Bx[i] = std::real (c); |
4413 Bz[i] = std::imag (c); | 4413 Bz[i] = std::imag (c); |
4414 } | 4414 } |
4415 | 4415 |
4416 F77_XFCN (dgttrs, DGTTRS, | 4416 F77_XFCN (dgttrs, DGTTRS, |
4417 (F77_CONST_CHAR_ARG2 (&job, 1), | 4417 (F77_CONST_CHAR_ARG2 (&job, 1), |
4418 nr, 1, DL, D, DU, DU2, pipvt, | 4418 nr, 1, DL, D, DU, DU2, pipvt, |
4419 Bx, b_nr, err | 4419 Bx, b_nr, err |
4420 F77_CHAR_ARG_LEN (1))); | 4420 F77_CHAR_ARG_LEN (1))); |
4421 | 4421 |
4422 if (err != 0) | 4422 if (err != 0) |
4423 { | 4423 { |
4426 | 4426 |
4427 err = -1; | 4427 err = -1; |
4428 break; | 4428 break; |
4429 } | 4429 } |
4430 | 4430 |
4431 F77_XFCN (dgttrs, DGTTRS, | 4431 F77_XFCN (dgttrs, DGTTRS, |
4432 (F77_CONST_CHAR_ARG2 (&job, 1), | 4432 (F77_CONST_CHAR_ARG2 (&job, 1), |
4433 nr, 1, DL, D, DU, DU2, pipvt, | 4433 nr, 1, DL, D, DU, DU2, pipvt, |
4434 Bz, b_nr, err | 4434 Bz, b_nr, err |
4435 F77_CHAR_ARG_LEN (1))); | 4435 F77_CHAR_ARG_LEN (1))); |
4436 | 4436 |
4437 if (err != 0) | 4437 if (err != 0) |
4438 { | 4438 { |
4441 | 4441 |
4442 err = -1; | 4442 err = -1; |
4443 break; | 4443 break; |
4444 } | 4444 } |
4445 | 4445 |
4446 // Count non-zeros in work vector and adjust | 4446 // Count non-zeros in work vector and adjust |
4447 // space in retval if needed | 4447 // space in retval if needed |
4448 octave_idx_type new_nnz = 0; | 4448 octave_idx_type new_nnz = 0; |
4449 for (octave_idx_type i = 0; i < nr; i++) | 4449 for (octave_idx_type i = 0; i < nr; i++) |
4450 if (Bx[i] != 0. || Bz[i] != 0.) | 4450 if (Bx[i] != 0. || Bz[i] != 0.) |
4451 new_nnz++; | 4451 new_nnz++; |
4460 | 4460 |
4461 for (octave_idx_type i = 0; i < nr; i++) | 4461 for (octave_idx_type i = 0; i < nr; i++) |
4462 if (Bx[i] != 0. || Bz[i] != 0.) | 4462 if (Bx[i] != 0. || Bz[i] != 0.) |
4463 { | 4463 { |
4464 retval.xridx(ii) = i; | 4464 retval.xridx(ii) = i; |
4465 retval.xdata(ii++) = | 4465 retval.xdata(ii++) = |
4466 Complex (Bx[i], Bz[i]); | 4466 Complex (Bx[i], Bz[i]); |
4467 } | 4467 } |
4468 | 4468 |
4469 retval.xcidx(j+1) = ii; | 4469 retval.xcidx(j+1) = ii; |
4470 } | 4470 } |
4506 { | 4506 { |
4507 octave_idx_type n_lower = mattype.nlower (); | 4507 octave_idx_type n_lower = mattype.nlower (); |
4508 octave_idx_type ldm = n_lower + 1; | 4508 octave_idx_type ldm = n_lower + 1; |
4509 Matrix m_band (ldm, nc); | 4509 Matrix m_band (ldm, nc); |
4510 double *tmp_data = m_band.fortran_vec (); | 4510 double *tmp_data = m_band.fortran_vec (); |
4511 | 4511 |
4512 if (! mattype.is_dense ()) | 4512 if (! mattype.is_dense ()) |
4513 { | 4513 { |
4514 octave_idx_type ii = 0; | 4514 octave_idx_type ii = 0; |
4515 | 4515 |
4516 for (octave_idx_type j = 0; j < ldm; j++) | 4516 for (octave_idx_type j = 0; j < ldm; j++) |
4517 for (octave_idx_type i = 0; i < nc; i++) | 4517 for (octave_idx_type i = 0; i < nc; i++) |
4533 | 4533 |
4534 char job = 'L'; | 4534 char job = 'L'; |
4535 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), | 4535 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), |
4536 nr, n_lower, tmp_data, ldm, err | 4536 nr, n_lower, tmp_data, ldm, err |
4537 F77_CHAR_ARG_LEN (1))); | 4537 F77_CHAR_ARG_LEN (1))); |
4538 | 4538 |
4539 if (err != 0) | 4539 if (err != 0) |
4540 { | 4540 { |
4541 // Matrix is not positive definite!! Fall through to | 4541 // Matrix is not positive definite!! Fall through to |
4542 // unsymmetric banded solver. | 4542 // unsymmetric banded solver. |
4543 mattype.mark_as_unsymmetric (); | 4543 mattype.mark_as_unsymmetric (); |
4544 typ = MatrixType::Banded; | 4544 typ = MatrixType::Banded; |
4545 rcond = 0.0; | 4545 rcond = 0.0; |
4546 err = 0; | 4546 err = 0; |
4547 } | 4547 } |
4548 else | 4548 else |
4549 { | 4549 { |
4550 if (calc_cond) | 4550 if (calc_cond) |
4551 { | 4551 { |
4552 Array<double> z (dim_vector (3 * nr, 1)); | 4552 Array<double> z (dim_vector (3 * nr, 1)); |
4553 double *pz = z.fortran_vec (); | 4553 double *pz = z.fortran_vec (); |
4554 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 4554 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
4555 octave_idx_type *piz = iz.fortran_vec (); | 4555 octave_idx_type *piz = iz.fortran_vec (); |
4556 | 4556 |
4557 F77_XFCN (dpbcon, DPBCON, | 4557 F77_XFCN (dpbcon, DPBCON, |
4558 (F77_CONST_CHAR_ARG2 (&job, 1), | 4558 (F77_CONST_CHAR_ARG2 (&job, 1), |
4559 nr, n_lower, tmp_data, ldm, | 4559 nr, n_lower, tmp_data, ldm, |
4560 anorm, rcond, pz, piz, err | 4560 anorm, rcond, pz, piz, err |
4561 F77_CHAR_ARG_LEN (1))); | 4561 F77_CHAR_ARG_LEN (1))); |
4562 | 4562 |
4563 if (err != 0) | 4563 if (err != 0) |
4564 err = -2; | 4564 err = -2; |
4565 | 4565 |
4566 volatile double rcond_plus_one = rcond + 1.0; | 4566 volatile double rcond_plus_one = rcond + 1.0; |
4567 | 4567 |
4568 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 4568 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
4588 retval = b; | 4588 retval = b; |
4589 double *result = retval.fortran_vec (); | 4589 double *result = retval.fortran_vec (); |
4590 | 4590 |
4591 octave_idx_type b_nc = b.cols (); | 4591 octave_idx_type b_nc = b.cols (); |
4592 | 4592 |
4593 F77_XFCN (dpbtrs, DPBTRS, | 4593 F77_XFCN (dpbtrs, DPBTRS, |
4594 (F77_CONST_CHAR_ARG2 (&job, 1), | 4594 (F77_CONST_CHAR_ARG2 (&job, 1), |
4595 nr, n_lower, b_nc, tmp_data, | 4595 nr, n_lower, b_nc, tmp_data, |
4596 ldm, result, b.rows(), err | 4596 ldm, result, b.rows(), err |
4597 F77_CHAR_ARG_LEN (1))); | 4597 F77_CHAR_ARG_LEN (1))); |
4598 | 4598 |
4599 if (err != 0) | 4599 if (err != 0) |
4600 { | 4600 { |
4601 (*current_liboctave_error_handler) | 4601 (*current_liboctave_error_handler) |
4602 ("SparseMatrix::solve solve failed"); | 4602 ("SparseMatrix::solve solve failed"); |
4603 err = -1; | 4603 err = -1; |
4604 } | 4604 } |
4605 } | 4605 } |
4606 } | 4606 } |
4613 octave_idx_type n_lower = mattype.nlower (); | 4613 octave_idx_type n_lower = mattype.nlower (); |
4614 octave_idx_type ldm = n_upper + 2 * n_lower + 1; | 4614 octave_idx_type ldm = n_upper + 2 * n_lower + 1; |
4615 | 4615 |
4616 Matrix m_band (ldm, nc); | 4616 Matrix m_band (ldm, nc); |
4617 double *tmp_data = m_band.fortran_vec (); | 4617 double *tmp_data = m_band.fortran_vec (); |
4618 | 4618 |
4619 if (! mattype.is_dense ()) | 4619 if (! mattype.is_dense ()) |
4620 { | 4620 { |
4621 octave_idx_type ii = 0; | 4621 octave_idx_type ii = 0; |
4622 | 4622 |
4623 for (octave_idx_type j = 0; j < ldm; j++) | 4623 for (octave_idx_type j = 0; j < ldm; j++) |
4624 for (octave_idx_type i = 0; i < nc; i++) | 4624 for (octave_idx_type i = 0; i < nc; i++) |
4644 } | 4644 } |
4645 | 4645 |
4646 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); | 4646 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); |
4647 octave_idx_type *pipvt = ipvt.fortran_vec (); | 4647 octave_idx_type *pipvt = ipvt.fortran_vec (); |
4648 | 4648 |
4649 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 4649 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
4650 ldm, pipvt, err)); | 4650 ldm, pipvt, err)); |
4651 | 4651 |
4652 // Throw-away extra info LAPACK gives so as to not | 4652 // Throw-away extra info LAPACK gives so as to not |
4653 // change output. | 4653 // change output. |
4654 if (err != 0) | 4654 if (err != 0) |
4655 { | 4655 { |
4656 err = -2; | 4656 err = -2; |
4657 rcond = 0.0; | 4657 rcond = 0.0; |
4658 | 4658 |
4659 if (sing_handler) | 4659 if (sing_handler) |
4663 } | 4663 } |
4664 else | 4664 else |
4665 (*current_liboctave_error_handler) | 4665 (*current_liboctave_error_handler) |
4666 ("matrix singular to machine precision"); | 4666 ("matrix singular to machine precision"); |
4667 | 4667 |
4668 } | 4668 } |
4669 else | 4669 else |
4670 { | 4670 { |
4671 if (calc_cond) | 4671 if (calc_cond) |
4672 { | 4672 { |
4673 char job = '1'; | 4673 char job = '1'; |
4674 Array<double> z (dim_vector (3 * nr, 1)); | 4674 Array<double> z (dim_vector (3 * nr, 1)); |
4675 double *pz = z.fortran_vec (); | 4675 double *pz = z.fortran_vec (); |
4676 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 4676 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
4677 octave_idx_type *piz = iz.fortran_vec (); | 4677 octave_idx_type *piz = iz.fortran_vec (); |
4678 | 4678 |
4679 F77_XFCN (dgbcon, DGBCON, | 4679 F77_XFCN (dgbcon, DGBCON, |
4680 (F77_CONST_CHAR_ARG2 (&job, 1), | 4680 (F77_CONST_CHAR_ARG2 (&job, 1), |
4681 nc, n_lower, n_upper, tmp_data, ldm, pipvt, | 4681 nc, n_lower, n_upper, tmp_data, ldm, pipvt, |
4682 anorm, rcond, pz, piz, err | 4682 anorm, rcond, pz, piz, err |
4683 F77_CHAR_ARG_LEN (1))); | 4683 F77_CHAR_ARG_LEN (1))); |
4684 | 4684 |
4685 if (err != 0) | 4685 if (err != 0) |
4686 err = -2; | 4686 err = -2; |
4687 | 4687 |
4688 volatile double rcond_plus_one = rcond + 1.0; | 4688 volatile double rcond_plus_one = rcond + 1.0; |
4689 | 4689 |
4690 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 4690 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
4711 double *result = retval.fortran_vec (); | 4711 double *result = retval.fortran_vec (); |
4712 | 4712 |
4713 octave_idx_type b_nc = b.cols (); | 4713 octave_idx_type b_nc = b.cols (); |
4714 | 4714 |
4715 char job = 'N'; | 4715 char job = 'N'; |
4716 F77_XFCN (dgbtrs, DGBTRS, | 4716 F77_XFCN (dgbtrs, DGBTRS, |
4717 (F77_CONST_CHAR_ARG2 (&job, 1), | 4717 (F77_CONST_CHAR_ARG2 (&job, 1), |
4718 nr, n_lower, n_upper, b_nc, tmp_data, | 4718 nr, n_lower, n_upper, b_nc, tmp_data, |
4719 ldm, pipvt, result, b.rows(), err | 4719 ldm, pipvt, result, b.rows(), err |
4720 F77_CHAR_ARG_LEN (1))); | 4720 F77_CHAR_ARG_LEN (1))); |
4721 } | 4721 } |
4728 return retval; | 4728 return retval; |
4729 } | 4729 } |
4730 | 4730 |
4731 SparseMatrix | 4731 SparseMatrix |
4732 SparseMatrix::bsolve (MatrixType &mattype, const SparseMatrix& b, | 4732 SparseMatrix::bsolve (MatrixType &mattype, const SparseMatrix& b, |
4733 octave_idx_type& err, double& rcond, | 4733 octave_idx_type& err, double& rcond, |
4734 solve_singularity_handler sing_handler, | 4734 solve_singularity_handler sing_handler, |
4735 bool calc_cond) const | 4735 bool calc_cond) const |
4736 { | 4736 { |
4737 SparseMatrix retval; | 4737 SparseMatrix retval; |
4738 | 4738 |
4756 octave_idx_type n_lower = mattype.nlower (); | 4756 octave_idx_type n_lower = mattype.nlower (); |
4757 octave_idx_type ldm = n_lower + 1; | 4757 octave_idx_type ldm = n_lower + 1; |
4758 | 4758 |
4759 Matrix m_band (ldm, nc); | 4759 Matrix m_band (ldm, nc); |
4760 double *tmp_data = m_band.fortran_vec (); | 4760 double *tmp_data = m_band.fortran_vec (); |
4761 | 4761 |
4762 if (! mattype.is_dense ()) | 4762 if (! mattype.is_dense ()) |
4763 { | 4763 { |
4764 octave_idx_type ii = 0; | 4764 octave_idx_type ii = 0; |
4765 | 4765 |
4766 for (octave_idx_type j = 0; j < ldm; j++) | 4766 for (octave_idx_type j = 0; j < ldm; j++) |
4767 for (octave_idx_type i = 0; i < nc; i++) | 4767 for (octave_idx_type i = 0; i < nc; i++) |
4783 | 4783 |
4784 char job = 'L'; | 4784 char job = 'L'; |
4785 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), | 4785 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), |
4786 nr, n_lower, tmp_data, ldm, err | 4786 nr, n_lower, tmp_data, ldm, err |
4787 F77_CHAR_ARG_LEN (1))); | 4787 F77_CHAR_ARG_LEN (1))); |
4788 | 4788 |
4789 if (err != 0) | 4789 if (err != 0) |
4790 { | 4790 { |
4791 mattype.mark_as_unsymmetric (); | 4791 mattype.mark_as_unsymmetric (); |
4792 typ = MatrixType::Banded; | 4792 typ = MatrixType::Banded; |
4793 rcond = 0.0; | 4793 rcond = 0.0; |
4794 err = 0; | 4794 err = 0; |
4795 } | 4795 } |
4796 else | 4796 else |
4797 { | 4797 { |
4798 if (calc_cond) | 4798 if (calc_cond) |
4799 { | 4799 { |
4800 Array<double> z (dim_vector (3 * nr, 1)); | 4800 Array<double> z (dim_vector (3 * nr, 1)); |
4801 double *pz = z.fortran_vec (); | 4801 double *pz = z.fortran_vec (); |
4802 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 4802 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
4803 octave_idx_type *piz = iz.fortran_vec (); | 4803 octave_idx_type *piz = iz.fortran_vec (); |
4804 | 4804 |
4805 F77_XFCN (dpbcon, DPBCON, | 4805 F77_XFCN (dpbcon, DPBCON, |
4806 (F77_CONST_CHAR_ARG2 (&job, 1), | 4806 (F77_CONST_CHAR_ARG2 (&job, 1), |
4807 nr, n_lower, tmp_data, ldm, | 4807 nr, n_lower, tmp_data, ldm, |
4808 anorm, rcond, pz, piz, err | 4808 anorm, rcond, pz, piz, err |
4809 F77_CHAR_ARG_LEN (1))); | 4809 F77_CHAR_ARG_LEN (1))); |
4810 | 4810 |
4811 if (err != 0) | 4811 if (err != 0) |
4812 err = -2; | 4812 err = -2; |
4813 | 4813 |
4814 volatile double rcond_plus_one = rcond + 1.0; | 4814 volatile double rcond_plus_one = rcond + 1.0; |
4815 | 4815 |
4816 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 4816 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
4847 for (volatile octave_idx_type j = 0; j < b_nc; j++) | 4847 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
4848 { | 4848 { |
4849 for (octave_idx_type i = 0; i < b_nr; i++) | 4849 for (octave_idx_type i = 0; i < b_nr; i++) |
4850 Bx[i] = b.elem (i, j); | 4850 Bx[i] = b.elem (i, j); |
4851 | 4851 |
4852 F77_XFCN (dpbtrs, DPBTRS, | 4852 F77_XFCN (dpbtrs, DPBTRS, |
4853 (F77_CONST_CHAR_ARG2 (&job, 1), | 4853 (F77_CONST_CHAR_ARG2 (&job, 1), |
4854 nr, n_lower, 1, tmp_data, | 4854 nr, n_lower, 1, tmp_data, |
4855 ldm, Bx, b_nr, err | 4855 ldm, Bx, b_nr, err |
4856 F77_CHAR_ARG_LEN (1))); | 4856 F77_CHAR_ARG_LEN (1))); |
4857 | 4857 |
4858 if (err != 0) | 4858 if (err != 0) |
4859 { | 4859 { |
4860 (*current_liboctave_error_handler) | 4860 (*current_liboctave_error_handler) |
4861 ("SparseMatrix::solve solve failed"); | 4861 ("SparseMatrix::solve solve failed"); |
4862 err = -1; | 4862 err = -1; |
4863 break; | 4863 break; |
4864 } | 4864 } |
4865 | 4865 |
4869 if (tmp != 0.0) | 4869 if (tmp != 0.0) |
4870 { | 4870 { |
4871 if (ii == x_nz) | 4871 if (ii == x_nz) |
4872 { | 4872 { |
4873 // Resize the sparse matrix | 4873 // Resize the sparse matrix |
4874 octave_idx_type sz = x_nz * | 4874 octave_idx_type sz = x_nz * |
4875 (b_nc - j) / b_nc; | 4875 (b_nc - j) / b_nc; |
4876 sz = (sz > 10 ? sz : 10) + x_nz; | 4876 sz = (sz > 10 ? sz : 10) + x_nz; |
4877 retval.change_capacity (sz); | 4877 retval.change_capacity (sz); |
4878 x_nz = sz; | 4878 x_nz = sz; |
4879 } | 4879 } |
4896 octave_idx_type n_lower = mattype.nlower (); | 4896 octave_idx_type n_lower = mattype.nlower (); |
4897 octave_idx_type ldm = n_upper + 2 * n_lower + 1; | 4897 octave_idx_type ldm = n_upper + 2 * n_lower + 1; |
4898 | 4898 |
4899 Matrix m_band (ldm, nc); | 4899 Matrix m_band (ldm, nc); |
4900 double *tmp_data = m_band.fortran_vec (); | 4900 double *tmp_data = m_band.fortran_vec (); |
4901 | 4901 |
4902 if (! mattype.is_dense ()) | 4902 if (! mattype.is_dense ()) |
4903 { | 4903 { |
4904 octave_idx_type ii = 0; | 4904 octave_idx_type ii = 0; |
4905 | 4905 |
4906 for (octave_idx_type j = 0; j < ldm; j++) | 4906 for (octave_idx_type j = 0; j < ldm; j++) |
4907 for (octave_idx_type i = 0; i < nc; i++) | 4907 for (octave_idx_type i = 0; i < nc; i++) |
4927 } | 4927 } |
4928 | 4928 |
4929 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); | 4929 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); |
4930 octave_idx_type *pipvt = ipvt.fortran_vec (); | 4930 octave_idx_type *pipvt = ipvt.fortran_vec (); |
4931 | 4931 |
4932 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 4932 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
4933 ldm, pipvt, err)); | 4933 ldm, pipvt, err)); |
4934 | 4934 |
4935 if (err != 0) | 4935 if (err != 0) |
4936 { | 4936 { |
4937 err = -2; | 4937 err = -2; |
4938 rcond = 0.0; | 4938 rcond = 0.0; |
4939 | 4939 |
4940 if (sing_handler) | 4940 if (sing_handler) |
4944 } | 4944 } |
4945 else | 4945 else |
4946 (*current_liboctave_error_handler) | 4946 (*current_liboctave_error_handler) |
4947 ("matrix singular to machine precision"); | 4947 ("matrix singular to machine precision"); |
4948 | 4948 |
4949 } | 4949 } |
4950 else | 4950 else |
4951 { | 4951 { |
4952 if (calc_cond) | 4952 if (calc_cond) |
4953 { | 4953 { |
4954 char job = '1'; | 4954 char job = '1'; |
4955 Array<double> z (dim_vector (3 * nr, 1)); | 4955 Array<double> z (dim_vector (3 * nr, 1)); |
4956 double *pz = z.fortran_vec (); | 4956 double *pz = z.fortran_vec (); |
4957 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 4957 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
4958 octave_idx_type *piz = iz.fortran_vec (); | 4958 octave_idx_type *piz = iz.fortran_vec (); |
4959 | 4959 |
4960 F77_XFCN (dgbcon, DGBCON, | 4960 F77_XFCN (dgbcon, DGBCON, |
4961 (F77_CONST_CHAR_ARG2 (&job, 1), | 4961 (F77_CONST_CHAR_ARG2 (&job, 1), |
4962 nc, n_lower, n_upper, tmp_data, ldm, pipvt, | 4962 nc, n_lower, n_upper, tmp_data, ldm, pipvt, |
4963 anorm, rcond, pz, piz, err | 4963 anorm, rcond, pz, piz, err |
4964 F77_CHAR_ARG_LEN (1))); | 4964 F77_CHAR_ARG_LEN (1))); |
4965 | 4965 |
4966 if (err != 0) | 4966 if (err != 0) |
4967 err = -2; | 4967 err = -2; |
4968 | 4968 |
4969 volatile double rcond_plus_one = rcond + 1.0; | 4969 volatile double rcond_plus_one = rcond + 1.0; |
4970 | 4970 |
4971 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 4971 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
4999 | 4999 |
5000 for (volatile octave_idx_type j = 0; j < b_nc; j++) | 5000 for (volatile octave_idx_type j = 0; j < b_nc; j++) |
5001 { | 5001 { |
5002 for (octave_idx_type i = 0; i < nr; i++) | 5002 for (octave_idx_type i = 0; i < nr; i++) |
5003 work[i] = 0.; | 5003 work[i] = 0.; |
5004 for (octave_idx_type i = b.cidx(j); | 5004 for (octave_idx_type i = b.cidx(j); |
5005 i < b.cidx(j+1); i++) | 5005 i < b.cidx(j+1); i++) |
5006 work[b.ridx(i)] = b.data(i); | 5006 work[b.ridx(i)] = b.data(i); |
5007 | 5007 |
5008 F77_XFCN (dgbtrs, DGBTRS, | 5008 F77_XFCN (dgbtrs, DGBTRS, |
5009 (F77_CONST_CHAR_ARG2 (&job, 1), | 5009 (F77_CONST_CHAR_ARG2 (&job, 1), |
5010 nr, n_lower, n_upper, 1, tmp_data, | 5010 nr, n_lower, n_upper, 1, tmp_data, |
5011 ldm, pipvt, work, b.rows (), err | 5011 ldm, pipvt, work, b.rows (), err |
5012 F77_CHAR_ARG_LEN (1))); | 5012 F77_CHAR_ARG_LEN (1))); |
5013 | 5013 |
5014 // Count non-zeros in work vector and adjust | 5014 // Count non-zeros in work vector and adjust |
5015 // space in retval if needed | 5015 // space in retval if needed |
5016 octave_idx_type new_nnz = 0; | 5016 octave_idx_type new_nnz = 0; |
5017 for (octave_idx_type i = 0; i < nr; i++) | 5017 for (octave_idx_type i = 0; i < nr; i++) |
5018 if (work[i] != 0.) | 5018 if (work[i] != 0.) |
5019 new_nnz++; | 5019 new_nnz++; |
5045 | 5045 |
5046 return retval; | 5046 return retval; |
5047 } | 5047 } |
5048 | 5048 |
5049 ComplexMatrix | 5049 ComplexMatrix |
5050 SparseMatrix::bsolve (MatrixType &mattype, const ComplexMatrix& b, | 5050 SparseMatrix::bsolve (MatrixType &mattype, const ComplexMatrix& b, |
5051 octave_idx_type& err, double& rcond, | 5051 octave_idx_type& err, double& rcond, |
5052 solve_singularity_handler sing_handler, | 5052 solve_singularity_handler sing_handler, |
5053 bool calc_cond) const | 5053 bool calc_cond) const |
5054 { | 5054 { |
5055 ComplexMatrix retval; | 5055 ComplexMatrix retval; |
5056 | 5056 |
5074 octave_idx_type n_lower = mattype.nlower (); | 5074 octave_idx_type n_lower = mattype.nlower (); |
5075 octave_idx_type ldm = n_lower + 1; | 5075 octave_idx_type ldm = n_lower + 1; |
5076 | 5076 |
5077 Matrix m_band (ldm, nc); | 5077 Matrix m_band (ldm, nc); |
5078 double *tmp_data = m_band.fortran_vec (); | 5078 double *tmp_data = m_band.fortran_vec (); |
5079 | 5079 |
5080 if (! mattype.is_dense ()) | 5080 if (! mattype.is_dense ()) |
5081 { | 5081 { |
5082 octave_idx_type ii = 0; | 5082 octave_idx_type ii = 0; |
5083 | 5083 |
5084 for (octave_idx_type j = 0; j < ldm; j++) | 5084 for (octave_idx_type j = 0; j < ldm; j++) |
5085 for (octave_idx_type i = 0; i < nc; i++) | 5085 for (octave_idx_type i = 0; i < nc; i++) |
5101 | 5101 |
5102 char job = 'L'; | 5102 char job = 'L'; |
5103 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), | 5103 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), |
5104 nr, n_lower, tmp_data, ldm, err | 5104 nr, n_lower, tmp_data, ldm, err |
5105 F77_CHAR_ARG_LEN (1))); | 5105 F77_CHAR_ARG_LEN (1))); |
5106 | 5106 |
5107 if (err != 0) | 5107 if (err != 0) |
5108 { | 5108 { |
5109 // Matrix is not positive definite!! Fall through to | 5109 // Matrix is not positive definite!! Fall through to |
5110 // unsymmetric banded solver. | 5110 // unsymmetric banded solver. |
5111 mattype.mark_as_unsymmetric (); | 5111 mattype.mark_as_unsymmetric (); |
5112 typ = MatrixType::Banded; | 5112 typ = MatrixType::Banded; |
5113 rcond = 0.0; | 5113 rcond = 0.0; |
5114 err = 0; | 5114 err = 0; |
5115 } | 5115 } |
5116 else | 5116 else |
5117 { | 5117 { |
5118 if (calc_cond) | 5118 if (calc_cond) |
5119 { | 5119 { |
5120 Array<double> z (dim_vector (3 * nr, 1)); | 5120 Array<double> z (dim_vector (3 * nr, 1)); |
5121 double *pz = z.fortran_vec (); | 5121 double *pz = z.fortran_vec (); |
5122 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 5122 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
5123 octave_idx_type *piz = iz.fortran_vec (); | 5123 octave_idx_type *piz = iz.fortran_vec (); |
5124 | 5124 |
5125 F77_XFCN (dpbcon, DPBCON, | 5125 F77_XFCN (dpbcon, DPBCON, |
5126 (F77_CONST_CHAR_ARG2 (&job, 1), | 5126 (F77_CONST_CHAR_ARG2 (&job, 1), |
5127 nr, n_lower, tmp_data, ldm, | 5127 nr, n_lower, tmp_data, ldm, |
5128 anorm, rcond, pz, piz, err | 5128 anorm, rcond, pz, piz, err |
5129 F77_CHAR_ARG_LEN (1))); | 5129 F77_CHAR_ARG_LEN (1))); |
5130 | 5130 |
5131 if (err != 0) | 5131 if (err != 0) |
5132 err = -2; | 5132 err = -2; |
5133 | 5133 |
5134 volatile double rcond_plus_one = rcond + 1.0; | 5134 volatile double rcond_plus_one = rcond + 1.0; |
5135 | 5135 |
5136 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 5136 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
5168 Complex c = b (i,j); | 5168 Complex c = b (i,j); |
5169 Bx[i] = std::real (c); | 5169 Bx[i] = std::real (c); |
5170 Bz[i] = std::imag (c); | 5170 Bz[i] = std::imag (c); |
5171 } | 5171 } |
5172 | 5172 |
5173 F77_XFCN (dpbtrs, DPBTRS, | 5173 F77_XFCN (dpbtrs, DPBTRS, |
5174 (F77_CONST_CHAR_ARG2 (&job, 1), | 5174 (F77_CONST_CHAR_ARG2 (&job, 1), |
5175 nr, n_lower, 1, tmp_data, | 5175 nr, n_lower, 1, tmp_data, |
5176 ldm, Bx, b_nr, err | 5176 ldm, Bx, b_nr, err |
5177 F77_CHAR_ARG_LEN (1))); | 5177 F77_CHAR_ARG_LEN (1))); |
5178 | 5178 |
5179 if (err != 0) | 5179 if (err != 0) |
5180 { | 5180 { |
5181 (*current_liboctave_error_handler) | 5181 (*current_liboctave_error_handler) |
5182 ("SparseMatrix::solve solve failed"); | 5182 ("SparseMatrix::solve solve failed"); |
5183 err = -1; | 5183 err = -1; |
5184 break; | 5184 break; |
5185 } | 5185 } |
5186 | 5186 |
5187 F77_XFCN (dpbtrs, DPBTRS, | 5187 F77_XFCN (dpbtrs, DPBTRS, |
5188 (F77_CONST_CHAR_ARG2 (&job, 1), | 5188 (F77_CONST_CHAR_ARG2 (&job, 1), |
5189 nr, n_lower, 1, tmp_data, | 5189 nr, n_lower, 1, tmp_data, |
5190 ldm, Bz, b.rows(), err | 5190 ldm, Bz, b.rows(), err |
5191 F77_CHAR_ARG_LEN (1))); | 5191 F77_CHAR_ARG_LEN (1))); |
5192 | 5192 |
5193 if (err != 0) | 5193 if (err != 0) |
5194 { | 5194 { |
5195 (*current_liboctave_error_handler) | 5195 (*current_liboctave_error_handler) |
5196 ("SparseMatrix::solve solve failed"); | 5196 ("SparseMatrix::solve solve failed"); |
5197 err = -1; | 5197 err = -1; |
5198 break; | 5198 break; |
5199 } | 5199 } |
5200 | 5200 |
5212 octave_idx_type n_lower = mattype.nlower (); | 5212 octave_idx_type n_lower = mattype.nlower (); |
5213 octave_idx_type ldm = n_upper + 2 * n_lower + 1; | 5213 octave_idx_type ldm = n_upper + 2 * n_lower + 1; |
5214 | 5214 |
5215 Matrix m_band (ldm, nc); | 5215 Matrix m_band (ldm, nc); |
5216 double *tmp_data = m_band.fortran_vec (); | 5216 double *tmp_data = m_band.fortran_vec (); |
5217 | 5217 |
5218 if (! mattype.is_dense ()) | 5218 if (! mattype.is_dense ()) |
5219 { | 5219 { |
5220 octave_idx_type ii = 0; | 5220 octave_idx_type ii = 0; |
5221 | 5221 |
5222 for (octave_idx_type j = 0; j < ldm; j++) | 5222 for (octave_idx_type j = 0; j < ldm; j++) |
5223 for (octave_idx_type i = 0; i < nc; i++) | 5223 for (octave_idx_type i = 0; i < nc; i++) |
5243 } | 5243 } |
5244 | 5244 |
5245 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); | 5245 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); |
5246 octave_idx_type *pipvt = ipvt.fortran_vec (); | 5246 octave_idx_type *pipvt = ipvt.fortran_vec (); |
5247 | 5247 |
5248 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 5248 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
5249 ldm, pipvt, err)); | 5249 ldm, pipvt, err)); |
5250 | 5250 |
5251 if (err != 0) | 5251 if (err != 0) |
5252 { | 5252 { |
5253 err = -2; | 5253 err = -2; |
5254 rcond = 0.0; | 5254 rcond = 0.0; |
5255 | 5255 |
5256 if (sing_handler) | 5256 if (sing_handler) |
5260 } | 5260 } |
5261 else | 5261 else |
5262 (*current_liboctave_error_handler) | 5262 (*current_liboctave_error_handler) |
5263 ("matrix singular to machine precision"); | 5263 ("matrix singular to machine precision"); |
5264 | 5264 |
5265 } | 5265 } |
5266 else | 5266 else |
5267 { | 5267 { |
5268 if (calc_cond) | 5268 if (calc_cond) |
5269 { | 5269 { |
5270 char job = '1'; | 5270 char job = '1'; |
5271 Array<double> z (dim_vector (3 * nr, 1)); | 5271 Array<double> z (dim_vector (3 * nr, 1)); |
5272 double *pz = z.fortran_vec (); | 5272 double *pz = z.fortran_vec (); |
5273 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 5273 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
5274 octave_idx_type *piz = iz.fortran_vec (); | 5274 octave_idx_type *piz = iz.fortran_vec (); |
5275 | 5275 |
5276 F77_XFCN (dpbcon, DPBCON, | 5276 F77_XFCN (dpbcon, DPBCON, |
5277 (F77_CONST_CHAR_ARG2 (&job, 1), | 5277 (F77_CONST_CHAR_ARG2 (&job, 1), |
5278 nr, n_lower, tmp_data, ldm, | 5278 nr, n_lower, tmp_data, ldm, |
5279 anorm, rcond, pz, piz, err | 5279 anorm, rcond, pz, piz, err |
5280 F77_CHAR_ARG_LEN (1))); | 5280 F77_CHAR_ARG_LEN (1))); |
5281 | 5281 |
5282 if (err != 0) | 5282 if (err != 0) |
5283 err = -2; | 5283 err = -2; |
5284 | 5284 |
5285 volatile double rcond_plus_one = rcond + 1.0; | 5285 volatile double rcond_plus_one = rcond + 1.0; |
5286 | 5286 |
5287 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 5287 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
5318 Complex c = b (i, j); | 5318 Complex c = b (i, j); |
5319 Bx[i] = std::real (c); | 5319 Bx[i] = std::real (c); |
5320 Bz[i] = std::imag (c); | 5320 Bz[i] = std::imag (c); |
5321 } | 5321 } |
5322 | 5322 |
5323 F77_XFCN (dgbtrs, DGBTRS, | 5323 F77_XFCN (dgbtrs, DGBTRS, |
5324 (F77_CONST_CHAR_ARG2 (&job, 1), | 5324 (F77_CONST_CHAR_ARG2 (&job, 1), |
5325 nr, n_lower, n_upper, 1, tmp_data, | 5325 nr, n_lower, n_upper, 1, tmp_data, |
5326 ldm, pipvt, Bx, b.rows (), err | 5326 ldm, pipvt, Bx, b.rows (), err |
5327 F77_CHAR_ARG_LEN (1))); | 5327 F77_CHAR_ARG_LEN (1))); |
5328 | 5328 |
5329 F77_XFCN (dgbtrs, DGBTRS, | 5329 F77_XFCN (dgbtrs, DGBTRS, |
5330 (F77_CONST_CHAR_ARG2 (&job, 1), | 5330 (F77_CONST_CHAR_ARG2 (&job, 1), |
5331 nr, n_lower, n_upper, 1, tmp_data, | 5331 nr, n_lower, n_upper, 1, tmp_data, |
5332 ldm, pipvt, Bz, b.rows (), err | 5332 ldm, pipvt, Bz, b.rows (), err |
5333 F77_CHAR_ARG_LEN (1))); | 5333 F77_CHAR_ARG_LEN (1))); |
5334 | 5334 |
5345 return retval; | 5345 return retval; |
5346 } | 5346 } |
5347 | 5347 |
5348 SparseComplexMatrix | 5348 SparseComplexMatrix |
5349 SparseMatrix::bsolve (MatrixType &mattype, const SparseComplexMatrix& b, | 5349 SparseMatrix::bsolve (MatrixType &mattype, const SparseComplexMatrix& b, |
5350 octave_idx_type& err, double& rcond, | 5350 octave_idx_type& err, double& rcond, |
5351 solve_singularity_handler sing_handler, | 5351 solve_singularity_handler sing_handler, |
5352 bool calc_cond) const | 5352 bool calc_cond) const |
5353 { | 5353 { |
5354 SparseComplexMatrix retval; | 5354 SparseComplexMatrix retval; |
5355 | 5355 |
5373 octave_idx_type n_lower = mattype.nlower (); | 5373 octave_idx_type n_lower = mattype.nlower (); |
5374 octave_idx_type ldm = n_lower + 1; | 5374 octave_idx_type ldm = n_lower + 1; |
5375 | 5375 |
5376 Matrix m_band (ldm, nc); | 5376 Matrix m_band (ldm, nc); |
5377 double *tmp_data = m_band.fortran_vec (); | 5377 double *tmp_data = m_band.fortran_vec (); |
5378 | 5378 |
5379 if (! mattype.is_dense ()) | 5379 if (! mattype.is_dense ()) |
5380 { | 5380 { |
5381 octave_idx_type ii = 0; | 5381 octave_idx_type ii = 0; |
5382 | 5382 |
5383 for (octave_idx_type j = 0; j < ldm; j++) | 5383 for (octave_idx_type j = 0; j < ldm; j++) |
5384 for (octave_idx_type i = 0; i < nc; i++) | 5384 for (octave_idx_type i = 0; i < nc; i++) |
5400 | 5400 |
5401 char job = 'L'; | 5401 char job = 'L'; |
5402 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), | 5402 F77_XFCN (dpbtrf, DPBTRF, (F77_CONST_CHAR_ARG2 (&job, 1), |
5403 nr, n_lower, tmp_data, ldm, err | 5403 nr, n_lower, tmp_data, ldm, err |
5404 F77_CHAR_ARG_LEN (1))); | 5404 F77_CHAR_ARG_LEN (1))); |
5405 | 5405 |
5406 if (err != 0) | 5406 if (err != 0) |
5407 { | 5407 { |
5408 // Matrix is not positive definite!! Fall through to | 5408 // Matrix is not positive definite!! Fall through to |
5409 // unsymmetric banded solver. | 5409 // unsymmetric banded solver. |
5410 mattype.mark_as_unsymmetric (); | 5410 mattype.mark_as_unsymmetric (); |
5411 typ = MatrixType::Banded; | 5411 typ = MatrixType::Banded; |
5412 | 5412 |
5413 rcond = 0.0; | 5413 rcond = 0.0; |
5414 err = 0; | 5414 err = 0; |
5415 } | 5415 } |
5416 else | 5416 else |
5417 { | 5417 { |
5418 if (calc_cond) | 5418 if (calc_cond) |
5419 { | 5419 { |
5420 Array<double> z (dim_vector (3 * nr, 1)); | 5420 Array<double> z (dim_vector (3 * nr, 1)); |
5421 double *pz = z.fortran_vec (); | 5421 double *pz = z.fortran_vec (); |
5422 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 5422 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
5423 octave_idx_type *piz = iz.fortran_vec (); | 5423 octave_idx_type *piz = iz.fortran_vec (); |
5424 | 5424 |
5425 F77_XFCN (dpbcon, DPBCON, | 5425 F77_XFCN (dpbcon, DPBCON, |
5426 (F77_CONST_CHAR_ARG2 (&job, 1), | 5426 (F77_CONST_CHAR_ARG2 (&job, 1), |
5427 nr, n_lower, tmp_data, ldm, | 5427 nr, n_lower, tmp_data, ldm, |
5428 anorm, rcond, pz, piz, err | 5428 anorm, rcond, pz, piz, err |
5429 F77_CHAR_ARG_LEN (1))); | 5429 F77_CHAR_ARG_LEN (1))); |
5430 | 5430 |
5431 if (err != 0) | 5431 if (err != 0) |
5432 err = -2; | 5432 err = -2; |
5433 | 5433 |
5434 volatile double rcond_plus_one = rcond + 1.0; | 5434 volatile double rcond_plus_one = rcond + 1.0; |
5435 | 5435 |
5436 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 5436 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
5473 Complex c = b (i,j); | 5473 Complex c = b (i,j); |
5474 Bx[i] = std::real (c); | 5474 Bx[i] = std::real (c); |
5475 Bz[i] = std::imag (c); | 5475 Bz[i] = std::imag (c); |
5476 } | 5476 } |
5477 | 5477 |
5478 F77_XFCN (dpbtrs, DPBTRS, | 5478 F77_XFCN (dpbtrs, DPBTRS, |
5479 (F77_CONST_CHAR_ARG2 (&job, 1), | 5479 (F77_CONST_CHAR_ARG2 (&job, 1), |
5480 nr, n_lower, 1, tmp_data, | 5480 nr, n_lower, 1, tmp_data, |
5481 ldm, Bx, b_nr, err | 5481 ldm, Bx, b_nr, err |
5482 F77_CHAR_ARG_LEN (1))); | 5482 F77_CHAR_ARG_LEN (1))); |
5483 | 5483 |
5484 if (err != 0) | 5484 if (err != 0) |
5485 { | 5485 { |
5486 (*current_liboctave_error_handler) | 5486 (*current_liboctave_error_handler) |
5487 ("SparseMatrix::solve solve failed"); | 5487 ("SparseMatrix::solve solve failed"); |
5488 err = -1; | 5488 err = -1; |
5489 break; | 5489 break; |
5490 } | 5490 } |
5491 | 5491 |
5492 F77_XFCN (dpbtrs, DPBTRS, | 5492 F77_XFCN (dpbtrs, DPBTRS, |
5493 (F77_CONST_CHAR_ARG2 (&job, 1), | 5493 (F77_CONST_CHAR_ARG2 (&job, 1), |
5494 nr, n_lower, 1, tmp_data, | 5494 nr, n_lower, 1, tmp_data, |
5495 ldm, Bz, b_nr, err | 5495 ldm, Bz, b_nr, err |
5496 F77_CHAR_ARG_LEN (1))); | 5496 F77_CHAR_ARG_LEN (1))); |
5497 | 5497 |
5502 | 5502 |
5503 err = -1; | 5503 err = -1; |
5504 break; | 5504 break; |
5505 } | 5505 } |
5506 | 5506 |
5507 // Count non-zeros in work vector and adjust | 5507 // Count non-zeros in work vector and adjust |
5508 // space in retval if needed | 5508 // space in retval if needed |
5509 octave_idx_type new_nnz = 0; | 5509 octave_idx_type new_nnz = 0; |
5510 for (octave_idx_type i = 0; i < nr; i++) | 5510 for (octave_idx_type i = 0; i < nr; i++) |
5511 if (Bx[i] != 0. || Bz[i] != 0.) | 5511 if (Bx[i] != 0. || Bz[i] != 0.) |
5512 new_nnz++; | 5512 new_nnz++; |
5521 | 5521 |
5522 for (octave_idx_type i = 0; i < nr; i++) | 5522 for (octave_idx_type i = 0; i < nr; i++) |
5523 if (Bx[i] != 0. || Bz[i] != 0.) | 5523 if (Bx[i] != 0. || Bz[i] != 0.) |
5524 { | 5524 { |
5525 retval.xridx(ii) = i; | 5525 retval.xridx(ii) = i; |
5526 retval.xdata(ii++) = | 5526 retval.xdata(ii++) = |
5527 Complex (Bx[i], Bz[i]); | 5527 Complex (Bx[i], Bz[i]); |
5528 } | 5528 } |
5529 | 5529 |
5530 retval.xcidx(j+1) = ii; | 5530 retval.xcidx(j+1) = ii; |
5531 } | 5531 } |
5542 octave_idx_type n_lower = mattype.nlower (); | 5542 octave_idx_type n_lower = mattype.nlower (); |
5543 octave_idx_type ldm = n_upper + 2 * n_lower + 1; | 5543 octave_idx_type ldm = n_upper + 2 * n_lower + 1; |
5544 | 5544 |
5545 Matrix m_band (ldm, nc); | 5545 Matrix m_band (ldm, nc); |
5546 double *tmp_data = m_band.fortran_vec (); | 5546 double *tmp_data = m_band.fortran_vec (); |
5547 | 5547 |
5548 if (! mattype.is_dense ()) | 5548 if (! mattype.is_dense ()) |
5549 { | 5549 { |
5550 octave_idx_type ii = 0; | 5550 octave_idx_type ii = 0; |
5551 | 5551 |
5552 for (octave_idx_type j = 0; j < ldm; j++) | 5552 for (octave_idx_type j = 0; j < ldm; j++) |
5553 for (octave_idx_type i = 0; i < nc; i++) | 5553 for (octave_idx_type i = 0; i < nc; i++) |
5573 } | 5573 } |
5574 | 5574 |
5575 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); | 5575 Array<octave_idx_type> ipvt (dim_vector (nr, 1)); |
5576 octave_idx_type *pipvt = ipvt.fortran_vec (); | 5576 octave_idx_type *pipvt = ipvt.fortran_vec (); |
5577 | 5577 |
5578 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, | 5578 F77_XFCN (dgbtrf, DGBTRF, (nr, nr, n_lower, n_upper, tmp_data, |
5579 ldm, pipvt, err)); | 5579 ldm, pipvt, err)); |
5580 | 5580 |
5581 if (err != 0) | 5581 if (err != 0) |
5582 { | 5582 { |
5583 err = -2; | 5583 err = -2; |
5584 rcond = 0.0; | 5584 rcond = 0.0; |
5585 | 5585 |
5586 if (sing_handler) | 5586 if (sing_handler) |
5590 } | 5590 } |
5591 else | 5591 else |
5592 (*current_liboctave_error_handler) | 5592 (*current_liboctave_error_handler) |
5593 ("matrix singular to machine precision"); | 5593 ("matrix singular to machine precision"); |
5594 | 5594 |
5595 } | 5595 } |
5596 else | 5596 else |
5597 { | 5597 { |
5598 if (calc_cond) | 5598 if (calc_cond) |
5599 { | 5599 { |
5600 char job = '1'; | 5600 char job = '1'; |
5601 Array<double> z (dim_vector (3 * nr, 1)); | 5601 Array<double> z (dim_vector (3 * nr, 1)); |
5602 double *pz = z.fortran_vec (); | 5602 double *pz = z.fortran_vec (); |
5603 Array<octave_idx_type> iz (dim_vector (nr, 1)); | 5603 Array<octave_idx_type> iz (dim_vector (nr, 1)); |
5604 octave_idx_type *piz = iz.fortran_vec (); | 5604 octave_idx_type *piz = iz.fortran_vec (); |
5605 | 5605 |
5606 F77_XFCN (dgbcon, DGBCON, | 5606 F77_XFCN (dgbcon, DGBCON, |
5607 (F77_CONST_CHAR_ARG2 (&job, 1), | 5607 (F77_CONST_CHAR_ARG2 (&job, 1), |
5608 nc, n_lower, n_upper, tmp_data, ldm, pipvt, | 5608 nc, n_lower, n_upper, tmp_data, ldm, pipvt, |
5609 anorm, rcond, pz, piz, err | 5609 anorm, rcond, pz, piz, err |
5610 F77_CHAR_ARG_LEN (1))); | 5610 F77_CHAR_ARG_LEN (1))); |
5611 | 5611 |
5612 if (err != 0) | 5612 if (err != 0) |
5613 err = -2; | 5613 err = -2; |
5614 | 5614 |
5615 volatile double rcond_plus_one = rcond + 1.0; | 5615 volatile double rcond_plus_one = rcond + 1.0; |
5616 | 5616 |
5617 if (rcond_plus_one == 1.0 || xisnan (rcond)) | 5617 if (rcond_plus_one == 1.0 || xisnan (rcond)) |
5649 for (octave_idx_type i = 0; i < nr; i++) | 5649 for (octave_idx_type i = 0; i < nr; i++) |
5650 { | 5650 { |
5651 Bx[i] = 0.; | 5651 Bx[i] = 0.; |
5652 Bz[i] = 0.; | 5652 Bz[i] = 0.; |
5653 } | 5653 } |
5654 for (octave_idx_type i = b.cidx(j); | 5654 for (octave_idx_type i = b.cidx(j); |
5655 i < b.cidx(j+1); i++) | 5655 i < b.cidx(j+1); i++) |
5656 { | 5656 { |
5657 Complex c = b.data(i); | 5657 Complex c = b.data(i); |
5658 Bx[b.ridx(i)] = std::real (c); | 5658 Bx[b.ridx(i)] = std::real (c); |
5659 Bz[b.ridx(i)] = std::imag (c); | 5659 Bz[b.ridx(i)] = std::imag (c); |
5660 } | 5660 } |
5661 | 5661 |
5662 F77_XFCN (dgbtrs, DGBTRS, | 5662 F77_XFCN (dgbtrs, DGBTRS, |
5663 (F77_CONST_CHAR_ARG2 (&job, 1), | 5663 (F77_CONST_CHAR_ARG2 (&job, 1), |
5664 nr, n_lower, n_upper, 1, tmp_data, | 5664 nr, n_lower, n_upper, 1, tmp_data, |
5665 ldm, pipvt, Bx, b.rows (), err | 5665 ldm, pipvt, Bx, b.rows (), err |
5666 F77_CHAR_ARG_LEN (1))); | 5666 F77_CHAR_ARG_LEN (1))); |
5667 | 5667 |
5668 F77_XFCN (dgbtrs, DGBTRS, | 5668 F77_XFCN (dgbtrs, DGBTRS, |
5669 (F77_CONST_CHAR_ARG2 (&job, 1), | 5669 (F77_CONST_CHAR_ARG2 (&job, 1), |
5670 nr, n_lower, n_upper, 1, tmp_data, | 5670 nr, n_lower, n_upper, 1, tmp_data, |
5671 ldm, pipvt, Bz, b.rows (), err | 5671 ldm, pipvt, Bz, b.rows (), err |
5672 F77_CHAR_ARG_LEN (1))); | 5672 F77_CHAR_ARG_LEN (1))); |
5673 | 5673 |
5674 // Count non-zeros in work vector and adjust | 5674 // Count non-zeros in work vector and adjust |
5675 // space in retval if needed | 5675 // space in retval if needed |
5676 octave_idx_type new_nnz = 0; | 5676 octave_idx_type new_nnz = 0; |
5677 for (octave_idx_type i = 0; i < nr; i++) | 5677 for (octave_idx_type i = 0; i < nr; i++) |
5678 if (Bx[i] != 0. || Bz[i] != 0.) | 5678 if (Bx[i] != 0. || Bz[i] != 0.) |
5679 new_nnz++; | 5679 new_nnz++; |
5688 | 5688 |
5689 for (octave_idx_type i = 0; i < nr; i++) | 5689 for (octave_idx_type i = 0; i < nr; i++) |
5690 if (Bx[i] != 0. || Bz[i] != 0.) | 5690 if (Bx[i] != 0. || Bz[i] != 0.) |
5691 { | 5691 { |
5692 retval.xridx(ii) = i; | 5692 retval.xridx(ii) = i; |
5693 retval.xdata(ii++) = | 5693 retval.xdata(ii++) = |
5694 Complex (Bx[i], Bz[i]); | 5694 Complex (Bx[i], Bz[i]); |
5695 } | 5695 } |
5696 retval.xcidx(j+1) = ii; | 5696 retval.xcidx(j+1) = ii; |
5697 } | 5697 } |
5698 | 5698 |
5701 } | 5701 } |
5702 } | 5702 } |
5703 else if (typ != MatrixType::Banded_Hermitian) | 5703 else if (typ != MatrixType::Banded_Hermitian) |
5704 (*current_liboctave_error_handler) ("incorrect matrix type"); | 5704 (*current_liboctave_error_handler) ("incorrect matrix type"); |
5705 } | 5705 } |
5706 | 5706 |
5707 return retval; | 5707 return retval; |
5708 } | 5708 } |
5709 | 5709 |
5710 void * | 5710 void * |
5711 SparseMatrix::factorize (octave_idx_type& err, double &rcond, Matrix &Control, | 5711 SparseMatrix::factorize (octave_idx_type& err, double &rcond, Matrix &Control, |
5753 int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 0, | 5753 int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 0, |
5754 &Symbolic, control, info); | 5754 &Symbolic, control, info); |
5755 | 5755 |
5756 if (status < 0) | 5756 if (status < 0) |
5757 { | 5757 { |
5758 (*current_liboctave_error_handler) | 5758 (*current_liboctave_error_handler) |
5759 ("SparseMatrix::solve symbolic factorization failed"); | 5759 ("SparseMatrix::solve symbolic factorization failed"); |
5760 err = -1; | 5760 err = -1; |
5761 | 5761 |
5762 UMFPACK_DNAME (report_status) (control, status); | 5762 UMFPACK_DNAME (report_status) (control, status); |
5763 UMFPACK_DNAME (report_info) (control, info); | 5763 UMFPACK_DNAME (report_info) (control, info); |
5776 rcond = Info (UMFPACK_RCOND); | 5776 rcond = Info (UMFPACK_RCOND); |
5777 else | 5777 else |
5778 rcond = 1.; | 5778 rcond = 1.; |
5779 volatile double rcond_plus_one = rcond + 1.0; | 5779 volatile double rcond_plus_one = rcond + 1.0; |
5780 | 5780 |
5781 if (status == UMFPACK_WARNING_singular_matrix || | 5781 if (status == UMFPACK_WARNING_singular_matrix || |
5782 rcond_plus_one == 1.0 || xisnan (rcond)) | 5782 rcond_plus_one == 1.0 || xisnan (rcond)) |
5783 { | 5783 { |
5784 UMFPACK_DNAME (report_numeric) (Numeric, control); | 5784 UMFPACK_DNAME (report_numeric) (Numeric, control); |
5785 | 5785 |
5786 err = -2; | 5786 err = -2; |
5793 rcond); | 5793 rcond); |
5794 | 5794 |
5795 } | 5795 } |
5796 else if (status < 0) | 5796 else if (status < 0) |
5797 { | 5797 { |
5798 (*current_liboctave_error_handler) | 5798 (*current_liboctave_error_handler) |
5799 ("SparseMatrix::solve numeric factorization failed"); | 5799 ("SparseMatrix::solve numeric factorization failed"); |
5800 | 5800 |
5801 UMFPACK_DNAME (report_status) (control, status); | 5801 UMFPACK_DNAME (report_status) (control, status); |
5802 UMFPACK_DNAME (report_info) (control, info); | 5802 UMFPACK_DNAME (report_info) (control, info); |
5803 | 5803 |
5804 err = -1; | 5804 err = -1; |
5805 } | 5805 } |
5806 else | 5806 else |
5807 { | 5807 { |
5808 UMFPACK_DNAME (report_numeric) (Numeric, control); | 5808 UMFPACK_DNAME (report_numeric) (Numeric, control); |
5819 return Numeric; | 5819 return Numeric; |
5820 } | 5820 } |
5821 | 5821 |
5822 Matrix | 5822 Matrix |
5823 SparseMatrix::fsolve (MatrixType &mattype, const Matrix& b, | 5823 SparseMatrix::fsolve (MatrixType &mattype, const Matrix& b, |
5824 octave_idx_type& err, double& rcond, | 5824 octave_idx_type& err, double& rcond, |
5825 solve_singularity_handler sing_handler, | 5825 solve_singularity_handler sing_handler, |
5826 bool calc_cond) const | 5826 bool calc_cond) const |
5827 { | 5827 { |
5828 Matrix retval; | 5828 Matrix retval; |
5829 | 5829 |
5942 } | 5942 } |
5943 else | 5943 else |
5944 (*current_liboctave_error_handler) | 5944 (*current_liboctave_error_handler) |
5945 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", | 5945 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", |
5946 rcond); | 5946 rcond); |
5947 | 5947 |
5948 return retval; | 5948 return retval; |
5949 } | 5949 } |
5950 | 5950 |
5951 cholmod_dense *X; | 5951 cholmod_dense *X; |
5952 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 5952 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
5980 | 5980 |
5981 if (typ == MatrixType::Full) | 5981 if (typ == MatrixType::Full) |
5982 { | 5982 { |
5983 #ifdef HAVE_UMFPACK | 5983 #ifdef HAVE_UMFPACK |
5984 Matrix Control, Info; | 5984 Matrix Control, Info; |
5985 void *Numeric = | 5985 void *Numeric = |
5986 factorize (err, rcond, Control, Info, sing_handler, calc_cond); | 5986 factorize (err, rcond, Control, Info, sing_handler, calc_cond); |
5987 | 5987 |
5988 if (err == 0) | 5988 if (err == 0) |
5989 { | 5989 { |
5990 const double *Bx = b.fortran_vec (); | 5990 const double *Bx = b.fortran_vec (); |
5999 const octave_idx_type *Ai = ridx (); | 5999 const octave_idx_type *Ai = ridx (); |
6000 const double *Ax = data (); | 6000 const double *Ax = data (); |
6001 | 6001 |
6002 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) | 6002 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) |
6003 { | 6003 { |
6004 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, | 6004 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, |
6005 Ai, Ax, &result[iidx], &Bx[iidx], | 6005 Ai, Ax, &result[iidx], &Bx[iidx], |
6006 Numeric, control, info); | 6006 Numeric, control, info); |
6007 if (status < 0) | 6007 if (status < 0) |
6008 { | 6008 { |
6009 (*current_liboctave_error_handler) | 6009 (*current_liboctave_error_handler) |
6010 ("SparseMatrix::solve solve failed"); | 6010 ("SparseMatrix::solve solve failed"); |
6011 | 6011 |
6012 UMFPACK_DNAME (report_status) (control, status); | 6012 UMFPACK_DNAME (report_status) (control, status); |
6013 | 6013 |
6014 err = -1; | 6014 err = -1; |
6015 | 6015 |
6016 break; | 6016 break; |
6017 } | 6017 } |
6018 } | 6018 } |
6019 | 6019 |
6020 UMFPACK_DNAME (report_info) (control, info); | 6020 UMFPACK_DNAME (report_info) (control, info); |
6021 | 6021 |
6022 UMFPACK_DNAME (free_numeric) (&Numeric); | 6022 UMFPACK_DNAME (free_numeric) (&Numeric); |
6023 } | 6023 } |
6024 else | 6024 else |
6025 mattype.mark_as_rectangular (); | 6025 mattype.mark_as_rectangular (); |
6026 | 6026 |
6029 #endif | 6029 #endif |
6030 } | 6030 } |
6031 else if (typ != MatrixType::Hermitian) | 6031 else if (typ != MatrixType::Hermitian) |
6032 (*current_liboctave_error_handler) ("incorrect matrix type"); | 6032 (*current_liboctave_error_handler) ("incorrect matrix type"); |
6033 } | 6033 } |
6034 | 6034 |
6035 return retval; | 6035 return retval; |
6036 } | 6036 } |
6037 | 6037 |
6038 SparseMatrix | 6038 SparseMatrix |
6039 SparseMatrix::fsolve (MatrixType &mattype, const SparseMatrix& b, | 6039 SparseMatrix::fsolve (MatrixType &mattype, const SparseMatrix& b, |
6167 } | 6167 } |
6168 else | 6168 else |
6169 (*current_liboctave_error_handler) | 6169 (*current_liboctave_error_handler) |
6170 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", | 6170 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", |
6171 rcond); | 6171 rcond); |
6172 | 6172 |
6173 return retval; | 6173 return retval; |
6174 } | 6174 } |
6175 | 6175 |
6176 cholmod_sparse *X; | 6176 cholmod_sparse *X; |
6177 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 6177 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
6178 X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm); | 6178 X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm); |
6179 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 6179 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
6180 | 6180 |
6181 retval = SparseMatrix (static_cast<octave_idx_type>(X->nrow), | 6181 retval = SparseMatrix (static_cast<octave_idx_type>(X->nrow), |
6182 static_cast<octave_idx_type>(X->ncol), | 6182 static_cast<octave_idx_type>(X->ncol), |
6183 static_cast<octave_idx_type>(X->nzmax)); | 6183 static_cast<octave_idx_type>(X->nzmax)); |
6184 for (octave_idx_type j = 0; | 6184 for (octave_idx_type j = 0; |
6185 j <= static_cast<octave_idx_type>(X->ncol); j++) | 6185 j <= static_cast<octave_idx_type>(X->ncol); j++) |
6186 retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j]; | 6186 retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j]; |
6187 for (octave_idx_type j = 0; | 6187 for (octave_idx_type j = 0; |
6188 j < static_cast<octave_idx_type>(X->nzmax); j++) | 6188 j < static_cast<octave_idx_type>(X->nzmax); j++) |
6189 { | 6189 { |
6190 retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j]; | 6190 retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j]; |
6191 retval.xdata(j) = static_cast<double *>(X->x)[j]; | 6191 retval.xdata(j) = static_cast<double *>(X->x)[j]; |
6192 } | 6192 } |
6210 | 6210 |
6211 if (typ == MatrixType::Full) | 6211 if (typ == MatrixType::Full) |
6212 { | 6212 { |
6213 #ifdef HAVE_UMFPACK | 6213 #ifdef HAVE_UMFPACK |
6214 Matrix Control, Info; | 6214 Matrix Control, Info; |
6215 void *Numeric = factorize (err, rcond, Control, Info, | 6215 void *Numeric = factorize (err, rcond, Control, Info, |
6216 sing_handler, calc_cond); | 6216 sing_handler, calc_cond); |
6217 | 6217 |
6218 if (err == 0) | 6218 if (err == 0) |
6219 { | 6219 { |
6220 octave_idx_type b_nr = b.rows (); | 6220 octave_idx_type b_nr = b.rows (); |
6240 { | 6240 { |
6241 | 6241 |
6242 for (octave_idx_type i = 0; i < b_nr; i++) | 6242 for (octave_idx_type i = 0; i < b_nr; i++) |
6243 Bx[i] = b.elem (i, j); | 6243 Bx[i] = b.elem (i, j); |
6244 | 6244 |
6245 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, | 6245 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, |
6246 Ai, Ax, Xx, Bx, Numeric, control, | 6246 Ai, Ax, Xx, Bx, Numeric, control, |
6247 info); | 6247 info); |
6248 if (status < 0) | 6248 if (status < 0) |
6249 { | 6249 { |
6250 (*current_liboctave_error_handler) | 6250 (*current_liboctave_error_handler) |
6251 ("SparseMatrix::solve solve failed"); | 6251 ("SparseMatrix::solve solve failed"); |
6252 | 6252 |
6253 UMFPACK_DNAME (report_status) (control, status); | 6253 UMFPACK_DNAME (report_status) (control, status); |
6254 | 6254 |
6255 err = -1; | 6255 err = -1; |
6256 | 6256 |
6257 break; | 6257 break; |
6258 } | 6258 } |
6259 | 6259 |
6260 for (octave_idx_type i = 0; i < b_nr; i++) | 6260 for (octave_idx_type i = 0; i < b_nr; i++) |
6261 { | 6261 { |
6262 double tmp = Xx[i]; | 6262 double tmp = Xx[i]; |
6263 if (tmp != 0.0) | 6263 if (tmp != 0.0) |
6264 { | 6264 { |
6291 #endif | 6291 #endif |
6292 } | 6292 } |
6293 else if (typ != MatrixType::Hermitian) | 6293 else if (typ != MatrixType::Hermitian) |
6294 (*current_liboctave_error_handler) ("incorrect matrix type"); | 6294 (*current_liboctave_error_handler) ("incorrect matrix type"); |
6295 } | 6295 } |
6296 | 6296 |
6297 return retval; | 6297 return retval; |
6298 } | 6298 } |
6299 | 6299 |
6300 ComplexMatrix | 6300 ComplexMatrix |
6301 SparseMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, | 6301 SparseMatrix::fsolve (MatrixType &mattype, const ComplexMatrix& b, |
6302 octave_idx_type& err, double& rcond, | 6302 octave_idx_type& err, double& rcond, |
6303 solve_singularity_handler sing_handler, | 6303 solve_singularity_handler sing_handler, |
6304 bool calc_cond) const | 6304 bool calc_cond) const |
6305 { | 6305 { |
6306 ComplexMatrix retval; | 6306 ComplexMatrix retval; |
6419 } | 6419 } |
6420 else | 6420 else |
6421 (*current_liboctave_error_handler) | 6421 (*current_liboctave_error_handler) |
6422 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", | 6422 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", |
6423 rcond); | 6423 rcond); |
6424 | 6424 |
6425 return retval; | 6425 return retval; |
6426 } | 6426 } |
6427 | 6427 |
6428 cholmod_dense *X; | 6428 cholmod_dense *X; |
6429 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 6429 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
6457 | 6457 |
6458 if (typ == MatrixType::Full) | 6458 if (typ == MatrixType::Full) |
6459 { | 6459 { |
6460 #ifdef HAVE_UMFPACK | 6460 #ifdef HAVE_UMFPACK |
6461 Matrix Control, Info; | 6461 Matrix Control, Info; |
6462 void *Numeric = factorize (err, rcond, Control, Info, | 6462 void *Numeric = factorize (err, rcond, Control, Info, |
6463 sing_handler, calc_cond); | 6463 sing_handler, calc_cond); |
6464 | 6464 |
6465 if (err == 0) | 6465 if (err == 0) |
6466 { | 6466 { |
6467 octave_idx_type b_nr = b.rows (); | 6467 octave_idx_type b_nr = b.rows (); |
6478 | 6478 |
6479 retval.resize (b_nr, b_nc); | 6479 retval.resize (b_nr, b_nc); |
6480 | 6480 |
6481 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); | 6481 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); |
6482 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); | 6482 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); |
6483 | 6483 |
6484 for (octave_idx_type j = 0; j < b_nc; j++) | 6484 for (octave_idx_type j = 0; j < b_nc; j++) |
6485 { | 6485 { |
6486 for (octave_idx_type i = 0; i < b_nr; i++) | 6486 for (octave_idx_type i = 0; i < b_nr; i++) |
6487 { | 6487 { |
6488 Complex c = b (i,j); | 6488 Complex c = b (i,j); |
6489 Bx[i] = std::real (c); | 6489 Bx[i] = std::real (c); |
6490 Bz[i] = std::imag (c); | 6490 Bz[i] = std::imag (c); |
6491 } | 6491 } |
6492 | 6492 |
6493 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, | 6493 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, |
6494 Ai, Ax, Xx, Bx, Numeric, control, | 6494 Ai, Ax, Xx, Bx, Numeric, control, |
6495 info); | 6495 info); |
6496 int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, | 6496 int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, |
6497 Ap, Ai, Ax, Xz, Bz, Numeric, | 6497 Ap, Ai, Ax, Xz, Bz, Numeric, |
6498 control, info) ; | 6498 control, info) ; |
6499 | 6499 |
6500 if (status < 0 || status2 < 0) | 6500 if (status < 0 || status2 < 0) |
6501 { | 6501 { |
6502 (*current_liboctave_error_handler) | 6502 (*current_liboctave_error_handler) |
6503 ("SparseMatrix::solve solve failed"); | 6503 ("SparseMatrix::solve solve failed"); |
6504 | 6504 |
6505 UMFPACK_DNAME (report_status) (control, status); | 6505 UMFPACK_DNAME (report_status) (control, status); |
6506 | 6506 |
6507 err = -1; | 6507 err = -1; |
6508 | 6508 |
6509 break; | 6509 break; |
6510 } | 6510 } |
6511 | 6511 |
6525 #endif | 6525 #endif |
6526 } | 6526 } |
6527 else if (typ != MatrixType::Hermitian) | 6527 else if (typ != MatrixType::Hermitian) |
6528 (*current_liboctave_error_handler) ("incorrect matrix type"); | 6528 (*current_liboctave_error_handler) ("incorrect matrix type"); |
6529 } | 6529 } |
6530 | 6530 |
6531 return retval; | 6531 return retval; |
6532 } | 6532 } |
6533 | 6533 |
6534 SparseComplexMatrix | 6534 SparseComplexMatrix |
6535 SparseMatrix::fsolve (MatrixType &mattype, const SparseComplexMatrix& b, | 6535 SparseMatrix::fsolve (MatrixType &mattype, const SparseComplexMatrix& b, |
6536 octave_idx_type& err, double& rcond, | 6536 octave_idx_type& err, double& rcond, |
6537 solve_singularity_handler sing_handler, | 6537 solve_singularity_handler sing_handler, |
6538 bool calc_cond) const | 6538 bool calc_cond) const |
6539 { | 6539 { |
6540 SparseComplexMatrix retval; | 6540 SparseComplexMatrix retval; |
6663 } | 6663 } |
6664 else | 6664 else |
6665 (*current_liboctave_error_handler) | 6665 (*current_liboctave_error_handler) |
6666 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", | 6666 ("SparseMatrix::solve matrix singular to machine precision, rcond = %g", |
6667 rcond); | 6667 rcond); |
6668 | 6668 |
6669 return retval; | 6669 return retval; |
6670 } | 6670 } |
6671 | 6671 |
6672 cholmod_sparse *X; | 6672 cholmod_sparse *X; |
6673 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 6673 BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
6674 X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm); | 6674 X = CHOLMOD_NAME(spsolve) (CHOLMOD_A, L, B, cm); |
6675 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; | 6675 END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; |
6676 | 6676 |
6677 retval = SparseComplexMatrix | 6677 retval = SparseComplexMatrix |
6678 (static_cast<octave_idx_type>(X->nrow), | 6678 (static_cast<octave_idx_type>(X->nrow), |
6679 static_cast<octave_idx_type>(X->ncol), | 6679 static_cast<octave_idx_type>(X->ncol), |
6680 static_cast<octave_idx_type>(X->nzmax)); | 6680 static_cast<octave_idx_type>(X->nzmax)); |
6681 for (octave_idx_type j = 0; | 6681 for (octave_idx_type j = 0; |
6682 j <= static_cast<octave_idx_type>(X->ncol); j++) | 6682 j <= static_cast<octave_idx_type>(X->ncol); j++) |
6683 retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j]; | 6683 retval.xcidx(j) = static_cast<octave_idx_type *>(X->p)[j]; |
6684 for (octave_idx_type j = 0; | 6684 for (octave_idx_type j = 0; |
6685 j < static_cast<octave_idx_type>(X->nzmax); j++) | 6685 j < static_cast<octave_idx_type>(X->nzmax); j++) |
6686 { | 6686 { |
6687 retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j]; | 6687 retval.xridx(j) = static_cast<octave_idx_type *>(X->i)[j]; |
6688 retval.xdata(j) = static_cast<Complex *>(X->x)[j]; | 6688 retval.xdata(j) = static_cast<Complex *>(X->x)[j]; |
6689 } | 6689 } |
6707 | 6707 |
6708 if (typ == MatrixType::Full) | 6708 if (typ == MatrixType::Full) |
6709 { | 6709 { |
6710 #ifdef HAVE_UMFPACK | 6710 #ifdef HAVE_UMFPACK |
6711 Matrix Control, Info; | 6711 Matrix Control, Info; |
6712 void *Numeric = factorize (err, rcond, Control, Info, | 6712 void *Numeric = factorize (err, rcond, Control, Info, |
6713 sing_handler, calc_cond); | 6713 sing_handler, calc_cond); |
6714 | 6714 |
6715 if (err == 0) | 6715 if (err == 0) |
6716 { | 6716 { |
6717 octave_idx_type b_nr = b.rows (); | 6717 octave_idx_type b_nr = b.rows (); |
6732 octave_idx_type ii = 0; | 6732 octave_idx_type ii = 0; |
6733 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); | 6733 retval = SparseComplexMatrix (b_nr, b_nc, x_nz); |
6734 | 6734 |
6735 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); | 6735 OCTAVE_LOCAL_BUFFER (double, Xx, b_nr); |
6736 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); | 6736 OCTAVE_LOCAL_BUFFER (double, Xz, b_nr); |
6737 | 6737 |
6738 retval.xcidx(0) = 0; | 6738 retval.xcidx(0) = 0; |
6739 for (octave_idx_type j = 0; j < b_nc; j++) | 6739 for (octave_idx_type j = 0; j < b_nc; j++) |
6740 { | 6740 { |
6741 for (octave_idx_type i = 0; i < b_nr; i++) | 6741 for (octave_idx_type i = 0; i < b_nr; i++) |
6742 { | 6742 { |
6744 Bx[i] = std::real (c); | 6744 Bx[i] = std::real (c); |
6745 Bz[i] = std::imag (c); | 6745 Bz[i] = std::imag (c); |
6746 } | 6746 } |
6747 | 6747 |
6748 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, | 6748 status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, |
6749 Ai, Ax, Xx, Bx, Numeric, control, | 6749 Ai, Ax, Xx, Bx, Numeric, control, |
6750 info); | 6750 info); |
6751 int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, | 6751 int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, |
6752 Ap, Ai, Ax, Xz, Bz, Numeric, | 6752 Ap, Ai, Ax, Xz, Bz, Numeric, |
6753 control, info) ; | 6753 control, info) ; |
6754 | 6754 |
6755 if (status < 0 || status2 < 0) | 6755 if (status < 0 || status2 < 0) |
6756 { | 6756 { |
6757 (*current_liboctave_error_handler) | 6757 (*current_liboctave_error_handler) |
6758 ("SparseMatrix::solve solve failed"); | 6758 ("SparseMatrix::solve solve failed"); |
6759 | 6759 |
6760 UMFPACK_DNAME (report_status) (control, status); | 6760 UMFPACK_DNAME (report_status) (control, status); |
6761 | 6761 |
6762 err = -1; | 6762 err = -1; |
6763 | 6763 |
6764 break; | 6764 break; |
6765 } | 6765 } |
6766 | 6766 |
6797 #endif | 6797 #endif |
6798 } | 6798 } |
6799 else if (typ != MatrixType::Hermitian) | 6799 else if (typ != MatrixType::Hermitian) |
6800 (*current_liboctave_error_handler) ("incorrect matrix type"); | 6800 (*current_liboctave_error_handler) ("incorrect matrix type"); |
6801 } | 6801 } |
6802 | 6802 |
6803 return retval; | 6803 return retval; |
6804 } | 6804 } |
6805 | 6805 |
6806 Matrix | 6806 Matrix |
6807 SparseMatrix::solve (MatrixType &mattype, const Matrix& b) const | 6807 SparseMatrix::solve (MatrixType &mattype, const Matrix& b) const |
6810 double rcond; | 6810 double rcond; |
6811 return solve (mattype, b, info, rcond, 0); | 6811 return solve (mattype, b, info, rcond, 0); |
6812 } | 6812 } |
6813 | 6813 |
6814 Matrix | 6814 Matrix |
6815 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, | 6815 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, |
6816 octave_idx_type& info) const | 6816 octave_idx_type& info) const |
6817 { | 6817 { |
6818 double rcond; | 6818 double rcond; |
6819 return solve (mattype, b, info, rcond, 0); | 6819 return solve (mattype, b, info, rcond, 0); |
6820 } | 6820 } |
6821 | 6821 |
6822 Matrix | 6822 Matrix |
6823 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, | 6823 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& info, |
6824 double& rcond) const | 6824 double& rcond) const |
6825 { | 6825 { |
6826 return solve (mattype, b, info, rcond, 0); | 6826 return solve (mattype, b, info, rcond, 0); |
6827 } | 6827 } |
6828 | 6828 |
6829 Matrix | 6829 Matrix |
6830 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& err, | 6830 SparseMatrix::solve (MatrixType &mattype, const Matrix& b, octave_idx_type& err, |
6831 double& rcond, solve_singularity_handler sing_handler, | 6831 double& rcond, solve_singularity_handler sing_handler, |
6832 bool singular_fallback) const | 6832 bool singular_fallback) const |
6833 { | 6833 { |
6834 Matrix retval; | 6834 Matrix retval; |
6835 int typ = mattype.type (false); | 6835 int typ = mattype.type (false); |
6844 retval = utsolve (mattype, b, err, rcond, sing_handler, false); | 6844 retval = utsolve (mattype, b, err, rcond, sing_handler, false); |
6845 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | 6845 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
6846 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); | 6846 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); |
6847 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) | 6847 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) |
6848 retval = bsolve (mattype, b, err, rcond, sing_handler, false); | 6848 retval = bsolve (mattype, b, err, rcond, sing_handler, false); |
6849 else if (typ == MatrixType::Tridiagonal || | 6849 else if (typ == MatrixType::Tridiagonal || |
6850 typ == MatrixType::Tridiagonal_Hermitian) | 6850 typ == MatrixType::Tridiagonal_Hermitian) |
6851 retval = trisolve (mattype, b, err, rcond, sing_handler, false); | 6851 retval = trisolve (mattype, b, err, rcond, sing_handler, false); |
6852 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | 6852 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
6853 retval = fsolve (mattype, b, err, rcond, sing_handler, true); | 6853 retval = fsolve (mattype, b, err, rcond, sing_handler, true); |
6854 else if (typ != MatrixType::Rectangular) | 6854 else if (typ != MatrixType::Rectangular) |
6878 double rcond; | 6878 double rcond; |
6879 return solve (mattype, b, info, rcond, 0); | 6879 return solve (mattype, b, info, rcond, 0); |
6880 } | 6880 } |
6881 | 6881 |
6882 SparseMatrix | 6882 SparseMatrix |
6883 SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, | 6883 SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, |
6884 octave_idx_type& info) const | 6884 octave_idx_type& info) const |
6885 { | 6885 { |
6886 double rcond; | 6886 double rcond; |
6887 return solve (mattype, b, info, rcond, 0); | 6887 return solve (mattype, b, info, rcond, 0); |
6888 } | 6888 } |
6893 { | 6893 { |
6894 return solve (mattype, b, info, rcond, 0); | 6894 return solve (mattype, b, info, rcond, 0); |
6895 } | 6895 } |
6896 | 6896 |
6897 SparseMatrix | 6897 SparseMatrix |
6898 SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, | 6898 SparseMatrix::solve (MatrixType &mattype, const SparseMatrix& b, |
6899 octave_idx_type& err, double& rcond, | 6899 octave_idx_type& err, double& rcond, |
6900 solve_singularity_handler sing_handler, | 6900 solve_singularity_handler sing_handler, |
6901 bool singular_fallback) const | 6901 bool singular_fallback) const |
6902 { | 6902 { |
6903 SparseMatrix retval; | 6903 SparseMatrix retval; |
6912 retval = utsolve (mattype, b, err, rcond, sing_handler, false); | 6912 retval = utsolve (mattype, b, err, rcond, sing_handler, false); |
6913 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | 6913 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
6914 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); | 6914 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); |
6915 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) | 6915 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) |
6916 retval = bsolve (mattype, b, err, rcond, sing_handler, false); | 6916 retval = bsolve (mattype, b, err, rcond, sing_handler, false); |
6917 else if (typ == MatrixType::Tridiagonal || | 6917 else if (typ == MatrixType::Tridiagonal || |
6918 typ == MatrixType::Tridiagonal_Hermitian) | 6918 typ == MatrixType::Tridiagonal_Hermitian) |
6919 retval = trisolve (mattype, b, err, rcond, sing_handler, false); | 6919 retval = trisolve (mattype, b, err, rcond, sing_handler, false); |
6920 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | 6920 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
6921 retval = fsolve (mattype, b, err, rcond, sing_handler, true); | 6921 retval = fsolve (mattype, b, err, rcond, sing_handler, true); |
6922 else if (typ != MatrixType::Rectangular) | 6922 else if (typ != MatrixType::Rectangular) |
6929 { | 6929 { |
6930 rcond = 1.; | 6930 rcond = 1.; |
6931 #ifdef USE_QRSOLVE | 6931 #ifdef USE_QRSOLVE |
6932 retval = qrsolve (*this, b, err); | 6932 retval = qrsolve (*this, b, err); |
6933 #else | 6933 #else |
6934 retval = dmsolve<SparseMatrix, SparseMatrix, | 6934 retval = dmsolve<SparseMatrix, SparseMatrix, |
6935 SparseMatrix> (*this, b, err); | 6935 SparseMatrix> (*this, b, err); |
6936 #endif | 6936 #endif |
6937 } | 6937 } |
6938 | 6938 |
6939 return retval; | 6939 return retval; |
6946 double rcond; | 6946 double rcond; |
6947 return solve (mattype, b, info, rcond, 0); | 6947 return solve (mattype, b, info, rcond, 0); |
6948 } | 6948 } |
6949 | 6949 |
6950 ComplexMatrix | 6950 ComplexMatrix |
6951 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, | 6951 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, |
6952 octave_idx_type& info) const | 6952 octave_idx_type& info) const |
6953 { | 6953 { |
6954 double rcond; | 6954 double rcond; |
6955 return solve (mattype, b, info, rcond, 0); | 6955 return solve (mattype, b, info, rcond, 0); |
6956 } | 6956 } |
6957 | 6957 |
6958 ComplexMatrix | 6958 ComplexMatrix |
6959 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, | 6959 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, |
6960 octave_idx_type& info, double& rcond) const | 6960 octave_idx_type& info, double& rcond) const |
6961 { | 6961 { |
6962 return solve (mattype, b, info, rcond, 0); | 6962 return solve (mattype, b, info, rcond, 0); |
6963 } | 6963 } |
6964 | 6964 |
6965 ComplexMatrix | 6965 ComplexMatrix |
6966 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, | 6966 SparseMatrix::solve (MatrixType &mattype, const ComplexMatrix& b, |
6967 octave_idx_type& err, double& rcond, | 6967 octave_idx_type& err, double& rcond, |
6968 solve_singularity_handler sing_handler, | 6968 solve_singularity_handler sing_handler, |
6969 bool singular_fallback) const | 6969 bool singular_fallback) const |
6970 { | 6970 { |
6971 ComplexMatrix retval; | 6971 ComplexMatrix retval; |
6972 int typ = mattype.type (false); | 6972 int typ = mattype.type (false); |
6980 retval = utsolve (mattype, b, err, rcond, sing_handler, false); | 6980 retval = utsolve (mattype, b, err, rcond, sing_handler, false); |
6981 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | 6981 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
6982 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); | 6982 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); |
6983 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) | 6983 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) |
6984 retval = bsolve (mattype, b, err, rcond, sing_handler, false); | 6984 retval = bsolve (mattype, b, err, rcond, sing_handler, false); |
6985 else if (typ == MatrixType::Tridiagonal || | 6985 else if (typ == MatrixType::Tridiagonal || |
6986 typ == MatrixType::Tridiagonal_Hermitian) | 6986 typ == MatrixType::Tridiagonal_Hermitian) |
6987 retval = trisolve (mattype, b, err, rcond, sing_handler, false); | 6987 retval = trisolve (mattype, b, err, rcond, sing_handler, false); |
6988 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | 6988 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
6989 retval = fsolve (mattype, b, err, rcond, sing_handler, true); | 6989 retval = fsolve (mattype, b, err, rcond, sing_handler, true); |
6990 else if (typ != MatrixType::Rectangular) | 6990 else if (typ != MatrixType::Rectangular) |
6997 { | 6997 { |
6998 rcond = 1.; | 6998 rcond = 1.; |
6999 #ifdef USE_QRSOLVE | 6999 #ifdef USE_QRSOLVE |
7000 retval = qrsolve (*this, b, err); | 7000 retval = qrsolve (*this, b, err); |
7001 #else | 7001 #else |
7002 retval = dmsolve<ComplexMatrix, SparseMatrix, | 7002 retval = dmsolve<ComplexMatrix, SparseMatrix, |
7003 ComplexMatrix> (*this, b, err); | 7003 ComplexMatrix> (*this, b, err); |
7004 #endif | 7004 #endif |
7005 } | 7005 } |
7006 | 7006 |
7007 return retval; | 7007 return retval; |
7014 double rcond; | 7014 double rcond; |
7015 return solve (mattype, b, info, rcond, 0); | 7015 return solve (mattype, b, info, rcond, 0); |
7016 } | 7016 } |
7017 | 7017 |
7018 SparseComplexMatrix | 7018 SparseComplexMatrix |
7019 SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, | 7019 SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, |
7020 octave_idx_type& info) const | 7020 octave_idx_type& info) const |
7021 { | 7021 { |
7022 double rcond; | 7022 double rcond; |
7023 return solve (mattype, b, info, rcond, 0); | 7023 return solve (mattype, b, info, rcond, 0); |
7024 } | 7024 } |
7029 { | 7029 { |
7030 return solve (mattype, b, info, rcond, 0); | 7030 return solve (mattype, b, info, rcond, 0); |
7031 } | 7031 } |
7032 | 7032 |
7033 SparseComplexMatrix | 7033 SparseComplexMatrix |
7034 SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, | 7034 SparseMatrix::solve (MatrixType &mattype, const SparseComplexMatrix& b, |
7035 octave_idx_type& err, double& rcond, | 7035 octave_idx_type& err, double& rcond, |
7036 solve_singularity_handler sing_handler, | 7036 solve_singularity_handler sing_handler, |
7037 bool singular_fallback) const | 7037 bool singular_fallback) const |
7038 { | 7038 { |
7039 SparseComplexMatrix retval; | 7039 SparseComplexMatrix retval; |
7048 retval = utsolve (mattype, b, err, rcond, sing_handler, false); | 7048 retval = utsolve (mattype, b, err, rcond, sing_handler, false); |
7049 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) | 7049 else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower) |
7050 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); | 7050 retval = ltsolve (mattype, b, err, rcond, sing_handler, false); |
7051 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) | 7051 else if (typ == MatrixType::Banded || typ == MatrixType::Banded_Hermitian) |
7052 retval = bsolve (mattype, b, err, rcond, sing_handler, false); | 7052 retval = bsolve (mattype, b, err, rcond, sing_handler, false); |
7053 else if (typ == MatrixType::Tridiagonal || | 7053 else if (typ == MatrixType::Tridiagonal || |
7054 typ == MatrixType::Tridiagonal_Hermitian) | 7054 typ == MatrixType::Tridiagonal_Hermitian) |
7055 retval = trisolve (mattype, b, err, rcond, sing_handler, false); | 7055 retval = trisolve (mattype, b, err, rcond, sing_handler, false); |
7056 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) | 7056 else if (typ == MatrixType::Full || typ == MatrixType::Hermitian) |
7057 retval = fsolve (mattype, b, err, rcond, sing_handler, true); | 7057 retval = fsolve (mattype, b, err, rcond, sing_handler, true); |
7058 else if (typ != MatrixType::Rectangular) | 7058 else if (typ != MatrixType::Rectangular) |
7065 { | 7065 { |
7066 rcond = 1.; | 7066 rcond = 1.; |
7067 #ifdef USE_QRSOLVE | 7067 #ifdef USE_QRSOLVE |
7068 retval = qrsolve (*this, b, err); | 7068 retval = qrsolve (*this, b, err); |
7069 #else | 7069 #else |
7070 retval = dmsolve<SparseComplexMatrix, SparseMatrix, | 7070 retval = dmsolve<SparseComplexMatrix, SparseMatrix, |
7071 SparseComplexMatrix> (*this, b, err); | 7071 SparseComplexMatrix> (*this, b, err); |
7072 #endif | 7072 #endif |
7073 } | 7073 } |
7074 | 7074 |
7075 return retval; | 7075 return retval; |
7117 double rcond; | 7117 double rcond; |
7118 return solve (mattype, b, info, rcond, 0); | 7118 return solve (mattype, b, info, rcond, 0); |
7119 } | 7119 } |
7120 | 7120 |
7121 ComplexColumnVector | 7121 ComplexColumnVector |
7122 SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b, octave_idx_type& info, | 7122 SparseMatrix::solve (MatrixType &mattype, const ComplexColumnVector& b, octave_idx_type& info, |
7123 double& rcond) const | 7123 double& rcond) const |
7124 { | 7124 { |
7125 return solve (mattype, b, info, rcond, 0); | 7125 return solve (mattype, b, info, rcond, 0); |
7126 } | 7126 } |
7127 | 7127 |
7147 double rcond; | 7147 double rcond; |
7148 return solve (b, info, rcond, 0); | 7148 return solve (b, info, rcond, 0); |
7149 } | 7149 } |
7150 | 7150 |
7151 Matrix | 7151 Matrix |
7152 SparseMatrix::solve (const Matrix& b, octave_idx_type& info, | 7152 SparseMatrix::solve (const Matrix& b, octave_idx_type& info, |
7153 double& rcond) const | 7153 double& rcond) const |
7154 { | 7154 { |
7155 return solve (b, info, rcond, 0); | 7155 return solve (b, info, rcond, 0); |
7156 } | 7156 } |
7157 | 7157 |
7158 Matrix | 7158 Matrix |
7159 SparseMatrix::solve (const Matrix& b, octave_idx_type& err, | 7159 SparseMatrix::solve (const Matrix& b, octave_idx_type& err, |
7160 double& rcond, | 7160 double& rcond, |
7161 solve_singularity_handler sing_handler) const | 7161 solve_singularity_handler sing_handler) const |
7162 { | 7162 { |
7163 MatrixType mattype (*this); | 7163 MatrixType mattype (*this); |
7164 return solve (mattype, b, err, rcond, sing_handler); | 7164 return solve (mattype, b, err, rcond, sing_handler); |
7165 } | 7165 } |
7171 double rcond; | 7171 double rcond; |
7172 return solve (b, info, rcond, 0); | 7172 return solve (b, info, rcond, 0); |
7173 } | 7173 } |
7174 | 7174 |
7175 SparseMatrix | 7175 SparseMatrix |
7176 SparseMatrix::solve (const SparseMatrix& b, | 7176 SparseMatrix::solve (const SparseMatrix& b, |
7177 octave_idx_type& info) const | 7177 octave_idx_type& info) const |
7178 { | 7178 { |
7179 double rcond; | 7179 double rcond; |
7180 return solve (b, info, rcond, 0); | 7180 return solve (b, info, rcond, 0); |
7181 } | 7181 } |
7186 { | 7186 { |
7187 return solve (b, info, rcond, 0); | 7187 return solve (b, info, rcond, 0); |
7188 } | 7188 } |
7189 | 7189 |
7190 SparseMatrix | 7190 SparseMatrix |
7191 SparseMatrix::solve (const SparseMatrix& b, | 7191 SparseMatrix::solve (const SparseMatrix& b, |
7192 octave_idx_type& err, double& rcond, | 7192 octave_idx_type& err, double& rcond, |
7193 solve_singularity_handler sing_handler) const | 7193 solve_singularity_handler sing_handler) const |
7194 { | 7194 { |
7195 MatrixType mattype (*this); | 7195 MatrixType mattype (*this); |
7196 return solve (mattype, b, err, rcond, sing_handler); | 7196 return solve (mattype, b, err, rcond, sing_handler); |
7197 } | 7197 } |
7198 | 7198 |
7199 ComplexMatrix | 7199 ComplexMatrix |
7200 SparseMatrix::solve (const ComplexMatrix& b, | 7200 SparseMatrix::solve (const ComplexMatrix& b, |
7201 octave_idx_type& info) const | 7201 octave_idx_type& info) const |
7202 { | 7202 { |
7203 double rcond; | 7203 double rcond; |
7204 return solve (b, info, rcond, 0); | 7204 return solve (b, info, rcond, 0); |
7205 } | 7205 } |
7206 | 7206 |
7207 ComplexMatrix | 7207 ComplexMatrix |
7208 SparseMatrix::solve (const ComplexMatrix& b, | 7208 SparseMatrix::solve (const ComplexMatrix& b, |
7209 octave_idx_type& info, double& rcond) const | 7209 octave_idx_type& info, double& rcond) const |
7210 { | 7210 { |
7211 return solve (b, info, rcond, 0); | 7211 return solve (b, info, rcond, 0); |
7212 } | 7212 } |
7213 | 7213 |
7214 ComplexMatrix | 7214 ComplexMatrix |
7215 SparseMatrix::solve (const ComplexMatrix& b, | 7215 SparseMatrix::solve (const ComplexMatrix& b, |
7216 octave_idx_type& err, double& rcond, | 7216 octave_idx_type& err, double& rcond, |
7217 solve_singularity_handler sing_handler) const | 7217 solve_singularity_handler sing_handler) const |
7218 { | 7218 { |
7219 MatrixType mattype (*this); | 7219 MatrixType mattype (*this); |
7220 return solve (mattype, b, err, rcond, sing_handler); | 7220 return solve (mattype, b, err, rcond, sing_handler); |
7221 } | 7221 } |
7227 double rcond; | 7227 double rcond; |
7228 return solve (b, info, rcond, 0); | 7228 return solve (b, info, rcond, 0); |
7229 } | 7229 } |
7230 | 7230 |
7231 SparseComplexMatrix | 7231 SparseComplexMatrix |
7232 SparseMatrix::solve (const SparseComplexMatrix& b, | 7232 SparseMatrix::solve (const SparseComplexMatrix& b, |
7233 octave_idx_type& info) const | 7233 octave_idx_type& info) const |
7234 { | 7234 { |
7235 double rcond; | 7235 double rcond; |
7236 return solve (b, info, rcond, 0); | 7236 return solve (b, info, rcond, 0); |
7237 } | 7237 } |
7242 { | 7242 { |
7243 return solve (b, info, rcond, 0); | 7243 return solve (b, info, rcond, 0); |
7244 } | 7244 } |
7245 | 7245 |
7246 SparseComplexMatrix | 7246 SparseComplexMatrix |
7247 SparseMatrix::solve (const SparseComplexMatrix& b, | 7247 SparseMatrix::solve (const SparseComplexMatrix& b, |
7248 octave_idx_type& err, double& rcond, | 7248 octave_idx_type& err, double& rcond, |
7249 solve_singularity_handler sing_handler) const | 7249 solve_singularity_handler sing_handler) const |
7250 { | 7250 { |
7251 MatrixType mattype (*this); | 7251 MatrixType mattype (*this); |
7252 return solve (mattype, b, err, rcond, sing_handler); | 7252 return solve (mattype, b, err, rcond, sing_handler); |
7294 double rcond; | 7294 double rcond; |
7295 return solve (b, info, rcond, 0); | 7295 return solve (b, info, rcond, 0); |
7296 } | 7296 } |
7297 | 7297 |
7298 ComplexColumnVector | 7298 ComplexColumnVector |
7299 SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, | 7299 SparseMatrix::solve (const ComplexColumnVector& b, octave_idx_type& info, |
7300 double& rcond) const | 7300 double& rcond) const |
7301 { | 7301 { |
7302 return solve (b, info, rcond, 0); | 7302 return solve (b, info, rcond, 0); |
7303 } | 7303 } |
7304 | 7304 |
7452 } | 7452 } |
7453 | 7453 |
7454 return false; | 7454 return false; |
7455 } | 7455 } |
7456 | 7456 |
7457 SparseBoolMatrix | 7457 SparseBoolMatrix |
7458 SparseMatrix::operator ! (void) const | 7458 SparseMatrix::operator ! (void) const |
7459 { | 7459 { |
7460 if (any_element_is_nan ()) | 7460 if (any_element_is_nan ()) |
7461 gripe_nan_to_logical_conversion (); | 7461 gripe_nan_to_logical_conversion (); |
7462 | 7462 |
7463 octave_idx_type nr = rows (); | 7463 octave_idx_type nr = rows (); |
7464 octave_idx_type nc = cols (); | 7464 octave_idx_type nc = cols (); |
7465 octave_idx_type nz1 = nnz (); | 7465 octave_idx_type nz1 = nnz (); |
7466 octave_idx_type nz2 = nr*nc - nz1; | 7466 octave_idx_type nz2 = nr*nc - nz1; |
7467 | 7467 |
7468 SparseBoolMatrix r (nr, nc, nz2); | 7468 SparseBoolMatrix r (nr, nc, nz2); |
7469 | 7469 |
7470 octave_idx_type ii = 0; | 7470 octave_idx_type ii = 0; |
7471 octave_idx_type jj = 0; | 7471 octave_idx_type jj = 0; |
7472 r.cidx (0) = 0; | 7472 r.cidx (0) = 0; |
7473 for (octave_idx_type i = 0; i < nc; i++) | 7473 for (octave_idx_type i = 0; i < nc; i++) |
7474 { | 7474 { |
7520 { | 7520 { |
7521 if ((rows() == 1 && dim == -1) || dim == 1) | 7521 if ((rows() == 1 && dim == -1) || dim == 1) |
7522 return transpose (). prod (0). transpose(); | 7522 return transpose (). prod (0). transpose(); |
7523 else | 7523 else |
7524 { | 7524 { |
7525 SPARSE_REDUCTION_OP (SparseMatrix, double, *=, | 7525 SPARSE_REDUCTION_OP (SparseMatrix, double, *=, |
7526 (cidx(j+1) - cidx(j) < nr ? 0.0 : 1.0), 1.0); | 7526 (cidx(j+1) - cidx(j) < nr ? 0.0 : 1.0), 1.0); |
7527 } | 7527 } |
7528 } | 7528 } |
7529 | 7529 |
7530 SparseMatrix | 7530 SparseMatrix |
7542 | 7542 |
7543 #define COL_EXPR \ | 7543 #define COL_EXPR \ |
7544 double d = data (i); \ | 7544 double d = data (i); \ |
7545 tmp[j] += d * d | 7545 tmp[j] += d * d |
7546 | 7546 |
7547 SPARSE_BASE_REDUCTION_OP (SparseMatrix, double, ROW_EXPR, COL_EXPR, | 7547 SPARSE_BASE_REDUCTION_OP (SparseMatrix, double, ROW_EXPR, COL_EXPR, |
7548 0.0, 0.0); | 7548 0.0, 0.0); |
7549 | 7549 |
7550 #undef ROW_EXPR | 7550 #undef ROW_EXPR |
7551 #undef COL_EXPR | 7551 #undef COL_EXPR |
7552 } | 7552 } |
7604 | 7604 |
7605 return read_sparse_matrix<elt_type> (is, a, octave_read_value<double>); | 7605 return read_sparse_matrix<elt_type> (is, a, octave_read_value<double>); |
7606 } | 7606 } |
7607 | 7607 |
7608 SparseMatrix | 7608 SparseMatrix |
7609 SparseMatrix::squeeze (void) const | 7609 SparseMatrix::squeeze (void) const |
7610 { | 7610 { |
7611 return MSparse<double>::squeeze (); | 7611 return MSparse<double>::squeeze (); |
7612 } | 7612 } |
7613 | 7613 |
7614 SparseMatrix | 7614 SparseMatrix |
7615 SparseMatrix::reshape (const dim_vector& new_dims) const | 7615 SparseMatrix::reshape (const dim_vector& new_dims) const |
7616 { | 7616 { |
7786 SparseMatrix | 7786 SparseMatrix |
7787 min (const SparseMatrix& a, const SparseMatrix& b) | 7787 min (const SparseMatrix& a, const SparseMatrix& b) |
7788 { | 7788 { |
7789 SparseMatrix r; | 7789 SparseMatrix r; |
7790 | 7790 |
7791 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) | 7791 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) |
7792 { | 7792 { |
7793 octave_idx_type a_nr = a.rows (); | 7793 octave_idx_type a_nr = a.rows (); |
7794 octave_idx_type a_nc = a.cols (); | 7794 octave_idx_type a_nc = a.cols (); |
7795 | 7795 |
7796 octave_idx_type b_nr = b.rows (); | 7796 octave_idx_type b_nr = b.rows (); |
7799 if (a_nr != b_nr || a_nc != b_nc) | 7799 if (a_nr != b_nr || a_nc != b_nc) |
7800 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); | 7800 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); |
7801 else | 7801 else |
7802 { | 7802 { |
7803 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); | 7803 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); |
7804 | 7804 |
7805 octave_idx_type jx = 0; | 7805 octave_idx_type jx = 0; |
7806 r.cidx (0) = 0; | 7806 r.cidx (0) = 0; |
7807 for (octave_idx_type i = 0 ; i < a_nc ; i++) | 7807 for (octave_idx_type i = 0 ; i < a_nc ; i++) |
7808 { | 7808 { |
7809 octave_idx_type ja = a.cidx(i); | 7809 octave_idx_type ja = a.cidx(i); |
7810 octave_idx_type ja_max = a.cidx(i+1); | 7810 octave_idx_type ja_max = a.cidx(i+1); |
7811 bool ja_lt_max= ja < ja_max; | 7811 bool ja_lt_max= ja < ja_max; |
7812 | 7812 |
7813 octave_idx_type jb = b.cidx(i); | 7813 octave_idx_type jb = b.cidx(i); |
7814 octave_idx_type jb_max = b.cidx(i+1); | 7814 octave_idx_type jb_max = b.cidx(i+1); |
7815 bool jb_lt_max = jb < jb_max; | 7815 bool jb_lt_max = jb < jb_max; |
7816 | 7816 |
7817 while (ja_lt_max || jb_lt_max ) | 7817 while (ja_lt_max || jb_lt_max ) |
7818 { | 7818 { |
7819 octave_quit (); | 7819 octave_quit (); |
7820 if ((! jb_lt_max) || | 7820 if ((! jb_lt_max) || |
7821 (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) | 7821 (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) |
7858 jb_lt_max= jb < jb_max; | 7858 jb_lt_max= jb < jb_max; |
7859 } | 7859 } |
7860 } | 7860 } |
7861 r.cidx(i+1) = jx; | 7861 r.cidx(i+1) = jx; |
7862 } | 7862 } |
7863 | 7863 |
7864 r.maybe_compress (); | 7864 r.maybe_compress (); |
7865 } | 7865 } |
7866 } | 7866 } |
7867 else | 7867 else |
7868 (*current_liboctave_error_handler) ("matrix size mismatch"); | 7868 (*current_liboctave_error_handler) ("matrix size mismatch"); |
7936 SparseMatrix | 7936 SparseMatrix |
7937 max (const SparseMatrix& a, const SparseMatrix& b) | 7937 max (const SparseMatrix& a, const SparseMatrix& b) |
7938 { | 7938 { |
7939 SparseMatrix r; | 7939 SparseMatrix r; |
7940 | 7940 |
7941 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) | 7941 if ((a.rows() == b.rows()) && (a.cols() == b.cols())) |
7942 { | 7942 { |
7943 octave_idx_type a_nr = a.rows (); | 7943 octave_idx_type a_nr = a.rows (); |
7944 octave_idx_type a_nc = a.cols (); | 7944 octave_idx_type a_nc = a.cols (); |
7945 | 7945 |
7946 octave_idx_type b_nr = b.rows (); | 7946 octave_idx_type b_nr = b.rows (); |
7949 if (a_nr != b_nr || a_nc != b_nc) | 7949 if (a_nr != b_nr || a_nc != b_nc) |
7950 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); | 7950 gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc); |
7951 else | 7951 else |
7952 { | 7952 { |
7953 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); | 7953 r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ())); |
7954 | 7954 |
7955 octave_idx_type jx = 0; | 7955 octave_idx_type jx = 0; |
7956 r.cidx (0) = 0; | 7956 r.cidx (0) = 0; |
7957 for (octave_idx_type i = 0 ; i < a_nc ; i++) | 7957 for (octave_idx_type i = 0 ; i < a_nc ; i++) |
7958 { | 7958 { |
7959 octave_idx_type ja = a.cidx(i); | 7959 octave_idx_type ja = a.cidx(i); |
7960 octave_idx_type ja_max = a.cidx(i+1); | 7960 octave_idx_type ja_max = a.cidx(i+1); |
7961 bool ja_lt_max= ja < ja_max; | 7961 bool ja_lt_max= ja < ja_max; |
7962 | 7962 |
7963 octave_idx_type jb = b.cidx(i); | 7963 octave_idx_type jb = b.cidx(i); |
7964 octave_idx_type jb_max = b.cidx(i+1); | 7964 octave_idx_type jb_max = b.cidx(i+1); |
7965 bool jb_lt_max = jb < jb_max; | 7965 bool jb_lt_max = jb < jb_max; |
7966 | 7966 |
7967 while (ja_lt_max || jb_lt_max ) | 7967 while (ja_lt_max || jb_lt_max ) |
7968 { | 7968 { |
7969 octave_quit (); | 7969 octave_quit (); |
7970 if ((! jb_lt_max) || | 7970 if ((! jb_lt_max) || |
7971 (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) | 7971 (ja_lt_max && (a.ridx(ja) < b.ridx(jb)))) |
8008 jb_lt_max= jb < jb_max; | 8008 jb_lt_max= jb < jb_max; |
8009 } | 8009 } |
8010 } | 8010 } |
8011 r.cidx(i+1) = jx; | 8011 r.cidx(i+1) = jx; |
8012 } | 8012 } |
8013 | 8013 |
8014 r.maybe_compress (); | 8014 r.maybe_compress (); |
8015 } | 8015 } |
8016 } | 8016 } |
8017 else | 8017 else |
8018 (*current_liboctave_error_handler) ("matrix size mismatch"); | 8018 (*current_liboctave_error_handler) ("matrix size mismatch"); |