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");