Mercurial > hg > octave-thorsten
changeset 1948:d7dec93d4b87
[project @ 1996-02-14 03:45:49 by jwe]
author | jwe |
---|---|
date | Wed, 14 Feb 1996 03:47:59 +0000 |
parents | 5ab3c25a3cf9 |
children | 4689b52b4c6f |
files | liboctave/CMatrix.cc liboctave/chMatrix.cc liboctave/dMatrix.cc |
diffstat | 3 files changed, 933 insertions(+), 2904 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/CMatrix.cc +++ b/liboctave/CMatrix.cc @@ -801,43 +801,54 @@ ComplexMatrix ComplexMatrix::inverse (int& info, double& rcond, int force) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); - int len = length (); + if (nr != nc) - { - (*current_liboctave_error_handler) ("inverse requires square matrix"); - return ComplexMatrix (); - } - - info = 0; - - int *ipvt = new int [nr]; - Complex *z = new Complex [nr]; - Complex *tmp_data = dup (data (), len); - - F77_FCN (zgeco, ZGECO) (tmp_data, nr, nc, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0) - info = -1; - - if (info == -1 && ! force) - { - copy (tmp_data, data (), len); // Restore contents. - } + (*current_liboctave_error_handler) ("inverse requires square matrix"); else { - Complex *dummy = 0; - - F77_FCN (zgedi, ZGEDI) (tmp_data, nr, nc, ipvt, dummy, z, 1); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<Complex> z (nr); + Complex *pz = z.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nc, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + info = -1; + + if (info == -1 && ! force) + retval = *this; // Restore contents. + else + { + Complex *dummy = 0; + + F77_XFCN (zgedi, ZGEDI, (tmp_data, nr, nc, pipvt, dummy, + pz, 1)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in zgedi"); + } + } } - delete [] ipvt; - delete [] z; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexMatrix @@ -884,9 +895,13 @@ ComplexMatrix ComplexMatrix::fourier (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -899,25 +914,31 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); + F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); + + return retval; } ComplexMatrix ComplexMatrix::ifourier (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -930,28 +951,34 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); + F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); for (int j = 0; j < npts*nsamples; j++) tmp_data[j] = tmp_data[j] / (double) npts; - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexMatrix ComplexMatrix::fourier2d (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -964,47 +991,54 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; + F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); npts = nc; nsamples = nr; nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); + + wsave.resize (nn); + pwsave = wsave.fortran_vec (); + + Array<Complex> row (npts); + Complex *prow = row.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) { for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftf, CFFTF) (npts, row, wsave); + prow[i] = tmp_data[i*nr + j]; + + F77_FCN (cfftf, CFFTF) (npts, prow, pwsave); for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i]; + tmp_data[i*nr + j] = prow[i]; } - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexMatrix ComplexMatrix::ifourier2d (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -1017,15 +1051,17 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; + F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); for (int j = 0; j < npts*nsamples; j++) tmp_data[j] = tmp_data[j] / (double) npts; @@ -1033,26 +1069,27 @@ npts = nc; nsamples = nr; nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); + + wsave.resize (nn); + pwsave = wsave.fortran_vec (); + + Array<Complex> row (npts); + Complex *prow = row.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) { for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftb, CFFTB) (npts, row, wsave); + prow[i] = tmp_data[i*nr + j]; + + F77_FCN (cfftb, CFFTB) (npts, prow, pwsave); for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i] / (double) npts; + tmp_data[i*nr + j] = prow[i] / (double) npts; } - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexDET @@ -1088,29 +1125,42 @@ else { info = 0; - int *ipvt = new int [nr]; - - Complex *z = new Complex [nr]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -1; - retval = ComplexDET (); - } + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<Complex> z (nr); + Complex *pz = z.fortran_vec (); + + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); else { - Complex d[2]; - F77_FCN (zgedi, ZGEDI) (tmp_data, nr, nr, ipvt, d, z, 10); - retval = ComplexDET (d); + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -1; + retval = ComplexDET (); + } + else + { + Complex d[2]; + + F77_XFCN (zgedi, ZGEDI, (tmp_data, nr, nr, pipvt, d, pz, 10)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgedi"); + else + retval = ComplexDET (d); + } } - - delete [] tmp_data; - delete [] ipvt; - delete [] z; } return retval; @@ -1159,42 +1209,59 @@ int nr = rows (); int nc = cols (); - int b_nr = b.rows (); - int b_nc = b.cols (); - if (nr == 0 || nc == 0 || nr != nc || nr != b_nr) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of linear equations"); - return ComplexMatrix (); - } - - info = 0; - int *ipvt = new int [nr]; - - Complex *z = new Complex [nr]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } + + if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch in solution of linear equations"); else { - Complex *result = dup (b.data (), b.length ()); - - for (int j = 0; j < b_nc; j++) - F77_FCN (zgesl, ZGESL) (tmp_data, nr, nr, ipvt, &result[nr*j], 0); - - retval = ComplexMatrix (result, b_nr, b_nc); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<Complex> z (nr); + Complex *pz = z.fortran_vec (); + + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in zgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -2; + } + else + { + retval = b; + Complex *result = retval.fortran_vec (); + + int b_nc = b.cols (); + + for (volatile int j = 0; j < b_nc; j++) + { + F77_XFCN (zgesl, ZGESL, (tmp_data, nr, nr, pipvt, + &result[nr*j], 0)); + + if (f77_exception_encountered) + { + (*current_liboctave_error_handler) + ("unrecoverable error in dgesl"); + + break; + } + } + } + } } - delete [] tmp_data; - delete [] ipvt; - delete [] z; - return retval; } @@ -1221,40 +1288,50 @@ int nr = rows (); int nc = cols (); - int b_len = b.length (); - if (nr == 0 || nc == 0 || nr != nc || nr != b_len) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of linear equations"); - return ComplexColumnVector (); - } - - info = 0; - int *ipvt = new int [nr]; - - Complex *z = new Complex [nr]; - Complex *tmp_data = dup (data (), length ()); - - F77_FCN (zgeco, ZGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } + + if (nr == 0 || nc == 0 || nr != nc || nr != b.length ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch in solution of linear equations"); else { - Complex *result = dup (b.data (), b_len); - - F77_FCN (zgesl, ZGESL) (tmp_data, nr, nr, ipvt, result, 0); - - retval = ComplexColumnVector (result, b_len); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<Complex> z (nr); + Complex *pz = z.fortran_vec (); + + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + F77_XFCN (zgeco, ZGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -2; + } + else + { + retval = b; + Complex *result = retval.fortran_vec (); + + F77_XFCN (zgesl, ZGESL, (tmp_data, nr, nr, pipvt, result, 0)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgesl"); + } + } } - delete [] tmp_data; - delete [] ipvt; - delete [] z; - return retval; } @@ -1276,57 +1353,63 @@ ComplexMatrix ComplexMatrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const { + ComplexMatrix retval; + int nrhs = b.cols (); int m = rows (); int n = cols (); if (m == 0 || n == 0 || m != b.rows ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch solution of linear equations"); + else { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of linear equations"); - return Matrix (); + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + int nrr = m > n ? m : n; + ComplexMatrix result (nrr, nrhs); + + for (int j = 0; j < nrhs; j++) + for (int i = 0; i < m; i++) + result.elem (i, j) = b.elem (i, j); + + Complex *presult = result.fortran_vec (); + + int len_s = m < n ? m : n; + Array<double> s (len_s); + double *ps = s.fortran_vec (); + double rcond = -1.0; + int lwork; + if (m < n) + lwork = 2*m + (nrhs > n ? nrhs : n); + else + lwork = 2*n + (nrhs > m ? nrhs : m); + + Array<Complex> work (lwork); + Complex *pwork = work.fortran_vec (); + + int lrwork = (5 * (m < n ? m : n)) - 4; + lrwork = lrwork > 1 ? lrwork : 1; + Array<double> rwork (lrwork); + double *prwork = rwork.fortran_vec (); + + F77_XFCN (zgelss, ZGELSS, (m, n, nrhs, tmp_data, m, presult, + nrr, ps, rcond, rank, pwork, lwork, + prwork, info)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in zgelss"); + else + { + ComplexMatrix retval (n, nrhs); + for (int j = 0; j < nrhs; j++) + for (int i = 0; i < n; i++) + retval.elem (i, j) = result.elem (i, j); + } } - Complex *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - ComplexMatrix result (nrr, nrhs); - - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < m; i++) - result.elem (i, j) = b.elem (i, j); - - Complex *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 2*m + (nrhs > n ? nrhs : n); - else - lwork = 2*n + (nrhs > m ? nrhs : m); - - Complex *work = new Complex [lwork]; - - int lrwork = (5 * (m < n ? m : n)) - 4; - lrwork = lrwork > 1 ? lrwork : 1; - double *rwork = new double [lrwork]; - - F77_FCN (zgelss, ZGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, rwork, info); - - ComplexMatrix retval (n, nrhs); - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < n; i++) - retval.elem (i, j) = result.elem (i, j); - - delete [] tmp_data; - delete [] s; - delete [] work; - delete [] rwork; - return retval; } @@ -1349,55 +1432,63 @@ ComplexMatrix::lssolve (const ComplexColumnVector& b, int& info, int& rank) const { + ComplexColumnVector retval; + int nrhs = 1; int m = rows (); int n = cols (); if (m == 0 || n == 0 || m != b.length ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch solution of least squares problem"); + else { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of least squares problem"); - return ComplexColumnVector (); + ComplexMatrix atmp = *this; + Complex *tmp_data = atmp.fortran_vec (); + + int nrr = m > n ? m : n; + ComplexColumnVector result (nrr); + + for (int i = 0; i < m; i++) + result.elem (i) = b.elem (i); + + Complex *presult = result.fortran_vec (); + + int len_s = m < n ? m : n; + Array<double> s (len_s); + double *ps = s.fortran_vec (); + + double rcond = -1.0; + + int lwork; + if (m < n) + lwork = 2*m + (nrhs > n ? nrhs : n); + else + lwork = 2*n + (nrhs > m ? nrhs : m); + + Array<Complex> work (lwork); + Complex *pwork = work.fortran_vec (); + + int lrwork = (5 * (m < n ? m : n)) - 4; + lrwork = lrwork > 1 ? lrwork : 1; + Array<double> rwork (lrwork); + double *prwork = rwork.fortran_vec (); + + F77_XFCN (zgelss, ZGELSS, (m, n, nrhs, tmp_data, m, presult, + nrr, ps, rcond, rank, pwork, lwork, + prwork, info)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in zgelss"); + else + { + ComplexColumnVector retval (n); + for (int i = 0; i < n; i++) + retval.elem (i) = result.elem (i); + } } - Complex *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - ComplexColumnVector result (nrr); - - for (int i = 0; i < m; i++) - result.elem (i) = b.elem (i); - - Complex *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 2*m + (nrhs > n ? nrhs : n); - else - lwork = 2*n + (nrhs > m ? nrhs : m); - - Complex *work = new Complex [lwork]; - - int lrwork = (5 * (m < n ? m : n)) - 4; - lrwork = lrwork > 1 ? lrwork : 1; - double *rwork = new double [lrwork]; - - F77_FCN (zgelss, ZGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, rwork, info); - - ComplexColumnVector retval (n); - for (int i = 0; i < n; i++) - retval.elem (i) = result.elem (i); - - delete [] tmp_data; - delete [] s; - delete [] work; - delete [] rwork; - return retval; } @@ -1538,24 +1629,32 @@ ComplexMatrix operator * (const ComplexColumnVector& v, const ComplexRowVector& a) { + ComplexMatrix retval; + int len = v.length (); int a_len = a.length (); + if (len != a_len) + (*current_liboctave_error_handler) + ("nonconformant vector multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant vector multiplication attempted"); - return ComplexMatrix (); + if (len != 0) + { + retval.resize (len, a_len); + Complex *c = retval.fortran_vec (); + + F77_XFCN (zgemm, ZGEMM, ("N", "N", len, a_len, 1, 1.0, + v.data (), len, a.data (), 1, 0.0, + c, len, 1L, 1L)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in zgemm"); + } } - if (len == 0) - return ComplexMatrix (len, len, 0.0); - - Complex *c = new Complex [len * a_len]; - - F77_FCN (zgemm, ZGEMM) ("N", "N", len, a_len, 1, 1.0, v.data (), - len, a.data (), 1, 0.0, c, len, 1L, 1L); - - return ComplexMatrix (c, len, a_len); + return retval; } // diagonal matrix by scalar -> matrix operations @@ -1767,51 +1866,58 @@ ComplexMatrix operator * (const Matrix& m, const ComplexDiagMatrix& a) { + ComplexMatrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nr = a.rows (); int a_nc = a.cols (); + if (nc != a_nr) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return ComplexMatrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return ComplexMatrix (nr, a_nc, 0.0); - - Complex *c = new Complex [nr*a_nc]; - Complex *ctmp = 0; - - for (int j = 0; j < a.length (); j++) - { - int idx = j * nr; - ctmp = c + idx; - if (a.elem (j, j) == 1.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = m.elem (i, j); - } - else if (a.elem (j, j) == 0.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = 0.0; - } + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, a_nc, 0.0); else { - for (int i = 0; i < nr; i++) - ctmp[i] = a.elem (j, j) * m.elem (i, j); + retval.resize (nr, a_nc); + Complex *c = retval.fortran_vec (); + + Complex *ctmp = 0; + + for (int j = 0; j < a.length (); j++) + { + int idx = j * nr; + ctmp = c + idx; + if (a.elem (j, j) == 1.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = m.elem (i, j); + } + else if (a.elem (j, j) == 0.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = 0.0; + } + else + { + for (int i = 0; i < nr; i++) + ctmp[i] = a.elem (j, j) * m.elem (i, j); + } + } + + if (a_nr < a_nc) + { + for (int i = nr * nc; i < nr * a_nc; i++) + ctmp[i] = 0.0; + } } } - if (a_nr < a_nc) - { - for (int i = nr * nc; i < nr * a_nc; i++) - ctmp[i] = 0.0; - } - - return ComplexMatrix (c, nr, a_nc); + return retval; } // diagonal matrix by matrix -> matrix operations @@ -2351,50 +2457,56 @@ ComplexMatrix operator * (const ComplexMatrix& m, const DiagMatrix& a) { + ComplexMatrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nc = a.cols (); + if (nc != a.rows ()) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return ComplexMatrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return ComplexMatrix (nr, nc, 0.0); - - Complex *c = new Complex [nr*a_nc]; - Complex *ctmp = 0; - - for (int j = 0; j < a.length (); j++) - { - int idx = j * nr; - ctmp = c + idx; - if (a.elem (j, j) == 1.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = m.elem (i, j); - } - else if (a.elem (j, j) == 0.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = 0.0; - } + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, nc, 0.0); else { - for (int i = 0; i < nr; i++) - ctmp[i] = a.elem (j, j) * m.elem (i, j); + retval.resize (nr, a_nc); + Complex *c = retval.fortran_vec (); + Complex *ctmp = 0; + + for (int j = 0; j < a.length (); j++) + { + int idx = j * nr; + ctmp = c + idx; + if (a.elem (j, j) == 1.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = m.elem (i, j); + } + else if (a.elem (j, j) == 0.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = 0.0; + } + else + { + for (int i = 0; i < nr; i++) + ctmp[i] = a.elem (j, j) * m.elem (i, j); + } + } + + if (a.rows () < a_nc) + { + for (int i = nr * nc; i < nr * a_nc; i++) + ctmp[i] = 0.0; + } } } - if (a.rows () < a_nc) - { - for (int i = nr * nc; i < nr * a_nc; i++) - ctmp[i] = 0.0; - } - - return ComplexMatrix (c, nr, a_nc); + return retval; } ComplexMatrix @@ -2444,50 +2556,56 @@ ComplexMatrix operator * (const ComplexMatrix& m, const ComplexDiagMatrix& a) { + ComplexMatrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nc = a.cols (); + if (nc != a.rows ()) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return ComplexMatrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return ComplexMatrix (nr, nc, 0.0); - - Complex *c = new Complex [nr*a_nc]; - Complex *ctmp = 0; - - for (int j = 0; j < a.length (); j++) - { - int idx = j * nr; - ctmp = c + idx; - if (a.elem (j, j) == 1.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = m.elem (i, j); - } - else if (a.elem (j, j) == 0.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = 0.0; - } + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, nc, 0.0); else { - for (int i = 0; i < nr; i++) - ctmp[i] = a.elem (j, j) * m.elem (i, j); + retval.resize (nr, nc); + Complex *c = retval.fortran_vec (); + Complex *ctmp = 0; + + for (int j = 0; j < a.length (); j++) + { + int idx = j * nr; + ctmp = c + idx; + if (a.elem (j, j) == 1.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = m.elem (i, j); + } + else if (a.elem (j, j) == 0.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = 0.0; + } + else + { + for (int i = 0; i < nr; i++) + ctmp[i] = a.elem (j, j) * m.elem (i, j); + } + } + + if (a.rows () < a_nc) + { + for (int i = nr * nc; i < nr * a_nc; i++) + ctmp[i] = 0.0; + } } } - if (a.rows () < a_nc) - { - for (int i = nr * nc; i < nr * a_nc; i++) - ctmp[i] = 0.0; - } - - return ComplexMatrix (c, nr, a_nc); + return retval; } // matrix by matrix -> matrix operations @@ -2578,28 +2696,39 @@ ComplexMatrix operator * (const ComplexMatrix& m, const ComplexMatrix& a) { + ComplexMatrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nc = a.cols (); + if (nc != a.rows ()) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return ComplexMatrix (); + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, nc, 0.0); + else + { + int ld = nr; + int lda = a.rows (); + + retval.resize (nr, a_nc); + Complex *c = retval.fortran_vec (); + + F77_XFCN (zgemm, ZGEMM, ("N", "N", nr, a_nc, nc, 1.0, + m.data (), ld, a.data (), lda, 0.0, + c, nr, 1L, 1L)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in zgemm"); + } } - if (nr == 0 || nc == 0 || a_nc == 0) - return ComplexMatrix (nr, nc, 0.0); - - int ld = nr; - int lda = a.rows (); - - Complex *c = new Complex [nr*a_nc]; - - F77_FCN (zgemm, ZGEMM) ("N", "N", nr, a_nc, nc, 1.0, m.data (), ld, - a.data (), lda, 0.0, c, nr, 1L, 1L); - - return ComplexMatrix (c, nr, a_nc); + return retval; } ComplexMatrix
--- a/liboctave/chMatrix.cc +++ b/liboctave/chMatrix.cc @@ -126,2233 +126,6 @@ return retval; } -#if 0 -Matrix& -Matrix::insert (const RowVector& a, int r, int c) -{ - int a_len = a.length (); - if (r < 0 || r >= rows () || c < 0 || c + a_len - 1 > cols ()) - { - (*current_liboctave_error_handler) ("range error for insert"); - return *this; - } - - for (int i = 0; i < a_len; i++) - elem (r, c+i) = a.elem (i); - - return *this; -} - -Matrix& -Matrix::insert (const ColumnVector& a, int r, int c) -{ - int a_len = a.length (); - if (r < 0 || r + a_len - 1 > rows () || c < 0 || c >= cols ()) - { - (*current_liboctave_error_handler) ("range error for insert"); - return *this; - } - - for (int i = 0; i < a_len; i++) - elem (r+i, c) = a.elem (i); - - return *this; -} - -Matrix& -Matrix::insert (const DiagMatrix& a, int r, int c) -{ - if (r < 0 || r + a.rows () - 1 > rows () - || c < 0 || c + a.cols () - 1 > cols ()) - { - (*current_liboctave_error_handler) ("range error for insert"); - return *this; - } - - for (int i = 0; i < a.length (); i++) - elem (r+i, c+i) = a.elem (i, i); - - return *this; -} - -Matrix& -Matrix::fill (double val) -{ - int nr = rows (); - int nc = cols (); - if (nr > 0 && nc > 0) - for (int j = 0; j < nc; j++) - for (int i = 0; i < nr; i++) - elem (i, j) = val; - - return *this; -} - -Matrix& -Matrix::fill (double val, int r1, int c1, int r2, int c2) -{ - int nr = rows (); - int nc = cols (); - if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0 - || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc) - { - (*current_liboctave_error_handler) ("range error for fill"); - return *this; - } - - if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; } - if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; } - - for (int j = c1; j <= c2; j++) - for (int i = r1; i <= r2; i++) - elem (i, j) = val; - - return *this; -} - -Matrix -Matrix::append (const Matrix& a) const -{ - int nr = rows (); - int nc = cols (); - if (nr != a.rows ()) - { - (*current_liboctave_error_handler) ("row dimension mismatch for append"); - return Matrix (); - } - - int nc_insert = nc; - Matrix retval (nr, nc + a.cols ()); - retval.insert (*this, 0, 0); - retval.insert (a, 0, nc_insert); - return retval; -} - -Matrix -Matrix::append (const RowVector& a) const -{ - int nr = rows (); - int nc = cols (); - if (nr != 1) - { - (*current_liboctave_error_handler) ("row dimension mismatch for append"); - return Matrix (); - } - - int nc_insert = nc; - Matrix retval (nr, nc + a.length ()); - retval.insert (*this, 0, 0); - retval.insert (a, 0, nc_insert); - return retval; -} - -Matrix -Matrix::append (const ColumnVector& a) const -{ - int nr = rows (); - int nc = cols (); - if (nr != a.length ()) - { - (*current_liboctave_error_handler) ("row dimension mismatch for append"); - return Matrix (); - } - - int nc_insert = nc; - Matrix retval (nr, nc + 1); - retval.insert (*this, 0, 0); - retval.insert (a, 0, nc_insert); - return retval; -} - -Matrix -Matrix::append (const DiagMatrix& a) const -{ - int nr = rows (); - int nc = cols (); - if (nr != a.rows ()) - { - (*current_liboctave_error_handler) ("row dimension mismatch for append"); - return *this; - } - - int nc_insert = nc; - Matrix retval (nr, nc + a.cols ()); - retval.insert (*this, 0, 0); - retval.insert (a, 0, nc_insert); - return retval; -} - -Matrix -Matrix::stack (const Matrix& a) const -{ - int nr = rows (); - int nc = cols (); - if (nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("column dimension mismatch for stack"); - return Matrix (); - } - - int nr_insert = nr; - Matrix retval (nr + a.rows (), nc); - retval.insert (*this, 0, 0); - retval.insert (a, nr_insert, 0); - return retval; -} - -Matrix -Matrix::stack (const RowVector& a) const -{ - int nr = rows (); - int nc = cols (); - if (nc != a.length ()) - { - (*current_liboctave_error_handler) - ("column dimension mismatch for stack"); - return Matrix (); - } - - int nr_insert = nr; - Matrix retval (nr + 1, nc); - retval.insert (*this, 0, 0); - retval.insert (a, nr_insert, 0); - return retval; -} - -Matrix -Matrix::stack (const ColumnVector& a) const -{ - int nr = rows (); - int nc = cols (); - if (nc != 1) - { - (*current_liboctave_error_handler) - ("column dimension mismatch for stack"); - return Matrix (); - } - - int nr_insert = nr; - Matrix retval (nr + a.length (), nc); - retval.insert (*this, 0, 0); - retval.insert (a, nr_insert, 0); - return retval; -} - -Matrix -Matrix::stack (const DiagMatrix& a) const -{ - int nr = rows (); - int nc = cols (); - if (nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("column dimension mismatch for stack"); - return Matrix (); - } - - int nr_insert = nr; - Matrix retval (nr + a.rows (), nc); - retval.insert (*this, 0, 0); - retval.insert (a, nr_insert, 0); - return retval; -} - -Matrix -Matrix::transpose (void) const -{ - int nr = rows (); - int nc = cols (); - Matrix result (nc, nr); - if (length () > 0) - { - for (int j = 0; j < nc; j++) - for (int i = 0; i < nr; i++) - result.elem (j, i) = elem (i, j); - } - return result; -} - -Matrix -real (const ComplexMatrix& a) -{ - int a_len = a.length (); - Matrix retval; - if (a_len > 0) - retval = Matrix (real_dup (a.data (), a_len), a.rows (), a.cols ()); - return retval; -} - -Matrix -imag (const ComplexMatrix& a) -{ - int a_len = a.length (); - Matrix retval; - if (a_len > 0) - retval = Matrix (imag_dup (a.data (), a_len), a.rows (), a.cols ()); - return retval; -} - -Matrix -Matrix::extract (int r1, int c1, int r2, int c2) const -{ - if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; } - if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; } - - int new_r = r2 - r1 + 1; - int new_c = c2 - c1 + 1; - - Matrix result (new_r, new_c); - - for (int j = 0; j < new_c; j++) - for (int i = 0; i < new_r; i++) - result.elem (i, j) = elem (r1+i, c1+j); - - return result; -} - -// extract row or column i. - -RowVector -Matrix::row (int i) const -{ - int nc = cols (); - if (i < 0 || i >= rows ()) - { - (*current_liboctave_error_handler) ("invalid row selection"); - return RowVector (); - } - - RowVector retval (nc); - for (int j = 0; j < nc; j++) - retval.elem (j) = elem (i, j); - - return retval; -} - -RowVector -Matrix::row (char *s) const -{ - if (! s) - { - (*current_liboctave_error_handler) ("invalid row selection"); - return RowVector (); - } - - char c = *s; - if (c == 'f' || c == 'F') - return row (0); - else if (c == 'l' || c == 'L') - return row (rows () - 1); - else - { - (*current_liboctave_error_handler) ("invalid row selection"); - return RowVector (); - } -} - -ColumnVector -Matrix::column (int i) const -{ - int nr = rows (); - if (i < 0 || i >= cols ()) - { - (*current_liboctave_error_handler) ("invalid column selection"); - return ColumnVector (); - } - - ColumnVector retval (nr); - for (int j = 0; j < nr; j++) - retval.elem (j) = elem (j, i); - - return retval; -} - -ColumnVector -Matrix::column (char *s) const -{ - if (! s) - { - (*current_liboctave_error_handler) ("invalid column selection"); - return ColumnVector (); - } - - char c = *s; - if (c == 'f' || c == 'F') - return column (0); - else if (c == 'l' || c == 'L') - return column (cols () - 1); - else - { - (*current_liboctave_error_handler) ("invalid column selection"); - return ColumnVector (); - } -} - -Matrix -Matrix::inverse (void) const -{ - int info; - double rcond; - return inverse (info, rcond); -} - -Matrix -Matrix::inverse (int& info) const -{ - double rcond; - return inverse (info, rcond); -} - -Matrix -Matrix::inverse (int& info, double& rcond) const -{ - int nr = rows (); - int nc = cols (); - int len = length (); - if (nr != nc || nr == 0 || nc == 0) - { - (*current_liboctave_error_handler) ("inverse requires square matrix"); - return Matrix (); - } - - info = 0; - - int *ipvt = new int [nr]; - double *z = new double [nr]; - double *tmp_data = dup (data (), len); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nc, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -1; - copy (tmp_data, data (), len); // Restore matrix contents. - } - else - { - double *dummy = 0; - - F77_FCN (dgedi, DGEDI) (tmp_data, nr, nc, ipvt, dummy, z, 1); - } - - delete [] ipvt; - delete [] z; - - return Matrix (tmp_data, nr, nc); -} - -Matrix -Matrix::pseudo_inverse (double tol) -{ - SVD result (*this); - - DiagMatrix S = result.singular_values (); - Matrix U = result.left_singular_matrix (); - Matrix V = result.right_singular_matrix (); - - ColumnVector sigma = S.diag (); - - int r = sigma.length () - 1; - int nr = rows (); - int nc = cols (); - - if (tol <= 0.0) - { - if (nr > nc) - tol = nr * sigma.elem (0) * DBL_EPSILON; - else - tol = nc * sigma.elem (0) * DBL_EPSILON; - } - - while (r >= 0 && sigma.elem (r) < tol) - r--; - - if (r < 0) - return Matrix (nc, nr, 0.0); - else - { - Matrix Ur = U.extract (0, 0, nr-1, r); - DiagMatrix D = DiagMatrix (sigma.extract (0, r)) . inverse (); - Matrix Vr = V.extract (0, 0, nc-1, r); - return Vr * D * Ur.transpose (); - } -} - -ComplexMatrix -Matrix::fourier (void) const -{ - int nr = rows (); - int nc = cols (); - int npts, nsamples; - if (nr == 1 || nc == 1) - { - npts = nr > nc ? nr : nc; - nsamples = 1; - } - else - { - npts = nr; - nsamples = nc; - } - - int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); -} - -ComplexMatrix -Matrix::ifourier (void) const -{ - int nr = rows (); - int nc = cols (); - int npts, nsamples; - if (nr == 1 || nc == 1) - { - npts = nr > nc ? nr : nc; - nsamples = 1; - } - else - { - npts = nr; - nsamples = nc; - } - - int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); - - for (int j = 0; j < npts*nsamples; j++) - tmp_data[j] = tmp_data[j] / (double) npts; - - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); -} - -ComplexMatrix -Matrix::fourier2d (void) const -{ - int nr = rows (); - int nc = cols (); - int npts, nsamples; - if (nr == 1 || nc == 1) - { - npts = nr > nc ? nr : nc; - nsamples = 1; - } - else - { - npts = nr; - nsamples = nc; - } - - int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; - - npts = nc; - nsamples = nr; - nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - { - for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftf, CFFTF) (npts, row, wsave); - - for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i]; - } - - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); -} - -ComplexMatrix -Matrix::ifourier2d (void) const -{ - int nr = rows (); - int nc = cols (); - int npts, nsamples; - if (nr == 1 || nc == 1) - { - npts = nr > nc ? nr : nc; - nsamples = 1; - } - else - { - npts = nr; - nsamples = nc; - } - - int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; - - for (int j = 0; j < npts*nsamples; j++) - tmp_data[j] = tmp_data[j] / (double) npts; - - npts = nc; - nsamples = nr; - nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); - - for (int j = 0; j < nsamples; j++) - { - for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftb, CFFTB) (npts, row, wsave); - - for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i] / (double) npts; - } - - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); -} - -DET -Matrix::determinant (void) const -{ - int info; - double rcond; - return determinant (info, rcond); -} - -DET -Matrix::determinant (int& info) const -{ - double rcond; - return determinant (info, rcond); -} - -DET -Matrix::determinant (int& info, double& rcond) const -{ - DET retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 0 || nc == 0) - { - double d[2]; - d[0] = 1.0; - d[1] = 0.0; - retval = DET (d); - } - else - { - info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -1; - retval = DET (); - } - else - { - double d[2]; - F77_FCN (dgedi, DGEDI) (tmp_data, nr, nr, ipvt, d, z, 10); - retval = DET (d); - } - - delete [] tmp_data; - delete [] ipvt; - delete [] z; - } - - return retval; -} - -Matrix -Matrix::solve (const Matrix& b) const -{ - int info; - double rcond; - return solve (b, info, rcond); -} - -Matrix -Matrix::solve (const Matrix& b, int& info) const -{ - double rcond; - return solve (b, info, rcond); -} - -Matrix -Matrix::solve (const Matrix& b, int& info, double& rcond) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of linear equations"); - return Matrix (); - } - - info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } - else - { - double *result = dup (b.data (), b.length ()); - - int b_nc = b.cols (); - for (int j = 0; j < b_nc; j++) - F77_FCN (dgesl, DGESL) (tmp_data, nr, nr, ipvt, &result[nr*j], 0); - - retval = Matrix (result, b.rows (), b_nc); - } - - delete [] tmp_data; - delete [] ipvt; - delete [] z; - - return retval; -} - -ComplexMatrix -Matrix::solve (const ComplexMatrix& b) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b); -} - -ComplexMatrix -Matrix::solve (const ComplexMatrix& b, int& info) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b, info); -} - -ComplexMatrix -Matrix::solve (const ComplexMatrix& b, int& info, double& rcond) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b, info, rcond); -} - -ColumnVector -Matrix::solve (const ColumnVector& b) const -{ - int info; double rcond; - return solve (b, info, rcond); -} - -ColumnVector -Matrix::solve (const ColumnVector& b, int& info) const -{ - double rcond; - return solve (b, info, rcond); -} - -ColumnVector -Matrix::solve (const ColumnVector& b, int& info, double& rcond) const -{ - ColumnVector retval; - - int nr = rows (); - int nc = cols (); - if (nr == 0 || nc == 0 || nr != nc || nr != b.length ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of linear equations"); - return ColumnVector (); - } - - info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } - else - { - int b_len = b.length (); - - double *result = dup (b.data (), b_len); - - F77_FCN (dgesl, DGESL) (tmp_data, nr, nr, ipvt, result, 0); - - retval = ColumnVector (result, b_len); - } - - delete [] tmp_data; - delete [] ipvt; - delete [] z; - - return retval; -} - -ComplexColumnVector -Matrix::solve (const ComplexColumnVector& b) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b); -} - -ComplexColumnVector -Matrix::solve (const ComplexColumnVector& b, int& info) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b, info); -} - -ComplexColumnVector -Matrix::solve (const ComplexColumnVector& b, int& info, double& rcond) const -{ - ComplexMatrix tmp (*this); - return tmp.solve (b, info, rcond); -} - -Matrix -Matrix::lssolve (const Matrix& b) const -{ - int info; - int rank; - return lssolve (b, info, rank); -} - -Matrix -Matrix::lssolve (const Matrix& b, int& info) const -{ - int rank; - return lssolve (b, info, rank); -} - -Matrix -Matrix::lssolve (const Matrix& b, int& info, int& rank) const -{ - int nrhs = b.cols (); - - int m = rows (); - int n = cols (); - - if (m == 0 || n == 0 || m != b.rows ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of least squares problem"); - return Matrix (); - } - - double *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - Matrix result (nrr, nrhs); - - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < m; i++) - result.elem (i, j) = b.elem (i, j); - - double *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 3*m + (2*m > nrhs ? (2*m > n ? 2*m : n) : (nrhs > n ? nrhs : n)); - else - lwork = 3*n + (2*n > nrhs ? (2*n > m ? 2*n : m) : (nrhs > m ? nrhs : m)); - - double *work = new double [lwork]; - - F77_FCN (dgelss, DGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, info); - - Matrix retval (n, nrhs); - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < n; i++) - retval.elem (i, j) = result.elem (i, j); - - delete [] tmp_data; - delete [] s; - delete [] work; - - return retval; -} - -ComplexMatrix -Matrix::lssolve (const ComplexMatrix& b) const -{ - ComplexMatrix tmp (*this); - int info; - int rank; - return tmp.lssolve (b, info, rank); -} - -ComplexMatrix -Matrix::lssolve (const ComplexMatrix& b, int& info) const -{ - ComplexMatrix tmp (*this); - int rank; - return tmp.lssolve (b, info, rank); -} - -ComplexMatrix -Matrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const -{ - ComplexMatrix tmp (*this); - return tmp.lssolve (b, info, rank); -} - -ColumnVector -Matrix::lssolve (const ColumnVector& b) const -{ - int info; - int rank; - return lssolve (b, info, rank); -} - -ColumnVector -Matrix::lssolve (const ColumnVector& b, int& info) const -{ - int rank; - return lssolve (b, info, rank); -} - -ColumnVector -Matrix::lssolve (const ColumnVector& b, int& info, int& rank) const -{ - int nrhs = 1; - - int m = rows (); - int n = cols (); - - if (m == 0 || n == 0 || m != b.length ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of least squares problem"); - return ColumnVector (); - } - - double *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - ColumnVector result (nrr); - - for (int i = 0; i < m; i++) - result.elem (i) = b.elem (i); - - double *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 3*m + (2*m > nrhs ? (2*m > n ? 2*m : n) : (nrhs > n ? nrhs : n)); - else - lwork = 3*n + (2*n > nrhs ? (2*n > m ? 2*n : m) : (nrhs > m ? nrhs : m)); - - double *work = new double [lwork]; - - F77_FCN (dgelss, DGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, info); - - ColumnVector retval (n); - for (int i = 0; i < n; i++) - retval.elem (i) = result.elem (i); - - delete [] tmp_data; - delete [] s; - delete [] work; - - return retval; -} - -ComplexColumnVector -Matrix::lssolve (const ComplexColumnVector& b) const -{ - ComplexMatrix tmp (*this); - return tmp.lssolve (b); -} - -ComplexColumnVector -Matrix::lssolve (const ComplexColumnVector& b, int& info) const -{ - ComplexMatrix tmp (*this); - return tmp.lssolve (b, info); -} - -ComplexColumnVector -Matrix::lssolve (const ComplexColumnVector& b, int& info, int& rank) const -{ - ComplexMatrix tmp (*this); - return tmp.lssolve (b, info, rank); -} - -Matrix& -Matrix::operator += (const Matrix& a) -{ - int nr = rows (); - int nc = cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix += operation attempted"); - return *this; - } - - if (nr == 0 || nc == 0) - return *this; - - double *d = fortran_vec (); // Ensures only one reference to my privates! - - add2 (d, a.data (), length ()); - - return *this; -} - -Matrix& -Matrix::operator -= (const Matrix& a) -{ - int nr = rows (); - int nc = cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix -= operation attempted"); - return *this; - } - - if (nr == 0 || nc == 0) - return *this; - - double *d = fortran_vec (); // Ensures only one reference to my privates! - - subtract2 (d, a.data (), length ()); - - return *this; -} - -Matrix& -Matrix::operator += (const DiagMatrix& a) -{ - if (rows () != a.rows () || cols () != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix += operation attempted"); - return *this; - } - - for (int i = 0; i < a.length (); i++) - elem (i, i) += a.elem (i, i); - - return *this; -} - -Matrix& -Matrix::operator -= (const DiagMatrix& a) -{ - if (rows () != a.rows () || cols () != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix += operation attempted"); - return *this; - } - - for (int i = 0; i < a.length (); i++) - elem (i, i) -= a.elem (i, i); - - return *this; -} - -// unary operations - -Matrix -Matrix::operator ! (void) const -{ - int nr = rows (); - int nc = cols (); - - Matrix b (nr, nc); - - for (int j = 0; j < nc; j++) - for (int i = 0; i < nr; i++) - b.elem (i, j) = ! elem (i, j); - - return b; -} - -// column vector by row vector -> matrix operations - -Matrix -operator * (const ColumnVector& v, const RowVector& a) -{ - int len = v.length (); - int a_len = a.length (); - if (len != a_len) - { - (*current_liboctave_error_handler) - ("nonconformant vector multiplication attempted"); - return Matrix (); - } - - if (len == 0) - return Matrix (len, len, 0.0); - - double *c = new double [len * a_len]; - - F77_FCN (dgemm, DGEMM) ("N", "N", len, a_len, 1, 1.0, v.data (), - len, a.data (), 1, 0.0, c, len, 1L, 1L); - - return Matrix (c, len, a_len); -} - -// diagonal matrix by scalar -> matrix operations - -Matrix -operator + (const DiagMatrix& a, double s) -{ - Matrix tmp (a.rows (), a.cols (), s); - return a + tmp; -} - -Matrix -operator - (const DiagMatrix& a, double s) -{ - Matrix tmp (a.rows (), a.cols (), -s); - return a + tmp; -} - -// scalar by diagonal matrix -> matrix operations - -Matrix -operator + (double s, const DiagMatrix& a) -{ - Matrix tmp (a.rows (), a.cols (), s); - return tmp + a; -} - -Matrix -operator - (double s, const DiagMatrix& a) -{ - Matrix tmp (a.rows (), a.cols (), s); - return tmp - a; -} - -// matrix by diagonal matrix -> matrix operations - -Matrix -operator + (const Matrix& m, const DiagMatrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix addition attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0) - return Matrix (nr, nc); - - Matrix result (m); - int a_len = a.length (); - for (int i = 0; i < a_len; i++) - result.elem (i, i) += a.elem (i, i); - - return result; -} - -Matrix -operator - (const Matrix& m, const DiagMatrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix subtraction attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0) - return Matrix (nr, nc); - - Matrix result (m); - int a_len = a.length (); - for (int i = 0; i < a_len; i++) - result.elem (i, i) -= a.elem (i, i); - - return result; -} - -Matrix -operator * (const Matrix& m, const DiagMatrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - int a_nr = a.rows (); - int a_nc = a.cols (); - if (nc != a_nr) - { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return Matrix (nr, a_nc, 0.0); - - double *c = new double [nr*a_nc]; - double *ctmp = 0; - - int a_len = a.length (); - for (int j = 0; j < a_len; j++) - { - int idx = j * nr; - ctmp = c + idx; - if (a.elem (j, j) == 1.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = m.elem (i, j); - } - else if (a.elem (j, j) == 0.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = 0.0; - } - else - { - for (int i = 0; i < nr; i++) - ctmp[i] = a.elem (j, j) * m.elem (i, j); - } - } - - if (a_nr < a_nc) - { - for (int i = nr * nc; i < nr * a_nc; i++) - ctmp[i] = 0.0; - } - - return Matrix (c, nr, a_nc); -} - -// diagonal matrix by matrix -> matrix operations - -Matrix -operator + (const DiagMatrix& m, const Matrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix addition attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0) - return Matrix (nr, nc); - - Matrix result (a); - for (int i = 0; i < m.length (); i++) - result.elem (i, i) += m.elem (i, i); - - return result; -} - -Matrix -operator - (const DiagMatrix& m, const Matrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - if (nr != a.rows () || nc != a.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant matrix subtraction attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0) - return Matrix (nr, nc); - - Matrix result (-a); - for (int i = 0; i < m.length (); i++) - result.elem (i, i) += m.elem (i, i); - - return result; -} - -Matrix -operator * (const DiagMatrix& m, const Matrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - int a_nr = a.rows (); - int a_nc = a.cols (); - if (nc != a_nr) - { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return Matrix (nr, a_nc, 0.0); - - Matrix c (nr, a_nc); - - for (int i = 0; i < m.length (); i++) - { - if (m.elem (i, i) == 1.0) - { - for (int j = 0; j < a_nc; j++) - c.elem (i, j) = a.elem (i, j); - } - else if (m.elem (i, i) == 0.0) - { - for (int j = 0; j < a_nc; j++) - c.elem (i, j) = 0.0; - } - else - { - for (int j = 0; j < a_nc; j++) - c.elem (i, j) = m.elem (i, i) * a.elem (i, j); - } - } - - if (nr > nc) - { - for (int j = 0; j < a_nc; j++) - for (int i = a_nr; i < nr; i++) - c.elem (i, j) = 0.0; - } - - return c; -} - -// matrix by matrix -> matrix operations - -Matrix -operator * (const Matrix& m, const Matrix& a) -{ - int nr = m.rows (); - int nc = m.cols (); - int a_nr = a.rows (); - int a_nc = a.cols (); - if (nc != a_nr) - { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return Matrix (nr, a_nc, 0.0); - - int ld = nr; - int lda = a_nr; - - double *c = new double [nr*a_nc]; - - F77_FCN (dgemm, DGEMM) ("N", "N", nr, a_nc, nc, 1.0, m.data (), - ld, a.data (), lda, 0.0, c, nr, 1L, 1L); - - return Matrix (c, nr, a_nc); -} - -// other operations. - -Matrix -map (d_d_Mapper f, const Matrix& a) -{ - Matrix b (a); - b.map (f); - return b; -} - -Matrix -map (d_c_Mapper f, const ComplexMatrix& a) -{ - int a_nc = a.cols (); - int a_nr = a.rows (); - Matrix b (a_nr, a_nc); - for (int j = 0; j < a_nc; j++) - for (int i = 0; i < a_nr; i++) - b.elem (i, j) = f (a.elem (i, j)); - return b; -} - -void -Matrix::map (d_d_Mapper f) -{ - double *d = fortran_vec (); // Ensures only one reference to my privates! - - for (int i = 0; i < length (); i++) - d[i] = f (d[i]); -} - -// XXX FIXME XXX Do these really belong here? They should maybe be -// cleaned up a bit, no? What about corresponding functions for the -// Vectors? - -Matrix -Matrix::all (void) const -{ - int nr = rows (); - int nc = cols (); - Matrix retval; - if (nr > 0 && nc > 0) - { - if (nr == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 1.0; - for (int j = 0; j < nc; j++) - { - if (elem (0, j) == 0.0) - { - retval.elem (0, 0) = 0.0; - break; - } - } - } - else if (nc == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 1.0; - for (int i = 0; i < nr; i++) - { - if (elem (i, 0) == 0.0) - { - retval.elem (0, 0) = 0.0; - break; - } - } - } - else - { - retval.resize (1, nc); - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = 1.0; - for (int i = 0; i < nr; i++) - { - if (elem (i, j) == 0.0) - { - retval.elem (0, j) = 0.0; - break; - } - } - } - } - } - return retval; -} - -Matrix -Matrix::any (void) const -{ - int nr = rows (); - int nc = cols (); - Matrix retval; - if (nr > 0 && nc > 0) - { - if (nr == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int j = 0; j < nc; j++) - { - if (elem (0, j) != 0.0) - { - retval.elem (0, 0) = 1.0; - break; - } - } - } - else if (nc == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int i = 0; i < nr; i++) - { - if (elem (i, 0) != 0.0) - { - retval.elem (0, 0) = 1.0; - break; - } - } - } - else - { - retval.resize (1, nc); - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = 0.0; - for (int i = 0; i < nr; i++) - { - if (elem (i, j) != 0.0) - { - retval.elem (0, j) = 1.0; - break; - } - } - } - } - } - return retval; -} - -Matrix -Matrix::cumprod (void) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 1) - { - retval.resize (1, nc); - if (nc > 0) - { - double prod = elem (0, 0); - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = prod; - if (j < nc - 1) - prod *= elem (0, j+1); - } - } - } - else if (nc == 1) - { - retval.resize (nr, 1); - if (nr > 0) - { - double prod = elem (0, 0); - for (int i = 0; i < nr; i++) - { - retval.elem (i, 0) = prod; - if (i < nr - 1) - prod *= elem (i+1, 0); - } - } - } - else - { - retval.resize (nr, nc); - if (nr > 0 && nc > 0) - { - for (int j = 0; j < nc; j++) - { - double prod = elem (0, j); - for (int i = 0; i < nr; i++) - { - retval.elem (i, j) = prod; - if (i < nr - 1) - prod *= elem (i+1, j); - } - } - } - } - return retval; -} - -Matrix -Matrix::cumsum (void) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 1) - { - retval.resize (1, nc); - if (nc > 0) - { - double sum = elem (0, 0); - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = sum; - if (j < nc - 1) - sum += elem (0, j+1); - } - } - } - else if (nc == 1) - { - retval.resize (nr, 1); - if (nr > 0) - { - double sum = elem (0, 0); - for (int i = 0; i < nr; i++) - { - retval.elem (i, 0) = sum; - if (i < nr - 1) - sum += elem (i+1, 0); - } - } - } - else - { - retval.resize (nr, nc); - if (nr > 0 && nc > 0) - { - for (int j = 0; j < nc; j++) - { - double sum = elem (0, j); - for (int i = 0; i < nr; i++) - { - retval.elem (i, j) = sum; - if (i < nr - 1) - sum += elem (i+1, j); - } - } - } - } - return retval; -} - -Matrix -Matrix::prod (void) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 1.0; - for (int j = 0; j < nc; j++) - retval.elem (0, 0) *= elem (0, j); - } - else if (nc == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 1.0; - for (int i = 0; i < nr; i++) - retval.elem (0, 0) *= elem (i, 0); - } - else - { - if (nc == 0) - { - retval.resize (1, 1); - retval.elem (0, 0) = 1.0; - } - else - retval.resize (1, nc); - - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = 1.0; - for (int i = 0; i < nr; i++) - retval.elem (0, j) *= elem (i, j); - } - } - return retval; -} - -Matrix -Matrix::sum (void) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int j = 0; j < nc; j++) - retval.elem (0, 0) += elem (0, j); - } - else if (nc == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int i = 0; i < nr; i++) - retval.elem (0, 0) += elem (i, 0); - } - else - { - if (nc == 0) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - } - else - retval.resize (1, nc); - - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = 0.0; - for (int i = 0; i < nr; i++) - retval.elem (0, j) += elem (i, j); - } - } - return retval; -} - -Matrix -Matrix::sumsq (void) const -{ - Matrix retval; - - int nr = rows (); - int nc = cols (); - - if (nr == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int j = 0; j < nc; j++) - { - double d = elem (0, j); - retval.elem (0, 0) += d * d; - } - } - else if (nc == 1) - { - retval.resize (1, 1); - retval.elem (0, 0) = 0.0; - for (int i = 0; i < nr; i++) - { - double d = elem (i, 0); - retval.elem (0, 0) += d * d; - } - } - else - { - retval.resize (1, nc); - for (int j = 0; j < nc; j++) - { - retval.elem (0, j) = 0.0; - for (int i = 0; i < nr; i++) - { - double d = elem (i, j); - retval.elem (0, j) += d * d; - } - } - } - return retval; -} - -ColumnVector -Matrix::diag (void) const -{ - return diag (0); -} - -ColumnVector -Matrix::diag (int k) const -{ - int nnr = rows (); - int nnc = cols (); - if (k > 0) - nnc -= k; - else if (k < 0) - nnr += k; - - ColumnVector d; - - if (nnr > 0 && nnc > 0) - { - int ndiag = (nnr < nnc) ? nnr : nnc; - - d.resize (ndiag); - - if (k > 0) - { - for (int i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i+k); - } - else if ( k < 0) - { - for (int i = 0; i < ndiag; i++) - d.elem (i) = elem (i-k, i); - } - else - { - for (int i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i); - } - } - else - cerr << "diag: requested diagonal out of range\n"; - - return d; -} - -ColumnVector -Matrix::row_min (void) const -{ - ColumnVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nr); - - for (int i = 0; i < nr; i++) - { - double res = elem (i, 0); - for (int j = 1; j < nc; j++) - if (elem (i, j) < res) - res = elem (i, j); - result.elem (i) = res; - } - } - - return result; -} - -ColumnVector -Matrix::row_min_loc (void) const -{ - ColumnVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nr); - - for (int i = 0; i < nr; i++) - { - int res = 0; - for (int j = 0; j < nc; j++) - if (elem (i, j) < elem (i, res)) - res = j; - result.elem (i) = (double) (res + 1); - } - } - - return result; -} - -ColumnVector -Matrix::row_max (void) const -{ - ColumnVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nr); - - for (int i = 0; i < nr; i++) - { - double res = elem (i, 0); - for (int j = 1; j < nc; j++) - if (elem (i, j) > res) - res = elem (i, j); - result.elem (i) = res; - } - } - - return result; -} - -ColumnVector -Matrix::row_max_loc (void) const -{ - ColumnVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nr); - - for (int i = 0; i < nr; i++) - { - int res = 0; - for (int j = 0; j < nc; j++) - if (elem (i, j) > elem (i, res)) - res = j; - result.elem (i) = (double) (res + 1); - } - } - - return result; -} - -RowVector -Matrix::column_min (void) const -{ - RowVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nc); - - for (int j = 0; j < nc; j++) - { - double res = elem (0, j); - for (int i = 1; i < nr; i++) - if (elem (i, j) < res) - res = elem (i, j); - result.elem (j) = res; - } - } - - return result; -} -RowVector -Matrix::column_min_loc (void) const -{ - RowVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nc); - - for (int j = 0; j < nc; j++) - { - int res = 0; - for (int i = 0; i < nr; i++) - if (elem (i, j) < elem (res, j)) - res = i; - result.elem (j) = (double) (res + 1); - } - } - - return result; -} - - -RowVector -Matrix::column_max (void) const -{ - RowVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nc); - - for (int j = 0; j < nc; j++) - { - double res = elem (0, j); - for (int i = 1; i < nr; i++) - if (elem (i, j) > res) - res = elem (i, j); - result.elem (j) = res; - } - } - - return result; -} - -RowVector -Matrix::column_max_loc (void) const -{ - RowVector result; - - int nr = rows (); - int nc = cols (); - - if (nr > 0 && nc > 0) - { - result.resize (nc); - - for (int j = 0; j < nc; j++) - { - int res = 0; - for (int i = 0; i < nr; i++) - if (elem (i, j) > elem (res, j)) - res = i; - result.elem (j) = (double) (res + 1); - } - } - - return result; -} - -ostream& -operator << (ostream& os, const Matrix& a) -{ -// int field_width = os.precision () + 7; - - for (int i = 0; i < a.rows (); i++) - { - for (int j = 0; j < a.cols (); j++) - os << " " /* setw (field_width) */ << a.elem (i, j); - os << "\n"; - } - return os; -} - -istream& -operator >> (istream& is, Matrix& a) -{ - int nr = a.rows (); - int nc = a.cols (); - - if (nr < 1 || nc < 1) - is.clear (ios::badbit); - else - { - double tmp; - for (int i = 0; i < nr; i++) - for (int j = 0; j < nc; j++) - { - is >> tmp; - if (is) - a.elem (i, j) = tmp; - else - break; - } - } - - return is; -} - -// Read an array of data from a file in binary format. - -int -Matrix::read (FILE *fptr, const char *type) -{ - // Allocate buffer pointers. - - union - { - void *vd; - char *ch; - u_char *uc; - short *sh; - u_short *us; - int *in; - u_int *ui; - long *ln; - u_long *ul; - float *fl; - double *db; - } - buf; - - // Convert data to double. - - if (! type) - { - (*current_liboctave_error_handler) - ("fread: invalid NULL type parameter"); - return 0; - } - - int count; - int nitems = length (); - - double *d = fortran_vec (); // Ensures only one reference to my privates! - -#define DO_FREAD(TYPE,ELEM) \ - do \ - { \ - size_t size = sizeof (TYPE); \ - buf.ch = new char [size * nitems]; \ - count = fread (buf.ch, size, nitems, fptr); \ - for (int k = 0; k < count; k++) \ - d[k] = buf.ELEM[k]; \ - delete [] buf.ch; \ - } \ - while (0) - - if (strcasecmp (type, "double") == 0) - DO_FREAD (double, db); - else if (strcasecmp (type, "char") == 0) - DO_FREAD (char, ch); - else if (strcasecmp (type, "uchar") == 0) - DO_FREAD (u_char, uc); - else if (strcasecmp (type, "short") == 0) - DO_FREAD (short, sh); - else if (strcasecmp (type, "ushort") == 0) - DO_FREAD (u_short, us); - else if (strcasecmp (type, "int") == 0) - DO_FREAD (int, in); - else if (strcasecmp (type, "uint") == 0) - DO_FREAD (u_int, ui); - else if (strcasecmp (type, "long") == 0) - DO_FREAD (long, ul); - else if (strcasecmp (type, "float") == 0) - DO_FREAD (float, fl); - else - { - (*current_liboctave_error_handler) - ("fread: invalid NULL type parameter"); - return 0; - } - - return count; -} - -// Write the data array to a file in binary format. - -int -Matrix::write (FILE *fptr, const char *type) -{ - // Allocate buffer pointers. - - union - { - void *vd; - char *ch; - u_char *uc; - short *sh; - u_short *us; - int *in; - u_int *ui; - long *ln; - u_long *ul; - float *fl; - double *db; - } - buf; - - int nitems = length (); - - double *d = fortran_vec (); - - // Convert from double to correct size. - - if (! type) - { - (*current_liboctave_error_handler) - ("fwrite: invalid NULL type parameter"); - return 0; - } - - size_t size; - int count; - -#define DO_FWRITE(TYPE,ELEM) \ - do \ - { \ - size = sizeof (TYPE); \ - buf.ELEM = new TYPE [nitems]; \ - for (int k = 0; k < nitems; k++) \ - buf.ELEM[k] = (TYPE) d[k]; \ - count = fwrite (buf.ELEM, size, nitems, fptr); \ - delete [] buf.ELEM; \ - } \ - while (0) - - if (strcasecmp (type, "double") == 0) - DO_FWRITE (double, db); - else if (strcasecmp (type, "char") == 0) - DO_FWRITE (char, ch); - else if (strcasecmp (type, "uchar") == 0) - DO_FWRITE (u_char, uc); - else if (strcasecmp (type, "short") == 0) - DO_FWRITE (short, sh); - else if (strcasecmp (type, "ushort") == 0) - DO_FWRITE (u_short, us); - else if (strcasecmp (type, "int") == 0) - DO_FWRITE (int, in); - else if (strcasecmp (type, "uint") == 0) - DO_FWRITE (u_int, ui); - else if (strcasecmp (type, "long") == 0) - DO_FWRITE (long, ln); - else if (strcasecmp (type, "ulong") == 0) - DO_FWRITE (u_long, ul); - else if (strcasecmp (type, "float") == 0) - DO_FWRITE (float, fl); - else - { - (*current_liboctave_error_handler) - ("fwrite: unrecognized type parameter %s", type); - return 0; - } - - return count; -} -#endif - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -524,43 +524,54 @@ Matrix Matrix::inverse (int& info, double& rcond, int force) const { + Matrix retval; + int nr = rows (); int nc = cols (); - int len = length (); + if (nr != nc || nr == 0 || nc == 0) - { - (*current_liboctave_error_handler) ("inverse requires square matrix"); - return Matrix (); - } - - info = 0; - - int *ipvt = new int [nr]; - double *z = new double [nr]; - double *tmp_data = dup (data (), len); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nc, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - - if (rcond_plus_one == 1.0) - info = -1; - - if (info == -1 && ! force) - { - copy (tmp_data, data (), len); // Restore matrix contents. - } + (*current_liboctave_error_handler) ("inverse requires square matrix"); else { - double *dummy = 0; - - F77_FCN (dgedi, DGEDI) (tmp_data, nr, nc, ipvt, dummy, z, 1); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<double> z (nr); + double *pz = z.fortran_vec (); + + retval = *this; + double *tmp_data = retval.fortran_vec (); + + F77_XFCN (dgeco, DGECO, (tmp_data, nr, nc, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in dgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + info = -1; + + if (info == -1 && ! force) + retval = *this; // Restore matrix contents. + else + { + double *dummy = 0; + + F77_XFCN (dgedi, DGEDI, (tmp_data, nr, nc, pipvt, dummy, + pz, 1)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgedi"); + } + } } - delete [] ipvt; - delete [] z; - - return Matrix (tmp_data, nr, nc); + return retval; } Matrix @@ -603,9 +614,13 @@ ComplexMatrix Matrix::fourier (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -618,25 +633,31 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); + F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); + + return retval; } ComplexMatrix Matrix::ifourier (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -649,28 +670,34 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); + F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); for (int j = 0; j < npts*nsamples; j++) tmp_data[j] = tmp_data[j] / (double) npts; - delete [] wsave; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexMatrix Matrix::fourier2d (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -683,47 +710,54 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; + F77_FCN (cfftf, CFFTF) (npts, &tmp_data[npts*j], pwsave); npts = nc; nsamples = nr; nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); + + wsave.resize (nn); + pwsave = wsave.fortran_vec (); + + Array<Complex> row (npts); + Complex *prow = row.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) { for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftf, CFFTF) (npts, row, wsave); + prow[i] = tmp_data[i*nr + j]; + + F77_FCN (cfftf, CFFTF) (npts, prow, pwsave); for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i]; + tmp_data[i*nr + j] = prow[i]; } - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } ComplexMatrix Matrix::ifourier2d (void) const { + ComplexMatrix retval; + int nr = rows (); int nc = cols (); + int npts, nsamples; + if (nr == 1 || nc == 1) { npts = nr > nc ? nr : nc; @@ -736,15 +770,17 @@ } int nn = 4*npts+15; - Complex *wsave = new Complex [nn]; - Complex *tmp_data = make_complex (data (), length ()); - - F77_FCN (cffti, CFFTI) (npts, wsave); + + Array<Complex> wsave (nn); + Complex *pwsave = wsave.fortran_vec (); + + retval = *this; + Complex *tmp_data = retval.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) - F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], wsave); - - delete [] wsave; + F77_FCN (cfftb, CFFTB) (npts, &tmp_data[npts*j], pwsave); for (int j = 0; j < npts*nsamples; j++) tmp_data[j] = tmp_data[j] / (double) npts; @@ -752,26 +788,27 @@ npts = nc; nsamples = nr; nn = 4*npts+15; - wsave = new Complex [nn]; - Complex *row = new Complex[npts]; - - F77_FCN (cffti, CFFTI) (npts, wsave); + + wsave.resize (nn); + pwsave = wsave.fortran_vec (); + + Array<Complex> row (npts); + Complex *prow = row.fortran_vec (); + + F77_FCN (cffti, CFFTI) (npts, pwsave); for (int j = 0; j < nsamples; j++) { for (int i = 0; i < npts; i++) - row[i] = tmp_data[i*nr + j]; - - F77_FCN (cfftb, CFFTB) (npts, row, wsave); + prow[i] = tmp_data[i*nr + j]; + + F77_FCN (cfftb, CFFTB) (npts, prow, pwsave); for (int i = 0; i < npts; i++) - tmp_data[i*nr + j] = row[i] / (double) npts; + tmp_data[i*nr + j] = prow[i] / (double) npts; } - delete [] wsave; - delete [] row; - - return ComplexMatrix (tmp_data, nr, nc); + return retval; } DET @@ -807,29 +844,42 @@ else { info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -1; - retval = DET (); - } + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<double> z (nr); + double *pz = z.fortran_vec (); + + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + F77_XFCN (dgeco, DGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in dgeco"); else { - double d[2]; - F77_FCN (dgedi, DGEDI) (tmp_data, nr, nr, ipvt, d, z, 10); - retval = DET (d); + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -1; + retval = DET (); + } + else + { + double d[2]; + + F77_XFCN (dgedi, DGEDI, (tmp_data, nr, nr, pipvt, d, pz, 10)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgedi"); + else + retval = DET (d); + } } - - delete [] tmp_data; - delete [] ipvt; - delete [] z; } return retval; @@ -857,41 +907,59 @@ int nr = rows (); int nc = cols (); + if (nr == 0 || nc == 0 || nr != nc || nr != b.rows ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of linear equations"); - return Matrix (); - } - - info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } + (*current_liboctave_error_handler) + ("matrix dimension mismatch solution of linear equations"); else { - double *result = dup (b.data (), b.length ()); - - int b_nc = b.cols (); - for (int j = 0; j < b_nc; j++) - F77_FCN (dgesl, DGESL) (tmp_data, nr, nr, ipvt, &result[nr*j], 0); - - retval = Matrix (result, b.rows (), b_nc); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<double> z (nr); + double *pz = z.fortran_vec (); + + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + F77_XFCN (dgeco, DGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in dgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -2; + } + else + { + retval = b; + double *result = retval.fortran_vec (); + + int b_nc = b.cols (); + + for (volatile int j = 0; j < b_nc; j++) + { + F77_XFCN (dgesl, DGESL, (tmp_data, nr, nr, pipvt, + &result[nr*j], 0)); + + if (f77_exception_encountered) + { + (*current_liboctave_error_handler) + ("unrecoverable error in dgesl"); + + break; + } + } + } + } } - delete [] tmp_data; - delete [] ipvt; - delete [] z; - return retval; } @@ -937,41 +1005,50 @@ int nr = rows (); int nc = cols (); + if (nr == 0 || nc == 0 || nr != nc || nr != b.length ()) - { - (*current_liboctave_error_handler) - ("matrix dimension mismatch solution of linear equations"); - return ColumnVector (); - } - - info = 0; - int *ipvt = new int [nr]; - - double *z = new double [nr]; - double *tmp_data = dup (data (), length ()); - - F77_FCN (dgeco, DGECO) (tmp_data, nr, nr, ipvt, rcond, z); - - volatile double rcond_plus_one = rcond + 1.0; - if (rcond_plus_one == 1.0) - { - info = -2; - } + (*current_liboctave_error_handler) + ("matrix dimension mismatch solution of linear equations"); else { - int b_len = b.length (); - - double *result = dup (b.data (), b_len); - - F77_FCN (dgesl, DGESL) (tmp_data, nr, nr, ipvt, result, 0); - - retval = ColumnVector (result, b_len); + info = 0; + + Array<int> ipvt (nr); + int *pipvt = ipvt.fortran_vec (); + + Array<double> z (nr); + double *pz = z.fortran_vec (); + + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + F77_XFCN (dgeco, DGECO, (tmp_data, nr, nr, pipvt, rcond, pz)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgeco"); + else + { + volatile double rcond_plus_one = rcond + 1.0; + + if (rcond_plus_one == 1.0) + { + info = -2; + } + else + { + retval = b; + double *result = retval.fortran_vec (); + + F77_XFCN (dgesl, DGESL, (tmp_data, nr, nr, pipvt, result, 0)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgesl"); + } + } } - delete [] tmp_data; - delete [] ipvt; - delete [] z; - return retval; } @@ -1014,52 +1091,63 @@ Matrix Matrix::lssolve (const Matrix& b, int& info, int& rank) const { + Matrix retval; + int nrhs = b.cols (); int m = rows (); int n = cols (); if (m == 0 || n == 0 || m != b.rows ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch in solution of least squares problem"); + else { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of least squares problem"); - return Matrix (); + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + int nrr = m > n ? m : n; + Matrix result (nrr, nrhs); + + for (int j = 0; j < nrhs; j++) + for (int i = 0; i < m; i++) + result.elem (i, j) = b.elem (i, j); + + double *presult = result.fortran_vec (); + + int len_s = m < n ? m : n; + Array<double> s (len_s); + double *ps = s.fortran_vec (); + + double rcond = -1.0; + + int lwork; + if (m < n) + lwork = 3*m + (2*m > nrhs + ? (2*m > n ? 2*m : n) + : (nrhs > n ? nrhs : n)); + else + lwork = 3*n + (2*n > nrhs + ? (2*n > m ? 2*n : m) + : (nrhs > m ? nrhs : m)); + + Array<double> work (lwork); + double *pwork = work.fortran_vec (); + + F77_XFCN (dgelss, DGELSS, (m, n, nrhs, tmp_data, m, presult, nrr, ps, + rcond, rank, pwork, lwork, info)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in dgelss"); + else + { + retval.resize (n, nrhs); + for (int j = 0; j < nrhs; j++) + for (int i = 0; i < n; i++) + retval.elem (i, j) = result.elem (i, j); + } } - double *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - Matrix result (nrr, nrhs); - - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < m; i++) - result.elem (i, j) = b.elem (i, j); - - double *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 3*m + (2*m > nrhs ? (2*m > n ? 2*m : n) : (nrhs > n ? nrhs : n)); - else - lwork = 3*n + (2*n > nrhs ? (2*n > m ? 2*n : m) : (nrhs > m ? nrhs : m)); - - double *work = new double [lwork]; - - F77_FCN (dgelss, DGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, info); - - Matrix retval (n, nrhs); - for (int j = 0; j < nrhs; j++) - for (int i = 0; i < n; i++) - retval.elem (i, j) = result.elem (i, j); - - delete [] tmp_data; - delete [] s; - delete [] work; - return retval; } @@ -1105,50 +1193,61 @@ ColumnVector Matrix::lssolve (const ColumnVector& b, int& info, int& rank) const { + ColumnVector retval; + int nrhs = 1; int m = rows (); int n = cols (); if (m == 0 || n == 0 || m != b.length ()) + (*current_liboctave_error_handler) + ("matrix dimension mismatch in solution of least squares problem"); + else { - (*current_liboctave_error_handler) - ("matrix dimension mismatch in solution of least squares problem"); - return ColumnVector (); + Matrix atmp = *this; + double *tmp_data = atmp.fortran_vec (); + + int nrr = m > n ? m : n; + ColumnVector result (nrr); + + for (int i = 0; i < m; i++) + result.elem (i) = b.elem (i); + + double *presult = result.fortran_vec (); + + int len_s = m < n ? m : n; + Array<double> s (len_s); + double *ps = s.fortran_vec (); + + double rcond = -1.0; + + int lwork; + if (m < n) + lwork = 3*m + (2*m > nrhs + ? (2*m > n ? 2*m : n) + : (nrhs > n ? nrhs : n)); + else + lwork = 3*n + (2*n > nrhs + ? (2*n > m ? 2*n : m) + : (nrhs > m ? nrhs : m)); + + Array<double> work (lwork); + double *pwork = work.fortran_vec (); + + F77_XFCN (dgelss, DGELSS, (m, n, nrhs, tmp_data, m, presult, nrr, + ps, rcond, rank, pwork, lwork, info)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) ("unrecoverable error in dgelss"); + else + { + retval.resize (n); + for (int i = 0; i < n; i++) + retval.elem (i) = result.elem (i); + } } - double *tmp_data = dup (data (), length ()); - - int nrr = m > n ? m : n; - ColumnVector result (nrr); - - for (int i = 0; i < m; i++) - result.elem (i) = b.elem (i); - - double *presult = result.fortran_vec (); - - int len_s = m < n ? m : n; - double *s = new double [len_s]; - double rcond = -1.0; - int lwork; - if (m < n) - lwork = 3*m + (2*m > nrhs ? (2*m > n ? 2*m : n) : (nrhs > n ? nrhs : n)); - else - lwork = 3*n + (2*n > nrhs ? (2*n > m ? 2*n : m) : (nrhs > m ? nrhs : m)); - - double *work = new double [lwork]; - - F77_FCN (dgelss, DGELSS) (m, n, nrhs, tmp_data, m, presult, nrr, s, - rcond, rank, work, lwork, info); - - ColumnVector retval (n); - for (int i = 0; i < n; i++) - retval.elem (i) = result.elem (i); - - delete [] tmp_data; - delete [] s; - delete [] work; - return retval; } @@ -1387,24 +1486,32 @@ Matrix operator * (const ColumnVector& v, const RowVector& a) { + Matrix retval; + int len = v.length (); int a_len = a.length (); + if (len != a_len) + (*current_liboctave_error_handler) + ("nonconformant vector multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant vector multiplication attempted"); - return Matrix (); + if (len != 0) + { + retval.resize (len, a_len); + double *c = retval.fortran_vec (); + + F77_XFCN (dgemm, DGEMM, ("N", "N", len, a_len, 1, 1.0, + v.data (), len, a.data (), 1, 0.0, + c, len, 1L, 1L)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgemm"); + } } - if (len == 0) - return Matrix (len, len, 0.0); - - double *c = new double [len * a_len]; - - F77_FCN (dgemm, DGEMM) ("N", "N", len, a_len, 1, 1.0, v.data (), - len, a.data (), 1, 0.0, c, len, 1L, 1L); - - return Matrix (c, len, a_len); + return retval; } // diagonal matrix by scalar -> matrix operations @@ -1490,52 +1597,61 @@ Matrix operator * (const Matrix& m, const DiagMatrix& a) { + Matrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nr = a.rows (); int a_nc = a.cols (); + if (nc != a_nr) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return Matrix (); - } - - if (nr == 0 || nc == 0 || a_nc == 0) - return Matrix (nr, a_nc, 0.0); - - double *c = new double [nr*a_nc]; - double *ctmp = 0; - - int a_len = a.length (); - for (int j = 0; j < a_len; j++) - { - int idx = j * nr; - ctmp = c + idx; - if (a.elem (j, j) == 1.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = m.elem (i, j); - } - else if (a.elem (j, j) == 0.0) - { - for (int i = 0; i < nr; i++) - ctmp[i] = 0.0; - } + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, a_nc, 0.0); else { - for (int i = 0; i < nr; i++) - ctmp[i] = a.elem (j, j) * m.elem (i, j); + retval.resize (nr, a_nc); + double *c = retval.fortran_vec (); + + double *ctmp = 0; + + int a_len = a.length (); + + for (int j = 0; j < a_len; j++) + { + int idx = j * nr; + ctmp = c + idx; + + if (a.elem (j, j) == 1.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = m.elem (i, j); + } + else if (a.elem (j, j) == 0.0) + { + for (int i = 0; i < nr; i++) + ctmp[i] = 0.0; + } + else + { + for (int i = 0; i < nr; i++) + ctmp[i] = a.elem (j, j) * m.elem (i, j); + } + } + + if (a_nr < a_nc) + { + for (int i = nr * nc; i < nr * a_nc; i++) + ctmp[i] = 0.0; + } } } - if (a_nr < a_nc) - { - for (int i = nr * nc; i < nr * a_nc; i++) - ctmp[i] = 0.0; - } - - return Matrix (c, nr, a_nc); + return retval; } // diagonal matrix by matrix -> matrix operations @@ -1637,29 +1753,40 @@ Matrix operator * (const Matrix& m, const Matrix& a) { + Matrix retval; + int nr = m.rows (); int nc = m.cols (); + int a_nr = a.rows (); int a_nc = a.cols (); + if (nc != a_nr) + (*current_liboctave_error_handler) + ("nonconformant matrix multiplication attempted"); + else { - (*current_liboctave_error_handler) - ("nonconformant matrix multiplication attempted"); - return Matrix (); + if (nr == 0 || nc == 0 || a_nc == 0) + retval.resize (nr, a_nc, 0.0); + else + { + int ld = nr; + int lda = a_nr; + + retval.resize (nr, a_nc); + double *c = retval.fortran_vec (); + + F77_XFCN (dgemm, DGEMM, ("N", "N", nr, a_nc, nc, 1.0, + m.data (), ld, a.data (), lda, 0.0, + c, nr, 1L, 1L)); + + if (f77_exception_encountered) + (*current_liboctave_error_handler) + ("unrecoverable error in dgemm"); + } } - if (nr == 0 || nc == 0 || a_nc == 0) - return Matrix (nr, a_nc, 0.0); - - int ld = nr; - int lda = a_nr; - - double *c = new double [nr*a_nc]; - - F77_FCN (dgemm, DGEMM) ("N", "N", nr, a_nc, nc, 1.0, m.data (), - ld, a.data (), lda, 0.0, c, nr, 1L, 1L); - - return Matrix (c, nr, a_nc); + return retval; } // other operations.