Mercurial > octave-nkf
comparison liboctave/CSparse.cc @ 5322:22994a5730f9
[project @ 2005-04-29 13:04:24 by dbateman]
author | dbateman |
---|---|
date | Fri, 29 Apr 2005 13:04:25 +0000 |
parents | 4c8a2e4e0717 |
children | a103c41e68b2 |
comparison
equal
deleted
inserted
replaced
5321:84b72a402b86 | 5322:22994a5730f9 |
---|---|
96 const Complex*, const Complex*, const octave_idx_type*, | 96 const Complex*, const Complex*, const octave_idx_type*, |
97 Complex *, const octave_idx_type&, octave_idx_type& | 97 Complex *, const octave_idx_type&, octave_idx_type& |
98 F77_CHAR_ARG_LEN_DECL); | 98 F77_CHAR_ARG_LEN_DECL); |
99 | 99 |
100 F77_RET_T | 100 F77_RET_T |
101 F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, | 101 F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, double*, Complex*, |
102 Complex*, const octave_idx_type&, octave_idx_type&); | 102 Complex*, const octave_idx_type&, octave_idx_type&); |
103 | 103 |
104 F77_RET_T | 104 F77_RET_T |
105 F77_FUNC (zgtsv, ZGTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, | 105 F77_FUNC (zgtsv, ZGTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, |
106 Complex*, Complex*, const octave_idx_type&, octave_idx_type&); | 106 Complex*, Complex*, const octave_idx_type&, octave_idx_type&); |
647 err = 0; | 647 err = 0; |
648 | 648 |
649 // Setup the control parameters | 649 // Setup the control parameters |
650 Matrix Control (UMFPACK_CONTROL, 1); | 650 Matrix Control (UMFPACK_CONTROL, 1); |
651 double *control = Control.fortran_vec (); | 651 double *control = Control.fortran_vec (); |
652 umfpack_zi_defaults (control); | 652 UMFPACK_ZNAME (defaults) (control); |
653 | 653 |
654 double tmp = Voctave_sparse_controls.get_key ("spumoni"); | 654 double tmp = Voctave_sparse_controls.get_key ("spumoni"); |
655 if (!xisnan (tmp)) | 655 if (!xisnan (tmp)) |
656 Control (UMFPACK_PRL) = tmp; | 656 Control (UMFPACK_PRL) = tmp; |
657 | 657 |
668 Control (UMFPACK_FIXQ) = tmp; | 668 Control (UMFPACK_FIXQ) = tmp; |
669 | 669 |
670 // Turn-off UMFPACK scaling for LU | 670 // Turn-off UMFPACK scaling for LU |
671 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; | 671 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; |
672 | 672 |
673 umfpack_zi_report_control (control); | 673 UMFPACK_ZNAME (report_control) (control); |
674 | 674 |
675 const octave_idx_type *Ap = cidx (); | 675 const octave_idx_type *Ap = cidx (); |
676 const octave_idx_type *Ai = ridx (); | 676 const octave_idx_type *Ai = ridx (); |
677 const Complex *Ax = data (); | 677 const Complex *Ax = data (); |
678 | 678 |
679 umfpack_zi_report_matrix (nr, nc, Ap, Ai, | 679 UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai, |
680 X_CAST (const double *, Ax), | 680 X_CAST (const double *, Ax), |
681 NULL, 1, control); | 681 NULL, 1, control); |
682 | 682 |
683 void *Symbolic; | 683 void *Symbolic; |
684 Matrix Info (1, UMFPACK_INFO); | 684 Matrix Info (1, UMFPACK_INFO); |
685 double *info = Info.fortran_vec (); | 685 double *info = Info.fortran_vec (); |
686 int status = umfpack_zi_qsymbolic | 686 int status = UMFPACK_ZNAME (qsymbolic) |
687 (nr, nc, Ap, Ai, X_CAST (const double *, Ax), NULL, | 687 (nr, nc, Ap, Ai, X_CAST (const double *, Ax), NULL, |
688 NULL, &Symbolic, control, info); | 688 NULL, &Symbolic, control, info); |
689 | 689 |
690 if (status < 0) | 690 if (status < 0) |
691 { | 691 { |
692 (*current_liboctave_error_handler) | 692 (*current_liboctave_error_handler) |
693 ("SparseComplexMatrix::determinant symbolic factorization failed"); | 693 ("SparseComplexMatrix::determinant symbolic factorization failed"); |
694 | 694 |
695 umfpack_zi_report_status (control, status); | 695 UMFPACK_ZNAME (report_status) (control, status); |
696 umfpack_zi_report_info (control, info); | 696 UMFPACK_ZNAME (report_info) (control, info); |
697 | 697 |
698 umfpack_zi_free_symbolic (&Symbolic) ; | 698 UMFPACK_ZNAME (free_symbolic) (&Symbolic) ; |
699 } | 699 } |
700 else | 700 else |
701 { | 701 { |
702 umfpack_zi_report_symbolic (Symbolic, control); | 702 UMFPACK_ZNAME (report_symbolic) (Symbolic, control); |
703 | 703 |
704 void *Numeric; | 704 void *Numeric; |
705 status = umfpack_zi_numeric (Ap, Ai, X_CAST (const double *, Ax), | 705 status = UMFPACK_ZNAME (numeric) (Ap, Ai, |
706 NULL, Symbolic, &Numeric, | 706 X_CAST (const double *, Ax), NULL, |
707 control, info) ; | 707 Symbolic, &Numeric, control, info) ; |
708 umfpack_zi_free_symbolic (&Symbolic) ; | 708 UMFPACK_ZNAME (free_symbolic) (&Symbolic) ; |
709 | 709 |
710 rcond = Info (UMFPACK_RCOND); | 710 rcond = Info (UMFPACK_RCOND); |
711 | 711 |
712 if (status < 0) | 712 if (status < 0) |
713 { | 713 { |
714 (*current_liboctave_error_handler) | 714 (*current_liboctave_error_handler) |
715 ("SparseComplexMatrix::determinant numeric factorization failed"); | 715 ("SparseComplexMatrix::determinant numeric factorization failed"); |
716 | 716 |
717 umfpack_zi_report_status (control, status); | 717 UMFPACK_ZNAME (report_status) (control, status); |
718 umfpack_zi_report_info (control, info); | 718 UMFPACK_ZNAME (report_info) (control, info); |
719 | 719 |
720 umfpack_zi_free_numeric (&Numeric); | 720 UMFPACK_ZNAME (free_numeric) (&Numeric); |
721 } | 721 } |
722 else | 722 else |
723 { | 723 { |
724 umfpack_zi_report_numeric (Numeric, control); | 724 UMFPACK_ZNAME (report_numeric) (Numeric, control); |
725 | 725 |
726 Complex d[2]; | 726 Complex d[2]; |
727 double d_exponent; | 727 double d_exponent; |
728 | 728 |
729 status = umfpack_zi_get_determinant | 729 status = UMFPACK_ZNAME (get_determinant) |
730 (X_CAST (double *, &d[0]), NULL, &d_exponent, | 730 (X_CAST (double *, &d[0]), NULL, &d_exponent, |
731 Numeric, info); | 731 Numeric, info); |
732 d[1] = d_exponent; | 732 d[1] = d_exponent; |
733 | 733 |
734 if (status < 0) | 734 if (status < 0) |
735 { | 735 { |
736 (*current_liboctave_error_handler) | 736 (*current_liboctave_error_handler) |
737 ("SparseComplexMatrix::determinant error calculating determinant"); | 737 ("SparseComplexMatrix::determinant error calculating determinant"); |
738 | 738 |
739 umfpack_zi_report_status (control, status); | 739 UMFPACK_ZNAME (report_status) (control, status); |
740 umfpack_zi_report_info (control, info); | 740 UMFPACK_ZNAME (report_info) (control, info); |
741 | 741 |
742 umfpack_zi_free_numeric (&Numeric); | 742 UMFPACK_ZNAME (free_numeric) (&Numeric); |
743 } | 743 } |
744 else | 744 else |
745 retval = ComplexDET (d); | 745 retval = ComplexDET (d); |
746 } | 746 } |
747 } | 747 } |
1050 anorm = atmp; | 1050 anorm = atmp; |
1051 } | 1051 } |
1052 | 1052 |
1053 if (typ == SparseType::Permuted_Upper) | 1053 if (typ == SparseType::Permuted_Upper) |
1054 { | 1054 { |
1055 retval.resize (b.rows (), b.cols ()); | 1055 retval.resize (nr, b_cols); |
1056 octave_idx_type *perm = mattype.triangular_perm (); | |
1056 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1057 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1057 octave_idx_type *p_perm = mattype.triangular_row_perm (); | |
1058 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
1059 | |
1060 (*current_liboctave_warning_handler) | |
1061 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
1062 | 1058 |
1063 for (octave_idx_type j = 0; j < b_cols; j++) | 1059 for (octave_idx_type j = 0; j < b_cols; j++) |
1064 { | 1060 { |
1065 for (octave_idx_type i = 0; i < nr; i++) | 1061 for (octave_idx_type i = 0; i < nr; i++) |
1066 work[i] = b(i,j); | 1062 work[i] = b(i,j); |
1067 | 1063 |
1068 for (octave_idx_type k = nr-1; k >= 0; k--) | 1064 for (octave_idx_type k = nr-1; k >= 0; k--) |
1069 { | 1065 { |
1070 octave_idx_type iidx = q_perm[k]; | 1066 octave_idx_type kidx = perm[k]; |
1071 if (work[iidx] != 0.) | 1067 |
1068 if (work[k] != 0.) | |
1072 { | 1069 { |
1073 if (ridx(cidx(iidx+1)-1) != iidx) | 1070 if (ridx(cidx(kidx+1)-1) != k) |
1074 { | 1071 { |
1075 err = -2; | 1072 err = -2; |
1076 goto triangular_error; | 1073 goto triangular_error; |
1077 } | 1074 } |
1078 | 1075 |
1079 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1076 Complex tmp = work[k] / data(cidx(kidx+1)-1); |
1080 work[iidx] = tmp; | 1077 work[k] = tmp; |
1081 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1078 for (octave_idx_type i = cidx(kidx); |
1079 i < cidx(kidx+1)-1; i++) | |
1082 { | 1080 { |
1083 octave_idx_type idx2 = q_perm[ridx(i)]; | 1081 octave_idx_type iidx = ridx(i); |
1084 work[idx2] = | 1082 work[iidx] = work[iidx] - tmp * data(i); |
1085 work[idx2] - tmp * data(i); | |
1086 } | 1083 } |
1087 } | 1084 } |
1088 } | 1085 } |
1089 | 1086 |
1090 for (octave_idx_type i = 0; i < nr; i++) | 1087 for (octave_idx_type i = 0; i < nr; i++) |
1091 retval (i, j) = work[p_perm[i]]; | 1088 retval (perm[i], j) = work[i]; |
1092 } | 1089 } |
1093 | 1090 |
1094 // Calculation of 1-norm of inv(*this) | 1091 // Calculation of 1-norm of inv(*this) |
1095 for (octave_idx_type i = 0; i < nr; i++) | 1092 for (octave_idx_type i = 0; i < nr; i++) |
1096 work[i] = 0.; | 1093 work[i] = 0.; |
1097 | 1094 |
1098 for (octave_idx_type j = 0; j < nr; j++) | 1095 for (octave_idx_type j = 0; j < nr; j++) |
1099 { | 1096 { |
1100 work[q_perm[j]] = 1.; | 1097 work[j] = 1.; |
1101 | 1098 |
1102 for (octave_idx_type k = j; k >= 0; k--) | 1099 for (octave_idx_type k = j; k >= 0; k--) |
1103 { | 1100 { |
1104 octave_idx_type iidx = q_perm[k]; | 1101 octave_idx_type iidx = perm[k]; |
1105 | 1102 |
1106 if (work[iidx] != 0.) | 1103 if (work[k] != 0.) |
1107 { | 1104 { |
1108 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1105 Complex tmp = work[k] / data(cidx(iidx+1)-1); |
1109 work[iidx] = tmp; | 1106 work[k] = tmp; |
1110 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1107 for (octave_idx_type i = cidx(iidx); |
1108 i < cidx(iidx+1)-1; i++) | |
1111 { | 1109 { |
1112 octave_idx_type idx2 = q_perm[ridx(i)]; | 1110 octave_idx_type idx2 = ridx(i); |
1113 work[idx2] = work[idx2] - tmp * data(i); | 1111 work[idx2] = work[idx2] - tmp * data(i); |
1114 } | 1112 } |
1115 } | 1113 } |
1116 } | 1114 } |
1117 double atmp = 0; | 1115 double atmp = 0; |
1267 octave_idx_type ii = 0; | 1265 octave_idx_type ii = 0; |
1268 octave_idx_type x_nz = b_nz; | 1266 octave_idx_type x_nz = b_nz; |
1269 | 1267 |
1270 if (typ == SparseType::Permuted_Upper) | 1268 if (typ == SparseType::Permuted_Upper) |
1271 { | 1269 { |
1270 octave_idx_type *perm = mattype.triangular_perm (); | |
1272 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1271 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1273 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 1272 |
1274 octave_idx_type *q_perm = mattype.triangular_col_perm (); | 1273 OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); |
1275 | 1274 for (octave_idx_type i = 0; i < nr; i++) |
1276 (*current_liboctave_warning_handler) | 1275 rperm[perm[i]] = i; |
1277 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
1278 | 1276 |
1279 for (octave_idx_type j = 0; j < b_nc; j++) | 1277 for (octave_idx_type j = 0; j < b_nc; j++) |
1280 { | 1278 { |
1281 for (octave_idx_type i = 0; i < nr; i++) | 1279 for (octave_idx_type i = 0; i < nr; i++) |
1282 work[i] = 0.; | 1280 work[i] = 0.; |
1283 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) | 1281 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1284 work[b.ridx(i)] = b.data(i); | 1282 work[b.ridx(i)] = b.data(i); |
1285 | 1283 |
1286 for (octave_idx_type k = nr-1; k >= 0; k--) | 1284 for (octave_idx_type k = nr-1; k >= 0; k--) |
1287 { | 1285 { |
1288 octave_idx_type iidx = q_perm[k]; | 1286 octave_idx_type kidx = perm[k]; |
1289 if (work[iidx] != 0.) | 1287 |
1288 if (work[k] != 0.) | |
1290 { | 1289 { |
1291 if (ridx(cidx(iidx+1)-1) != iidx) | 1290 if (ridx(cidx(kidx+1)-1) != k) |
1292 { | 1291 { |
1293 err = -2; | 1292 err = -2; |
1294 goto triangular_error; | 1293 goto triangular_error; |
1295 } | 1294 } |
1296 | 1295 |
1297 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1296 Complex tmp = work[k] / data(cidx(kidx+1)-1); |
1298 work[iidx] = tmp; | 1297 work[k] = tmp; |
1299 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1298 for (octave_idx_type i = cidx(kidx); |
1299 i < cidx(kidx+1)-1; i++) | |
1300 { | 1300 { |
1301 octave_idx_type idx2 = q_perm[ridx(i)]; | 1301 octave_idx_type iidx = ridx(i); |
1302 work[idx2] = | 1302 work[iidx] = work[iidx] - tmp * data(i); |
1303 work[idx2] - tmp * data(i); | |
1304 } | 1303 } |
1305 } | 1304 } |
1306 } | 1305 } |
1307 | 1306 |
1308 // Count non-zeros in work vector and adjust space in | 1307 // Count non-zeros in work vector and adjust space in |
1319 retval.change_capacity (sz); | 1318 retval.change_capacity (sz); |
1320 x_nz = sz; | 1319 x_nz = sz; |
1321 } | 1320 } |
1322 | 1321 |
1323 for (octave_idx_type i = 0; i < nr; i++) | 1322 for (octave_idx_type i = 0; i < nr; i++) |
1324 if (work[p_perm[i]] != 0.) | 1323 if (work[rperm[i]] != 0.) |
1325 { | 1324 { |
1326 retval.xridx(ii) = i; | 1325 retval.xridx(ii) = i; |
1327 retval.xdata(ii++) = work[p_perm[i]]; | 1326 retval.xdata(ii++) = work[rperm[i]]; |
1328 } | 1327 } |
1329 retval.xcidx(j+1) = ii; | 1328 retval.xcidx(j+1) = ii; |
1330 } | 1329 } |
1331 | 1330 |
1332 retval.maybe_compress (); | 1331 retval.maybe_compress (); |
1335 for (octave_idx_type i = 0; i < nr; i++) | 1334 for (octave_idx_type i = 0; i < nr; i++) |
1336 work[i] = 0.; | 1335 work[i] = 0.; |
1337 | 1336 |
1338 for (octave_idx_type j = 0; j < nr; j++) | 1337 for (octave_idx_type j = 0; j < nr; j++) |
1339 { | 1338 { |
1340 work[q_perm[j]] = 1.; | 1339 work[j] = 1.; |
1341 | 1340 |
1342 for (octave_idx_type k = j; k >= 0; k--) | 1341 for (octave_idx_type k = j; k >= 0; k--) |
1343 { | 1342 { |
1344 octave_idx_type iidx = q_perm[k]; | 1343 octave_idx_type iidx = perm[k]; |
1345 | 1344 |
1346 if (work[iidx] != 0.) | 1345 if (work[k] != 0.) |
1347 { | 1346 { |
1348 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1347 Complex tmp = work[k] / data(cidx(iidx+1)-1); |
1349 work[iidx] = tmp; | 1348 work[k] = tmp; |
1350 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1349 for (octave_idx_type i = cidx(iidx); |
1350 i < cidx(iidx+1)-1; i++) | |
1351 { | 1351 { |
1352 octave_idx_type idx2 = q_perm[ridx(i)]; | 1352 octave_idx_type idx2 = ridx(i); |
1353 work[idx2] = work[idx2] - tmp * data(i); | 1353 work[idx2] = work[idx2] - tmp * data(i); |
1354 } | 1354 } |
1355 } | 1355 } |
1356 } | 1356 } |
1357 double atmp = 0; | 1357 double atmp = 0; |
1524 anorm = atmp; | 1524 anorm = atmp; |
1525 } | 1525 } |
1526 | 1526 |
1527 if (typ == SparseType::Permuted_Upper) | 1527 if (typ == SparseType::Permuted_Upper) |
1528 { | 1528 { |
1529 retval.resize (b.rows (), b.cols ()); | 1529 retval.resize (nr, b_nc); |
1530 octave_idx_type *perm = mattype.triangular_perm (); | |
1530 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1531 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1531 octave_idx_type *p_perm = mattype.triangular_row_perm (); | |
1532 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
1533 | |
1534 (*current_liboctave_warning_handler) | |
1535 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
1536 | 1532 |
1537 for (octave_idx_type j = 0; j < b_nc; j++) | 1533 for (octave_idx_type j = 0; j < b_nc; j++) |
1538 { | 1534 { |
1539 for (octave_idx_type i = 0; i < nr; i++) | 1535 for (octave_idx_type i = 0; i < nr; i++) |
1540 work[i] = b(i,j); | 1536 work[i] = b(i,j); |
1541 | 1537 |
1542 for (octave_idx_type k = nr-1; k >= 0; k--) | 1538 for (octave_idx_type k = nr-1; k >= 0; k--) |
1543 { | 1539 { |
1544 octave_idx_type iidx = q_perm[k]; | 1540 octave_idx_type kidx = perm[k]; |
1545 if (work[iidx] != 0.) | 1541 |
1542 if (work[k] != 0.) | |
1546 { | 1543 { |
1547 if (ridx(cidx(iidx+1)-1) != iidx) | 1544 if (ridx(cidx(kidx+1)-1) != k) |
1548 { | 1545 { |
1549 err = -2; | 1546 err = -2; |
1550 goto triangular_error; | 1547 goto triangular_error; |
1551 } | 1548 } |
1552 | 1549 |
1553 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1550 Complex tmp = work[k] / data(cidx(kidx+1)-1); |
1554 work[iidx] = tmp; | 1551 work[k] = tmp; |
1555 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1552 for (octave_idx_type i = cidx(kidx); |
1553 i < cidx(kidx+1)-1; i++) | |
1556 { | 1554 { |
1557 octave_idx_type idx2 = q_perm[ridx(i)]; | 1555 octave_idx_type iidx = ridx(i); |
1558 work[idx2] = | 1556 work[iidx] = work[iidx] - tmp * data(i); |
1559 work[idx2] - tmp * data(i); | |
1560 } | 1557 } |
1561 } | 1558 } |
1562 } | 1559 } |
1563 | 1560 |
1564 for (octave_idx_type i = 0; i < nr; i++) | 1561 for (octave_idx_type i = 0; i < nr; i++) |
1565 retval (i, j) = work[p_perm[i]]; | 1562 retval (perm[i], j) = work[i]; |
1566 | |
1567 } | 1563 } |
1568 | 1564 |
1569 // Calculation of 1-norm of inv(*this) | 1565 // Calculation of 1-norm of inv(*this) |
1570 for (octave_idx_type i = 0; i < nr; i++) | 1566 for (octave_idx_type i = 0; i < nr; i++) |
1571 work[i] = 0.; | 1567 work[i] = 0.; |
1572 | 1568 |
1573 for (octave_idx_type j = 0; j < nr; j++) | 1569 for (octave_idx_type j = 0; j < nr; j++) |
1574 { | 1570 { |
1575 work[q_perm[j]] = 1.; | 1571 work[j] = 1.; |
1576 | 1572 |
1577 for (octave_idx_type k = j; k >= 0; k--) | 1573 for (octave_idx_type k = j; k >= 0; k--) |
1578 { | 1574 { |
1579 octave_idx_type iidx = q_perm[k]; | 1575 octave_idx_type iidx = perm[k]; |
1580 | 1576 |
1581 if (work[iidx] != 0.) | 1577 if (work[k] != 0.) |
1582 { | 1578 { |
1583 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1579 Complex tmp = work[k] / data(cidx(iidx+1)-1); |
1584 work[iidx] = tmp; | 1580 work[k] = tmp; |
1585 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1581 for (octave_idx_type i = cidx(iidx); |
1582 i < cidx(iidx+1)-1; i++) | |
1586 { | 1583 { |
1587 octave_idx_type idx2 = q_perm[ridx(i)]; | 1584 octave_idx_type idx2 = ridx(i); |
1588 work[idx2] = work[idx2] - tmp * data(i); | 1585 work[idx2] = work[idx2] - tmp * data(i); |
1589 } | 1586 } |
1590 } | 1587 } |
1591 } | 1588 } |
1592 double atmp = 0; | 1589 double atmp = 0; |
1742 octave_idx_type ii = 0; | 1739 octave_idx_type ii = 0; |
1743 octave_idx_type x_nz = b_nz; | 1740 octave_idx_type x_nz = b_nz; |
1744 | 1741 |
1745 if (typ == SparseType::Permuted_Upper) | 1742 if (typ == SparseType::Permuted_Upper) |
1746 { | 1743 { |
1744 octave_idx_type *perm = mattype.triangular_perm (); | |
1747 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 1745 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
1748 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 1746 |
1749 octave_idx_type *q_perm = mattype.triangular_col_perm (); | 1747 OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); |
1750 | 1748 for (octave_idx_type i = 0; i < nr; i++) |
1751 (*current_liboctave_warning_handler) | 1749 rperm[perm[i]] = i; |
1752 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
1753 | 1750 |
1754 for (octave_idx_type j = 0; j < b_nc; j++) | 1751 for (octave_idx_type j = 0; j < b_nc; j++) |
1755 { | 1752 { |
1756 for (octave_idx_type i = 0; i < nr; i++) | 1753 for (octave_idx_type i = 0; i < nr; i++) |
1757 work[i] = 0.; | 1754 work[i] = 0.; |
1758 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) | 1755 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
1759 work[b.ridx(i)] = b.data(i); | 1756 work[b.ridx(i)] = b.data(i); |
1760 | 1757 |
1761 for (octave_idx_type k = nr-1; k >= 0; k--) | 1758 for (octave_idx_type k = nr-1; k >= 0; k--) |
1762 { | 1759 { |
1763 octave_idx_type iidx = q_perm[k]; | 1760 octave_idx_type kidx = perm[k]; |
1764 if (work[iidx] != 0.) | 1761 |
1762 if (work[k] != 0.) | |
1765 { | 1763 { |
1766 if (ridx(cidx(iidx+1)-1) != iidx) | 1764 if (ridx(cidx(kidx+1)-1) != k) |
1767 { | 1765 { |
1768 err = -2; | 1766 err = -2; |
1769 goto triangular_error; | 1767 goto triangular_error; |
1770 } | 1768 } |
1771 | 1769 |
1772 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1770 Complex tmp = work[k] / data(cidx(kidx+1)-1); |
1773 work[iidx] = tmp; | 1771 work[k] = tmp; |
1774 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1772 for (octave_idx_type i = cidx(kidx); |
1773 i < cidx(kidx+1)-1; i++) | |
1775 { | 1774 { |
1776 octave_idx_type idx2 = q_perm[ridx(i)]; | 1775 octave_idx_type iidx = ridx(i); |
1777 work[idx2] = | 1776 work[iidx] = work[iidx] - tmp * data(i); |
1778 work[idx2] - tmp * data(i); | |
1779 } | 1777 } |
1780 } | 1778 } |
1781 } | 1779 } |
1782 | 1780 |
1783 // Count non-zeros in work vector and adjust space in | 1781 // Count non-zeros in work vector and adjust space in |
1794 retval.change_capacity (sz); | 1792 retval.change_capacity (sz); |
1795 x_nz = sz; | 1793 x_nz = sz; |
1796 } | 1794 } |
1797 | 1795 |
1798 for (octave_idx_type i = 0; i < nr; i++) | 1796 for (octave_idx_type i = 0; i < nr; i++) |
1799 if (work[p_perm[i]] != 0.) | 1797 if (work[rperm[i]] != 0.) |
1800 { | 1798 { |
1801 retval.xridx(ii) = i; | 1799 retval.xridx(ii) = i; |
1802 retval.xdata(ii++) = work[p_perm[i]]; | 1800 retval.xdata(ii++) = work[rperm[i]]; |
1803 } | 1801 } |
1804 retval.xcidx(j+1) = ii; | 1802 retval.xcidx(j+1) = ii; |
1805 } | 1803 } |
1806 | 1804 |
1807 retval.maybe_compress (); | 1805 retval.maybe_compress (); |
1810 for (octave_idx_type i = 0; i < nr; i++) | 1808 for (octave_idx_type i = 0; i < nr; i++) |
1811 work[i] = 0.; | 1809 work[i] = 0.; |
1812 | 1810 |
1813 for (octave_idx_type j = 0; j < nr; j++) | 1811 for (octave_idx_type j = 0; j < nr; j++) |
1814 { | 1812 { |
1815 work[q_perm[j]] = 1.; | 1813 work[j] = 1.; |
1816 | 1814 |
1817 for (octave_idx_type k = j; k >= 0; k--) | 1815 for (octave_idx_type k = j; k >= 0; k--) |
1818 { | 1816 { |
1819 octave_idx_type iidx = q_perm[k]; | 1817 octave_idx_type iidx = perm[k]; |
1820 | 1818 |
1821 if (work[iidx] != 0.) | 1819 if (work[k] != 0.) |
1822 { | 1820 { |
1823 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 1821 Complex tmp = work[k] / data(cidx(iidx+1)-1); |
1824 work[iidx] = tmp; | 1822 work[k] = tmp; |
1825 for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) | 1823 for (octave_idx_type i = cidx(iidx); |
1824 i < cidx(iidx+1)-1; i++) | |
1826 { | 1825 { |
1827 octave_idx_type idx2 = q_perm[ridx(i)]; | 1826 octave_idx_type idx2 = ridx(i); |
1828 work[idx2] = work[idx2] - tmp * data(i); | 1827 work[idx2] = work[idx2] - tmp * data(i); |
1829 } | 1828 } |
1830 } | 1829 } |
1831 } | 1830 } |
1832 double atmp = 0; | 1831 double atmp = 0; |
2001 | 2000 |
2002 if (typ == SparseType::Permuted_Lower) | 2001 if (typ == SparseType::Permuted_Lower) |
2003 { | 2002 { |
2004 retval.resize (b.rows (), b.cols ()); | 2003 retval.resize (b.rows (), b.cols ()); |
2005 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2004 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2006 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 2005 octave_idx_type *perm = mattype.triangular_perm (); |
2007 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
2008 | |
2009 (*current_liboctave_warning_handler) | |
2010 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
2011 | 2006 |
2012 for (octave_idx_type j = 0; j < b_cols; j++) | 2007 for (octave_idx_type j = 0; j < b_cols; j++) |
2013 { | 2008 { |
2014 for (octave_idx_type i = 0; i < nr; i++) | 2009 for (octave_idx_type i = 0; i < nr; i++) |
2015 work[i] = b(i,j); | 2010 work[perm[i]] = b(i,j); |
2016 | 2011 |
2017 for (octave_idx_type k = 0; k < nr; k++) | 2012 for (octave_idx_type k = 0; k < nr; k++) |
2018 { | 2013 { |
2019 octave_idx_type iidx = q_perm[k]; | 2014 if (work[k] != 0.) |
2020 if (work[iidx] != 0.) | |
2021 { | 2015 { |
2022 if (ridx(cidx(iidx)) != iidx) | 2016 octave_idx_type minr = nr; |
2017 octave_idx_type mini = 0; | |
2018 | |
2019 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2020 if (perm[ridx(i)] < minr) | |
2021 { | |
2022 minr = perm[ridx(i)]; | |
2023 mini = i; | |
2024 } | |
2025 | |
2026 if (minr != k) | |
2023 { | 2027 { |
2024 err = -2; | 2028 err = -2; |
2025 goto triangular_error; | 2029 goto triangular_error; |
2026 } | 2030 } |
2027 | 2031 |
2028 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2032 Complex tmp = work[k] / data(mini); |
2029 work[iidx] = tmp; | 2033 work[k] = tmp; |
2030 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2034 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
2031 { | 2035 { |
2032 octave_idx_type idx2 = q_perm[ridx(i)]; | 2036 if (i == mini) |
2033 work[idx2] = | 2037 continue; |
2034 work[idx2] - tmp * data(i); | 2038 |
2039 octave_idx_type iidx = perm[ridx(i)]; | |
2040 work[iidx] = work[iidx] - tmp * data(i); | |
2035 } | 2041 } |
2036 } | 2042 } |
2037 } | 2043 } |
2038 | 2044 |
2039 for (octave_idx_type i = 0; i < nr; i++) | 2045 for (octave_idx_type i = 0; i < nr; i++) |
2040 retval (i, j) = work[p_perm[i]]; | 2046 retval (i, j) = work[i]; |
2041 | |
2042 } | 2047 } |
2043 | 2048 |
2044 // Calculation of 1-norm of inv(*this) | 2049 // Calculation of 1-norm of inv(*this) |
2045 for (octave_idx_type i = 0; i < nr; i++) | 2050 for (octave_idx_type i = 0; i < nr; i++) |
2046 work[i] = 0.; | 2051 work[i] = 0.; |
2047 | 2052 |
2048 for (octave_idx_type j = 0; j < nr; j++) | 2053 for (octave_idx_type j = 0; j < nr; j++) |
2049 { | 2054 { |
2050 work[q_perm[j]] = 1.; | 2055 work[j] = 1.; |
2051 | 2056 |
2052 for (octave_idx_type k = 0; k < nr; k++) | 2057 for (octave_idx_type k = 0; k < nr; k++) |
2053 { | 2058 { |
2054 octave_idx_type iidx = q_perm[k]; | 2059 if (work[k] != 0.) |
2055 | |
2056 if (work[iidx] != 0.) | |
2057 { | 2060 { |
2058 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2061 octave_idx_type minr = nr; |
2059 work[iidx] = tmp; | 2062 octave_idx_type mini = 0; |
2060 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2063 |
2064 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2065 if (perm[ridx(i)] < minr) | |
2066 { | |
2067 minr = perm[ridx(i)]; | |
2068 mini = i; | |
2069 } | |
2070 | |
2071 Complex tmp = work[k] / data(mini); | |
2072 work[k] = tmp; | |
2073 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2061 { | 2074 { |
2062 octave_idx_type idx2 = q_perm[ridx(i)]; | 2075 if (i == mini) |
2063 work[idx2] = work[idx2] - tmp * data(i); | 2076 continue; |
2077 | |
2078 octave_idx_type iidx = perm[ridx(i)]; | |
2079 work[iidx] = work[iidx] - tmp * data(i); | |
2064 } | 2080 } |
2065 } | 2081 } |
2066 } | 2082 } |
2083 | |
2067 double atmp = 0; | 2084 double atmp = 0; |
2068 for (octave_idx_type i = 0; i < j+1; i++) | 2085 for (octave_idx_type i = j; i < nr; i++) |
2069 { | 2086 { |
2070 atmp += std::abs(work[i]); | 2087 atmp += std::abs(work[i]); |
2071 work[i] = 0.; | 2088 work[i] = 0.; |
2072 } | 2089 } |
2073 if (atmp > ainvnorm) | 2090 if (atmp > ainvnorm) |
2219 octave_idx_type x_nz = b_nz; | 2236 octave_idx_type x_nz = b_nz; |
2220 | 2237 |
2221 if (typ == SparseType::Permuted_Lower) | 2238 if (typ == SparseType::Permuted_Lower) |
2222 { | 2239 { |
2223 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2240 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2224 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 2241 octave_idx_type *perm = mattype.triangular_perm (); |
2225 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
2226 | |
2227 (*current_liboctave_warning_handler) | |
2228 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
2229 | 2242 |
2230 for (octave_idx_type j = 0; j < b_nc; j++) | 2243 for (octave_idx_type j = 0; j < b_nc; j++) |
2231 { | 2244 { |
2232 for (octave_idx_type i = 0; i < nr; i++) | 2245 for (octave_idx_type i = 0; i < nr; i++) |
2233 work[i] = 0.; | 2246 work[i] = 0.; |
2234 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) | 2247 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2235 work[b.ridx(i)] = b.data(i); | 2248 work[perm[b.ridx(i)]] = b.data(i); |
2236 | 2249 |
2237 for (octave_idx_type k = 0; k < nr; k++) | 2250 for (octave_idx_type k = 0; k < nr; k++) |
2238 { | 2251 { |
2239 octave_idx_type iidx = q_perm[k]; | 2252 if (work[k] != 0.) |
2240 if (work[iidx] != 0.) | |
2241 { | 2253 { |
2242 if (ridx(cidx(iidx)) != iidx) | 2254 octave_idx_type minr = nr; |
2255 octave_idx_type mini = 0; | |
2256 | |
2257 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2258 if (perm[ridx(i)] < minr) | |
2259 { | |
2260 minr = perm[ridx(i)]; | |
2261 mini = i; | |
2262 } | |
2263 | |
2264 if (minr != k) | |
2243 { | 2265 { |
2244 err = -2; | 2266 err = -2; |
2245 goto triangular_error; | 2267 goto triangular_error; |
2246 } | 2268 } |
2247 | 2269 |
2248 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2270 Complex tmp = work[k] / data(mini); |
2249 work[iidx] = tmp; | 2271 work[k] = tmp; |
2250 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2272 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
2251 { | 2273 { |
2252 octave_idx_type idx2 = q_perm[ridx(i)]; | 2274 if (i == mini) |
2253 work[idx2] = | 2275 continue; |
2254 work[idx2] - tmp * data(i); | 2276 |
2277 octave_idx_type iidx = perm[ridx(i)]; | |
2278 work[iidx] = work[iidx] - tmp * data(i); | |
2255 } | 2279 } |
2256 } | 2280 } |
2257 } | 2281 } |
2258 | 2282 |
2259 // Count non-zeros in work vector and adjust space in | 2283 // Count non-zeros in work vector and adjust space in |
2270 retval.change_capacity (sz); | 2294 retval.change_capacity (sz); |
2271 x_nz = sz; | 2295 x_nz = sz; |
2272 } | 2296 } |
2273 | 2297 |
2274 for (octave_idx_type i = 0; i < nr; i++) | 2298 for (octave_idx_type i = 0; i < nr; i++) |
2275 if (work[p_perm[i]] != 0.) | 2299 if (work[i] != 0.) |
2276 { | 2300 { |
2277 retval.xridx(ii) = i; | 2301 retval.xridx(ii) = i; |
2278 retval.xdata(ii++) = work[p_perm[i]]; | 2302 retval.xdata(ii++) = work[i]; |
2279 } | 2303 } |
2280 retval.xcidx(j+1) = ii; | 2304 retval.xcidx(j+1) = ii; |
2281 } | 2305 } |
2282 | 2306 |
2283 retval.maybe_compress (); | 2307 retval.maybe_compress (); |
2286 for (octave_idx_type i = 0; i < nr; i++) | 2310 for (octave_idx_type i = 0; i < nr; i++) |
2287 work[i] = 0.; | 2311 work[i] = 0.; |
2288 | 2312 |
2289 for (octave_idx_type j = 0; j < nr; j++) | 2313 for (octave_idx_type j = 0; j < nr; j++) |
2290 { | 2314 { |
2291 work[q_perm[j]] = 1.; | 2315 work[j] = 1.; |
2292 | 2316 |
2293 for (octave_idx_type k = 0; k < nr; k++) | 2317 for (octave_idx_type k = 0; k < nr; k++) |
2294 { | 2318 { |
2295 octave_idx_type iidx = q_perm[k]; | 2319 if (work[k] != 0.) |
2296 | |
2297 if (work[iidx] != 0.) | |
2298 { | 2320 { |
2299 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2321 octave_idx_type minr = nr; |
2300 work[iidx] = tmp; | 2322 octave_idx_type mini = 0; |
2301 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2323 |
2324 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2325 if (perm[ridx(i)] < minr) | |
2326 { | |
2327 minr = perm[ridx(i)]; | |
2328 mini = i; | |
2329 } | |
2330 | |
2331 Complex tmp = work[k] / data(mini); | |
2332 work[k] = tmp; | |
2333 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2302 { | 2334 { |
2303 octave_idx_type idx2 = q_perm[ridx(i)]; | 2335 if (i == mini) |
2304 work[idx2] = work[idx2] - tmp * data(i); | 2336 continue; |
2337 | |
2338 octave_idx_type iidx = perm[ridx(i)]; | |
2339 work[iidx] = work[iidx] - tmp * data(i); | |
2305 } | 2340 } |
2306 } | 2341 } |
2307 } | 2342 } |
2343 | |
2308 double atmp = 0; | 2344 double atmp = 0; |
2309 for (octave_idx_type i = 0; i < j+1; i++) | 2345 for (octave_idx_type i = j; i < nr; i++) |
2310 { | 2346 { |
2311 atmp += std::abs(work[i]); | 2347 atmp += std::abs(work[i]); |
2312 work[i] = 0.; | 2348 work[i] = 0.; |
2313 } | 2349 } |
2314 if (atmp > ainvnorm) | 2350 if (atmp > ainvnorm) |
2480 | 2516 |
2481 if (typ == SparseType::Permuted_Lower) | 2517 if (typ == SparseType::Permuted_Lower) |
2482 { | 2518 { |
2483 retval.resize (b.rows (), b.cols ()); | 2519 retval.resize (b.rows (), b.cols ()); |
2484 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2520 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2485 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 2521 octave_idx_type *perm = mattype.triangular_perm (); |
2486 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
2487 | |
2488 (*current_liboctave_warning_handler) | |
2489 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
2490 | 2522 |
2491 for (octave_idx_type j = 0; j < b_nc; j++) | 2523 for (octave_idx_type j = 0; j < b_nc; j++) |
2492 { | 2524 { |
2493 for (octave_idx_type i = 0; i < nr; i++) | 2525 for (octave_idx_type i = 0; i < nr; i++) |
2494 work[i] = b(i,j); | 2526 work[perm[i]] = b(i,j); |
2495 | 2527 |
2496 for (octave_idx_type k = 0; k < nr; k++) | 2528 for (octave_idx_type k = 0; k < nr; k++) |
2497 { | 2529 { |
2498 octave_idx_type iidx = q_perm[k]; | 2530 if (work[k] != 0.) |
2499 if (work[iidx] != 0.) | |
2500 { | 2531 { |
2501 if (ridx(cidx(iidx)) != iidx) | 2532 octave_idx_type minr = nr; |
2533 octave_idx_type mini = 0; | |
2534 | |
2535 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2536 if (perm[ridx(i)] < minr) | |
2537 { | |
2538 minr = perm[ridx(i)]; | |
2539 mini = i; | |
2540 } | |
2541 | |
2542 if (minr != k) | |
2502 { | 2543 { |
2503 err = -2; | 2544 err = -2; |
2504 goto triangular_error; | 2545 goto triangular_error; |
2505 } | 2546 } |
2506 | 2547 |
2507 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2548 Complex tmp = work[k] / data(mini); |
2508 work[iidx] = tmp; | 2549 work[k] = tmp; |
2509 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2550 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
2510 { | 2551 { |
2511 octave_idx_type idx2 = q_perm[ridx(i)]; | 2552 if (i == mini) |
2512 work[idx2] = | 2553 continue; |
2513 work[idx2] - tmp * data(i); | 2554 |
2555 octave_idx_type iidx = perm[ridx(i)]; | |
2556 work[iidx] = work[iidx] - tmp * data(i); | |
2514 } | 2557 } |
2515 } | 2558 } |
2516 } | 2559 } |
2517 | 2560 |
2518 for (octave_idx_type i = 0; i < nr; i++) | 2561 for (octave_idx_type i = 0; i < nr; i++) |
2519 retval (i, j) = work[p_perm[i]]; | 2562 retval (i, j) = work[i]; |
2520 | |
2521 } | 2563 } |
2522 | 2564 |
2523 // Calculation of 1-norm of inv(*this) | 2565 // Calculation of 1-norm of inv(*this) |
2524 for (octave_idx_type i = 0; i < nr; i++) | 2566 for (octave_idx_type i = 0; i < nr; i++) |
2525 work[i] = 0.; | 2567 work[i] = 0.; |
2526 | 2568 |
2527 for (octave_idx_type j = 0; j < nr; j++) | 2569 for (octave_idx_type j = 0; j < nr; j++) |
2528 { | 2570 { |
2529 work[q_perm[j]] = 1.; | 2571 work[j] = 1.; |
2530 | 2572 |
2531 for (octave_idx_type k = 0; k < nr; k++) | 2573 for (octave_idx_type k = 0; k < nr; k++) |
2532 { | 2574 { |
2533 octave_idx_type iidx = q_perm[k]; | 2575 if (work[k] != 0.) |
2534 | |
2535 if (work[iidx] != 0.) | |
2536 { | 2576 { |
2537 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2577 octave_idx_type minr = nr; |
2538 work[iidx] = tmp; | 2578 octave_idx_type mini = 0; |
2539 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2579 |
2580 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2581 if (perm[ridx(i)] < minr) | |
2582 { | |
2583 minr = perm[ridx(i)]; | |
2584 mini = i; | |
2585 } | |
2586 | |
2587 Complex tmp = work[k] / data(mini); | |
2588 work[k] = tmp; | |
2589 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2540 { | 2590 { |
2541 octave_idx_type idx2 = q_perm[ridx(i)]; | 2591 if (i == mini) |
2542 work[idx2] = work[idx2] - tmp * data(i); | 2592 continue; |
2593 | |
2594 octave_idx_type iidx = perm[ridx(i)]; | |
2595 work[iidx] = work[iidx] - tmp * data(i); | |
2543 } | 2596 } |
2544 } | 2597 } |
2545 } | 2598 } |
2599 | |
2546 double atmp = 0; | 2600 double atmp = 0; |
2547 for (octave_idx_type i = 0; i < j+1; i++) | 2601 for (octave_idx_type i = j; i < nr; i++) |
2548 { | 2602 { |
2549 atmp += std::abs(work[i]); | 2603 atmp += std::abs(work[i]); |
2550 work[i] = 0.; | 2604 work[i] = 0.; |
2551 } | 2605 } |
2552 if (atmp > ainvnorm) | 2606 if (atmp > ainvnorm) |
2699 octave_idx_type x_nz = b_nz; | 2753 octave_idx_type x_nz = b_nz; |
2700 | 2754 |
2701 if (typ == SparseType::Permuted_Lower) | 2755 if (typ == SparseType::Permuted_Lower) |
2702 { | 2756 { |
2703 OCTAVE_LOCAL_BUFFER (Complex, work, nr); | 2757 OCTAVE_LOCAL_BUFFER (Complex, work, nr); |
2704 octave_idx_type *p_perm = mattype.triangular_row_perm (); | 2758 octave_idx_type *perm = mattype.triangular_perm (); |
2705 octave_idx_type *q_perm = mattype.triangular_col_perm (); | |
2706 | |
2707 (*current_liboctave_warning_handler) | |
2708 ("SparseComplexMatrix::solve XXX FIXME XXX permuted triangular code not tested"); | |
2709 | 2759 |
2710 for (octave_idx_type j = 0; j < b_nc; j++) | 2760 for (octave_idx_type j = 0; j < b_nc; j++) |
2711 { | 2761 { |
2712 for (octave_idx_type i = 0; i < nr; i++) | 2762 for (octave_idx_type i = 0; i < nr; i++) |
2713 work[i] = 0.; | 2763 work[i] = 0.; |
2714 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) | 2764 for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) |
2715 work[b.ridx(i)] = b.data(i); | 2765 work[perm[b.ridx(i)]] = b.data(i); |
2716 | 2766 |
2717 for (octave_idx_type k = 0; k < nr; k++) | 2767 for (octave_idx_type k = 0; k < nr; k++) |
2718 { | 2768 { |
2719 octave_idx_type iidx = q_perm[k]; | 2769 if (work[k] != 0.) |
2720 if (work[iidx] != 0.) | |
2721 { | 2770 { |
2722 if (ridx(cidx(iidx)) != iidx) | 2771 octave_idx_type minr = nr; |
2772 octave_idx_type mini = 0; | |
2773 | |
2774 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2775 if (perm[ridx(i)] < minr) | |
2776 { | |
2777 minr = perm[ridx(i)]; | |
2778 mini = i; | |
2779 } | |
2780 | |
2781 if (minr != k) | |
2723 { | 2782 { |
2724 err = -2; | 2783 err = -2; |
2725 goto triangular_error; | 2784 goto triangular_error; |
2726 } | 2785 } |
2727 | 2786 |
2728 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2787 Complex tmp = work[k] / data(mini); |
2729 work[iidx] = tmp; | 2788 work[k] = tmp; |
2730 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2789 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) |
2731 { | 2790 { |
2732 octave_idx_type idx2 = q_perm[ridx(i)]; | 2791 if (i == mini) |
2733 work[idx2] = | 2792 continue; |
2734 work[idx2] - tmp * data(i); | 2793 |
2794 octave_idx_type iidx = perm[ridx(i)]; | |
2795 work[iidx] = work[iidx] - tmp * data(i); | |
2735 } | 2796 } |
2736 } | 2797 } |
2737 } | 2798 } |
2738 | 2799 |
2739 // Count non-zeros in work vector and adjust space in | 2800 // Count non-zeros in work vector and adjust space in |
2750 retval.change_capacity (sz); | 2811 retval.change_capacity (sz); |
2751 x_nz = sz; | 2812 x_nz = sz; |
2752 } | 2813 } |
2753 | 2814 |
2754 for (octave_idx_type i = 0; i < nr; i++) | 2815 for (octave_idx_type i = 0; i < nr; i++) |
2755 if (work[p_perm[i]] != 0.) | 2816 if (work[i] != 0.) |
2756 { | 2817 { |
2757 retval.xridx(ii) = i; | 2818 retval.xridx(ii) = i; |
2758 retval.xdata(ii++) = work[p_perm[i]]; | 2819 retval.xdata(ii++) = work[i]; |
2759 } | 2820 } |
2760 retval.xcidx(j+1) = ii; | 2821 retval.xcidx(j+1) = ii; |
2761 } | 2822 } |
2762 | 2823 |
2763 retval.maybe_compress (); | 2824 retval.maybe_compress (); |
2766 for (octave_idx_type i = 0; i < nr; i++) | 2827 for (octave_idx_type i = 0; i < nr; i++) |
2767 work[i] = 0.; | 2828 work[i] = 0.; |
2768 | 2829 |
2769 for (octave_idx_type j = 0; j < nr; j++) | 2830 for (octave_idx_type j = 0; j < nr; j++) |
2770 { | 2831 { |
2771 work[q_perm[j]] = 1.; | 2832 work[j] = 1.; |
2772 | 2833 |
2773 for (octave_idx_type k = 0; k < nr; k++) | 2834 for (octave_idx_type k = 0; k < nr; k++) |
2774 { | 2835 { |
2775 octave_idx_type iidx = q_perm[k]; | 2836 if (work[k] != 0.) |
2776 | |
2777 if (work[iidx] != 0.) | |
2778 { | 2837 { |
2779 Complex tmp = work[iidx] / data(cidx(iidx+1)-1); | 2838 octave_idx_type minr = nr; |
2780 work[iidx] = tmp; | 2839 octave_idx_type mini = 0; |
2781 for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) | 2840 |
2841 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2842 if (perm[ridx(i)] < minr) | |
2843 { | |
2844 minr = perm[ridx(i)]; | |
2845 mini = i; | |
2846 } | |
2847 | |
2848 Complex tmp = work[k] / data(mini); | |
2849 work[k] = tmp; | |
2850 for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) | |
2782 { | 2851 { |
2783 octave_idx_type idx2 = q_perm[ridx(i)]; | 2852 if (i == mini) |
2784 work[idx2] = work[idx2] - tmp * data(i); | 2853 continue; |
2854 | |
2855 octave_idx_type iidx = perm[ridx(i)]; | |
2856 work[iidx] = work[iidx] - tmp * data(i); | |
2785 } | 2857 } |
2786 } | 2858 } |
2787 } | 2859 } |
2860 | |
2788 double atmp = 0; | 2861 double atmp = 0; |
2789 for (octave_idx_type i = 0; i < j+1; i++) | 2862 for (octave_idx_type i = j; i < nr; i++) |
2790 { | 2863 { |
2791 atmp += std::abs(work[i]); | 2864 atmp += std::abs(work[i]); |
2792 work[i] = 0.; | 2865 work[i] = 0.; |
2793 } | 2866 } |
2794 if (atmp > ainvnorm) | 2867 if (atmp > ainvnorm) |
2940 volatile int typ = mattype.type (); | 3013 volatile int typ = mattype.type (); |
2941 mattype.info (); | 3014 mattype.info (); |
2942 | 3015 |
2943 if (typ == SparseType::Tridiagonal_Hermitian) | 3016 if (typ == SparseType::Tridiagonal_Hermitian) |
2944 { | 3017 { |
2945 OCTAVE_LOCAL_BUFFER (Complex, D, nr); | 3018 OCTAVE_LOCAL_BUFFER (double, D, nr); |
2946 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); | 3019 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); |
2947 | 3020 |
2948 if (mattype.is_dense ()) | 3021 if (mattype.is_dense ()) |
2949 { | 3022 { |
2950 octave_idx_type ii = 0; | 3023 octave_idx_type ii = 0; |
2951 | 3024 |
2952 for (octave_idx_type j = 0; j < nc-1; j++) | 3025 for (octave_idx_type j = 0; j < nc-1; j++) |
2953 { | 3026 { |
2954 D[j] = data(ii++); | 3027 D[j] = std::real(data(ii++)); |
2955 DL[j] = data(ii); | 3028 DL[j] = data(ii); |
2956 ii += 2; | 3029 ii += 2; |
2957 } | 3030 } |
2958 D[nc-1] = data(ii); | 3031 D[nc-1] = std::real(data(ii)); |
2959 } | 3032 } |
2960 else | 3033 else |
2961 { | 3034 { |
2962 D[0] = 0.; | 3035 D[0] = 0.; |
2963 for (octave_idx_type i = 0; i < nr - 1; i++) | 3036 for (octave_idx_type i = 0; i < nr - 1; i++) |
2968 | 3041 |
2969 for (octave_idx_type j = 0; j < nc; j++) | 3042 for (octave_idx_type j = 0; j < nc; j++) |
2970 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) | 3043 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
2971 { | 3044 { |
2972 if (ridx(i) == j) | 3045 if (ridx(i) == j) |
2973 D[j] = data(i); | 3046 D[j] = std::real(data(i)); |
2974 else if (ridx(i) == j + 1) | 3047 else if (ridx(i) == j + 1) |
2975 DL[j] = data(i); | 3048 DL[j] = data(i); |
2976 } | 3049 } |
2977 } | 3050 } |
2978 | 3051 |
3030 if (ridx(i) == j) | 3103 if (ridx(i) == j) |
3031 D[j] = data(i); | 3104 D[j] = data(i); |
3032 else if (ridx(i) == j + 1) | 3105 else if (ridx(i) == j + 1) |
3033 DL[j] = data(i); | 3106 DL[j] = data(i); |
3034 else if (ridx(i) == j - 1) | 3107 else if (ridx(i) == j - 1) |
3035 DU[j] = data(i); | 3108 DU[j-1] = data(i); |
3036 } | 3109 } |
3037 } | 3110 } |
3038 | 3111 |
3039 octave_idx_type b_nc = b.cols(); | 3112 octave_idx_type b_nc = b.cols(); |
3040 retval = ComplexMatrix (b); | 3113 retval = ComplexMatrix (b); |
3127 if (ridx(i) == j) | 3200 if (ridx(i) == j) |
3128 D[j] = data(i); | 3201 D[j] = data(i); |
3129 else if (ridx(i) == j + 1) | 3202 else if (ridx(i) == j + 1) |
3130 DL[j] = data(i); | 3203 DL[j] = data(i); |
3131 else if (ridx(i) == j - 1) | 3204 else if (ridx(i) == j - 1) |
3132 DU[j] = data(i); | 3205 DU[j-1] = data(i); |
3133 } | 3206 } |
3134 } | 3207 } |
3135 | 3208 |
3136 F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); | 3209 F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); |
3137 | 3210 |
3236 { | 3309 { |
3237 // Print spparms("spumoni") info if requested | 3310 // Print spparms("spumoni") info if requested |
3238 volatile int typ = mattype.type (); | 3311 volatile int typ = mattype.type (); |
3239 mattype.info (); | 3312 mattype.info (); |
3240 | 3313 |
3241 // Note can't treat symmetric case as there is no dpttrf function | |
3242 if (typ == SparseType::Tridiagonal_Hermitian) | 3314 if (typ == SparseType::Tridiagonal_Hermitian) |
3243 { | 3315 { |
3244 OCTAVE_LOCAL_BUFFER (Complex, D, nr); | 3316 OCTAVE_LOCAL_BUFFER (double, D, nr); |
3245 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); | 3317 OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); |
3246 | 3318 |
3247 if (mattype.is_dense ()) | 3319 if (mattype.is_dense ()) |
3248 { | 3320 { |
3249 octave_idx_type ii = 0; | 3321 octave_idx_type ii = 0; |
3250 | 3322 |
3251 for (octave_idx_type j = 0; j < nc-1; j++) | 3323 for (octave_idx_type j = 0; j < nc-1; j++) |
3252 { | 3324 { |
3253 D[j] = data(ii++); | 3325 D[j] = std::real(data(ii++)); |
3254 DL[j] = data(ii); | 3326 DL[j] = data(ii); |
3255 ii += 2; | 3327 ii += 2; |
3256 } | 3328 } |
3257 D[nc-1] = data(ii); | 3329 D[nc-1] = std::real(data(ii)); |
3258 } | 3330 } |
3259 else | 3331 else |
3260 { | 3332 { |
3261 D[0] = 0.; | 3333 D[0] = 0.; |
3262 for (octave_idx_type i = 0; i < nr - 1; i++) | 3334 for (octave_idx_type i = 0; i < nr - 1; i++) |
3267 | 3339 |
3268 for (octave_idx_type j = 0; j < nc; j++) | 3340 for (octave_idx_type j = 0; j < nc; j++) |
3269 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) | 3341 for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) |
3270 { | 3342 { |
3271 if (ridx(i) == j) | 3343 if (ridx(i) == j) |
3272 D[j] = data(i); | 3344 D[j] = std::real (data(i)); |
3273 else if (ridx(i) == j + 1) | 3345 else if (ridx(i) == j + 1) |
3274 DL[j] = data(i); | 3346 DL[j] = data(i); |
3275 } | 3347 } |
3276 } | 3348 } |
3277 | 3349 |
3333 if (ridx(i) == j) | 3405 if (ridx(i) == j) |
3334 D[j] = data(i); | 3406 D[j] = data(i); |
3335 else if (ridx(i) == j + 1) | 3407 else if (ridx(i) == j + 1) |
3336 DL[j] = data(i); | 3408 DL[j] = data(i); |
3337 else if (ridx(i) == j - 1) | 3409 else if (ridx(i) == j - 1) |
3338 DU[j] = data(i); | 3410 DU[j-1] = data(i); |
3339 } | 3411 } |
3340 } | 3412 } |
3341 | 3413 |
3342 octave_idx_type b_nr = b.rows(); | 3414 octave_idx_type b_nr = b.rows(); |
3343 octave_idx_type b_nc = b.cols(); | 3415 octave_idx_type b_nc = b.cols(); |
3433 if (ridx(i) == j) | 3505 if (ridx(i) == j) |
3434 D[j] = data(i); | 3506 D[j] = data(i); |
3435 else if (ridx(i) == j + 1) | 3507 else if (ridx(i) == j + 1) |
3436 DL[j] = data(i); | 3508 DL[j] = data(i); |
3437 else if (ridx(i) == j - 1) | 3509 else if (ridx(i) == j - 1) |
3438 DU[j] = data(i); | 3510 DU[j-1] = data(i); |
3439 } | 3511 } |
3440 } | 3512 } |
3441 | 3513 |
3442 F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); | 3514 F77_XFCN (zgttrf, ZGTTRF, (nr, DL, D, DU, DU2, pipvt, err)); |
3443 | 3515 |
4455 | 4527 |
4456 #ifdef HAVE_UMFPACK | 4528 #ifdef HAVE_UMFPACK |
4457 // Setup the control parameters | 4529 // Setup the control parameters |
4458 Control = Matrix (UMFPACK_CONTROL, 1); | 4530 Control = Matrix (UMFPACK_CONTROL, 1); |
4459 double *control = Control.fortran_vec (); | 4531 double *control = Control.fortran_vec (); |
4460 umfpack_zi_defaults (control); | 4532 UMFPACK_ZNAME (defaults) (control); |
4461 | 4533 |
4462 double tmp = Voctave_sparse_controls.get_key ("spumoni"); | 4534 double tmp = Voctave_sparse_controls.get_key ("spumoni"); |
4463 if (!xisnan (tmp)) | 4535 if (!xisnan (tmp)) |
4464 Control (UMFPACK_PRL) = tmp; | 4536 Control (UMFPACK_PRL) = tmp; |
4465 tmp = Voctave_sparse_controls.get_key ("piv_tol"); | 4537 tmp = Voctave_sparse_controls.get_key ("piv_tol"); |
4472 // Set whether we are allowed to modify Q or not | 4544 // Set whether we are allowed to modify Q or not |
4473 tmp = Voctave_sparse_controls.get_key ("autoamd"); | 4545 tmp = Voctave_sparse_controls.get_key ("autoamd"); |
4474 if (!xisnan (tmp)) | 4546 if (!xisnan (tmp)) |
4475 Control (UMFPACK_FIXQ) = tmp; | 4547 Control (UMFPACK_FIXQ) = tmp; |
4476 | 4548 |
4477 umfpack_zi_report_control (control); | 4549 UMFPACK_ZNAME (report_control) (control); |
4478 | 4550 |
4479 const octave_idx_type *Ap = cidx (); | 4551 const octave_idx_type *Ap = cidx (); |
4480 const octave_idx_type *Ai = ridx (); | 4552 const octave_idx_type *Ai = ridx (); |
4481 const Complex *Ax = data (); | 4553 const Complex *Ax = data (); |
4482 octave_idx_type nr = rows (); | 4554 octave_idx_type nr = rows (); |
4483 octave_idx_type nc = cols (); | 4555 octave_idx_type nc = cols (); |
4484 | 4556 |
4485 umfpack_zi_report_matrix (nr, nc, Ap, Ai, X_CAST (const double *, Ax), | 4557 UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai, |
4486 NULL, 1, control); | 4558 X_CAST (const double *, Ax), NULL, 1, control); |
4487 | 4559 |
4488 void *Symbolic; | 4560 void *Symbolic; |
4489 Info = Matrix (1, UMFPACK_INFO); | 4561 Info = Matrix (1, UMFPACK_INFO); |
4490 double *info = Info.fortran_vec (); | 4562 double *info = Info.fortran_vec (); |
4491 int status = umfpack_zi_qsymbolic (nr, nc, Ap, Ai, | 4563 int status = UMFPACK_ZNAME (qsymbolic) (nr, nc, Ap, Ai, |
4492 X_CAST (const double *, Ax), | 4564 X_CAST (const double *, Ax), |
4493 NULL, NULL, &Symbolic, control, info); | 4565 NULL, NULL, &Symbolic, control, info); |
4494 | 4566 |
4495 if (status < 0) | 4567 if (status < 0) |
4496 { | 4568 { |
4497 (*current_liboctave_error_handler) | 4569 (*current_liboctave_error_handler) |
4498 ("SparseComplexMatrix::solve symbolic factorization failed"); | 4570 ("SparseComplexMatrix::solve symbolic factorization failed"); |
4499 err = -1; | 4571 err = -1; |
4500 | 4572 |
4501 umfpack_zi_report_status (control, status); | 4573 UMFPACK_ZNAME (report_status) (control, status); |
4502 umfpack_zi_report_info (control, info); | 4574 UMFPACK_ZNAME (report_info) (control, info); |
4503 | 4575 |
4504 umfpack_zi_free_symbolic (&Symbolic) ; | 4576 UMFPACK_ZNAME (free_symbolic) (&Symbolic) ; |
4505 } | 4577 } |
4506 else | 4578 else |
4507 { | 4579 { |
4508 umfpack_zi_report_symbolic (Symbolic, control); | 4580 UMFPACK_ZNAME (report_symbolic) (Symbolic, control); |
4509 | 4581 |
4510 status = umfpack_zi_numeric (Ap, Ai, X_CAST (const double *, Ax), NULL, | 4582 status = UMFPACK_ZNAME (numeric) (Ap, Ai, |
4583 X_CAST (const double *, Ax), NULL, | |
4511 Symbolic, &Numeric, control, info) ; | 4584 Symbolic, &Numeric, control, info) ; |
4512 umfpack_zi_free_symbolic (&Symbolic) ; | 4585 UMFPACK_ZNAME (free_symbolic) (&Symbolic) ; |
4513 | 4586 |
4514 #ifdef HAVE_LSSOLVE | 4587 #ifdef HAVE_LSSOLVE |
4515 rcond = Info (UMFPACK_RCOND); | 4588 rcond = Info (UMFPACK_RCOND); |
4516 volatile double rcond_plus_one = rcond + 1.0; | 4589 volatile double rcond_plus_one = rcond + 1.0; |
4517 | 4590 |
4518 if (status == UMFPACK_WARNING_singular_matrix || | 4591 if (status == UMFPACK_WARNING_singular_matrix || |
4519 rcond_plus_one == 1.0 || xisnan (rcond)) | 4592 rcond_plus_one == 1.0 || xisnan (rcond)) |
4520 { | 4593 { |
4521 umfpack_zi_report_numeric (Numeric, control); | 4594 UMFPACK_ZNAME (report_numeric) (Numeric, control); |
4522 | 4595 |
4523 err = -2; | 4596 err = -2; |
4524 | 4597 |
4525 if (sing_handler) | 4598 if (sing_handler) |
4526 sing_handler (rcond); | 4599 sing_handler (rcond); |
4535 if (status < 0) | 4608 if (status < 0) |
4536 { | 4609 { |
4537 (*current_liboctave_error_handler) | 4610 (*current_liboctave_error_handler) |
4538 ("SparseComplexMatrix::solve numeric factorization failed"); | 4611 ("SparseComplexMatrix::solve numeric factorization failed"); |
4539 | 4612 |
4540 umfpack_zi_report_status (control, status); | 4613 UMFPACK_ZNAME (report_status) (control, status); |
4541 umfpack_zi_report_info (control, info); | 4614 UMFPACK_ZNAME (report_info) (control, info); |
4542 | 4615 |
4543 err = -1; | 4616 err = -1; |
4544 } | 4617 } |
4545 else | 4618 else |
4546 { | 4619 { |
4547 umfpack_zi_report_numeric (Numeric, control); | 4620 UMFPACK_ZNAME (report_numeric) (Numeric, control); |
4548 } | 4621 } |
4549 } | 4622 } |
4550 | 4623 |
4551 if (err != 0) | 4624 if (err != 0) |
4552 umfpack_zi_free_numeric (&Numeric); | 4625 UMFPACK_ZNAME (free_numeric) (&Numeric); |
4553 #else | 4626 #else |
4554 (*current_liboctave_error_handler) ("UMFPACK not installed"); | 4627 (*current_liboctave_error_handler) ("UMFPACK not installed"); |
4555 #endif | 4628 #endif |
4556 | 4629 |
4557 return Numeric; | 4630 return Numeric; |
4618 Complex *Xx = retval.fortran_vec (); | 4691 Complex *Xx = retval.fortran_vec (); |
4619 | 4692 |
4620 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) | 4693 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) |
4621 { | 4694 { |
4622 #ifdef UMFPACK_SEPARATE_SPLIT | 4695 #ifdef UMFPACK_SEPARATE_SPLIT |
4623 status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 4696 status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, |
4624 X_CAST (const double *, Ax), | 4697 Ai, X_CAST (const double *, Ax), |
4625 NULL, | 4698 NULL, |
4626 X_CAST (double *, &Xx[iidx]), | 4699 X_CAST (double *, &Xx[iidx]), |
4627 NULL, | 4700 NULL, |
4628 &Bx[iidx], Bz, Numeric, | 4701 &Bx[iidx], Bz, Numeric, |
4629 control, info); | 4702 control, info); |
4630 #else | 4703 #else |
4631 for (octave_idx_type i = 0; i < b_nr; i++) | 4704 for (octave_idx_type i = 0; i < b_nr; i++) |
4632 Bz[i] = b.elem (i, j); | 4705 Bz[i] = b.elem (i, j); |
4633 | 4706 |
4634 status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 4707 status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, |
4635 X_CAST (const double *, Ax), | 4708 Ai, X_CAST (const double *, Ax), |
4636 NULL, | 4709 NULL, |
4637 X_CAST (double *, &Xx[iidx]), | 4710 X_CAST (double *, &Xx[iidx]), |
4638 NULL, | 4711 NULL, |
4639 X_CAST (const double *, Bz), | 4712 X_CAST (const double *, Bz), |
4640 NULL, Numeric, | 4713 NULL, Numeric, |
4644 if (status < 0) | 4717 if (status < 0) |
4645 { | 4718 { |
4646 (*current_liboctave_error_handler) | 4719 (*current_liboctave_error_handler) |
4647 ("SparseComplexMatrix::solve solve failed"); | 4720 ("SparseComplexMatrix::solve solve failed"); |
4648 | 4721 |
4649 umfpack_zi_report_status (control, status); | 4722 UMFPACK_ZNAME (report_status) (control, status); |
4650 | 4723 |
4651 err = -1; | 4724 err = -1; |
4652 | 4725 |
4653 break; | 4726 break; |
4654 } | 4727 } |
4671 rcond); | 4744 rcond); |
4672 | 4745 |
4673 } | 4746 } |
4674 #endif | 4747 #endif |
4675 | 4748 |
4676 umfpack_zi_report_info (control, info); | 4749 UMFPACK_ZNAME (report_info) (control, info); |
4677 | 4750 |
4678 umfpack_zi_free_numeric (&Numeric); | 4751 UMFPACK_ZNAME (free_numeric) (&Numeric); |
4679 } | 4752 } |
4680 #else | 4753 #else |
4681 (*current_liboctave_error_handler) ("UMFPACK not installed"); | 4754 (*current_liboctave_error_handler) ("UMFPACK not installed"); |
4682 #endif | 4755 #endif |
4683 } | 4756 } |
4760 | 4833 |
4761 #ifdef UMFPACK_SEPARATE_SPLIT | 4834 #ifdef UMFPACK_SEPARATE_SPLIT |
4762 for (octave_idx_type i = 0; i < b_nr; i++) | 4835 for (octave_idx_type i = 0; i < b_nr; i++) |
4763 Bx[i] = b.elem (i, j); | 4836 Bx[i] = b.elem (i, j); |
4764 | 4837 |
4765 status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 4838 status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, |
4766 X_CAST (const double *, Ax), | 4839 Ai, X_CAST (const double *, Ax), |
4767 NULL, | 4840 NULL, |
4768 X_CAST (double *, Xx), NULL, | 4841 X_CAST (double *, Xx), NULL, |
4769 Bx, Bz, Numeric, control, | 4842 Bx, Bz, Numeric, control, |
4770 info); | 4843 info); |
4771 #else | 4844 #else |
4772 for (octave_idx_type i = 0; i < b_nr; i++) | 4845 for (octave_idx_type i = 0; i < b_nr; i++) |
4773 Bz[i] = b.elem (i, j); | 4846 Bz[i] = b.elem (i, j); |
4774 | 4847 |
4775 status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 4848 status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai, |
4776 X_CAST (const double *, Ax), | 4849 X_CAST (const double *, Ax), |
4777 NULL, | 4850 NULL, |
4778 X_CAST (double *, Xx), NULL, | 4851 X_CAST (double *, Xx), NULL, |
4779 X_CAST (double *, Bz), NULL, | 4852 X_CAST (double *, Bz), NULL, |
4780 Numeric, control, | 4853 Numeric, control, |
4783 if (status < 0) | 4856 if (status < 0) |
4784 { | 4857 { |
4785 (*current_liboctave_error_handler) | 4858 (*current_liboctave_error_handler) |
4786 ("SparseComplexMatrix::solve solve failed"); | 4859 ("SparseComplexMatrix::solve solve failed"); |
4787 | 4860 |
4788 umfpack_zi_report_status (control, status); | 4861 UMFPACK_ZNAME (report_status) (control, status); |
4789 | 4862 |
4790 err = -1; | 4863 err = -1; |
4791 | 4864 |
4792 break; | 4865 break; |
4793 } | 4866 } |
4831 rcond); | 4904 rcond); |
4832 | 4905 |
4833 } | 4906 } |
4834 #endif | 4907 #endif |
4835 | 4908 |
4836 umfpack_zi_report_info (control, info); | 4909 UMFPACK_ZNAME (report_info) (control, info); |
4837 | 4910 |
4838 umfpack_zi_free_numeric (&Numeric); | 4911 UMFPACK_ZNAME (free_numeric) (&Numeric); |
4839 } | 4912 } |
4840 #else | 4913 #else |
4841 (*current_liboctave_error_handler) ("UMFPACK not installed"); | 4914 (*current_liboctave_error_handler) ("UMFPACK not installed"); |
4842 #endif | 4915 #endif |
4843 } | 4916 } |
4902 Complex *Xx = retval.fortran_vec (); | 4975 Complex *Xx = retval.fortran_vec (); |
4903 | 4976 |
4904 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) | 4977 for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) |
4905 { | 4978 { |
4906 status = | 4979 status = |
4907 umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 4980 UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai, |
4908 X_CAST (const double *, Ax), | 4981 X_CAST (const double *, Ax), |
4909 NULL, X_CAST (double *, &Xx[iidx]), | 4982 NULL, X_CAST (double *, &Xx[iidx]), |
4910 NULL, X_CAST (const double *, &Bx[iidx]), | 4983 NULL, X_CAST (const double *, &Bx[iidx]), |
4911 NULL, Numeric, control, info); | 4984 NULL, Numeric, control, info); |
4912 | 4985 |
4913 if (status < 0) | 4986 if (status < 0) |
4914 { | 4987 { |
4915 (*current_liboctave_error_handler) | 4988 (*current_liboctave_error_handler) |
4916 ("SparseComplexMatrix::solve solve failed"); | 4989 ("SparseComplexMatrix::solve solve failed"); |
4917 | 4990 |
4918 umfpack_zi_report_status (control, status); | 4991 UMFPACK_ZNAME (report_status) (control, status); |
4919 | 4992 |
4920 err = -1; | 4993 err = -1; |
4921 | 4994 |
4922 break; | 4995 break; |
4923 } | 4996 } |
4940 rcond); | 5013 rcond); |
4941 | 5014 |
4942 } | 5015 } |
4943 #endif | 5016 #endif |
4944 | 5017 |
4945 umfpack_zi_report_info (control, info); | 5018 UMFPACK_ZNAME (report_info) (control, info); |
4946 | 5019 |
4947 umfpack_zi_free_numeric (&Numeric); | 5020 UMFPACK_ZNAME (free_numeric) (&Numeric); |
4948 } | 5021 } |
4949 #else | 5022 #else |
4950 (*current_liboctave_error_handler) ("UMFPACK not installed"); | 5023 (*current_liboctave_error_handler) ("UMFPACK not installed"); |
4951 #endif | 5024 #endif |
4952 } | 5025 } |
5020 for (octave_idx_type j = 0; j < b_nc; j++) | 5093 for (octave_idx_type j = 0; j < b_nc; j++) |
5021 { | 5094 { |
5022 for (octave_idx_type i = 0; i < b_nr; i++) | 5095 for (octave_idx_type i = 0; i < b_nr; i++) |
5023 Bx[i] = b (i,j); | 5096 Bx[i] = b (i,j); |
5024 | 5097 |
5025 status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, | 5098 status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, |
5026 X_CAST (const double *, Ax), | 5099 Ai, X_CAST (const double *, Ax), |
5027 NULL, X_CAST (double *, Xx), | 5100 NULL, X_CAST (double *, Xx), |
5028 NULL, X_CAST (double *, Bx), | 5101 NULL, X_CAST (double *, Bx), |
5029 NULL, Numeric, control, info); | 5102 NULL, Numeric, control, info); |
5030 | 5103 |
5031 if (status < 0) | 5104 if (status < 0) |
5032 { | 5105 { |
5033 (*current_liboctave_error_handler) | 5106 (*current_liboctave_error_handler) |
5034 ("SparseComplexMatrix::solve solve failed"); | 5107 ("SparseComplexMatrix::solve solve failed"); |
5035 | 5108 |
5036 umfpack_zi_report_status (control, status); | 5109 UMFPACK_ZNAME (report_status) (control, status); |
5037 | 5110 |
5038 err = -1; | 5111 err = -1; |
5039 | 5112 |
5040 break; | 5113 break; |
5041 } | 5114 } |
5079 rcond); | 5152 rcond); |
5080 | 5153 |
5081 } | 5154 } |
5082 #endif | 5155 #endif |
5083 | 5156 |
5084 umfpack_zi_report_info (control, info); | 5157 UMFPACK_ZNAME (report_info) (control, info); |
5085 | 5158 |
5086 umfpack_zi_free_numeric (&Numeric); | 5159 UMFPACK_ZNAME (free_numeric) (&Numeric); |
5087 } | 5160 } |
5088 #else | 5161 #else |
5089 (*current_liboctave_error_handler) ("UMFPACK not installed"); | 5162 (*current_liboctave_error_handler) ("UMFPACK not installed"); |
5090 #endif | 5163 #endif |
5091 } | 5164 } |
5122 ComplexMatrix | 5195 ComplexMatrix |
5123 SparseComplexMatrix::solve (SparseType &mattype, const Matrix& b, octave_idx_type& err, | 5196 SparseComplexMatrix::solve (SparseType &mattype, const Matrix& b, octave_idx_type& err, |
5124 double& rcond, | 5197 double& rcond, |
5125 solve_singularity_handler sing_handler) const | 5198 solve_singularity_handler sing_handler) const |
5126 { | 5199 { |
5127 int typ = mattype.type (); | 5200 int typ = mattype.type (false); |
5128 | 5201 |
5129 if (typ == SparseType::Unknown) | 5202 if (typ == SparseType::Unknown) |
5130 typ = mattype.type (*this); | 5203 typ = mattype.type (*this); |
5131 | 5204 |
5132 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) | 5205 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) |
5176 SparseComplexMatrix | 5249 SparseComplexMatrix |
5177 SparseComplexMatrix::solve (SparseType &mattype, const SparseMatrix& b, | 5250 SparseComplexMatrix::solve (SparseType &mattype, const SparseMatrix& b, |
5178 octave_idx_type& err, double& rcond, | 5251 octave_idx_type& err, double& rcond, |
5179 solve_singularity_handler sing_handler) const | 5252 solve_singularity_handler sing_handler) const |
5180 { | 5253 { |
5181 int typ = mattype.type (); | 5254 int typ = mattype.type (false); |
5182 | 5255 |
5183 if (typ == SparseType::Unknown) | 5256 if (typ == SparseType::Unknown) |
5184 typ = mattype.type (*this); | 5257 typ = mattype.type (*this); |
5185 | 5258 |
5186 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) | 5259 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) |
5230 ComplexMatrix | 5303 ComplexMatrix |
5231 SparseComplexMatrix::solve (SparseType &mattype, const ComplexMatrix& b, | 5304 SparseComplexMatrix::solve (SparseType &mattype, const ComplexMatrix& b, |
5232 octave_idx_type& err, double& rcond, | 5305 octave_idx_type& err, double& rcond, |
5233 solve_singularity_handler sing_handler) const | 5306 solve_singularity_handler sing_handler) const |
5234 { | 5307 { |
5235 int typ = mattype.type (); | 5308 int typ = mattype.type (false); |
5236 | 5309 |
5237 if (typ == SparseType::Unknown) | 5310 if (typ == SparseType::Unknown) |
5238 typ = mattype.type (*this); | 5311 typ = mattype.type (*this); |
5239 | 5312 |
5240 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) | 5313 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) |
5285 SparseComplexMatrix | 5358 SparseComplexMatrix |
5286 SparseComplexMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, | 5359 SparseComplexMatrix::solve (SparseType &mattype, const SparseComplexMatrix& b, |
5287 octave_idx_type& err, double& rcond, | 5360 octave_idx_type& err, double& rcond, |
5288 solve_singularity_handler sing_handler) const | 5361 solve_singularity_handler sing_handler) const |
5289 { | 5362 { |
5290 int typ = mattype.type (); | 5363 int typ = mattype.type (false); |
5291 | 5364 |
5292 if (typ == SparseType::Unknown) | 5365 if (typ == SparseType::Unknown) |
5293 typ = mattype.type (*this); | 5366 typ = mattype.type (*this); |
5294 | 5367 |
5295 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) | 5368 if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) |