Mercurial > octave-nkf
diff liboctave/dSparse.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 |
line wrap: on
line diff
--- a/liboctave/dSparse.cc Fri Apr 29 05:20:01 2005 +0000 +++ b/liboctave/dSparse.cc Fri Apr 29 13:04:25 2005 +0000 @@ -106,7 +106,7 @@ F77_CHAR_ARG_LEN_DECL); F77_RET_T - F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, Complex*, Complex*, + F77_FUNC (zptsv, ZPTSV) (const octave_idx_type&, const octave_idx_type&, double*, Complex*, Complex*, const octave_idx_type&, octave_idx_type&); F77_RET_T @@ -735,7 +735,7 @@ // Setup the control parameters Matrix Control (UMFPACK_CONTROL, 1); double *control = Control.fortran_vec (); - umfpack_di_defaults (control); + UMFPACK_DNAME (defaults) (control); double tmp = Voctave_sparse_controls.get_key ("spumoni"); if (!xisnan (tmp)) @@ -756,38 +756,38 @@ // Turn-off UMFPACK scaling for LU Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; - umfpack_di_report_control (control); + UMFPACK_DNAME (report_control) (control); const octave_idx_type *Ap = cidx (); const octave_idx_type *Ai = ridx (); const double *Ax = data (); - umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); + UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control); void *Symbolic; Matrix Info (1, UMFPACK_INFO); double *info = Info.fortran_vec (); - int status = umfpack_di_qsymbolic (nr, nc, Ap, Ai, Ax, NULL, - &Symbolic, control, info); + int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, + Ax, NULL, &Symbolic, control, info); if (status < 0) { (*current_liboctave_error_handler) ("SparseMatrix::determinant symbolic factorization failed"); - umfpack_di_report_status (control, status); - umfpack_di_report_info (control, info); - - umfpack_di_free_symbolic (&Symbolic) ; + UMFPACK_DNAME (report_status) (control, status); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_symbolic) (&Symbolic) ; } else { - umfpack_di_report_symbolic (Symbolic, control); + UMFPACK_DNAME (report_symbolic) (Symbolic, control); void *Numeric; - status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, - control, info) ; - umfpack_di_free_symbolic (&Symbolic) ; + status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, + &Numeric, control, info) ; + UMFPACK_DNAME (free_symbolic) (&Symbolic) ; rcond = Info (UMFPACK_RCOND); @@ -796,29 +796,29 @@ (*current_liboctave_error_handler) ("SparseMatrix::determinant numeric factorization failed"); - umfpack_di_report_status (control, status); - umfpack_di_report_info (control, info); - - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (report_status) (control, status); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_numeric) (&Numeric); } else { - umfpack_di_report_numeric (Numeric, control); + UMFPACK_DNAME (report_numeric) (Numeric, control); double d[2]; - status = umfpack_di_get_determinant (&d[0], &d[1], Numeric, - info); + status = UMFPACK_DNAME (get_determinant) (&d[0], + &d[1], Numeric, info); if (status < 0) { (*current_liboctave_error_handler) ("SparseMatrix::determinant error calculating determinant"); - umfpack_di_report_status (control, status); - umfpack_di_report_info (control, info); - - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (report_status) (control, status); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_numeric) (&Numeric); } else retval = DET (d); @@ -1131,13 +1131,9 @@ if (typ == SparseType::Permuted_Upper) { - retval.resize (b.rows (), b.cols ()); + retval.resize (nr, b_cols); + octave_idx_type *perm = mattype.triangular_perm (); OCTAVE_LOCAL_BUFFER (double, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); for (octave_idx_type j = 0; j < b_cols; j++) { @@ -1146,28 +1142,29 @@ for (octave_idx_type k = nr-1; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + octave_idx_type kidx = perm[k]; + + if (work[k] != 0.) { - if (ridx(cidx(iidx+1)-1) != iidx) + if (ridx(cidx(kidx+1)-1) != k) { err = -2; goto triangular_error; } - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) + double tmp = work[k] / data(cidx(kidx+1)-1); + work[k] = tmp; + for (octave_idx_type i = cidx(kidx); + i < cidx(kidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + octave_idx_type iidx = ridx(i); + work[iidx] = work[iidx] - tmp * data(i); } } } for (octave_idx_type i = 0; i < nr; i++) - retval (i, j) = work[p_perm[i]]; + retval (perm[i], j) = work[i]; } // Calculation of 1-norm of inv(*this) @@ -1176,19 +1173,19 @@ for (octave_idx_type j = 0; j < nr; j++) { - work[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = j; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - - if (work[iidx] != 0.) + octave_idx_type iidx = perm[k]; + + if (work[k] != 0.) { - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; + double tmp = work[k] / data(cidx(iidx+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; + octave_idx_type idx2 = ridx(i); work[idx2] = work[idx2] - tmp * data(i); } } @@ -1347,12 +1344,12 @@ if (typ == SparseType::Permuted_Upper) { + octave_idx_type *perm = mattype.triangular_perm (); OCTAVE_LOCAL_BUFFER (double, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + + OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); + for (octave_idx_type i = 0; i < nr; i++) + rperm[perm[i]] = i; for (octave_idx_type j = 0; j < b_nc; j++) { @@ -1363,22 +1360,23 @@ for (octave_idx_type k = nr-1; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + octave_idx_type kidx = perm[k]; + + if (work[k] != 0.) { - if (ridx(cidx(iidx+1)-1) != iidx) + if (ridx(cidx(kidx+1)-1) != k) { err = -2; goto triangular_error; } - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) + double tmp = work[k] / data(cidx(kidx+1)-1); + work[k] = tmp; + for (octave_idx_type i = cidx(kidx); + i < cidx(kidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + octave_idx_type iidx = ridx(i); + work[iidx] = work[iidx] - tmp * data(i); } } } @@ -1399,10 +1397,10 @@ } for (octave_idx_type i = 0; i < nr; i++) - if (work[p_perm[i]] != 0.) + if (work[rperm[i]] != 0.) { retval.xridx(ii) = i; - retval.xdata(ii++) = work[p_perm[i]]; + retval.xdata(ii++) = work[rperm[i]]; } retval.xcidx(j+1) = ii; } @@ -1415,19 +1413,19 @@ for (octave_idx_type j = 0; j < nr; j++) { - work[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = j; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - - if (work[iidx] != 0.) + octave_idx_type iidx = perm[k]; + + if (work[k] != 0.) { - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; + double tmp = work[k] / data(cidx(iidx+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; + octave_idx_type idx2 = ridx(i); work[idx2] = work[idx2] - tmp * data(i); } } @@ -1603,75 +1601,71 @@ if (typ == SparseType::Permuted_Upper) { - retval.resize (b.rows (), b.cols ()); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + retval.resize (nr, b_nc); + octave_idx_type *perm = mattype.triangular_perm (); + OCTAVE_LOCAL_BUFFER (Complex, cwork, nr); for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) - work[i] = b(i,j); + cwork[i] = b(i,j); for (octave_idx_type k = nr-1; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + octave_idx_type kidx = perm[k]; + + if (cwork[k] != 0.) { - if (ridx(cidx(iidx+1)-1) != iidx) + if (ridx(cidx(kidx+1)-1) != k) { err = -2; goto triangular_error; } - Complex tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) + Complex tmp = cwork[k] / data(cidx(kidx+1)-1); + cwork[k] = tmp; + for (octave_idx_type i = cidx(kidx); + i < cidx(kidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + octave_idx_type iidx = ridx(i); + cwork[iidx] = cwork[iidx] - tmp * data(i); } } } for (octave_idx_type i = 0; i < nr; i++) - retval (i, j) = work[p_perm[i]]; - + retval (perm[i], j) = cwork[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (double, work2, nr); + OCTAVE_LOCAL_BUFFER (double, work, nr); for (octave_idx_type i = 0; i < nr; i++) - work2[i] = 0.; + work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { - work2[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = j; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - - if (work2[iidx] != 0.) + octave_idx_type iidx = perm[k]; + + if (work[k] != 0.) { - double tmp = work2[iidx] / data(cidx(iidx+1)-1); - work2[iidx] = tmp; + double tmp = work[k] / data(cidx(iidx+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work2[idx2] = work2[idx2] - tmp * data(i); + octave_idx_type idx2 = ridx(i); + work[idx2] = work[idx2] - tmp * data(i); } } } double atmp = 0; for (octave_idx_type i = 0; i < j+1; i++) { - atmp += fabs(work2[i]); - work2[i] = 0.; + atmp += fabs(work[i]); + work[i] = 0.; } if (atmp > ainvnorm) ainvnorm = atmp; @@ -1822,38 +1816,39 @@ if (typ == SparseType::Permuted_Upper) { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + octave_idx_type *perm = mattype.triangular_perm (); + OCTAVE_LOCAL_BUFFER (Complex, cwork, nr); + + OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); + for (octave_idx_type i = 0; i < nr; i++) + rperm[perm[i]] = i; for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) - work[i] = 0.; + cwork[i] = 0.; for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) - work[b.ridx(i)] = b.data(i); + cwork[b.ridx(i)] = b.data(i); for (octave_idx_type k = nr-1; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + octave_idx_type kidx = perm[k]; + + if (cwork[k] != 0.) { - if (ridx(cidx(iidx+1)-1) != iidx) + if (ridx(cidx(kidx+1)-1) != k) { err = -2; goto triangular_error; } - Complex tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) + Complex tmp = cwork[k] / data(cidx(kidx+1)-1); + cwork[k] = tmp; + for (octave_idx_type i = cidx(kidx); + i < cidx(kidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + octave_idx_type iidx = ridx(i); + cwork[iidx] = cwork[iidx] - tmp * data(i); } } } @@ -1862,7 +1857,7 @@ // retval if needed octave_idx_type new_nnz = 0; for (octave_idx_type i = 0; i < nr; i++) - if (work[i] != 0.) + if (cwork[i] != 0.) new_nnz++; if (ii + new_nnz > x_nz) @@ -1874,45 +1869,45 @@ } for (octave_idx_type i = 0; i < nr; i++) - if (work[p_perm[i]] != 0.) + if (cwork[rperm[i]] != 0.) { retval.xridx(ii) = i; - retval.xdata(ii++) = work[p_perm[i]]; + retval.xdata(ii++) = cwork[rperm[i]]; } retval.xcidx(j+1) = ii; } retval.maybe_compress (); - OCTAVE_LOCAL_BUFFER (double, work2, nr); // Calculation of 1-norm of inv(*this) + OCTAVE_LOCAL_BUFFER (double, work, nr); for (octave_idx_type i = 0; i < nr; i++) - work2[i] = 0.; + work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { - work2[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = j; k >= 0; k--) { - octave_idx_type iidx = q_perm[k]; - - if (work2[iidx] != 0.) + octave_idx_type iidx = perm[k]; + + if (work[k] != 0.) { - double tmp = work2[iidx] / data(cidx(iidx+1)-1); - work2[iidx] = tmp; + double tmp = work[k] / data(cidx(iidx+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(iidx); i < cidx(iidx+1)-1; i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work2[idx2] = work2[idx2] - tmp * data(i); + octave_idx_type idx2 = ridx(i); + work[idx2] = work[idx2] - tmp * data(i); } } } double atmp = 0; for (octave_idx_type i = 0; i < j+1; i++) { - atmp += fabs(work2[i]); - work2[i] = 0.; + atmp += fabs(work[i]); + work[i] = 0.; } if (atmp > ainvnorm) ainvnorm = atmp; @@ -2084,42 +2079,48 @@ { retval.resize (b.rows (), b.cols ()); OCTAVE_LOCAL_BUFFER (double, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + octave_idx_type *perm = mattype.triangular_perm (); for (octave_idx_type j = 0; j < b_cols; j++) { for (octave_idx_type i = 0; i < nr; i++) - work[i] = b(i,j); + work[perm[i]] = b(i,j); for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + if (work[k] != 0.) { - if (ridx(cidx(iidx)) != iidx) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + if (minr != k) { err = -2; goto triangular_error; } - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } for (octave_idx_type i = 0; i < nr; i++) - retval (i, j) = work[p_perm[i]]; - + retval (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) @@ -2128,25 +2129,37 @@ for (octave_idx_type j = 0; j < nr; j++) { - work[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - - if (work[iidx] != 0.) + if (work[k] != 0.) { - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } + double atmp = 0; - for (octave_idx_type i = 0; i < j+1; i++) + for (octave_idx_type i = j; i < nr; i++) { atmp += fabs(work[i]); work[i] = 0.; @@ -2302,37 +2315,44 @@ if (typ == SparseType::Permuted_Lower) { OCTAVE_LOCAL_BUFFER (double, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + octave_idx_type *perm = mattype.triangular_perm (); for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) work[i] = 0.; for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) - work[b.ridx(i)] = b.data(i); + work[perm[b.ridx(i)]] = b.data(i); for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + if (work[k] != 0.) { - if (ridx(cidx(iidx)) != iidx) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + if (minr != k) { err = -2; goto triangular_error; } - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } @@ -2353,10 +2373,10 @@ } for (octave_idx_type i = 0; i < nr; i++) - if (work[p_perm[i]] != 0.) + if (work[i] != 0.) { retval.xridx(ii) = i; - retval.xdata(ii++) = work[p_perm[i]]; + retval.xdata(ii++) = work[i]; } retval.xcidx(j+1) = ii; } @@ -2369,25 +2389,37 @@ for (octave_idx_type j = 0; j < nr; j++) { - work[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - - if (work[iidx] != 0.) + if (work[k] != 0.) { - double tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } + double atmp = 0; - for (octave_idx_type i = 0; i < j+1; i++) + for (octave_idx_type i = j; i < nr; i++) { atmp += fabs(work[i]); work[i] = 0.; @@ -2561,74 +2593,92 @@ if (typ == SparseType::Permuted_Lower) { retval.resize (b.rows (), b.cols ()); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + OCTAVE_LOCAL_BUFFER (Complex, cwork, nr); + octave_idx_type *perm = mattype.triangular_perm (); for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) - work[i] = b(i,j); + cwork[perm[i]] = b(i,j); for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + if (cwork[k] != 0.) { - if (ridx(cidx(iidx)) != iidx) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + if (minr != k) { err = -2; goto triangular_error; } - Complex tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + Complex tmp = cwork[k] / data(mini); + cwork[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + cwork[iidx] = cwork[iidx] - tmp * data(i); } } } for (octave_idx_type i = 0; i < nr; i++) - retval (i, j) = work[p_perm[i]]; - + retval (i, j) = cwork[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (double, work2, nr); + OCTAVE_LOCAL_BUFFER (double, work, nr); for (octave_idx_type i = 0; i < nr; i++) - work2[i] = 0.; + work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { - work2[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - - if (work2[iidx] != 0.) + if (work[k] != 0.) { - double tmp = work2[iidx] / data(cidx(iidx+1)-1); - work2[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work2[idx2] = work2[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } + double atmp = 0; - for (octave_idx_type i = 0; i < j+1; i++) + for (octave_idx_type i = j; i < nr; i++) { - atmp += fabs(work2[i]); - work2[i] = 0.; + atmp += fabs(work[i]); + work[i] = 0.; } if (atmp > ainvnorm) ainvnorm = atmp; @@ -2781,38 +2831,45 @@ if (typ == SparseType::Permuted_Lower) { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - octave_idx_type *p_perm = mattype.triangular_row_perm (); - octave_idx_type *q_perm = mattype.triangular_col_perm (); - - (*current_liboctave_warning_handler) - ("SparseMatrix::solve XXX FIXME XXX permuted triangular code not tested"); + OCTAVE_LOCAL_BUFFER (Complex, cwork, nr); + octave_idx_type *perm = mattype.triangular_perm (); for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) - work[i] = 0.; + cwork[i] = 0.; for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) - work[b.ridx(i)] = b.data(i); + cwork[perm[b.ridx(i)]] = b.data(i); for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - if (work[iidx] != 0.) + if (cwork[k] != 0.) { - if (ridx(cidx(iidx)) != iidx) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + if (minr != k) { err = -2; goto triangular_error; } - Complex tmp = work[iidx] / data(cidx(iidx+1)-1); - work[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + Complex tmp = cwork[k] / data(mini); + cwork[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work[idx2] = - work[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + cwork[iidx] = cwork[iidx] - tmp * data(i); } } } @@ -2821,7 +2878,7 @@ // retval if needed octave_idx_type new_nnz = 0; for (octave_idx_type i = 0; i < nr; i++) - if (work[i] != 0.) + if (cwork[i] != 0.) new_nnz++; if (ii + new_nnz > x_nz) @@ -2833,10 +2890,10 @@ } for (octave_idx_type i = 0; i < nr; i++) - if (work[p_perm[i]] != 0.) + if (cwork[i] != 0.) { retval.xridx(ii) = i; - retval.xdata(ii++) = work[p_perm[i]]; + retval.xdata(ii++) = cwork[i]; } retval.xcidx(j+1) = ii; } @@ -2844,34 +2901,46 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (double, work2, nr); + OCTAVE_LOCAL_BUFFER (double, work, nr); for (octave_idx_type i = 0; i < nr; i++) - work2[i] = 0.; + work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { - work2[q_perm[j]] = 1.; + work[j] = 1.; for (octave_idx_type k = 0; k < nr; k++) { - octave_idx_type iidx = q_perm[k]; - - if (work2[iidx] != 0.) + if (work[k] != 0.) { - double tmp = work2[iidx] / data(cidx(iidx+1)-1); - work2[iidx] = tmp; - for (octave_idx_type i = cidx(iidx)+1; i < cidx(iidx+1); i++) + octave_idx_type minr = nr; + octave_idx_type mini = 0; + + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + if (perm[ridx(i)] < minr) + { + minr = perm[ridx(i)]; + mini = i; + } + + double tmp = work[k] / data(mini); + work[k] = tmp; + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) { - octave_idx_type idx2 = q_perm[ridx(i)]; - work2[idx2] = work2[idx2] - tmp * data(i); + if (i == mini) + continue; + + octave_idx_type iidx = perm[ridx(i)]; + work[iidx] = work[iidx] - tmp * data(i); } } } + double atmp = 0; - for (octave_idx_type i = 0; i < j+1; i++) + for (octave_idx_type i = j; i < nr; i++) { - atmp += fabs(work2[i]); - work2[i] = 0.; + atmp += fabs(work[i]); + work[i] = 0.; } if (atmp > ainvnorm) ainvnorm = atmp; @@ -3115,7 +3184,7 @@ else if (ridx(i) == j + 1) DL[j] = data(i); else if (ridx(i) == j - 1) - DU[j] = data(i); + DU[j-1] = data(i); } } @@ -3211,7 +3280,7 @@ else if (ridx(i) == j + 1) DL[j] = data(i); else if (ridx(i) == j - 1) - DU[j] = data(i); + DU[j-1] = data(i); } } @@ -3319,10 +3388,9 @@ volatile int typ = mattype.type (); mattype.info (); - // Note can't treat symmetric case as there is no dpttrf function if (typ == SparseType::Tridiagonal_Hermitian) { - OCTAVE_LOCAL_BUFFER (Complex, D, nr); + OCTAVE_LOCAL_BUFFER (double, D, nr); OCTAVE_LOCAL_BUFFER (Complex, DL, nr - 1); if (mattype.is_dense ()) @@ -3416,7 +3484,7 @@ else if (ridx(i) == j + 1) DL[j] = data(i); else if (ridx(i) == j - 1) - DU[j] = data(i); + DU[j-1] = data(i); } } @@ -3516,7 +3584,7 @@ else if (ridx(i) == j + 1) DL[j] = data(i); else if (ridx(i) == j - 1) - DU[j] = data(i); + DU[j-1] = data(i); } } @@ -3564,7 +3632,6 @@ Bz[i] = std::imag (c); } - F77_XFCN (dgttrs, DGTTRS, (F77_CONST_CHAR_ARG2 (&job, 1), nr, 1, DL, D, DU, DU2, pipvt, @@ -4682,7 +4749,7 @@ // Setup the control parameters Control = Matrix (UMFPACK_CONTROL, 1); double *control = Control.fortran_vec (); - umfpack_di_defaults (control); + UMFPACK_DNAME (defaults) (control); double tmp = Voctave_sparse_controls.get_key ("spumoni"); if (!xisnan (tmp)) @@ -4699,7 +4766,7 @@ if (!xisnan (tmp)) Control (UMFPACK_FIXQ) = tmp; - umfpack_di_report_control (control); + UMFPACK_DNAME (report_control) (control); const octave_idx_type *Ap = cidx (); const octave_idx_type *Ai = ridx (); @@ -4707,12 +4774,12 @@ octave_idx_type nr = rows (); octave_idx_type nc = cols (); - umfpack_di_report_matrix (nr, nc, Ap, Ai, Ax, 1, control); + UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control); void *Symbolic; Info = Matrix (1, UMFPACK_INFO); double *info = Info.fortran_vec (); - int status = umfpack_di_qsymbolic (nr, nc, Ap, Ai, Ax, NULL, + int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, NULL, &Symbolic, control, info); if (status < 0) @@ -4721,18 +4788,18 @@ ("SparseMatrix::solve symbolic factorization failed"); err = -1; - umfpack_di_report_status (control, status); - umfpack_di_report_info (control, info); - - umfpack_di_free_symbolic (&Symbolic) ; + UMFPACK_DNAME (report_status) (control, status); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_symbolic) (&Symbolic) ; } else { - umfpack_di_report_symbolic (Symbolic, control); - - status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, - control, info) ; - umfpack_di_free_symbolic (&Symbolic) ; + UMFPACK_DNAME (report_symbolic) (Symbolic, control); + + status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, + &Numeric, control, info) ; + UMFPACK_DNAME (free_symbolic) (&Symbolic) ; #ifdef HAVE_LSSOLVE rcond = Info (UMFPACK_RCOND); @@ -4741,7 +4808,7 @@ if (status == UMFPACK_WARNING_singular_matrix || rcond_plus_one == 1.0 || xisnan (rcond)) { - umfpack_di_report_numeric (Numeric, control); + UMFPACK_DNAME (report_numeric) (Numeric, control); err = -2; @@ -4760,19 +4827,19 @@ (*current_liboctave_error_handler) ("SparseMatrix::solve numeric factorization failed"); - umfpack_di_report_status (control, status); - umfpack_di_report_info (control, info); + UMFPACK_DNAME (report_status) (control, status); + UMFPACK_DNAME (report_info) (control, info); err = -1; } else { - umfpack_di_report_numeric (Numeric, control); + UMFPACK_DNAME (report_numeric) (Numeric, control); } } if (err != 0) - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (free_numeric) (&Numeric); #else (*current_liboctave_error_handler) ("UMFPACK not installed"); @@ -4836,15 +4903,15 @@ for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr) { - status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, - &result[iidx], &Bx[iidx], + status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, + Ai, Ax, &result[iidx], &Bx[iidx], Numeric, control, info); if (status < 0) { (*current_liboctave_error_handler) ("SparseMatrix::solve solve failed"); - umfpack_di_report_status (control, status); + UMFPACK_DNAME (report_status) (control, status); err = -1; @@ -4871,9 +4938,9 @@ } #endif - umfpack_di_report_info (control, info); + UMFPACK_DNAME (report_info) (control, info); - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (free_numeric) (&Numeric); } #else (*current_liboctave_error_handler) ("UMFPACK not installed"); @@ -4951,15 +5018,15 @@ for (octave_idx_type i = 0; i < b_nr; i++) Bx[i] = b.elem (i, j); - status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, Xx, - Bx, Numeric, control, + status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, + Ai, Ax, Xx, Bx, Numeric, control, info); if (status < 0) { (*current_liboctave_error_handler) ("SparseMatrix::solve solve failed"); - umfpack_di_report_status (control, status); + UMFPACK_DNAME (report_status) (control, status); err = -1; @@ -5007,9 +5074,9 @@ } #endif - umfpack_di_report_info (control, info); - - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_numeric) (&Numeric); } #else (*current_liboctave_error_handler) ("UMFPACK not installed"); @@ -5088,11 +5155,11 @@ Bz[i] = std::imag (c); } - status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, - Xx, Bx, Numeric, control, + status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, + Ai, Ax, Xx, Bx, Numeric, control, info); - int status2 = umfpack_di_solve (UMFPACK_A, Ap, Ai, - Ax, Xz, Bz, Numeric, + int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, + Ap, Ai, Ax, Xz, Bz, Numeric, control, info) ; if (status < 0 || status2 < 0) @@ -5100,7 +5167,7 @@ (*current_liboctave_error_handler) ("SparseMatrix::solve solve failed"); - umfpack_di_report_status (control, status); + UMFPACK_DNAME (report_status) (control, status); err = -1; @@ -5130,9 +5197,9 @@ } #endif - umfpack_di_report_info (control, info); - - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_numeric) (&Numeric); } #else (*current_liboctave_error_handler) ("UMFPACK not installed"); @@ -5217,11 +5284,11 @@ Bz[i] = std::imag (c); } - status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, Xx, - Bx, Numeric, control, + status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap, + Ai, Ax, Xx, Bx, Numeric, control, info); - int status2 = umfpack_di_solve (UMFPACK_A, Ap, Ai, - Ax, Xz, Bz, Numeric, + int status2 = UMFPACK_DNAME (solve) (UMFPACK_A, + Ap, Ai, Ax, Xz, Bz, Numeric, control, info) ; if (status < 0 || status2 < 0) @@ -5229,7 +5296,7 @@ (*current_liboctave_error_handler) ("SparseMatrix::solve solve failed"); - umfpack_di_report_status (control, status); + UMFPACK_DNAME (report_status) (control, status); err = -1; @@ -5277,9 +5344,9 @@ } #endif - umfpack_di_report_info (control, info); - - umfpack_di_free_numeric (&Numeric); + UMFPACK_DNAME (report_info) (control, info); + + UMFPACK_DNAME (free_numeric) (&Numeric); } #else (*current_liboctave_error_handler) ("UMFPACK not installed"); @@ -5319,7 +5386,7 @@ double& rcond, solve_singularity_handler sing_handler) const { - int typ = mattype.type (); + int typ = mattype.type (false); if (typ == SparseType::Unknown) typ = mattype.type (*this); @@ -5373,7 +5440,7 @@ octave_idx_type& err, double& rcond, solve_singularity_handler sing_handler) const { - int typ = mattype.type (); + int typ = mattype.type (false); if (typ == SparseType::Unknown) typ = mattype.type (*this); @@ -5427,7 +5494,7 @@ octave_idx_type& err, double& rcond, solve_singularity_handler sing_handler) const { - int typ = mattype.type (); + int typ = mattype.type (false); if (typ == SparseType::Unknown) typ = mattype.type (*this); @@ -5481,7 +5548,7 @@ octave_idx_type& err, double& rcond, solve_singularity_handler sing_handler) const { - int typ = mattype.type (); + int typ = mattype.type (false); if (typ == SparseType::Unknown) typ = mattype.type (*this);