# HG changeset patch # User jwe # Date 825726852 0 # Node ID a4b0826e240c3eead508e5b14aff8c9789ad337b # Parent 7b56630a1e05bb55b7b508e6804c21c9de6b7951 [project @ 1996-03-02 00:33:22 by jwe] diff --git a/liboctave/Array-C.cc b/liboctave/Array-C.cc --- a/liboctave/Array-C.cc +++ b/liboctave/Array-C.cc @@ -23,14 +23,12 @@ // Instantiate Arrays of Complex values. +#include "oct-cmplx.h" + #include "Array.h" #include "Array.cc" -#include "oct-cmplx.h" - template class Array; -template class Array2; -template class DiagArray; template void assign (Array&, const Array&); template void assign (Array&, const Array&); @@ -38,12 +36,22 @@ template void assign (Array&, const Array&); template void assign (Array&, const Array&); +#include "Array2.h" +#include "Array2.cc" + +template class Array2; + template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); +#include "DiagArray2.h" +#include "DiagArray2.cc" + +template class DiagArray2; + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array-ch.cc b/liboctave/Array-ch.cc --- a/liboctave/Array-ch.cc +++ b/liboctave/Array-ch.cc @@ -23,22 +23,25 @@ // Instantiate Arrays of char values. -#define NO_DIAG_ARRAY 1 - #include "Array.h" #include "Array.cc" template class Array; -template class Array2; - -#ifndef NO_DIAG_ARRAY -template class DiagArray; -#endif template void assign (Array&, const Array&); +#include "Array2.h" +#include "Array2.cc" + +template class Array2; + template void assign (Array2&, const Array2&); +#include "DiagArray2.h" +#include "DiagArray2.cc" + +template class DiagArray2; + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array-d.cc b/liboctave/Array-d.cc --- a/liboctave/Array-d.cc +++ b/liboctave/Array-d.cc @@ -27,19 +27,27 @@ #include "Array.cc" template class Array; -template class Array2; -template class DiagArray; template void assign (Array&, const Array&); template void assign (Array&, const Array&); template void assign (Array&, const Array&); template void assign (Array&, const Array&); +#include "Array2.h" +#include "Array2.cc" + +template class Array2; + template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); +#include "DiagArray2.h" +#include "DiagArray2.cc" + +template class DiagArray2; + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array-i.cc b/liboctave/Array-i.cc --- a/liboctave/Array-i.cc +++ b/liboctave/Array-i.cc @@ -23,26 +23,29 @@ // Instantiate Arrays of integer values. -#define NO_DIAG_ARRAY 1 - #include "Array.h" #include "Array.cc" template class Array; -template class Array2; - -#ifndef NO_DIAG_ARRAY -template class DiagArray; -#endif template void assign (Array&, const Array&); template void assign (Array&, const Array&); template void assign (Array&, const Array&); +#include "Array2.h" +#include "Array2.cc" + +template class Array2; + template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); +#include "DiagArray2.h" +#include "DiagArray2.cc" + +template class DiagArray2; + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array-idx.h b/liboctave/Array-idx.h --- a/liboctave/Array-idx.h +++ b/liboctave/Array-idx.h @@ -217,6 +217,7 @@ return retval; } +#if 0 /* XXX */ template Array2 Array2::value (void) @@ -787,6 +788,7 @@ assert (0); return 0; } +#endif /* ;;; Local Variables: *** diff --git a/liboctave/Array-s.cc b/liboctave/Array-s.cc --- a/liboctave/Array-s.cc +++ b/liboctave/Array-s.cc @@ -23,24 +23,27 @@ // Instantiate Arrays of short int values. -#define NO_DIAG_ARRAY 1 - #include "Array.h" #include "Array.cc" template class Array; -template class Array2; - -#ifndef NO_DIAG_ARRAY -template class DiagArray; -#endif template void assign (Array&, const Array&); template void assign (Array&, const Array&); +#include "Array2.h" +#include "Array2.cc" + +template class Array2; + template void assign (Array2&, const Array2&); template void assign (Array2&, const Array2&); +#include "DiagArray2.h" +#include "DiagArray2.cc" + +template class DiagArray2; + /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array.cc b/liboctave/Array.cc --- a/liboctave/Array.cc +++ b/liboctave/Array.cc @@ -211,383 +211,6 @@ return rep->data; } -// Two dimensional array class. - -template -T& -Array2::checkelem (int i, int j) -{ - if (i < 0 || j < 0 || i >= d1 || j >= d2) - { - (*current_liboctave_error_handler) ("range error"); - static T foo; - return foo; - } - return Array::elem (d1*j+i); -} - -template -T -Array2::elem (int i, int j) const -{ - return Array::elem (d1*j+i); -} - -template -T -Array2::checkelem (int i, int j) const -{ - if (i < 0 || j < 0 || i >= d1 || j >= d2) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return Array::elem (d1*j+i); -} - -template -T -Array2::operator () (int i, int j) const -{ - if (i < 0 || j < 0 || i >= d1 || j >= d2) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return Array::elem (d1*j+i); -} - -template -void -Array2::resize (int r, int c) -{ - if (r < 0 || c < 0) - { - (*current_liboctave_error_handler) ("can't resize to negative dimension"); - return; - } - - if (r == dim1 () && c == dim2 ()) - return; - - ArrayRep *old_rep = rep; - const T *old_data = data (); - - int old_d1 = dim1 (); - int old_d2 = dim2 (); - int old_len = length (); - - rep = new ArrayRep (r*c); - - d1 = r; - d2 = c; - - if (old_data && old_len > 0) - { - int min_r = old_d1 < r ? old_d1 : r; - int min_c = old_d2 < c ? old_d2 : c; - - for (int j = 0; j < min_c; j++) - for (int i = 0; i < min_r; i++) - xelem (i, j) = old_data[old_d1*j+i]; - } - - if (--old_rep->count <= 0) - delete old_rep; -} - -template -void -Array2::resize (int r, int c, const T& val) -{ - if (r < 0 || c < 0) - { - (*current_liboctave_error_handler) ("can't resize to negative dimension"); - return; - } - - if (r == dim1 () && c == dim2 ()) - return; - - ArrayRep *old_rep = rep; - const T *old_data = data (); - int old_d1 = dim1 (); - int old_d2 = dim2 (); - int old_len = length (); - - rep = new ArrayRep (r*c); - - d1 = r; - d2 = c; - - int min_r = old_d1 < r ? old_d1 : r; - int min_c = old_d2 < c ? old_d2 : c; - - if (old_data && old_len > 0) - { - for (int j = 0; j < min_c; j++) - for (int i = 0; i < min_r; i++) - xelem (i, j) = old_data[old_d1*j+i]; - } - - for (int j = 0; j < min_c; j++) - for (int i = min_r; i < r; i++) - xelem (i, j) = val; - - for (int j = min_c; j < c; j++) - for (int i = 0; i < r; i++) - xelem (i, j) = val; - - if (--old_rep->count <= 0) - delete old_rep; -} - -template -Array2& -Array2::insert (const Array2& a, int r, int c) -{ - int a_rows = a.rows (); - int a_cols = a.cols (); - - if (r < 0 || r + a_rows > rows () || c < 0 || c + a_cols > cols ()) - { - (*current_liboctave_error_handler) ("range error for insert"); - return *this; - } - - for (int j = 0; j < a_cols; j++) - for (int i = 0; i < a_rows; i++) - elem (r+i, c+j) = a.elem (i, j); - - return *this; -} - -// Three dimensional array class. - -template -T& -Array3::checkelem (int i, int j, int k) -{ - if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3) - { - (*current_liboctave_error_handler) ("range error"); - static T foo; - return foo; - } - return Array2::elem (i, d1*k+j); -} - -template -T -Array3::elem (int i, int j, int k) const -{ - return Array2::elem (i, d2*k+j); -} - -template -T -Array3::checkelem (int i, int j, int k) const -{ - if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return Array2::elem (i, d1*k+j); -} - -template -T -Array3::operator () (int i, int j, int k) const -{ - if (i < 0 || j < 0 || k < 0 || i >= d1 || j >= d2 || k >= d3) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return Array2::elem (i, d2*k+j); -} - -template -void -Array3::resize (int n, int m, int k) -{ - assert (0); // XXX FIXME XXX -} - -template -void -Array3::resize (int n, int m, int k, const T& val) -{ - assert (0); // XXX FIXME XXX -} - -// A two-dimensional array with diagonal elements only. - -#ifndef NO_DIAG_ARRAY -#if 1 -template -T& -DiagArray::elem (int r, int c) -{ - static T foo (0); - return (r == c) ? Array::elem (r) : foo; -} - -template -T& -DiagArray::checkelem (int r, int c) -{ - static T foo (0); - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - return foo; - } - return (r == c) ? Array::elem (r) : foo; -} - -template -T& -DiagArray::operator () (int r, int c) -{ - static T foo (0); - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - return foo; - } - return (r == c) ? Array::elem (r) : foo; -} -#endif - -template -T& -DiagArray::xelem (int r, int c) -{ - static T foo (0); - return (r == c) ? Array::xelem (r) : foo; -} - -template -T -DiagArray::elem (int r, int c) const -{ - return (r == c) ? Array::elem (r) : T (0); -} - -template -T -DiagArray::checkelem (int r, int c) const -{ - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return (r == c) ? Array::elem (r) : T (0); -} - -template -T -DiagArray::operator () (int r, int c) const -{ - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - T foo; - static T *bar = &foo; - return foo; - } - return (r == c) ? Array::elem (r) : T (0); -} - -template -void -DiagArray::resize (int r, int c) -{ - if (r < 0 || c < 0) - { - (*current_liboctave_error_handler) ("can't resize to negative dimensions"); - return; - } - - if (r == dim1 () && c == dim2 ()) - return; - - ArrayRep *old_rep = rep; - const T *old_data = data (); - int old_len = length (); - - int new_len = r < c ? r : c; - - rep = new ArrayRep (new_len); - - nr = r; - nc = c; - - if (old_data && old_len > 0) - { - int min_len = old_len < new_len ? old_len : new_len; - - for (int i = 0; i < min_len; i++) - xelem (i, i) = old_data[i]; - } - - if (--old_rep->count <= 0) - delete old_rep; -} - -template -void -DiagArray::resize (int r, int c, const T& val) -{ - if (r < 0 || c < 0) - { - (*current_liboctave_error_handler) ("can't resize to negative dimensions"); - return; - } - - if (r == dim1 () && c == dim2 ()) - return; - - ArrayRep *old_rep = rep; - const T *old_data = data (); - int old_len = length (); - - int new_len = r < c ? r : c; - - rep = new ArrayRep (new_len); - - nr = r; - nc = c; - - int min_len = old_len < new_len ? old_len : new_len; - - if (old_data && old_len > 0) - { - for (int i = 0; i < min_len; i++) - xelem (i, i) = old_data[i]; - } - - for (int i = min_len; i < new_len; i++) - xelem (i, i) = val; - - if (--old_rep->count <= 0) - delete old_rep; -} -#endif - /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/Array.h b/liboctave/Array.h --- a/liboctave/Array.h +++ b/liboctave/Array.h @@ -37,16 +37,6 @@ class idx_vector; -// Classes we declare. - -template class Array; -template class Array2; -template class Array3; - -#ifndef NO_DIAG_ARRAY -template class DiagArray; -#endif - // One dimensional array class. Handles the reference counting for // all the derived classes. @@ -173,13 +163,14 @@ T& checkelem (int n); T& operator () (int n) { return checkelem (n); } + T elem (int n) const; + T checkelem (int n) const; + T operator () (int n) const; + // No checking. T& xelem (int n) { return rep->elem (n); } - - T elem (int n) const; - T checkelem (int n) const; - T operator () (int n) const; + T xelem (int n) const { return rep->elem (n); } void resize (int n); void resize (int n, const T& val); @@ -221,410 +212,6 @@ template int assign (Array& lhs, const Array& rhs); -// Two dimensional array class. - -template -class Array2 : public Array -{ -protected: - - Array2 (T *d, int n, int m) : Array (d, n*m) - { - d1 = n; - d2 = m; - set_max_indices (2); - } - -public: - - // These really need to be protected (and they will be in the - // future, so don't depend on them being here!), but they can't be - // until template friends work correctly in g++. - - int d1; - int d2; - - Array2 (void) : Array () - { - d1 = 0; - d2 = 0; - set_max_indices (2); - } - - Array2 (int n, int m) : Array (n*m) - { - d1 = n; - d2 = m; - set_max_indices (2); - } - - Array2 (int n, int m, const T& val) : Array (n*m, val) - { - d1 = n; - d2 = m; - set_max_indices (2); - } - - Array2 (const Array2& a) : Array (a) - { - d1 = a.d1; - d2 = a.d2; - set_max_indices (2); - } - - Array2 (const Array& a, int n, int m) : Array (a) - { - d1 = n; - d2 = m; - set_max_indices (2); - } - -#ifndef NO_DIAG_ARRAY - Array2 (const DiagArray& a) : Array (a.rows () * a.cols (), T (0)) - { - for (int i = 0; i < a.length (); i++) - elem (i, i) = a.elem (i, i); - - set_max_indices (2); - } -#endif - - ~Array2 (void) { } - - Array2& operator = (const Array2& a) - { - if (this != &a && rep != a.rep) - { - Array::operator = (a); - d1 = a.d1; - d2 = a.d2; - } - - return *this; - } - - int dim1 (void) const { return d1; } - int dim2 (void) const { return d2; } - - int rows (void) const { return d1; } - int cols (void) const { return d2; } - int columns (void) const { return d2; } - - T& elem (int i, int j) { return Array::elem (d1*j+i); } - T& checkelem (int i, int j); - T& operator () (int i, int j) { return checkelem (i, j); } - - // No checking. - - T& xelem (int i, int j) { return Array::xelem (d1*j+i); } - - T elem (int i, int j) const; - T checkelem (int i, int j) const; - T operator () (int i, int j) const; - - void resize (int n, int m); - void resize (int n, int m, const T& val); - - Array2& insert (const Array2& a, int r, int c); - -#ifdef HEAVYWEIGHT_INDEXING - void maybe_delete_elements (idx_vector& i, idx_vector& j); - - Array2 value (void); -#endif -}; - -template -int assign (Array2& lhs, const Array2& rhs); - -// Three dimensional array class. - -template -class Array3 : public Array2 -{ -protected: - - int d3; - - Array3 (T *d, int n, int m, int k) : Array2 (d, n, m*k) - { - d2 = m; - d3 = k; - set_max_indices (3); - } - -public: - - Array3 (void) : Array2 () - { - d2 = 0; - d3 = 0; - set_max_indices (3); - } - - Array3 (int n, int m, int k) : Array2 (n, m*k) - { - d2 = m; - d3 = k; - set_max_indices (3); - } - - Array3 (int n, int m, int k, const T& val) : Array2 (n, m*k, val) - { - d2 = m; - d3 = k; - set_max_indices (3); - } - - Array3 (const Array3& a) : Array2 (a) - { - d2 = a.d2; - d3 = a.d3; - set_max_indices (3); - } - - ~Array3 (void) { } - - Array3& operator = (const Array3& a) - { - if (this != &a && rep != a.rep) - { - Array::operator = (a); - d1 = a.d1; - d2 = a.d2; - d3 = a.d3; - } - - return *this; - } - - int dim3 (void) const { return d3; } - - T& elem (int i, int j, int k) { return Array2::elem (i, d2*k+j); } - T& checkelem (int i, int j, int k); - T& operator () (int i, int j, int k) { return checkelem (i, j, k); } - - // No checking. - - T& xelem (int i, int j, int k) { return Array2::xelem (i, d2*k+j); } - - T elem (int i, int j, int k) const; - T checkelem (int i, int j, int k) const; - T operator () (int i, int j, int k) const; - - void resize (int n, int m, int k); - void resize (int n, int m, int k, const T& val); - -#ifdef HEAVYWEIGHT_INDEXING - void maybe_delete_elements (idx_vector& i, idx_vector& j, idx_vector& k); - - Array3 value (void); -#endif -}; - -template -int assign (Array3& lhs, const Array3& rhs); - -// A two-dimensional array with diagonal elements only. -// -// Idea and example code for Proxy class and functions from: -// -// From: kanze@us-es.sel.de (James Kanze) -// Subject: Re: How to overload [] to do READ/WRITE differently ? -// Message-ID: -// Sender: news@us-es.sel.de -// Date: 29 Nov 1993 14:14:07 GMT -// -- -// James Kanze email: kanze@us-es.sel.de -// GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France - -#ifndef NO_DIAG_ARRAY -template -class DiagArray : public Array -{ -private: - T get (int i) { return Array::elem (i); } - void set (const T& val, int i) { Array::elem (i) = val; } - - class Proxy - { - public: - - Proxy (DiagArray *ref, int r, int c) - : i (r), j (c), object (ref) { } - - const Proxy& operator = (const T& val) const - { - if (i == j) - { - if (object) - object->set (val, i); - } - else - (*current_liboctave_error_handler) ("invalid assignment to off-diagonal in diagonal array"); - - return *this; - } - - operator T () const - { - if (object && i == j) - return object->get (i); - else - { - static T foo (0); - return foo; - } - } - - private: - - // XXX FIXME XXX -- this is declared private to keep the user from - // taking the address of a Proxy. Maybe it should be implemented - // by means of a companion function in the DiagArray class. - - T *operator& () const { assert (0); return (T *) 0; } - - int i; - int j; - - DiagArray *object; - - }; - -friend class Proxy; - -protected: - - int nr; - int nc; - - DiagArray (T *d, int r, int c) : Array (d, r < c ? r : c) - { - nr = r; - nc = c; - set_max_indices (2); - } - -public: - - DiagArray (void) : Array () - { - nr = 0; - nc = 0; - set_max_indices (2); - } - - DiagArray (int n) : Array (n) - { - nr = n; - nc = n; - set_max_indices (2); - } - - DiagArray (int n, const T& val) : Array (n, val) - { - nr = n; - nc = n; - set_max_indices (2); - } - - DiagArray (int r, int c) : Array (r < c ? r : c) - { - nr = r; - nc = c; - set_max_indices (2); - } - - DiagArray (int r, int c, const T& val) : Array (r < c ? r : c, val) - { - nr = r; - nc = c; - set_max_indices (2); - } - - DiagArray (const Array& a) : Array (a) - { - nr = nc = a.length (); - set_max_indices (2); - } - - DiagArray (const DiagArray& a) : Array (a) - { - nr = a.nr; - nc = a.nc; - set_max_indices (2); - } - - ~DiagArray (void) { } - - DiagArray& operator = (const DiagArray& a) - { - if (this != &a) - { - Array::operator = (a); - nr = a.nr; - nc = a.nc; - } - - return *this; - } - - int dim1 (void) const { return nr; } - int dim2 (void) const { return nc; } - - int rows (void) const { return nr; } - int cols (void) const { return nc; } - int columns (void) const { return nc; } - -#if 0 - Proxy elem (int r, int c) - { - return Proxy (this, r, c); - } - - Proxy checkelem (int r, int c) - { - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - return Proxy (0, r, c); - } - else - return Proxy (this, r, c); - } - - Proxy operator () (int r, int c) - { - if (r < 0 || c < 0 || r >= nr || c >= nc) - { - (*current_liboctave_error_handler) ("range error"); - return Proxy (0, r, c); - } - else - return Proxy (this, r, c); - } -#else - T& elem (int r, int c); - T& checkelem (int r, int c); - T& operator () (int r, int c); -#endif - - // No checking. - - T& xelem (int r, int c); - - T elem (int r, int c) const; - T checkelem (int r, int c) const; - T operator () (int r, int c) const; - - void resize (int n, int m); - void resize (int n, int m, const T& val); - - void maybe_delete_elements (idx_vector& i, idx_vector& j); -}; -#endif - #endif /* diff --git a/liboctave/CDiagMatrix.cc b/liboctave/CDiagMatrix.cc --- a/liboctave/CDiagMatrix.cc +++ b/liboctave/CDiagMatrix.cc @@ -38,22 +38,8 @@ // Complex Diagonal Matrix class -ComplexDiagMatrix::ComplexDiagMatrix (const RowVector& a) - : MDiagArray (a.length ()) -{ - for (int i = 0; i < length (); i++) - elem (i, i) = a.elem (i); -} - -ComplexDiagMatrix::ComplexDiagMatrix (const ColumnVector& a) - : MDiagArray (a.length ()) -{ - for (int i = 0; i < length (); i++) - elem (i, i) = a.elem (i); -} - ComplexDiagMatrix::ComplexDiagMatrix (const DiagMatrix& a) - : MDiagArray (a.rows (), a.cols ()) + : MDiagArray2 (a.rows (), a.cols ()) { for (int i = 0; i < length (); i++) elem (i, i) = a.elem (i, i); diff --git a/liboctave/CDiagMatrix.h b/liboctave/CDiagMatrix.h --- a/liboctave/CDiagMatrix.h +++ b/liboctave/CDiagMatrix.h @@ -28,7 +28,7 @@ #pragma interface #endif -#include "MArray.h" +#include "MDiagArray2.h" #include "dRowVector.h" #include "CRowVector.h" @@ -37,30 +37,29 @@ #include "mx-defs.h" -class ComplexDiagMatrix : public MDiagArray +class ComplexDiagMatrix : public MDiagArray2 { public: - ComplexDiagMatrix (void) : MDiagArray () { } - ComplexDiagMatrix (int n) : MDiagArray (n) { } - ComplexDiagMatrix (int n, const Complex& val) - : MDiagArray (n, n, val) { } - ComplexDiagMatrix (int r, int c) : MDiagArray (r, c) { } + ComplexDiagMatrix (void) : MDiagArray2 () { } + ComplexDiagMatrix (int r, int c) : MDiagArray2 (r, c) { } ComplexDiagMatrix (int r, int c, const Complex& val) - : MDiagArray (r, c, val) { } - ComplexDiagMatrix (const RowVector& a); - ComplexDiagMatrix (const ComplexRowVector& a) : MDiagArray (a) { } - ComplexDiagMatrix (const ColumnVector& a); + : MDiagArray2 (r, c, val) { } + ComplexDiagMatrix (const RowVector& a) + : MDiagArray2 (ComplexRowVector (a)) { } + ComplexDiagMatrix (const ComplexRowVector& a) : MDiagArray2 (a) { } + ComplexDiagMatrix (const ColumnVector& a) + : MDiagArray2 (ComplexColumnVector (a)) { } ComplexDiagMatrix (const ComplexColumnVector& a) - : MDiagArray (a) { } + : MDiagArray2 (a) { } ComplexDiagMatrix (const DiagMatrix& a); - ComplexDiagMatrix (const MDiagArray& a) - : MDiagArray (a) { } - ComplexDiagMatrix (const ComplexDiagMatrix& a) : MDiagArray (a) { } + ComplexDiagMatrix (const MDiagArray2& a) + : MDiagArray2 (a) { } + ComplexDiagMatrix (const ComplexDiagMatrix& a) : MDiagArray2 (a) { } ComplexDiagMatrix& operator = (const ComplexDiagMatrix& a) { - MDiagArray::operator = (a); + MDiagArray2::operator = (a); return *this; } @@ -159,7 +158,7 @@ private: ComplexDiagMatrix (Complex *d, int nr, int nc) - : MDiagArray (d, nr, nc) { } + : MDiagArray2 (d, nr, nc) { } }; #endif diff --git a/liboctave/CMatrix.h b/liboctave/CMatrix.h --- a/liboctave/CMatrix.h +++ b/liboctave/CMatrix.h @@ -28,7 +28,8 @@ #pragma interface #endif -#include "MArray.h" +#include "MArray2.h" +#include "MDiagArray2.h" #include "mx-defs.h" #include "oct-cmplx.h" @@ -54,7 +55,7 @@ ComplexMatrix (const MArray2& a) : MArray2 (a) { } ComplexMatrix (const ComplexMatrix& a) : MArray2 (a) { } ComplexMatrix (const DiagMatrix& a); - ComplexMatrix (const MDiagArray& a) : MArray2 (a) { } + // ComplexMatrix (const MDiagArray2& a) : MArray2 (a) { } ComplexMatrix (const ComplexDiagMatrix& a); ComplexMatrix (const charMatrix& a); diff --git a/liboctave/MArray-C.cc b/liboctave/MArray-C.cc --- a/liboctave/MArray-C.cc +++ b/liboctave/MArray-C.cc @@ -23,17 +23,27 @@ // Instantiate MArrays of Complex values. +#include "oct-cmplx.h" + #include "MArray.h" #include "MArray.cc" -#include "oct-cmplx.h" - template class MArray; -template class MArray2; -template class MDiagArray; INSTANTIATE_MARRAY_FRIENDS (Complex) + +#include "MArray2.h" +#include "MArray2.cc" + +template class MArray2; + INSTANTIATE_MARRAY2_FRIENDS (Complex) + +#include "MDiagArray2.h" +#include "MDiagArray2.cc" + +template class MDiagArray2; + INSTANTIATE_MDIAGARRAY_FRIENDS (Complex) /* diff --git a/liboctave/MArray-ch.cc b/liboctave/MArray-ch.cc --- a/liboctave/MArray-ch.cc +++ b/liboctave/MArray-ch.cc @@ -23,22 +23,26 @@ // Instantiate MArrays of char values. -#define NO_DIAG_ARRAY 1 - #include "MArray.h" #include "MArray.cc" template class MArray; + +INSTANTIATE_MARRAY_FRIENDS (char) + +#include "MArray2.h" +#include "MArray2.cc" + template class MArray2; -INSTANTIATE_MARRAY_FRIENDS (char) INSTANTIATE_MARRAY2_FRIENDS (char) -#ifndef NO_DIAG_ARRAY -template class MDiagArray; +#include "MDiagArray2.h" +#include "MDiagArray2.cc" + +template class MDiagArray2; INSTANTIATE_MDIAGARRAY_FRIENDS (char) -#endif /* ;;; Local Variables: *** diff --git a/liboctave/MArray-d.cc b/liboctave/MArray-d.cc --- a/liboctave/MArray-d.cc +++ b/liboctave/MArray-d.cc @@ -27,107 +27,22 @@ #include "MArray.cc" template class MArray; -template class MArray2; -template class MDiagArray; -template MArray -operator + (const MArray& a, const double& s); - -template MArray -operator - (const MArray& a, const double& s); - -template MArray -operator * (const MArray& a, const double& s); - -template MArray -operator / (const MArray& a, const double& s); - -template MArray -operator + (const double& s, const MArray& a); - -template MArray -operator - (const double& s, const MArray& a); - -template MArray -operator * (const double& s, const MArray& a); +INSTANTIATE_MARRAY_FRIENDS (double) -template MArray -operator / (const double& s, const MArray& a); - -template MArray -operator + (const MArray& a, const MArray& b); - -template MArray -operator - (const MArray& a, const MArray& b); - -template MArray -product (const MArray& a, const MArray& b); +#include "MArray2.h" +#include "MArray2.cc" -template MArray -quotient (const MArray& a, const MArray& b); - -template MArray -operator - (const MArray& a); - -template MArray2 -operator + (const MArray2& a, const double& s); - -template MArray2 -operator - (const MArray2& a, const double& s); - -template MArray2 -operator * (const MArray2& a, const double& s); +template class MArray2; -template MArray2 -operator / (const MArray2& a, const double& s); - -template MArray2 -operator + (const double& s, const MArray2& a); - -template MArray2 -operator - (const double& s, const MArray2& a); - -template MArray2 -operator * (const double& s, const MArray2& a); - -template MArray2 -operator / (const double& s, const MArray2& a); - -template MArray2 -operator + (const MArray2& a, const MArray2& b); - -template MArray2 -operator - (const MArray2& a, const MArray2& b); - -template MArray2 -product (const MArray2& a, const MArray2& b); +INSTANTIATE_MARRAY2_FRIENDS (double) -template MArray2 -quotient (const MArray2& a, const MArray2& b); - -template MArray2 -operator - (const MArray2& a); - -template MDiagArray -operator * (const MDiagArray& a, const double& s); - -template MDiagArray -operator / (const MDiagArray& a, const double& s); +#include "MDiagArray2.h" +#include "MDiagArray2.cc" -template MDiagArray -operator * (const double& s, const MDiagArray& a); - -template MDiagArray -operator + (const MDiagArray& a, const MDiagArray& b); +template class MDiagArray2; -template MDiagArray -operator - (const MDiagArray& a, const MDiagArray& b); - -template MDiagArray -product (const MDiagArray& a, const MDiagArray& b); - -template MDiagArray -operator - (const MDiagArray& a); +INSTANTIATE_MDIAGARRAY_FRIENDS (double) /* ;;; Local Variables: *** diff --git a/liboctave/MArray-i.cc b/liboctave/MArray-i.cc --- a/liboctave/MArray-i.cc +++ b/liboctave/MArray-i.cc @@ -23,22 +23,26 @@ // Instantiate MArrays of int values. -#define NO_DIAG_ARRAY 1 - #include "MArray.h" #include "MArray.cc" template class MArray; + +INSTANTIATE_MARRAY_FRIENDS (int) + +#include "MArray2.h" +#include "MArray2.cc" + template class MArray2; -INSTANTIATE_MARRAY_FRIENDS (int) INSTANTIATE_MARRAY2_FRIENDS (int) -#ifndef NO_DIAG_ARRAY -template class MDiagArray; +#include "MDiagArray2.h" +#include "MDiagArray2.cc" + +template class MDiagArray2; INSTANTIATE_MDIAGARRAY_FRIENDS (int) -#endif /* ;;; Local Variables: *** diff --git a/liboctave/MArray-s.cc b/liboctave/MArray-s.cc --- a/liboctave/MArray-s.cc +++ b/liboctave/MArray-s.cc @@ -23,22 +23,26 @@ // Instantiate MArrays of short int values. -#define NO_DIAG_ARRAY 1 - #include "MArray.h" #include "MArray.cc" template class MArray; + +INSTANTIATE_MARRAY_FRIENDS (short) + +#include "MArray2.h" +#include "MArray2.cc" + template class MArray2; -INSTANTIATE_MARRAY_FRIENDS (short) INSTANTIATE_MARRAY2_FRIENDS (short) -#ifndef NO_DIAG_ARRAY -template class MDiagArray; +#include "MDiagArray2.h" +#include "MDiagArray2.cc" + +template class MDiagArray2; INSTANTIATE_MDIAGARRAY_FRIENDS (short) -#endif /* ;;; Local Variables: *** diff --git a/liboctave/MArray.cc b/liboctave/MArray.cc --- a/liboctave/MArray.cc +++ b/liboctave/MArray.cc @@ -32,72 +32,7 @@ #include "MArray.h" #include "lo-error.h" -// Nothing like a little CPP abuse to brighten everyone's day. Would -// have been nice to do this with template functions but as of 2.5.x, -// g++ seems to fail to resolve them properly. - -#define DO_VS_OP(OP) \ - int l = a.length (); \ - T *result = 0; \ - if (l > 0) \ - { \ - result = new T [l]; \ - const T *x = a.data (); \ - for (int i = 0; i < l; i++) \ - result[i] = x[i] OP s; \ - } - -#define DO_SV_OP(OP) \ - int l = a.length (); \ - T *result = 0; \ - if (l > 0) \ - { \ - result = new T [l]; \ - const T *x = a.data (); \ - for (int i = 0; i < l; i++) \ - result[i] = s OP x[i]; \ - } - -#define DO_VV_OP(OP) \ - T *result = 0; \ - if (l > 0) \ - { \ - result = new T [l]; \ - const T *x = a.data (); \ - const T *y = b.data (); \ - for (int i = 0; i < l; i++) \ - result[i] = x[i] OP y[i]; \ - } - -#define NEG_V \ - int l = a.length (); \ - T *result = 0; \ - if (l > 0) \ - { \ - result = new T [l]; \ - const T *x = a.data (); \ - for (int i = 0; i < l; i++) \ - result[i] = -x[i]; \ - } - -#define DO_VS_OP2(OP) \ - int l = a.length (); \ - if (l > 0) \ - { \ - T *tmp = a.fortran_vec (); \ - for (int i = 0; i < l; i++) \ - tmp[i] OP s; \ - } - -#define DO_VV_OP2(OP) \ - do \ - { \ - T *a_tmp = a.fortran_vec (); \ - const T *b_tmp = b.data (); \ - for (int i = 0; i < l; i++) \ - a_tmp[i] += b_tmp[i]; \ - } \ - while (0) +#include "MArray-defs.h" // One dimensional array with math ops. @@ -220,264 +155,6 @@ return MArray (result, l); } -// Two dimensional array with math ops. - -#ifndef NO_DIAG_ARRAY -template -MArray2::MArray2 (const MDiagArray& a) - : Array2 (a.rows (), a.cols (), T (0)) -{ - for (int i = 0; i < a.length (); i++) - elem (i, i) = a.elem (i, i); -} -#endif - -// Element by element MArray2 by scalar ops. - -template -MArray2& -operator += (MArray2& a, const T& s) -{ - DO_VS_OP2 (+=) - return a; -} - -template -MArray2& -operator -= (MArray2& a, const T& s) -{ - DO_VS_OP2 (-=) - return a; -} - -// Element by element MArray2 by MArray2 ops. - -template -MArray2& -operator += (MArray2& a, const MArray2& b) -{ - int r = a.rows (); - int c = a.cols (); - if (r != b.rows () || c != b.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant += array operation attempted"); - } - else - { - if (r > 0 && c > 0) - { - int l = a.length (); - DO_VV_OP2 (+=); - } - } - return a; -} - -template -MArray2& -operator -= (MArray2& a, const MArray2& b) -{ - int r = a.rows (); - int c = a.cols (); - if (r != b.rows () || c != b.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant -= array operation attempted"); - } - else - { - if (r > 0 && c > 0) - { - int l = a.length (); - DO_VV_OP2 (-=); - } - } - return a; -} - -// Element by element MArray2 by scalar ops. - -#define MARRAY_A2S_OP(OP) \ - template \ - MArray2 \ - operator OP (const MArray2& a, const T& s) \ - { \ - DO_VS_OP (OP); \ - return MArray2 (result, a.rows (), a.cols ()); \ - } - -MARRAY_A2S_OP (+) -MARRAY_A2S_OP (-) -MARRAY_A2S_OP (*) -MARRAY_A2S_OP (/) - -// Element by element scalar by MArray2 ops. - -#define MARRAY_SA2_OP(OP) \ - template \ - MArray2 \ - operator OP (const T& s, const MArray2& a) \ - { \ - DO_SV_OP (OP); \ - return MArray2 (result, a.rows (), a.cols ()); \ - } - -MARRAY_SA2_OP (+) -MARRAY_SA2_OP (-) -MARRAY_SA2_OP (*) -MARRAY_SA2_OP (/) - -// Element by element MArray2 by MArray2 ops. - -#define MARRAY_A2A2_OP(FCN, OP, OP_STR) \ - template \ - MArray2 \ - FCN (const MArray2& a, const MArray2& b) \ - { \ - int r = a.rows (); \ - int c = a.cols (); \ - if (r != b.rows () || c != b.cols ()) \ - { \ - (*current_liboctave_error_handler) \ - ("nonconformant array " OP_STR " attempted"); \ - return MArray2 (); \ - } \ - if (r == 0 || c == 0) \ - return MArray2 (); \ - int l = a.length (); \ - DO_VV_OP (OP); \ - return MArray2 (result, r, c); \ - } - -MARRAY_A2A2_OP (operator +, +, "addition") -MARRAY_A2A2_OP (operator -, -, "subtraction") -MARRAY_A2A2_OP (product, *, "product") -MARRAY_A2A2_OP (quotient, /, "quotient") - -// Unary MArray2 ops. - -template -MArray2 -operator - (const MArray2& a) -{ - NEG_V; - return MArray2 (result, a.rows (), a.cols ()); -} - -// Two dimensional diagonal array with math ops. - -#ifndef NO_DIAG_ARRAY - -// Element by element MDiagArray by MDiagArray ops. - -template -MDiagArray& -operator += (MDiagArray& a, const MDiagArray& b) -{ - int r = a.rows (); - int c = a.cols (); - if (r != b.rows () || c != b.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant array " OP_STR " attempted"); - return MArray2 (); - } - else - { - int l = a.length (); - T *a_tmp = a.fortran_vec (); - const T *b_tmp = b.data (); - for (int i = 0; i < l; i++) - a_tmp[i] += b_tmp[i]; - } - return a; -} - -template -MDiagArray& -operator -= (MDiagArray& a, const MDiagArray& b) -{ - int r = a.rows (); - int c = a.cols (); - if (r != b.rows () || c != b.cols ()) - { - (*current_liboctave_error_handler) - ("nonconformant array " OP_STR " attempted"); - return MArray2 (); - } - else - { - int l = a.length (); - T *a_tmp = a.fortran_vec (); - const T *b_tmp = b.data (); - for (int i = 0; i < l; i++) - a_tmp[i] -= b_tmp[i]; - } - return a; -} - -// Element by element MDiagArray by scalar ops. - -#define MARRAY_DAS_OP(OP) \ - template \ - MDiagArray \ - operator OP (const MDiagArray& a, const T& s) \ - { \ - DO_VS_OP (OP); \ - return MDiagArray (result, a.rows (), a.cols ()); \ - } - -MARRAY_DAS_OP (*) -MARRAY_DAS_OP (/) - -// Element by element scalar by MDiagArray ops. - -template -MDiagArray -operator * (const T& s, const MDiagArray& a) -{ - DO_SV_OP (*); - return MDiagArray (result, a.rows (), a.cols ()); -} - -// Element by element MDiagArray by MDiagArray ops. - -#define MARRAY_DADA_OP(FCN, OP, OP_STR) \ - template \ - MDiagArray \ - FCN (const MDiagArray& a, const MDiagArray& b) \ - { \ - int r = a.rows (); \ - int c = a.cols (); \ - if (r != b.rows () || c != b.cols ()) \ - { \ - (*current_liboctave_error_handler) \ - ("nonconformant diagonal array " OP_STR " attempted"); \ - return MDiagArray (); \ - } \ - if (c == 0 || r == 0) \ - return MDiagArray (); \ - int l = a.length (); \ - DO_VV_OP (OP); \ - return MDiagArray (result, r, c); \ - } - -MARRAY_DADA_OP (operator +, +, "addition") -MARRAY_DADA_OP (operator -, -, "subtraction") -MARRAY_DADA_OP (product, *, "product") - -// Unary MDiagArray ops. - -template -MDiagArray -operator - (const MDiagArray& a) -{ - NEG_V; - return MDiagArray (result, a.rows (), a.cols ()); -} -#endif - /* ;;; Local Variables: *** ;;; mode: C++ *** diff --git a/liboctave/MArray.h b/liboctave/MArray.h --- a/liboctave/MArray.h +++ b/liboctave/MArray.h @@ -30,15 +30,6 @@ #include "Array.h" -// Classes we declare. - -template class MArray; -template class MArray2; - -#ifndef NO_DIAG_ARRAY -template class MDiagArray; -#endif - // One dimensional array with math ops. template @@ -53,7 +44,7 @@ MArray (void) : Array () { } MArray (int n) : Array (n) { } MArray (int n, const T& val) : Array (n, val) { } - MArray (const Array& a) : Array (a) { } +// MArray (const Array& a) : Array (a) { } MArray (const MArray& a) : Array (a) { } ~MArray (void) { } @@ -100,127 +91,20 @@ friend MArray operator - (const MArray& a); }; -// Two dimensional array with math ops. - -template -class MArray2 : public Array2 -{ -protected: - - MArray2 (T *d, int n, int m) : Array2 (d, n, m) { } - -public: - - MArray2 (void) : Array2 () { } - MArray2 (int n, int m) : Array2 (n, m) { } - MArray2 (int n, int m, const T& val) : Array2 (n, m, val) { } - MArray2 (const Array2& a) : Array2 (a) { } - MArray2 (const MArray2& a) : Array2 (a) { } - -#ifndef NO_DIAG_ARRAY - MArray2 (const MDiagArray& a); -#endif - - ~MArray2 (void) { } - - MArray2& operator = (const MArray2& a) - { - Array2::operator = (a); - return *this; - } - - // element by element MArray2 by scalar ops - - friend MArray2& operator += (MArray2& a, const T& s); - friend MArray2& operator -= (MArray2& a, const T& s); - - // element by element MArray2 by MArray2 ops - - friend MArray2& operator += (MArray2& a, const MArray2& b); - friend MArray2& operator -= (MArray2& a, const MArray2& b); - - // element by element MArray2 by scalar ops - - friend MArray2 operator + (const MArray2& a, const T& s); - friend MArray2 operator - (const MArray2& a, const T& s); - friend MArray2 operator * (const MArray2& a, const T& s); - friend MArray2 operator / (const MArray2& a, const T& s); - - // element by element scalar by MArray2 ops - - friend MArray2 operator + (const T& s, const MArray2& a); - friend MArray2 operator - (const T& s, const MArray2& a); - friend MArray2 operator * (const T& s, const MArray2& a); - friend MArray2 operator / (const T& s, const MArray2& a); - - // element by element MArray2 by MArray2 ops - - friend MArray2 operator + (const MArray2& a, const MArray2& b); - friend MArray2 operator - (const MArray2& a, const MArray2& b); - - friend MArray2 product (const MArray2& a, const MArray2& b); - friend MArray2 quotient (const MArray2& a, const MArray2& b); - - friend MArray2 operator - (const MArray2& a); -}; - -// Two dimensional diagonal array with math ops. - -#ifndef NO_DIAG_ARRAY -template -class MDiagArray : public DiagArray -{ -protected: - - MDiagArray (T *d, int r, int c) : DiagArray (d, r, c) { } - -public: - - MDiagArray (void) : DiagArray () { } - MDiagArray (int n) : DiagArray (n) { } -// MDiagArray (int n, const T& val) : DiagArray (n, val) { } - MDiagArray (int r, int c) : DiagArray (r, c) { } - MDiagArray (int r, int c, const T& val) : DiagArray (r, c, val) { } - MDiagArray (const DiagArray& a) : DiagArray (a) { } - MDiagArray (const MDiagArray& a) : DiagArray (a) { } - MDiagArray (const MArray& a) : DiagArray (a) { } - - ~MDiagArray (void) { } - - MDiagArray& operator = (const MDiagArray& a) - { - DiagArray::operator = (a); - return *this; - } - - // element by element MDiagArray by MDiagArray ops - - friend MDiagArray& operator += (MDiagArray& a, const MDiagArray& b); - friend MDiagArray& operator -= (MDiagArray& a, const MDiagArray& b); - - // element by element MDiagArray by scalar ops - - friend MDiagArray operator * (const MDiagArray& a, const T& s); - friend MDiagArray operator / (const MDiagArray& a, const T& s); - - // element by element scalar by MDiagArray ops - - friend MDiagArray operator * (const T& s, const MDiagArray& a); - - // element by element MDiagArray by MDiagArray ops - - friend MDiagArray operator + (const MDiagArray& a, - const MDiagArray& b); - - friend MDiagArray operator - (const MDiagArray& a, - const MDiagArray& b); - - friend MDiagArray product (const MDiagArray& a, - const MDiagArray& b); - - friend MDiagArray operator - (const MDiagArray& a); -}; -#endif +#define INSTANTIATE_MARRAY_FRIENDS(T) \ + template MArray operator + (const MArray& a, const T& s); \ + template MArray operator - (const MArray& a, const T& s); \ + template MArray operator * (const MArray& a, const T& s); \ + template MArray operator / (const MArray& a, const T& s); \ + template MArray operator + (const T& s, const MArray& a); \ + template MArray operator - (const T& s, const MArray& a); \ + template MArray operator * (const T& s, const MArray& a); \ + template MArray operator / (const T& s, const MArray& a); \ + template MArray operator + (const MArray& a, const MArray& b); \ + template MArray operator - (const MArray& a, const MArray& b); \ + template MArray product (const MArray& a, const MArray& b); \ + template MArray quotient (const MArray& a, const MArray& b); \ + template MArray operator - (const MArray& a); #endif diff --git a/liboctave/chMatrix.h b/liboctave/chMatrix.h --- a/liboctave/chMatrix.h +++ b/liboctave/chMatrix.h @@ -33,7 +33,7 @@ #include -#include "MArray.h" +#include "MArray2.h" #include "mx-defs.h" diff --git a/liboctave/dDiagMatrix.h b/liboctave/dDiagMatrix.h --- a/liboctave/dDiagMatrix.h +++ b/liboctave/dDiagMatrix.h @@ -28,34 +28,31 @@ #pragma interface #endif -#include "MArray.h" +#include "MDiagArray2.h" #include "dRowVector.h" #include "dColVector.h" #include "mx-defs.h" -class DiagMatrix : public MDiagArray +class DiagMatrix : public MDiagArray2 { friend class SVD; friend class ComplexSVD; public: - DiagMatrix (void) : MDiagArray () { } - DiagMatrix (int n) : MDiagArray (n) { } - DiagMatrix (int n, double val) : MDiagArray (n, n, val) { } - DiagMatrix (int r, int c) : MDiagArray (r, c) { } - DiagMatrix (int r, int c, double val) : MDiagArray (r, c, val) { } - DiagMatrix (const RowVector& a) : MDiagArray (a) { } - DiagMatrix (const ColumnVector& a) : MDiagArray (a) { } - DiagMatrix (const MDiagArray& a) : MDiagArray (a) { } - DiagMatrix (const DiagMatrix& a) : MDiagArray (a) { } -// DiagMatrix (double a) : MDiagArray (1, a) { } + DiagMatrix (void) : MDiagArray2 () { } + DiagMatrix (int r, int c) : MDiagArray2 (r, c) { } + DiagMatrix (int r, int c, double val) : MDiagArray2 (r, c, val) { } + DiagMatrix (const RowVector& a) : MDiagArray2 (a) { } + DiagMatrix (const ColumnVector& a) : MDiagArray2 (a) { } + DiagMatrix (const MDiagArray2& a) : MDiagArray2 (a) { } + DiagMatrix (const DiagMatrix& a) : MDiagArray2 (a) { } DiagMatrix& operator = (const DiagMatrix& a) { - MDiagArray::operator = (a); + MDiagArray2::operator = (a); return *this; } @@ -110,7 +107,7 @@ private: - DiagMatrix (double *d, int nr, int nc) : MDiagArray (d, nr, nc) { } + DiagMatrix (double *d, int nr, int nc) : MDiagArray2 (d, nr, nc) { } }; #endif diff --git a/liboctave/dMatrix.h b/liboctave/dMatrix.h --- a/liboctave/dMatrix.h +++ b/liboctave/dMatrix.h @@ -31,7 +31,8 @@ // For FILE... #include -#include "MArray.h" +#include "MArray2.h" +#include "MDiagArray2.h" #include "mx-defs.h" @@ -55,7 +56,7 @@ Matrix (int r, int c, double val) : MArray2 (r, c, val) { } Matrix (const MArray2& a) : MArray2 (a) { } Matrix (const Matrix& a) : MArray2 (a) { } - Matrix (const MDiagArray& a) : MArray2 (a) { } + // Matrix (const MDiagArray2& a) : MArray2 (a) { } Matrix (const DiagMatrix& a); Matrix (const charMatrix& a);