Mercurial > hg > octave-lyh
diff liboctave/CSparse.cc @ 5630:512d0d11ae39
[project @ 2006-02-20 22:05:30 by dbateman]
author | dbateman |
---|---|
date | Mon, 20 Feb 2006 22:05:32 +0000 |
parents | 9761b7d24e9e |
children | 69a4f320d95a |
line wrap: on
line diff
--- a/liboctave/CSparse.cc +++ b/liboctave/CSparse.cc @@ -1107,16 +1107,18 @@ } ComplexMatrix -SparseComplexMatrix::dsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, +SparseComplexMatrix::dsolve (SparseType &mattype, const Matrix& b, + octave_idx_type& err, double& rcond, solve_singularity_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc < nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1128,18 +1130,19 @@ if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) { - retval.resize (b.rows (), b.cols()); + retval.resize (nc, b.cols(), Complex(0.,0.)); if (typ == SparseType::Diagonal) for (octave_idx_type j = 0; j < b.cols(); j++) - for (octave_idx_type i = 0; i < nr; i++) - retval(i,j) = b(i,j) / data (i); + for (octave_idx_type i = 0; i < nm; i++) + retval(i,j) = b(i,j) / data (i); else for (octave_idx_type j = 0; j < b.cols(); j++) - for (octave_idx_type i = 0; i < nr; i++) - retval(i,j) = b(ridx(i),j) / data (i); + for (octave_idx_type k = 0; k < nc; k++) + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + retval(k,j) = b(ridx(i),j) / data (i); double dmax = 0., dmin = octave_Inf; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) { double tmp = std::abs(data(i)); if (tmp > dmax) @@ -1158,15 +1161,17 @@ SparseComplexMatrix SparseComplexMatrix::dsolve (SparseType &mattype, const SparseMatrix& b, - octave_idx_type& err, double& rcond, solve_singularity_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc < nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1178,10 +1183,9 @@ if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) { - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; @@ -1198,27 +1202,28 @@ else for (octave_idx_type j = 0; j < b.cols(); j++) { - for (octave_idx_type i = 0; i < nr; i++) - { - bool found = false; - octave_idx_type k; - for (k = b.cidx(j); k < b.cidx(j+1); k++) - if (ridx(i) == b.ridx(k)) + for (octave_idx_type l = 0; l < nc; l++) + for (octave_idx_type i = cidx(l); i < cidx(l+1); i++) + { + bool found = false; + octave_idx_type k; + for (k = b.cidx(j); k < b.cidx(j+1); k++) + if (ridx(i) == b.ridx(k)) + { + found = true; + break; + } + if (found) { - found = true; - break; + retval.xridx (ii) = l; + retval.xdata (ii++) = b.data(k) / data (i); } - if (found) - { - retval.xridx (ii) = i; - retval.xdata (ii++) = b.data(k) / data (i); - } - } + } retval.xcidx(j+1) = ii; } double dmax = 0., dmin = octave_Inf; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) { double tmp = std::abs(data(i)); if (tmp > dmax) @@ -1237,15 +1242,17 @@ ComplexMatrix SparseComplexMatrix::dsolve (SparseType &mattype, const ComplexMatrix& b, - octave_idx_type& err, double& rcond, solve_singularity_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc < nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1257,15 +1264,16 @@ if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) { - retval.resize (b.rows (), b.cols()); + retval.resize (nc, b.cols(), Complex(0.,0.)); if (typ == SparseType::Diagonal) for (octave_idx_type j = 0; j < b.cols(); j++) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) retval(i,j) = b(i,j) / data (i); else for (octave_idx_type j = 0; j < b.cols(); j++) - for (octave_idx_type i = 0; i < nr; i++) - retval(i,j) = b(ridx(i),j) / data (i); + for (octave_idx_type k = 0; k < nc; k++) + for (octave_idx_type i = cidx(k); i < cidx(k+1); i++) + retval(k,j) = b(ridx(i),j) / data (i); double dmax = 0., dmin = octave_Inf; for (octave_idx_type i = 0; i < nr; i++) @@ -1287,16 +1295,17 @@ SparseComplexMatrix SparseComplexMatrix::dsolve (SparseType &mattype, const SparseComplexMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc < nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1308,10 +1317,9 @@ if (typ == SparseType::Diagonal || typ == SparseType::Permuted_Diagonal) { - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; @@ -1328,27 +1336,28 @@ else for (octave_idx_type j = 0; j < b.cols(); j++) { - for (octave_idx_type i = 0; i < nr; i++) - { - bool found = false; - octave_idx_type k; - for (k = b.cidx(j); k < b.cidx(j+1); k++) - if (ridx(i) == b.ridx(k)) + for (octave_idx_type l = 0; l < nc; l++) + for (octave_idx_type i = cidx(l); i < cidx(l+1); i++) + { + bool found = false; + octave_idx_type k; + for (k = b.cidx(j); k < b.cidx(j+1); k++) + if (ridx(i) == b.ridx(k)) + { + found = true; + break; + } + if (found) { - found = true; - break; + retval.xridx (ii) = l; + retval.xdata (ii++) = b.data(k) / data (i); } - if (found) - { - retval.xridx (ii) = i; - retval.xdata (ii++) = b.data(k) / data (i); - } - } + } retval.xcidx(j+1) = ii; } double dmax = 0., dmin = octave_Inf; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) { double tmp = std::abs(data(i)); if (tmp > dmax) @@ -1366,17 +1375,18 @@ } ComplexMatrix -SparseComplexMatrix::utsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, - double& rcond, - solve_singularity_handler sing_handler) const +SparseComplexMatrix::utsolve (SparseType &mattype, const Matrix& b, + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1390,11 +1400,11 @@ { double anorm = 0.; double ainvnorm = 0.; - octave_idx_type b_cols = b.cols (); + octave_idx_type b_nc = b.cols (); rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -1405,16 +1415,18 @@ if (typ == SparseType::Permuted_Upper) { - retval.resize (nr, b_cols); + retval.resize (nc, b_nc); octave_idx_type *perm = mattype.triangular_perm (); OCTAVE_LOCAL_BUFFER (Complex, work, nr); - for (octave_idx_type j = 0; j < b_cols; j++) + for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) work[i] = b(i,j); - - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + + for (octave_idx_type k = nc-1; k >= 0; k--) { octave_idx_type kidx = perm[k]; @@ -1437,12 +1449,12 @@ } } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) retval (perm[i], j) = work[i]; } // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -1477,15 +1489,19 @@ } else { - retval = ComplexMatrix (b); - Complex *x_vec = retval.fortran_vec (); - - for (octave_idx_type j = 0; j < b_cols; j++) + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + retval.resize (nc, b_nc); + + for (octave_idx_type j = 0; j < b_nc; j++) { - octave_idx_type offset = j * nr; - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type i = 0; i < nr; i++) + work[i] = b(i,j); + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + + for (octave_idx_type k = nc-1; k >= 0; k--) { - if (x_vec[k+offset] != 0.) + if (work[k] != 0.) { if (ridx(cidx(k+1)-1) != k) { @@ -1493,22 +1509,22 @@ goto triangular_error; } - Complex tmp = x_vec[k+offset] / - data(cidx(k+1)-1); - x_vec[k+offset] = tmp; + Complex tmp = work[k] / data(cidx(k+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) { octave_idx_type iidx = ridx(i); - x_vec[iidx+offset] = - x_vec[iidx+offset] - tmp * data(i); + work[iidx] = work[iidx] - tmp * data(i); } } } + + for (octave_idx_type i = 0; i < nc; i++) + retval.xelem (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -1575,16 +1591,17 @@ SparseComplexMatrix SparseComplexMatrix::utsolve (SparseType &mattype, const SparseMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1601,7 +1618,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -1610,10 +1627,9 @@ anorm = atmp; } - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; octave_idx_type x_nz = b_nz; @@ -1621,20 +1637,20 @@ if (typ == SparseType::Permuted_Upper) { octave_idx_type *perm = mattype.triangular_perm (); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - - OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); - for (octave_idx_type i = 0; i < nr; i++) + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + + OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc); + for (octave_idx_type i = 0; i < nc; i++) rperm[perm[i]] = i; for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type k = nc-1; k >= 0; k--) { octave_idx_type kidx = perm[k]; @@ -1660,7 +1676,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -1672,7 +1688,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[rperm[i]] != 0.) { retval.xridx(ii) = i; @@ -1684,7 +1700,7 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -1719,16 +1735,16 @@ } else { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type k = nc-1; k >= 0; k--) { if (work[k] != 0.) { @@ -1751,7 +1767,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -1763,7 +1779,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -1775,7 +1791,7 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -1841,16 +1857,17 @@ ComplexMatrix SparseComplexMatrix::utsolve (SparseType &mattype, const ComplexMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -1868,7 +1885,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -1879,16 +1896,18 @@ if (typ == SparseType::Permuted_Upper) { - retval.resize (nr, b_nc); + retval.resize (nc, b_nc); octave_idx_type *perm = mattype.triangular_perm (); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); for (octave_idx_type j = 0; j < b_nc; j++) { for (octave_idx_type i = 0; i < nr; i++) work[i] = b(i,j); - - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + + for (octave_idx_type k = nc-1; k >= 0; k--) { octave_idx_type kidx = perm[k]; @@ -1911,12 +1930,12 @@ } } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) retval (perm[i], j) = work[i]; } // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -1951,15 +1970,19 @@ } else { - retval = b; - Complex *x_vec = retval.fortran_vec (); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + retval.resize (nc, b_nc); for (octave_idx_type j = 0; j < b_nc; j++) { - octave_idx_type offset = j * nr; - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type i = 0; i < nr; i++) + work[i] = b(i,j); + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + + for (octave_idx_type k = nc-1; k >= 0; k--) { - if (x_vec[k+offset] != 0.) + if (work[k] != 0.) { if (ridx(cidx(k+1)-1) != k) { @@ -1967,22 +1990,22 @@ goto triangular_error; } - Complex tmp = x_vec[k+offset] / - data(cidx(k+1)-1); - x_vec[k+offset] = tmp; + Complex tmp = work[k] / data(cidx(k+1)-1); + work[k] = tmp; for (octave_idx_type i = cidx(k); i < cidx(k+1)-1; i++) { octave_idx_type iidx = ridx(i); - x_vec[iidx+offset] = - x_vec[iidx+offset] - tmp * data(i); + work[iidx] = work[iidx] - tmp * data(i); } } } + + for (octave_idx_type i = 0; i < nc; i++) + retval.xelem (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -2049,16 +2072,17 @@ SparseComplexMatrix SparseComplexMatrix::utsolve (SparseType &mattype, const SparseComplexMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -2075,7 +2099,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -2084,10 +2108,9 @@ anorm = atmp; } - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; octave_idx_type x_nz = b_nz; @@ -2095,20 +2118,20 @@ if (typ == SparseType::Permuted_Upper) { octave_idx_type *perm = mattype.triangular_perm (); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - - OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nr); - for (octave_idx_type i = 0; i < nr; i++) + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + + OCTAVE_LOCAL_BUFFER (octave_idx_type, rperm, nc); + for (octave_idx_type i = 0; i < nc; i++) rperm[perm[i]] = i; for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); - for (octave_idx_type k = nr-1; k >= 0; k--) + for (octave_idx_type k = nc-1; k >= 0; k--) { octave_idx_type kidx = perm[k]; @@ -2134,7 +2157,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -2146,7 +2169,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[rperm[i]] != 0.) { retval.xridx(ii) = i; @@ -2158,7 +2181,7 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -2193,11 +2216,11 @@ } else { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); @@ -2225,7 +2248,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -2237,7 +2260,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -2249,7 +2272,7 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) @@ -2315,16 +2338,18 @@ } ComplexMatrix -SparseComplexMatrix::ltsolve (SparseType &mattype, const Matrix& b, octave_idx_type& err, - double& rcond, solve_singularity_handler sing_handler) const +SparseComplexMatrix::ltsolve (SparseType &mattype, const Matrix& b, + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -2338,11 +2363,11 @@ { double anorm = 0.; double ainvnorm = 0.; - octave_idx_type b_cols = b.cols (); + octave_idx_type b_nc = b.cols (); rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -2353,16 +2378,18 @@ if (typ == SparseType::Permuted_Lower) { - retval.resize (b.rows (), b.cols ()); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + retval.resize (nc, b_nc); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); octave_idx_type *perm = mattype.triangular_perm (); - for (octave_idx_type j = 0; j < b_cols; j++) + for (octave_idx_type j = 0; j < b_nc; j++) { + for (octave_idx_type i = 0; i < nm; i++) + work[i] = 0.; for (octave_idx_type i = 0; i < nr; i++) work[perm[i]] = b(i,j); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2395,19 +2422,19 @@ } } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) retval (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2435,7 +2462,7 @@ } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -2446,15 +2473,18 @@ } else { - retval = ComplexMatrix (b); - Complex *x_vec = retval.fortran_vec (); - - for (octave_idx_type j = 0; j < b_cols; j++) + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + retval.resize (nc, b_nc, 0.); + + for (octave_idx_type j = 0; j < b_nc; j++) { - octave_idx_type offset = j * nr; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type i = 0; i < nr; i++) + work[i] = b(i,j); + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + for (octave_idx_type k = 0; k < nc; k++) { - if (x_vec[k+offset] != 0.) + if (work[k] != 0.) { if (ridx(cidx(k)) != k) { @@ -2462,29 +2492,28 @@ goto triangular_error; } - Complex tmp = x_vec[k+offset] / - data(cidx(k)); - x_vec[k+offset] = tmp; + Complex tmp = work[k] / data(cidx(k)); + work[k] = tmp; for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) { octave_idx_type iidx = ridx(i); - x_vec[iidx+offset] = - x_vec[iidx+offset] - tmp * data(i); + work[iidx] = work[iidx] - tmp * data(i); } } } + for (octave_idx_type i = 0; i < nc; i++) + retval.xelem (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = j; k < nr; k++) + for (octave_idx_type k = j; k < nc; k++) { if (work[k] != 0.) @@ -2499,7 +2528,7 @@ } } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -2545,16 +2574,18 @@ SparseComplexMatrix SparseComplexMatrix::ltsolve (SparseType &mattype, const SparseMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); + err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -2571,7 +2602,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -2580,27 +2611,26 @@ anorm = atmp; } - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; octave_idx_type x_nz = b_nz; if (typ == SparseType::Permuted_Lower) { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); 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++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) work[perm[b.ridx(i)]] = b.data(i); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2636,7 +2666,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -2648,7 +2678,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -2660,14 +2690,14 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2695,7 +2725,7 @@ } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -2706,16 +2736,16 @@ } else { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2738,7 +2768,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -2750,7 +2780,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -2762,14 +2792,14 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = j; k < nr; k++) + for (octave_idx_type k = j; k < nc; k++) { if (work[k] != 0.) @@ -2784,7 +2814,7 @@ } } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -2831,16 +2861,17 @@ ComplexMatrix SparseComplexMatrix::ltsolve (SparseType &mattype, const ComplexMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { ComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -2858,7 +2889,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -2869,16 +2900,18 @@ if (typ == SparseType::Permuted_Lower) { - retval.resize (b.rows (), b.cols ()); - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + retval.resize (nc, b_nc); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); octave_idx_type *perm = mattype.triangular_perm (); for (octave_idx_type j = 0; j < b_nc; j++) { + for (octave_idx_type i = 0; i < nm; i++) + work[i] = 0.; for (octave_idx_type i = 0; i < nr; i++) work[perm[i]] = b(i,j); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2911,19 +2944,19 @@ } } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) retval (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -2951,7 +2984,7 @@ } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -2962,15 +2995,20 @@ } else { - retval = b; - Complex *x_vec = retval.fortran_vec (); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); + retval.resize (nc, b_nc, 0.); + for (octave_idx_type j = 0; j < b_nc; j++) { - octave_idx_type offset = j * nr; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type i = 0; i < nr; i++) + work[i] = b(i,j); + for (octave_idx_type i = nr; i < nc; i++) + work[i] = 0.; + + for (octave_idx_type k = 0; k < nc; k++) { - if (x_vec[k+offset] != 0.) + if (work[k] != 0.) { if (ridx(cidx(k)) != k) { @@ -2978,29 +3016,29 @@ goto triangular_error; } - Complex tmp = x_vec[k+offset] / - data(cidx(k)); - x_vec[k+offset] = tmp; + Complex tmp = work[k] / data(cidx(k)); + work[k] = tmp; for (octave_idx_type i = cidx(k)+1; i < cidx(k+1); i++) { octave_idx_type iidx = ridx(i); - x_vec[iidx+offset] = - x_vec[iidx+offset] - tmp * data(i); + work[iidx] = work[iidx] - tmp * data(i); } } } + + for (octave_idx_type i = 0; i < nc; i++) + retval.xelem (i, j) = work[i]; } // Calculation of 1-norm of inv(*this) - OCTAVE_LOCAL_BUFFER (Complex, work, nr); - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = j; k < nr; k++) + for (octave_idx_type k = j; k < nc; k++) { if (work[k] != 0.) @@ -3015,7 +3053,7 @@ } } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -3062,16 +3100,17 @@ SparseComplexMatrix SparseComplexMatrix::ltsolve (SparseType &mattype, const SparseComplexMatrix& b, - octave_idx_type& err, double& rcond, - solve_singularity_handler sing_handler) const + octave_idx_type& err, double& rcond, + solve_singularity_handler sing_handler) const { SparseComplexMatrix retval; octave_idx_type nr = rows (); octave_idx_type nc = cols (); + octave_idx_type nm = (nc > nr ? nc : nr); err = 0; - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + if (nr == 0 || nc == 0 || nr != b.rows ()) (*current_liboctave_error_handler) ("matrix dimension mismatch solution of linear equations"); else @@ -3088,7 +3127,7 @@ rcond = 0.; // Calculate the 1-norm of matrix for rcond calculation - for (octave_idx_type j = 0; j < nr; j++) + for (octave_idx_type j = 0; j < nc; j++) { double atmp = 0.; for (octave_idx_type i = cidx(j); i < cidx(j+1); i++) @@ -3097,27 +3136,26 @@ anorm = atmp; } - octave_idx_type b_nr = b.rows (); octave_idx_type b_nc = b.cols (); octave_idx_type b_nz = b.nzmax (); - retval = SparseComplexMatrix (b_nr, b_nc, b_nz); + retval = SparseComplexMatrix (nc, b_nc, b_nz); retval.xcidx(0) = 0; octave_idx_type ii = 0; octave_idx_type x_nz = b_nz; if (typ == SparseType::Permuted_Lower) { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); 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++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type i = b.cidx(j); i < b.cidx(j+1); i++) work[perm[b.ridx(i)]] = b.data(i); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -3153,7 +3191,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -3165,7 +3203,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -3177,14 +3215,14 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -3212,7 +3250,7 @@ } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -3223,16 +3261,16 @@ } else { - OCTAVE_LOCAL_BUFFER (Complex, work, nr); + OCTAVE_LOCAL_BUFFER (Complex, work, nm); for (octave_idx_type j = 0; j < b_nc; j++) { - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; 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); - for (octave_idx_type k = 0; k < nr; k++) + for (octave_idx_type k = 0; k < nc; k++) { if (work[k] != 0.) { @@ -3255,7 +3293,7 @@ // Count non-zeros in work vector and adjust space in // retval if needed octave_idx_type new_nnz = 0; - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) new_nnz++; @@ -3267,7 +3305,7 @@ x_nz = sz; } - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nc; i++) if (work[i] != 0.) { retval.xridx(ii) = i; @@ -3279,14 +3317,14 @@ retval.maybe_compress (); // Calculation of 1-norm of inv(*this) - for (octave_idx_type i = 0; i < nr; i++) + for (octave_idx_type i = 0; i < nm; i++) work[i] = 0.; for (octave_idx_type j = 0; j < nr; j++) { work[j] = 1.; - for (octave_idx_type k = j; k < nr; k++) + for (octave_idx_type k = j; k < nc; k++) { if (work[k] != 0.) @@ -3301,7 +3339,7 @@ } } double atmp = 0; - for (octave_idx_type i = j; i < nr; i++) + for (octave_idx_type i = j; i < nc; i++) { atmp += std::abs(work[i]); work[i] = 0.; @@ -4122,7 +4160,7 @@ Array<octave_idx_type> ipvt (nr); octave_idx_type *pipvt = ipvt.fortran_vec (); - F77_XFCN (zgbtrf, ZGBTRF, (nr, nr, n_lower, n_upper, tmp_data, + F77_XFCN (zgbtrf, ZGBTRF, (nr, nc, n_lower, n_upper, tmp_data, ldm, pipvt, err)); if (f77_exception_encountered)