# HG changeset patch # User Jaroslav Hajek # Date 1228468818 -3600 # Node ID e3c9102431a9c50c04622e87deb34d8af98600ba # Parent 0f8e810c69500cb42694dde9bfe25a25add0390b fix design problems of diag & perm matrix classes diff --git a/liboctave/CDiagMatrix.cc b/liboctave/CDiagMatrix.cc --- a/liboctave/CDiagMatrix.cc +++ b/liboctave/CDiagMatrix.cc @@ -529,47 +529,6 @@ // other operations -ComplexColumnVector -ComplexDiagMatrix::diag (octave_idx_type k) const -{ - octave_idx_type nnr = rows (); - octave_idx_type nnc = cols (); - if (k > 0) - nnc -= k; - else if (k < 0) - nnr += k; - - ComplexColumnVector d; - - if (nnr > 0 && nnc > 0) - { - octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; - - d.resize (ndiag); - - if (k > 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i+k); - } - else if ( k < 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i-k, i); - } - else - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i); - } - } - else - (*current_liboctave_error_handler) - ("diag: requested diagonal out of range"); - - return d; -} - ComplexDET ComplexDiagMatrix::determinant (void) const { diff --git a/liboctave/CDiagMatrix.h b/liboctave/CDiagMatrix.h --- a/liboctave/CDiagMatrix.h +++ b/liboctave/CDiagMatrix.h @@ -122,7 +122,8 @@ // other operations - ComplexColumnVector diag (octave_idx_type k = 0) const; + ComplexColumnVector diag (octave_idx_type k = 0) const + { return MDiagArray2::diag (k); } ComplexDET determinant (void) const; double rcond (void) const; diff --git a/liboctave/ChangeLog b/liboctave/ChangeLog --- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,21 @@ +2008-12-04 Jaroslav Hajek + + * DiagArray2.h (DiagArray2): Inherit Array privately. + (DiagArray2::dim1, dim2, rows, columns, cols, length, + nelem, numel, byte_size, dims): New methods. + (DiagArray2::diag): New method decl. + * DiagArray2.cc (DiagArray2::diag): New method. + * MDiagArray2.h (MDiagArray2::diag): New method. + * dDiagMatrix.cc (DiagMatrix::diag): Remove. + * fDiagMatrix.cc (FloatDiagMatrix::diag): Remove. + * CDiagMatrix.cc (ComplexDiagMatrix::diag): Remove. + * fCDiagMatrix.cc (FloatComplexDiagMatrix::diag): Remove. + + * PermMatrix.h (PermMatrix): Inherit Array privately. + (PermMatrix::dim1, dim2, rows, columns, cols, length, + nelem, numel, byte_size, dims): New methods. + + 2008-12-04 Jaroslav Hajek * dDiagMatrix.cc (DiagMatrix::determinant, DiagMatrix::rcond): New diff --git a/liboctave/CmplxQRP.cc b/liboctave/CmplxQRP.cc --- a/liboctave/CmplxQRP.cc +++ b/liboctave/CmplxQRP.cc @@ -129,7 +129,7 @@ ColumnVector ComplexQRP::Pvec (void) const { - Array pa (p); + Array pa (p.pvec ()); ColumnVector pv (MArray (pa) + 1.0); return pv; } diff --git a/liboctave/DiagArray2.cc b/liboctave/DiagArray2.cc --- a/liboctave/DiagArray2.cc +++ b/liboctave/DiagArray2.cc @@ -30,16 +30,41 @@ #include +#include + #include "DiagArray2.h" #include "lo-error.h" template +Array +DiagArray2::diag (octave_idx_type k) const +{ + Array d; + + if (k == 0) + { + // The main diagonal is shallow-copied. + d = *this; + d.dimensions = dim_vector (length ()); + } + else if (k > 0 && k < cols ()) + d = Array (std::min (cols () - k, rows ()), T ()); + else if (k < 0 && -k < rows ()) + d = Array (std::min (rows () + k, cols ()), T ()); + else + (*current_liboctave_error_handler) + ("diag: requested diagonal out of range"); + + return d; +} + +template DiagArray2 DiagArray2::transpose (void) const { DiagArray2 retval (*this); - retval.dimensions = dim_vector (this->dim2 (), this->dim1 ()); + retval.dimensions = dim_vector (dim2 (), dim1 ()); return retval; } @@ -47,7 +72,7 @@ DiagArray2 DiagArray2::hermitian (T (* fcn) (const T&)) const { - DiagArray2 retval (this->dim2 (), this->dim1 ()); + DiagArray2 retval (dim2 (), dim1 ()); const T *p = this->data (); T *q = retval.fortran_vec (); for (octave_idx_type i = 0; i < this->length (); i++) @@ -61,7 +86,7 @@ T DiagArray2::checkelem (octave_idx_type r, octave_idx_type c) const { - if (r < 0 || c < 0 || r >= this->dim1 () || c >= this->dim2 ()) + if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ()) { (*current_liboctave_error_handler) ("range error in DiagArray2"); return T (); @@ -79,7 +104,7 @@ return; } - if (r == this->dim1 () && c == this->dim2 ()) + if (r == dim1 () && c == dim2 ()) return; typename Array::ArrayRep *old_rep = Array::rep; @@ -114,7 +139,7 @@ return; } - if (r == this->dim1 () && c == this->dim2 ()) + if (r == dim1 () && c == dim2 ()) return; typename Array::ArrayRep *old_rep = Array::rep; diff --git a/liboctave/DiagArray2.h b/liboctave/DiagArray2.h --- a/liboctave/DiagArray2.h +++ b/liboctave/DiagArray2.h @@ -3,6 +3,7 @@ Copyright (C) 1996, 1997, 2000, 2002, 2003, 2004, 2005, 2006, 2007 John W. Eaton +Copyright (C) 2008 Jaroslav Hajek This file is part of Octave. @@ -31,8 +32,6 @@ #include "Array.h" #include "lo-error.h" -class idx_vector; - // A two-dimensional array with diagonal elements only. // // Idea and example code for Proxy class and functions from: @@ -46,9 +45,13 @@ // James Kanze email: kanze@us-es.sel.de // GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France +// Array is inherited privately because we abuse the dimensions variable +// for true dimensions. Therefore, the inherited Array object is not a valid +// Array object, and should not be publicly accessible. + template class -DiagArray2 : public Array +DiagArray2 : private Array { private: @@ -112,6 +115,8 @@ public: + typedef T element_type; + DiagArray2 (void) : Array (dim_vector (0, 0)) { } DiagArray2 (octave_idx_type r, octave_idx_type c) : Array (r < c ? r : c) @@ -131,7 +136,7 @@ { this->dimensions = a.dims (); } template - DiagArray2 (const DiagArray2& a) : Array (a) + DiagArray2 (const DiagArray2& a) : Array (a.diag ()) { this->dimensions = a.dims (); } ~DiagArray2 (void) { } @@ -144,6 +149,24 @@ return *this; } + + octave_idx_type dim1 (void) const { return Array::dimensions(0); } + octave_idx_type dim2 (void) const { return Array::dimensions(1); } + + octave_idx_type rows (void) const { return dim1 (); } + octave_idx_type cols (void) const { return dim2 (); } + octave_idx_type columns (void) const { return dim2 (); } + + octave_idx_type length (void) const { return Array::length (); } + octave_idx_type nelem (void) const { return dim1 () * dim2 (); } + octave_idx_type numel (void) const { return nelem (); } + + size_t byte_size (void) const { return length () * sizeof (T); } + + dim_vector dims (void) const { return Array::dimensions; } + + Array diag (octave_idx_type k = 0) const; + Proxy elem (octave_idx_type r, octave_idx_type c) { return Proxy (this, r, c); @@ -151,7 +174,7 @@ Proxy checkelem (octave_idx_type r, octave_idx_type c) { - if (r < 0 || c < 0 || r >= this->dim1 () || c >= this->dim2 ()) + if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ()) { (*current_liboctave_error_handler) ("range error in DiagArray2"); return Proxy (0, r, c); @@ -162,7 +185,7 @@ Proxy operator () (octave_idx_type r, octave_idx_type c) { - if (r < 0 || c < 0 || r >= this->dim1 () || c >= this->dim2 ()) + if (r < 0 || c < 0 || r >= dim1 () || c >= dim2 ()) { (*current_liboctave_error_handler) ("range error in DiagArray2"); return Proxy (0, r, c); @@ -204,6 +227,15 @@ DiagArray2 transpose (void) const; DiagArray2 hermitian (T (*fcn) (const T&) = 0) const; + + const T *data (void) const { return Array::data (); } + + const T *fortran_vec (void) const { return Array::fortran_vec (); } + + T *fortran_vec (void) { return Array::fortran_vec (); } + + void print_info (std::ostream& os, const std::string& prefix) const + { Array::print_info (os, prefix); } }; #endif diff --git a/liboctave/MDiagArray2.h b/liboctave/MDiagArray2.h --- a/liboctave/MDiagArray2.h +++ b/liboctave/MDiagArray2.h @@ -27,6 +27,7 @@ #include "DiagArray2.h" #include "MArray2.h" +#include "MArray.h" // Two dimensional diagonal array with math ops. @@ -88,9 +89,9 @@ { octave_idx_type retval = 0; - const T *d = this->Array::data (); + const T *d = this->data (); - octave_idx_type nel = this->Array::numel (); + octave_idx_type nel = this->length (); for (octave_idx_type i = 0; i < nel; i++) { @@ -101,6 +102,9 @@ return retval; } + MArray diag (octave_idx_type k = 0) const + { return DiagArray2::diag (k); } + MDiagArray2 transpose (void) const { return DiagArray2::transpose (); } MDiagArray2 hermitian (T (*fcn) (const T&) = 0) const { return DiagArray2::hermitian (fcn); } diff --git a/liboctave/PermMatrix.cc b/liboctave/PermMatrix.cc --- a/liboctave/PermMatrix.cc +++ b/liboctave/PermMatrix.cc @@ -123,7 +123,7 @@ PermMatrix operator *(const PermMatrix& a, const PermMatrix& b) { - const Array& ia = a, ib = b; + const Array ia = a.pvec (), ib = b.pvec (); PermMatrix r; octave_idx_type n = a.columns (); if (n != b.rows ()) diff --git a/liboctave/PermMatrix.h b/liboctave/PermMatrix.h --- a/liboctave/PermMatrix.h +++ b/liboctave/PermMatrix.h @@ -26,7 +26,11 @@ #include "Array.h" #include "mx-defs.h" -class PermMatrix : public Array +// Array is inherited privately because we abuse the dimensions variable +// for true dimensions. Therefore, the inherited Array object is not a valid +// Array object, and should not be publicly accessible. + +class PermMatrix : private Array { private: @@ -42,11 +46,35 @@ bool check = true); PermMatrix (const PermMatrix& m) - : Array (m), _colp(m._colp) - { this->dimensions = m.dims (); } + : Array (m), _colp(m._colp) { } PermMatrix (const idx_vector& idx, bool colp = false, octave_idx_type n = 0); + octave_idx_type dim1 (void) const + { return Array::dimensions(0); } + octave_idx_type dim2 (void) const + { return Array::dimensions(1); } + + octave_idx_type rows (void) const { return dim1 (); } + octave_idx_type cols (void) const { return dim2 (); } + octave_idx_type columns (void) const { return dim2 (); } + + octave_idx_type length (void) const + { return Array::length (); } + octave_idx_type nelem (void) const { return dim1 () * dim2 (); } + octave_idx_type numel (void) const { return nelem (); } + + size_t byte_size (void) const { return length () * sizeof (octave_idx_type); } + + dim_vector dims (void) const { return Array::dimensions; } + + Array pvec (void) const + { + Array retval (*this); + retval.dimensions = dim_vector (length ()); + return retval; + } + octave_idx_type elem (octave_idx_type i, octave_idx_type j) const { @@ -80,6 +108,18 @@ friend PermMatrix operator *(const PermMatrix& a, const PermMatrix& b); + const octave_idx_type *data (void) const + { return Array::data (); } + + const octave_idx_type *fortran_vec (void) const + { return Array::fortran_vec (); } + + octave_idx_type *fortran_vec (void) + { return Array::fortran_vec (); } + + void print_info (std::ostream& os, const std::string& prefix) const + { Array::print_info (os, prefix); } + private: bool _colp; }; diff --git a/liboctave/dDiagMatrix.cc b/liboctave/dDiagMatrix.cc --- a/liboctave/dDiagMatrix.cc +++ b/liboctave/dDiagMatrix.cc @@ -342,51 +342,6 @@ // other operations -ColumnVector -DiagMatrix::diag (octave_idx_type k) const -{ - ColumnVector d; - - octave_idx_type nnr = rows (); - octave_idx_type nnc = cols (); - - if (nnr == 0 || nnc == 0) - return d; - - if (k > 0) - nnc -= k; - else if (k < 0) - nnr += k; - - if (nnr > 0 && nnc > 0) - { - octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; - - d.resize (ndiag); - - if (k > 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i+k); - } - else if ( k < 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i-k, i); - } - else - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i); - } - } - else - (*current_liboctave_error_handler) - ("diag: requested diagonal out of range"); - - return d; -} - DET DiagMatrix::determinant (void) const { diff --git a/liboctave/dDiagMatrix.h b/liboctave/dDiagMatrix.h --- a/liboctave/dDiagMatrix.h +++ b/liboctave/dDiagMatrix.h @@ -97,7 +97,8 @@ // other operations - ColumnVector diag (octave_idx_type k = 0) const; + ColumnVector diag (octave_idx_type k = 0) const + { return MDiagArray2::diag (k); } DET determinant (void) const; double rcond (void) const; diff --git a/liboctave/dMatrix.cc b/liboctave/dMatrix.cc --- a/liboctave/dMatrix.cc +++ b/liboctave/dMatrix.cc @@ -251,7 +251,7 @@ Matrix::Matrix (const PermMatrix& a) : MArray2 (a.rows (), a.cols (), 0.0) { - const Array ia (a); + const Array ia (a.pvec ()); octave_idx_type len = a.rows (); if (a.is_col_perm ()) for (octave_idx_type i = 0; i < len; i++) diff --git a/liboctave/dbleQRP.cc b/liboctave/dbleQRP.cc --- a/liboctave/dbleQRP.cc +++ b/liboctave/dbleQRP.cc @@ -123,7 +123,7 @@ ColumnVector QRP::Pvec (void) const { - Array pa (p); + Array pa (p.pvec ()); ColumnVector pv (MArray (pa) + 1.0); return pv; } diff --git a/liboctave/fCDiagMatrix.cc b/liboctave/fCDiagMatrix.cc --- a/liboctave/fCDiagMatrix.cc +++ b/liboctave/fCDiagMatrix.cc @@ -550,47 +550,6 @@ // other operations -FloatComplexColumnVector -FloatComplexDiagMatrix::diag (octave_idx_type k) const -{ - octave_idx_type nnr = rows (); - octave_idx_type nnc = cols (); - if (k > 0) - nnc -= k; - else if (k < 0) - nnr += k; - - FloatComplexColumnVector d; - - if (nnr > 0 && nnc > 0) - { - octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; - - d.resize (ndiag); - - if (k > 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i+k); - } - else if ( k < 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i-k, i); - } - else - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i); - } - } - else - (*current_liboctave_error_handler) - ("diag: requested diagonal out of range"); - - return d; -} - FloatComplexDET FloatComplexDiagMatrix::determinant (void) const { diff --git a/liboctave/fCDiagMatrix.h b/liboctave/fCDiagMatrix.h --- a/liboctave/fCDiagMatrix.h +++ b/liboctave/fCDiagMatrix.h @@ -122,7 +122,8 @@ // other operations - FloatComplexColumnVector diag (octave_idx_type k = 0) const; + FloatComplexColumnVector diag (octave_idx_type k = 0) const + { return MDiagArray2::diag (k); } FloatComplexDET determinant (void) const; float rcond (void) const; diff --git a/liboctave/fCmplxQRP.cc b/liboctave/fCmplxQRP.cc --- a/liboctave/fCmplxQRP.cc +++ b/liboctave/fCmplxQRP.cc @@ -129,7 +129,7 @@ FloatColumnVector FloatComplexQRP::Pvec (void) const { - Array pa (p); + Array pa (p.pvec ()); FloatColumnVector pv (MArray (pa) + 1.0f); return pv; } diff --git a/liboctave/fDiagMatrix.cc b/liboctave/fDiagMatrix.cc --- a/liboctave/fDiagMatrix.cc +++ b/liboctave/fDiagMatrix.cc @@ -349,51 +349,6 @@ // other operations -FloatColumnVector -FloatDiagMatrix::diag (octave_idx_type k) const -{ - FloatColumnVector d; - - octave_idx_type nnr = rows (); - octave_idx_type nnc = cols (); - - if (nnr == 0 || nnc == 0) - return d; - - if (k > 0) - nnc -= k; - else if (k < 0) - nnr += k; - - if (nnr > 0 && nnc > 0) - { - octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc; - - d.resize (ndiag); - - if (k > 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i+k); - } - else if ( k < 0) - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i-k, i); - } - else - { - for (octave_idx_type i = 0; i < ndiag; i++) - d.elem (i) = elem (i, i); - } - } - else - (*current_liboctave_error_handler) - ("diag: requested diagonal out of range"); - - return d; -} - FloatDET FloatDiagMatrix::determinant (void) const { diff --git a/liboctave/fDiagMatrix.h b/liboctave/fDiagMatrix.h --- a/liboctave/fDiagMatrix.h +++ b/liboctave/fDiagMatrix.h @@ -97,7 +97,8 @@ // other operations - FloatColumnVector diag (octave_idx_type k = 0) const; + FloatColumnVector diag (octave_idx_type k = 0) const + { return MDiagArray2::diag (k); } FloatDET determinant (void) const; float rcond (void) const; diff --git a/liboctave/fMatrix.cc b/liboctave/fMatrix.cc --- a/liboctave/fMatrix.cc +++ b/liboctave/fMatrix.cc @@ -250,7 +250,7 @@ FloatMatrix::FloatMatrix (const PermMatrix& a) : MArray2 (a.rows (), a.cols (), 0.0) { - const Array ia (a); + const Array ia (a.pvec ()); octave_idx_type len = a.rows (); if (a.is_col_perm ()) for (octave_idx_type i = 0; i < len; i++) diff --git a/liboctave/floatQRP.cc b/liboctave/floatQRP.cc --- a/liboctave/floatQRP.cc +++ b/liboctave/floatQRP.cc @@ -123,7 +123,7 @@ FloatColumnVector FloatQRP::Pvec (void) const { - Array pa (p); + Array pa (p.pvec ()); FloatColumnVector pv (MArray (pa) + 1.0f); return pv; } diff --git a/liboctave/idx-vector.cc b/liboctave/idx-vector.cc --- a/liboctave/idx-vector.cc +++ b/liboctave/idx-vector.cc @@ -557,7 +557,7 @@ } } - delete left; + delete [] left; } return retval; diff --git a/liboctave/mx-op-defs.h b/liboctave/mx-op-defs.h --- a/liboctave/mx-op-defs.h +++ b/liboctave/mx-op-defs.h @@ -1301,10 +1301,10 @@ if (p.is_col_perm ()) \ { \ result = M (nr, nc); \ - result.assign (idx_vector (p), idx_vector::colon, x); \ + result.assign (p.pvec (), idx_vector::colon, x); \ } \ else \ - result = x.index (idx_vector (p), idx_vector::colon); \ + result = x.index (p.pvec (), idx_vector::colon); \ } \ \ return result; \ @@ -1320,11 +1320,11 @@ else \ { \ if (p.is_col_perm ()) \ - result = x.index (idx_vector::colon, idx_vector (p)); \ + result = x.index (idx_vector::colon, p.pvec ()); \ else \ { \ result = M (nr, nc); \ - result.assign (idx_vector::colon, idx_vector (p), x); \ + result.assign (idx_vector::colon, p.pvec (), x); \ } \ } \ \