changeset 238:780cbbc57b7c

[project @ 1993-11-30 20:23:04 by jwe]
author jwe
date Tue, 30 Nov 1993 20:23:04 +0000
parents 5a9e23307fb0
children 4f8134fa54a9
files libcruft/misc/lo-error.cc liboctave/Array.h liboctave/Bounds.cc liboctave/Bounds.h liboctave/ColVector.cc liboctave/CollocWt.cc liboctave/CollocWt.h liboctave/DAE.h liboctave/DAEFunc.cc liboctave/DAEFunc.h liboctave/DASSL.cc liboctave/DiagMatrix.cc liboctave/FEGrid.cc liboctave/FEGrid.h liboctave/FSQP.cc liboctave/FSQP.h liboctave/LP.cc liboctave/LP.h liboctave/LPsolve.cc liboctave/LPsolve.h liboctave/LSODE.cc liboctave/LinConst.cc liboctave/LinConst.h liboctave/Makefile.in liboctave/Matrix-ext.cc liboctave/Matrix.cc liboctave/Matrix.h liboctave/NLConst.cc liboctave/NLConst.h liboctave/NLEqn.cc liboctave/NLEqn.h liboctave/NLFunc.cc liboctave/NLFunc.h liboctave/NLP.h liboctave/NPSOL.cc liboctave/NPSOL.h liboctave/ODE.h liboctave/ODEFunc.cc liboctave/ODEFunc.h liboctave/Objective.cc liboctave/Objective.h liboctave/QLD.cc liboctave/QLD.h liboctave/QP.cc liboctave/QP.h liboctave/QPSOL.cc liboctave/QPSOL.h liboctave/Quad.cc liboctave/Quad.h liboctave/Range.cc liboctave/Range.h liboctave/RowVector.cc liboctave/f77-fcn.h liboctave/lo-error.h liboctave/mx-inlines.cc liboctave/sun-utils.cc liboctave/sun-utils.h liboctave/utils.cc
diffstat 58 files changed, 3430 insertions(+), 5341 deletions(-) [+]
line wrap: on
line diff
--- a/libcruft/misc/lo-error.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/libcruft/misc/lo-error.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <stdio.h>
--- a/liboctave/Array.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Array.h	Tue Nov 30 20:23:04 1993 +0000
@@ -21,112 +21,173 @@
 
 */
 
-// Written by John C. Campbell <jcc@che.utexas.edu>.
-
 #if !defined (_Array_h)
 #define _Array_h 1
 
-#include <iostream.h>
-#include <assert.h>
+#if defined (__GNUG__) && defined (USE_EXTERNAL_TEMPLATES)
+#pragma interface
+#endif
+
+// Classes we declare.
 
-template <class T> class Array;  
+template <class T> class ArrayRep;
+template <class T> class Array;
+template <class T> class Array2;
+template <class T> class Array3;
+template <class T> class DiagArray;
+
+/*
+ * The real representation of all arrays.
+ */
 
 template <class T>
 class ArrayRep
 {
+// Rethink resize()?
   friend class Array<T>;
+  friend class Array2<T>;
+  friend class Array3<T>;
+  friend class DiagArray<T>;
+
+protected:
+
+  ArrayRep (T *d, int l);
 
 public:
 
-  ArrayRep  (void);
-  ArrayRep  (int);
-  ArrayRep  (const ArrayRep<T>& a);
+  ArrayRep (void);
+  ArrayRep (int n);
+  ArrayRep (const ArrayRep<T>& a);
 
   ~ArrayRep (void);
-  
+
   int length (void) const;
-  
+
   T& elem (int n);
-  T& checkelem (int n);
-  T& operator () (int n);
-  
+
   T elem (int n) const;
-  T checkelem (int n) const;
-  T operator () (int n) const;
-  
+
+  void resize (int n);
+
 private:
-  
+
   T *data;
   int len;
   int count;
 };
 
+/*
+ * One dimensional array class.  Handles the reference counting for
+ * all the derived classes.
+ */
+
 template <class T>
 class Array
 {
+protected:
+
+  ArrayRep<T> *rep;
+
+  Array (T *d, int l);
+
 public:
-  
+
   Array (void);
-  Array (int);
-  Array (int n, T val);
+  Array (int n);
+  Array (int n, const T& val);
+
   Array (const Array<T>& a);
 
   ~Array (void);
 
   Array<T>& operator = (const Array<T>& a);
-  
+
+  int capacity (void) const;
   int length (void) const;
 
   T& elem (int n);
   T& checkelem (int n);
   T& operator () (int n);
 
+// No checking.
+  T& xelem (int n);
+
   T elem (int n) const;
   T checkelem (int n) const;
   T operator () (int n) const;
 
-protected:
+  void resize (int n);
+  void resize (int n, const T& val);
+
+  const T *data (void) const;
 
-  ArrayRep<T> *rep;
+  T *fortran_vec (void);
 };
 
+/*
+ * Two dimensional array class.
+ */
+
 template <class T>
 class Array2 : public Array<T>
 {
+protected:
+
+  int d1;
+  int d2;
+
+  Array2 (T *d, int n, int m);
+
 public:
 
   Array2 (void);
   Array2 (int n, int m);
-  Array2 (int n, int m, T val);
+  Array2 (int n, int m, const T& val);
   Array2 (const Array2<T>& a);
+  Array2 (const DiagArray<T>& a);
 
   Array2<T>& operator = (const Array2<T>& a);
 
   int dim1 (void) const;
   int dim2 (void) const;
- 
+
+  int rows (void) const;
+  int cols (void) const;
+  int columns (void) const;
+
   T& elem (int i, int j);
-  T& checkelem (int i, int j); 
+  T& checkelem (int i, int j);
   T& operator () (int i, int j);
-  
+
+// No checking.
+  T& xelem (int i, int j);
+
   T elem (int i, int j) const;
   T checkelem (int i, int j) const;
   T operator () (int i, int j) const;
 
-protected:
-  
-  int d1;
-  int d2;
+  void resize (int n, int m);
+  void resize (int n, int m, const T& val);
 };
 
+/*
+ * Three dimensional array class.
+ */
+
 template <class T>
 class Array3 : public Array2<T>
 {
+protected:
+
+  int d3;
+
+  Array3 (T *d, int n, int m, int k);
+
 public:
 
   Array3 (void);
   Array3 (int n, int m, int k);
-  Array3 (int n, int m, int k, T val);
+  Array3 (int n, int m, int k, const T& val);
   Array3 (const Array3<T>& a);
 
   Array3<T>& operator = (const Array3<T>& a);
@@ -134,32 +195,49 @@
   int dim3 (void) const;
 
   T& elem (int i, int j, int k);
-  T& checkelem (int i, int j, int k); 
-  T& operator()(int i,int j,int k);
-  
+  T& checkelem (int i, int j, int k);
+  T& operator () (int i, int j, int k);
+
+// No checking.
+  T& xelem (int i, int j, int k);
+
   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;
+  T checkelem (int i, int j, int k) const;
+  T operator () (int i, int j, int k) const;
 
-protected:
-  
-  int d3;
+  void resize (int n, int m, int k);
+  void resize (int n, int m, int k, const T& val);
 };
 
+/*
+ * A two-dimensional array with diagonal elements only.
+ */
+
 template <class T>
 class DiagArray : public Array<T>
 {
+protected:
+
+  int nr;
+  int nc;
+
+  DiagArray (T *d, int r, int c);
+
 public:
-  
+
   DiagArray (void);
-  DiagArray (int n): Array<T> (n) {}
+  DiagArray (int n);
+  DiagArray (int n, const T& val);
   DiagArray (int r, int c);
-  DiagArray (int r, int c, T val);
+  DiagArray (int r, int c, const T& val);
   DiagArray (const Array<T>& a);
   DiagArray (const DiagArray<T>& a);
 
   DiagArray<T>& operator = (const DiagArray<T>& a);
 
+  int dim1 (void) const;
+  int dim2 (void) const;
+
   int rows (void) const;
   int cols (void) const;
   int columns (void) const;
@@ -168,17 +246,18 @@
   T& checkelem (int r, int c);
   T& operator () (int r, int c);
 
+// 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;
 
-protected:
-
-  int nr;
-  int nc;
+  void resize (int n, int m);
+  void resize (int n, int m, const T& val);
 };
 
-#ifdef __GNUG__
+#if defined (__GNUG__) && ! defined (USE_EXTERNAL_TEMPLATES)
 #include "Array.cc"
 #endif
 
--- a/liboctave/Bounds.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Bounds.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <iostream.h>
+
 #include "Bounds.h"
 #include "lo-error.h"
 
--- a/liboctave/Bounds.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Bounds.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,8 @@
 #if !defined (_Bounds_h)
 #define _Bounds_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+class ostream;
 
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/ColVector.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/ColVector.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,17 +21,16 @@
 
 */
 
-// I\'m not sure how this is supposed to work if the .h file declares
-// several classes, each of which is defined in a separate file...
-//
-// #ifdef __GNUG__
-// #pragma implementation "Matrix.h"
-// #endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream.h>
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
+#include "f77-uscore.h"
 #include "lo-error.h"
-#include "f77-uscore.h"
 
 // Fortran functions we call.
 
@@ -69,111 +68,7 @@
  * Column Vector class.
  */
 
-ColumnVector::ColumnVector (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create column vector with negative dimension");
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  len = n;
-  if (n > 0)
-    data = new double [len];
-  else
-    data = (double *) NULL;
-}
-
-ColumnVector::ColumnVector (int n, double val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create column vector with negative dimension");
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  len = n;
-  if (n > 0)
-    {
-      data = new double [len];
-      copy (data, len, val);
-    }
-  else
-    data = (double *) NULL;
-}
-
-ColumnVector::ColumnVector (const ColumnVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-ColumnVector::ColumnVector (double a)
-{
-  len = 1;
-  data = new double [1];
-  data[0] = a;
-}
-
-ColumnVector&
-ColumnVector::operator = (const ColumnVector& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new double [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (double *) NULL;
-    }
-  return *this;
-}
-
-double&
-ColumnVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static double foo = 0.0;
-      return foo;
-    }
-#endif
-
-  return elem (n);
-}
-
-double
-ColumnVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return 0.0;
-    }
-#endif
-
-  return elem (n);
-}
-
+#if 0
 ColumnVector&
 ColumnVector::resize (int n)
 {
@@ -211,34 +106,35 @@
 
   return *this;
 }
+#endif
 
 int
 ColumnVector::operator == (const ColumnVector& a) const
 {
-  if (len != a.len)
+  int len = length ();
+  if (len != a.length ())
     return 0;
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), len);
 }
 
 int
 ColumnVector::operator != (const ColumnVector& a) const
 {
-  if (len != a.len)
-    return 1;
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 ColumnVector&
 ColumnVector::insert (const ColumnVector& a, int r)
 {
-  if (r < 0 || r + a.len - 1 > len)
+  int a_len = a.length ();
+  if (r < 0 || r + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[r+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i) = a.elem (i);
 
   return *this;
 }
@@ -246,14 +142,17 @@
 ColumnVector&
 ColumnVector::fill (double val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 ColumnVector&
 ColumnVector::fill (double val, int r1, int r2)
 {
+  int len = length ();
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -263,7 +162,7 @@
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
   for (int i = r1; i <= r2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -271,8 +170,9 @@
 ColumnVector
 ColumnVector::stack (const ColumnVector& a) const
 {
+  int len = length ();
   int nr_insert = len;
-  ColumnVector retval (len + a.len);
+  ColumnVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nr_insert);
   return retval;
@@ -281,7 +181,8 @@
 RowVector
 ColumnVector::transpose (void) const
 {
-  return RowVector (dup (data, len), len);
+  int len = length ();
+  return RowVector (dup (data (), len), len);
 }
 
 // resize is the destructive equivalent for this one
@@ -296,93 +197,121 @@
   ColumnVector result (new_r);
 
   for (int i = 0; i < new_r; i++)
-    result.data[i] = elem (r1+i);
+    result.elem (i) = elem (r1+i);
 
   return result;
 }
 
-// column vector by scalar -> column vector operations
+// column vector by column vector -> column vector operations
 
-ColumnVector
-ColumnVector::operator + (double s) const
+ColumnVector&
+ColumnVector::operator += (const ColumnVector& a)
 {
-  return ColumnVector (add (data, len, s), len);
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return ColumnVector ();
+    }
+
+  if (len == 0)
+    return *this;
+
+  double *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
 }
 
-ColumnVector
-ColumnVector::operator - (double s) const
+ColumnVector&
+ColumnVector::operator -= (const ColumnVector& a)
 {
-  return ColumnVector (subtract (data, len, s), len);
-}
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return ColumnVector ();
+    }
 
-ColumnVector
-ColumnVector::operator * (double s) const
-{
-  return ColumnVector (multiply (data, len, s), len);
-}
+  if (len == 0)
+    return *this;
 
-ColumnVector
-ColumnVector::operator / (double s) const
-{
-  return ColumnVector (divide (data, len, s), len);
+  double *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
 }
 
 // scalar by column vector -> column vector operations
 
-ColumnVector
-operator + (double s, const ColumnVector& a)
+ComplexColumnVector
+operator + (const ColumnVector& a, const Complex& s)
 {
-  return ColumnVector (add (a.data, a.len, s), a.len);
+  int len = a.length ();
+  return ComplexColumnVector (add (a.data (), len, s), len);
 }
 
-ColumnVector
-operator - (double s, const ColumnVector& a)
+ComplexColumnVector
+operator - (const ColumnVector& a, const Complex& s)
 {
-  return ColumnVector (subtract (s, a.data, a.len), a.len);
+  int len = a.length ();
+  return ComplexColumnVector (subtract (a.data (), len, s), len);
 }
 
-ColumnVector
-operator * (double s, const ColumnVector& a)
+ComplexColumnVector
+operator * (const ColumnVector& a, const Complex& s)
 {
-  return ColumnVector (multiply (a.data, a.len, s), a.len);
-}
-
-ColumnVector
-operator / (double s, const ColumnVector& a)
-{
-  return ColumnVector (divide (s, a.data, a.len), a.len);
+  int len = a.length ();
+  return ComplexColumnVector (multiply (a.data (), len, s), len);
 }
 
 ComplexColumnVector
-ColumnVector::operator + (const Complex& s) const
+operator / (const ColumnVector& a, const Complex& s)
 {
-  return ComplexColumnVector (add (data, len, s), len);
+  int len = a.length ();
+  return ComplexColumnVector (divide (a.data (), len, s), len);
+}
+
+// scalar by column vector -> column vector operations
+
+ComplexColumnVector
+operator + (const Complex& s, const ColumnVector& a)
+{
+  int a_len = a.length ();
+  return ComplexColumnVector (add (a.data (), a_len, s), a_len);
 }
 
 ComplexColumnVector
-ColumnVector::operator - (const Complex& s) const
+operator - (const Complex& s, const ColumnVector& a)
 {
-  return ComplexColumnVector (subtract (data, len, s), len);
+  int a_len = a.length ();
+  return ComplexColumnVector (subtract (s, a.data (), a_len), a_len);
 }
 
 ComplexColumnVector
-ColumnVector::operator * (const Complex& s) const
+operator * (const Complex& s, const ColumnVector& a)
 {
-  return ComplexColumnVector (multiply (data, len, s), len);
+  int a_len = a.length ();
+  return ComplexColumnVector (multiply (a.data (), a_len, s), a_len);
 }
 
 ComplexColumnVector
-ColumnVector::operator / (const Complex& s) const
+operator / (const Complex& s, const ColumnVector& a)
 {
-  return ComplexColumnVector (divide (data, len, s), len);
+  int a_len = a.length ();
+  return ComplexColumnVector (divide (s, a.data (), a_len), a_len);
 }
 
 // column vector by row vector -> matrix operations
 
 Matrix
-ColumnVector::operator * (const RowVector& a) const
+operator * (const ColumnVector& v, const RowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  int a_len = a.length ();
+  if (len != a_len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector multiplication attempted");
@@ -397,77 +326,28 @@
   double alpha = 1.0;
   double beta  = 0.0;
   int anr = 1;
-  int anc = a.len;
 
-  double *c = new double [len * a.len];
+  double *c = new double [len * a_len];
 
-  F77_FCN (dgemm) (&transa, &transb, &len, &anc, &anr, &alpha, data,
-		   &len, a.data, &anr, &beta, c, &len, 1L, 1L);
+  F77_FCN (dgemm) (&transa, &transb, &len, &a_len, &anr, &alpha,
+		   v.data (), &len, a.data (), &anr, &beta, c, &len,
+		   1L, 1L); 
 
-  return Matrix (c, len, a.len);
+  return Matrix (c, len, a_len);
 }
 
 ComplexMatrix
-ColumnVector::operator * (const ComplexRowVector& a) const
+operator * (const ColumnVector& v, const ComplexRowVector& a)
 {
-  ComplexColumnVector tmp (*this);
+  ComplexColumnVector tmp (v);
   return tmp * a;
 }
 
-// column vector by column vector -> column vector operations
-
-ColumnVector
-ColumnVector::operator + (const ColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector addition attempted");
-      return ColumnVector ();
-    }
-
-  if (len == 0)
-    return ColumnVector (0);
-
-  return ColumnVector (add (data, a.data, len), len);
-}
-
-ColumnVector
-ColumnVector::operator - (const ColumnVector& a) const
+ComplexColumnVector
+operator + (const ColumnVector& v, const ComplexColumnVector& a)
 {
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector subtraction attempted");
-      return ColumnVector ();
-    }
-
-  if (len == 0)
-    return ColumnVector (0);
-
-  return ColumnVector (subtract (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ColumnVector::operator + (const ComplexColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector addition attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (add (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ColumnVector::operator - (const ComplexColumnVector& a) const
-{
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector subtraction attempted");
@@ -477,45 +357,31 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (subtract (data, a.data, len), len);
+  return ComplexColumnVector (add (v.data (), a.data (), len), len);
 }
 
-ColumnVector
-ColumnVector::product (const ColumnVector& a) const
+ComplexColumnVector
+operator - (const ColumnVector& v, const ComplexColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
-	("nonconformant vector product attempted");
-      return ColumnVector ();
+	("nonconformant vector subtraction attempted");
+      return ComplexColumnVector ();
     }
 
   if (len == 0)
-    return ColumnVector (0);
-
-  return ColumnVector (multiply (data, a.data, len), len);
-}
+    return ComplexColumnVector (0);
 
-ColumnVector
-ColumnVector::quotient (const ColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector quotient attempted");
-      return ColumnVector ();
-    }
-
-  if (len == 0)
-    return ColumnVector (0);
-
-  return ColumnVector (divide (data, a.data, len), len);
+  return ComplexColumnVector (subtract (v.data (), a.data (), len), len);
 }
 
 ComplexColumnVector
-ColumnVector::product (const ComplexColumnVector& a) const
+product (const ColumnVector& v, const ComplexColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector product attempted");
@@ -525,13 +391,14 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (multiply (data, a.data, len), len);
+  return ComplexColumnVector (multiply (v.data (), a.data (), len), len);
 }
 
 ComplexColumnVector
-ColumnVector::quotient (const ComplexColumnVector& a) const
+quotient (const ColumnVector& v, const ComplexColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector quotient attempted");
@@ -541,53 +408,10 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (divide (data, a.data, len), len);
-}
-
-ColumnVector&
-ColumnVector::operator += (const ColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return ColumnVector ();
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
+  return ComplexColumnVector (divide (v.data (), a.data (), len), len);
 }
 
-ColumnVector&
-ColumnVector::operator -= (const ColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return ColumnVector ();
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-// unary operations
-
-ColumnVector
-ColumnVector::operator - (void) const
-{
-  if (len == 0)
-    return ColumnVector (0);
-
-  return ColumnVector (negate (data, len), len);
-}
+// other operations
 
 ColumnVector
 map (d_d_Mapper f, const ColumnVector& a)
@@ -600,21 +424,22 @@
 void
 ColumnVector::map (d_d_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  for (int i = 0; i < length (); i++)
+    elem (i) = f (elem (i));
 }
 
 double
 ColumnVector::min (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0.0;
 
-  double res = data[0];
+  double res = elem (0);
 
   for (int i = 1; i < len; i++)
-    if (data[i] < res)
-      res = data[i];
+    if (elem (i) < res)
+      res = elem (i);
 
   return res;
 }
@@ -622,14 +447,15 @@
 double
 ColumnVector::max (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0.0;
 
-  double res = data[0];
+  double res = elem (0);
 
   for (int i = 1; i < len; i++)
-    if (data[i] > res)
-      res = data[i];
+    if (elem (i) > res)
+      res = elem (i);
 
   return res;
 }
@@ -638,8 +464,8 @@
 operator << (ostream& os, const ColumnVector& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.len; i++)
-    os << /* setw (field_width) << */ a.data[i] << "\n";
+  for (int i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
   return os;
 }
 
@@ -647,167 +473,14 @@
  * Complex Column Vector class
  */
 
-ComplexColumnVector::ComplexColumnVector (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create column vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (n > 0)
-    data = new Complex [len];
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexColumnVector::ComplexColumnVector (int n, double val)
+ComplexColumnVector::ComplexColumnVector (const ColumnVector& a)
+   : Array<Complex> (a.length ())
 {
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create column vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (n > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexColumnVector::ComplexColumnVector (int n, const Complex& val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create column vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (n > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexColumnVector::ComplexColumnVector (const ColumnVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
+  for (int i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
 }
 
-ComplexColumnVector::ComplexColumnVector (const ComplexColumnVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexColumnVector::ComplexColumnVector (double a)
-{
-  len = 1;
-  data = new Complex [1];
-  data[0] = a;
-}
-
-ComplexColumnVector::ComplexColumnVector (const Complex& a)
-{
-  len = 1;
-  data = new Complex [1];
-  data[0] = Complex (a);
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator = (const ColumnVector& a)
-{
-  delete [] data;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-
-  return *this;
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator = (const ComplexColumnVector& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new Complex [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (Complex *) NULL;
-    }
-  return *this;
-}
-
-Complex&
-ComplexColumnVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static Complex foo (0.0);
-      return foo;
-    }
-#endif
-
-  return elem (n);
-}
-
-Complex
-ComplexColumnVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return Complex (0.0);
-    }
-#endif
-
-  return elem (n);
-}
-
+#if 0
 ComplexColumnVector&
 ComplexColumnVector::resize (int n)
 {
@@ -856,21 +529,21 @@
 
   return *this;
 }
+#endif
 
 int
 ComplexColumnVector::operator == (const ComplexColumnVector& a) const
 {
-  if (len != a.len)
+  int len = length ();
+  if (len != a.length ())
     return 0;
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), len);
 }
 
 int
 ComplexColumnVector::operator != (const ComplexColumnVector& a) const
 {
-  if (len != a.len)
-    return 0;
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 // destructive insert/delete/reorder operations
@@ -878,14 +551,15 @@
 ComplexColumnVector&
 ComplexColumnVector::insert (const ColumnVector& a, int r)
 {
-  if (r < 0 || r + a.len - 1 > len)
+  int a_len = a.length ();
+  if (r < 0 || r + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[r+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i) = a.elem (i);
 
   return *this;
 }
@@ -893,14 +567,15 @@
 ComplexColumnVector&
 ComplexColumnVector::insert (const ComplexColumnVector& a, int r)
 {
-  if (r < 0 || r + a.len - 1 > len)
+  int a_len = a.length ();
+  if (r < 0 || r + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[r+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i) = a.elem (i);
 
   return *this;
 }
@@ -908,22 +583,27 @@
 ComplexColumnVector&
 ComplexColumnVector::fill (double val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 ComplexColumnVector&
 ComplexColumnVector::fill (const Complex& val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 ComplexColumnVector&
 ComplexColumnVector::fill (double val, int r1, int r2)
 {
+  int len = length ();
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -933,7 +613,7 @@
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
   for (int i = r1; i <= r2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -941,6 +621,7 @@
 ComplexColumnVector&
 ComplexColumnVector::fill (const Complex& val, int r1, int r2)
 {
+  int len = length ();
   if (r1 < 0 || r2 < 0 || r1 >= len || r2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -950,7 +631,7 @@
   if (r1 > r2) { int tmp = r1; r1 = r2; r2 = tmp; }
 
   for (int i = r1; i <= r2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -958,8 +639,9 @@
 ComplexColumnVector
 ComplexColumnVector::stack (const ColumnVector& a) const
 {
+  int len = length ();
   int nr_insert = len;
-  ComplexColumnVector retval (len + a.len);
+  ComplexColumnVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nr_insert);
   return retval;
@@ -968,8 +650,9 @@
 ComplexColumnVector
 ComplexColumnVector::stack (const ComplexColumnVector& a) const
 {
+  int len = length ();
   int nr_insert = len;
-  ComplexColumnVector retval (len + a.len);
+  ComplexColumnVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nr_insert);
   return retval;
@@ -978,39 +661,44 @@
 ComplexRowVector
 ComplexColumnVector::hermitian (void) const
 {
-  return ComplexRowVector (conj_dup (data, len), len);
+  int len = length ();
+  return ComplexRowVector (conj_dup (data (), len), len);
 }
 
 ComplexRowVector
 ComplexColumnVector::transpose (void) const
 {
-  return ComplexRowVector (dup (data, len), len);
+  int len = length ();
+  return ComplexRowVector (dup (data (), len), len);
 }
 
 ColumnVector
 real (const ComplexColumnVector& a)
 {
+  int a_len = a.length ();
   ColumnVector retval;
-  if (a.len > 0)
-    retval = ColumnVector (real_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = ColumnVector (real_dup (a.data (), a_len), a_len);
   return retval;
 }
 
 ColumnVector
 imag (const ComplexColumnVector& a)
 {
+  int a_len = a.length ();
   ColumnVector retval;
-  if (a.len > 0)
-    retval = ColumnVector (imag_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = ColumnVector (imag_dup (a.data (), a_len), a_len);
   return retval;
 }
 
 ComplexColumnVector
 conj (const ComplexColumnVector& a)
 {
+  int a_len = a.length ();
   ComplexColumnVector retval;
-  if (a.len > 0)
-    retval = ComplexColumnVector (conj_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = ComplexColumnVector (conj_dup (a.data (), a_len), a_len);
   return retval;
 }
 
@@ -1026,59 +714,122 @@
   ComplexColumnVector result (new_r);
 
   for (int i = 0; i < new_r; i++)
-    result.data[i] = elem (r1+i);
+    result.elem (i) = elem (r1+i);
 
   return result;
 }
 
+// column vector by column vector -> column vector operations
+
+ComplexColumnVector&
+ComplexColumnVector::operator += (const ColumnVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::operator -= (const ColumnVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::operator += (const ComplexColumnVector& a)
+{
+  int len = length ();
+
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexColumnVector&
+ComplexColumnVector::operator -= (const ComplexColumnVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
+}
+
 // column vector by scalar -> column vector operations
 
 ComplexColumnVector
-ComplexColumnVector::operator + (double s) const
-{
-  return ComplexColumnVector (add (data, len, s), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::operator - (double s) const
+operator + (const ComplexColumnVector& v, double s)
 {
-  return ComplexColumnVector (subtract (data, len, s), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::operator * (double s) const
-{
-  return ComplexColumnVector (multiply (data, len, s), len);
+  int len = v.length ();
+  return ComplexColumnVector (add (v.data (), len, s), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::operator / (double s) const
+operator - (const ComplexColumnVector& v, double s)
 {
-  return ComplexColumnVector (divide (data, len, s), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::operator + (const Complex& s) const
-{
-  return ComplexColumnVector (add (data, len, s), len);
+  int len = v.length ();
+  return ComplexColumnVector (subtract (v.data (), len, s), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::operator - (const Complex& s) const
+operator * (const ComplexColumnVector& v, double s)
 {
-  return ComplexColumnVector (subtract (data, len, s), len);
+  int len = v.length ();
+  return ComplexColumnVector (multiply (v.data (), len, s), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::operator * (const Complex& s) const
+operator / (const ComplexColumnVector& v, double s)
 {
-  return ComplexColumnVector (multiply (data, len, s), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::operator / (const Complex& s) const
-{
-  return ComplexColumnVector (divide (data, len, s), len);
+  int len = v.length ();
+  return ComplexColumnVector (divide (v.data (), len, s), len);
 }
 
 // scalar by column vector -> column vector operations
@@ -1086,64 +837,39 @@
 ComplexColumnVector
 operator + (double s, const ComplexColumnVector& a)
 {
-  return ComplexColumnVector (add (a.data, a.len, s), a.len);
+  int a_len = a.length ();
+  return ComplexColumnVector (add (a.data (), a_len, s), a_len);
 }
 
 ComplexColumnVector
 operator - (double s, const ComplexColumnVector& a)
 {
-  return ComplexColumnVector (subtract (s, a.data, a.len), a.len);
+  int a_len = a.length ();
+  return ComplexColumnVector (subtract (s, a.data (), a_len), a_len);
 }
 
 ComplexColumnVector
 operator * (double s, const ComplexColumnVector& a)
 {
-  return ComplexColumnVector (multiply (a.data, a.len, s), a.len);
+  int a_len = a.length ();
+  return ComplexColumnVector (multiply (a.data (), a_len, s), a_len);
 }
 
 ComplexColumnVector
 operator / (double s, const ComplexColumnVector& a)
 {
-  return ComplexColumnVector (divide (s, a.data, a.len), a.len);
-}
-
-ComplexColumnVector
-operator + (const Complex& s, const ComplexColumnVector& a)
-{
-  return ComplexColumnVector (add (a.data, a.len, s), a.len);
-}
-
-ComplexColumnVector
-operator - (const Complex& s, const ComplexColumnVector& a)
-{
-  return ComplexColumnVector (subtract (s, a.data, a.len), a.len);
-}
-
-ComplexColumnVector
-operator * (const Complex& s, const ComplexColumnVector& a)
-{
-  return ComplexColumnVector (multiply (a.data, a.len, s), a.len);
-}
-
-ComplexColumnVector
-operator / (const Complex& s, const ComplexColumnVector& a)
-{
-  return ComplexColumnVector (divide (s, a.data, a.len), a.len);
+  int a_len = a.length ();
+  return ComplexColumnVector (divide (s, a.data (), a_len), a_len);
 }
 
 // column vector by row vector -> matrix operations
 
 ComplexMatrix
-ComplexColumnVector::operator * (const RowVector& a) const
+operator * (const ComplexColumnVector& v, const ComplexRowVector& a)
 {
-  ComplexRowVector tmp (a);
-  return *this * tmp;
-}
-
-ComplexMatrix
-ComplexColumnVector::operator * (const ComplexRowVector& a) const
-{
-  if (len != a.len)
+  int len = v.length ();
+  int a_len = a.length ();
+  if (len != a_len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector multiplication attempted");
@@ -1158,22 +884,23 @@
   Complex alpha (1.0);
   Complex beta (0.0);
   int anr = 1;
-  int anc = a.len;
 
-  Complex *c = new Complex [len * a.len];
+  Complex *c = new Complex [len * a_len];
 
-  F77_FCN (zgemm) (&transa, &transb, &len, &anc, &anr, &alpha, data,
-		   &len, a.data, &anr, &beta, c, &len, 1L, 1L);
+  F77_FCN (zgemm) (&transa, &transb, &len, &a_len, &anr, &alpha,
+		   v.data (), &len, a.data (), &anr, &beta, c, &len,
+		   1L, 1L);
 
-  return ComplexMatrix (c, len, a.len);
+  return ComplexMatrix (c, len, a_len);
 }
 
 // column vector by column vector -> column vector operations
 
 ComplexColumnVector
-ComplexColumnVector::operator + (const ColumnVector& a) const
+operator + (const ComplexColumnVector& v, const ColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector addition attempted");
@@ -1183,13 +910,14 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (add (data, a.data, len), len);
+  return ComplexColumnVector (add (v.data (), a.data (), len), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::operator - (const ColumnVector& a) const
+operator - (const ComplexColumnVector& v, const ColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector subtraction attempted");
@@ -1199,45 +927,14 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (subtract (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::operator + (const ComplexColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector addition attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (add (data, a.data, len), len);
+  return ComplexColumnVector (subtract (v.data (), a.data (), len), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::operator - (const ComplexColumnVector& a) const
+product (const ComplexColumnVector& v, const ColumnVector& a)
 {
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector subtraction attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (subtract (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::product (const ColumnVector& a) const
-{
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector product attempted");
@@ -1247,13 +944,14 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (multiply (data, a.data, len), len);
+  return ComplexColumnVector (multiply (v.data (), a.data (), len), len);
 }
 
 ComplexColumnVector
-ComplexColumnVector::quotient (const ColumnVector& a) const
+quotient (const ComplexColumnVector& v, const ColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector quotient attempted");
@@ -1263,119 +961,10 @@
   if (len == 0)
     return ComplexColumnVector (0);
 
-  return ComplexColumnVector (divide (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::product (const ComplexColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector product attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (multiply (data, a.data, len), len);
-}
-
-ComplexColumnVector
-ComplexColumnVector::quotient (const ComplexColumnVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector quotient attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (divide (data, a.data, len), len);
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator += (const ColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
+  return ComplexColumnVector (divide (v.data (), a.data (), len), len);
 }
 
-ComplexColumnVector&
-ComplexColumnVector::operator -= (const ColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator += (const ComplexColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexColumnVector&
-ComplexColumnVector::operator -= (const ComplexColumnVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-// unary operations
-
-ComplexColumnVector
-ComplexColumnVector::operator - (void) const
-{
-  if (len == 0)
-    return ComplexColumnVector (0);
-
-  return ComplexColumnVector (negate (data, len), len);
-}
+// other operations
 
 ComplexColumnVector
 map (c_c_Mapper f, const ComplexColumnVector& a)
@@ -1388,8 +977,9 @@
 ColumnVector
 map (d_c_Mapper f, const ComplexColumnVector& a)
 {
-  ColumnVector b (a.len);
-  for (int i = 0; i < a.len; i++)
+  int a_len = a.length ();
+  ColumnVector b (a_len);
+  for (int i = 0; i < a_len; i++)
     b.elem (i) = f (a.elem (i));
   return b;
 }
@@ -1397,23 +987,24 @@
 void
 ComplexColumnVector::map (c_c_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  for (int i = 0; i < length (); i++)
+    elem (i) = f (elem (i));
 }
 
 Complex
 ComplexColumnVector::min (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0.0;
 
-  Complex res = data[0];
+  Complex res = elem (0);
   double absres = abs (res);
 
   for (int i = 1; i < len; i++)
-    if (abs (data[i]) < absres)
+    if (abs (elem (i)) < absres)
       {
-	res = data[i];
+	res = elem (i);
 	absres = abs (res);
       }
 
@@ -1423,16 +1014,17 @@
 Complex
 ComplexColumnVector::max (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0.0;
 
-  Complex res = data[0];
+  Complex res = elem (0);
   double absres = abs (res);
 
   for (int i = 1; i < len; i++)
-    if (abs (data[i]) > absres)
+    if (abs (elem (i)) > absres)
       {
-	res = data[i];
+	res = elem (i);
 	absres = abs (res);
       }
 
@@ -1445,8 +1037,8 @@
 operator << (ostream& os, const ComplexColumnVector& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.len; i++)
-    os << /* setw (field_width) << */ a.data[i] << "\n";
+  for (int i = 0; i < a.length (); i++)
+    os << /* setw (field_width) << */ a.elem (i) << "\n";
   return os;
 }
 
--- a/liboctave/CollocWt.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/CollocWt.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <iostream.h>
+
 #include "CollocWt.h"
 #include "f77-uscore.h"
 #include "lo-error.h"
--- a/liboctave/CollocWt.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/CollocWt.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,8 @@
 #if !defined (_CollocWt_h)
 #define _CollocWt_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+class ostream;
 
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/DAE.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/DAE.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,15 +24,9 @@
 #if !defined (_DAE_h)
 #define _DAE_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
 #include "ODE.h"
 #include "DAEFunc.h"
 #include "Matrix.h"
-#include "f77-uscore.h"
 
 #ifndef Vector
 #define Vector ColumnVector
--- a/liboctave/DAEFunc.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/DAEFunc.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "DAEFunc.h"
 
 DAEFunc::DAEFunc (void)
--- a/liboctave/DAEFunc.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/DAEFunc.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,6 @@
 #if !defined (_DAEFunc_h)
 #define _DAEFunc_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/DASSL.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/DASSL.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "DAE.h"
+#include "f77-uscore.h"
 #include "lo-error.h"
 
 extern "C"
@@ -232,7 +232,7 @@
 
   // Fix up the matrix of partial derivatives for dassl.
 
-  tmp_dfdx = tmp_dfdx + (*cj * tmp_dfdxdot);
+  tmp_dfdx = tmp_dfdx + (tmp_dfdxdot * (*cj));
 
   for (int j = 0; j < nn; j++)
     for (int i = 0; i < nn; i++)
--- a/liboctave/DiagMatrix.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/DiagMatrix.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,11 @@
 
 */
 
-// I\'m not sure how this is supposed to work if the .h file declares
-// several classes, each of which is defined in a separate file...
-//
-// #ifdef __GNUG__
-// #pragma implementation "Matrix.h"
-// #endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream.h>
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
@@ -36,200 +35,7 @@
  * Diagonal Matrix class.
  */
 
-DiagMatrix::DiagMatrix (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = n;
-  nc = n;
-  len = n;
-  if (len > 0)
-    data = new double [len];
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (int n, double val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = n;
-  nc = n;
-  len = n;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, len, val);
-    }
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (int r, int c)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = r < c ? r : c;
-  if (len > 0)
-    data = new double [len];
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (int r, int c, double val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = r < c ? r : c;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, len, val);
-    }
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (const RowVector& a)
-{
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (const ColumnVector& a)
-{
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (const DiagMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-DiagMatrix::DiagMatrix (double a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new double [1];
-  data[0] = a;
-}
-
-DiagMatrix&
-DiagMatrix::operator = (const DiagMatrix& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      nr = a.nr;
-      nc = a.nc;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new double [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (double *) NULL;
-    }
-  return *this;
-}
-
-double&
-DiagMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static double foo = 0.0;
-      return foo;
-    }
-#endif
-
-  return elem (r, c);
-}
-
-double
-DiagMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return 0.0;
-    }
-#endif
-
-  return elem (r, c);
-}
-
+#if 0
 DiagMatrix&
 DiagMatrix::resize (int r, int c)
 {
@@ -294,102 +100,114 @@
 
   return *this;
 }
+#endif
 
 int
 DiagMatrix::operator == (const DiagMatrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
+  if (rows () != a.rows () || cols () != a.cols ())
     return 0;
 
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), length ());
 }
 
 int
 DiagMatrix::operator != (const DiagMatrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
-    return 1;
-
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 DiagMatrix&
 DiagMatrix::fill (double val)
 {
-  copy (data, len, val);
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = val;
   return *this;
 }
 
 DiagMatrix&
 DiagMatrix::fill (double val, int beg, int end)
 {
-  if (beg < 0 || end >= len || end < beg)
+  if (beg < 0 || end >= length () || end < beg)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  if (end > beg)
-    copy (data+beg, beg-end, val);
+  for (int i = beg; i < end; i++)
+    elem (i, i) = val;
+
   return *this;
 }
 
 DiagMatrix&
 DiagMatrix::fill (const ColumnVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 DiagMatrix&
 DiagMatrix::fill (const RowVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 DiagMatrix&
 DiagMatrix::fill (const ColumnVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 DiagMatrix&
 DiagMatrix::fill (const RowVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 DiagMatrix
 DiagMatrix::transpose (void) const
 {
-  return DiagMatrix (dup (data, len), nc, nr);
+  return DiagMatrix (dup (data (), length ()), cols (), rows ());
 }
 
 Matrix
@@ -405,7 +223,7 @@
 
   for (int j = 0; j < new_c; j++)
     for (int i = 0; i < new_r; i++)
-      result.data[new_r*j+i] = elem (r1+i, c1+j);
+      result.elem (i, j) = elem (r1+i, c1+j);
 
   return result;
 }
@@ -415,6 +233,8 @@
 RowVector
 DiagMatrix::row (int i) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (i < 0 || i >= nr)
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -423,7 +243,7 @@
 
   RowVector retval (nc, 0.0);
   if (nr <= nc || (nr > nc && i < nc))
-    retval.data [i] = data[i];
+    retval.elem (i) = elem (i, i);
 
   return retval;
 }
@@ -441,7 +261,7 @@
   if (c == 'f' || c == 'F')
     return row (0);
   else if (c == 'l' || c == 'L')
-    return row (nr - 1);
+    return row (rows () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -452,6 +272,8 @@
 ColumnVector
 DiagMatrix::column (int i) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (i < 0 || i >= nc)
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -460,7 +282,7 @@
 
   ColumnVector retval (nr, 0.0);
   if (nr >= nc || (nr < nc && i < nr))
-    retval.data [i] = data[i];
+    retval.elem (i) = elem (i, i);
 
   return retval;
 }
@@ -478,7 +300,7 @@
   if (c == 'f' || c == 'F')
     return column (0);
   else if (c == 'l' || c == 'L')
-    return column (nc - 1);
+    return column (cols () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -487,94 +309,131 @@
 }
 
 DiagMatrix
-DiagMatrix::inverse (int &info) const
-{
-  if (nr != nc)
-    {
-      (*current_liboctave_error_handler) ("inverse requires square matrix");
-      return DiagMatrix ();
-    }
-
-  info = 0;
-  double *tmp_data = dup (data, len);
-  for (int i = 0; i < len; i++)
-    {
-      if (data[i] == 0.0)
-	{
-	  info = -1;
-	  copy (tmp_data, data, len); // Restore contents.
-	  break;
-	}
-      else
-	{
-	  tmp_data[i] = 1.0 / data[i];
-	}
-    }
-
-  return DiagMatrix (tmp_data, nr, nc);
-}
-
-DiagMatrix
 DiagMatrix::inverse (void) const
 {
   int info;
   return inverse (info);
 }
 
+DiagMatrix
+DiagMatrix::inverse (int &info) const
+{
+  int nr = rows ();
+  int nc = cols ();
+  int len = length ();
+  if (nr != nc)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return DiagMatrix ();
+    }
+
+  info = 0;
+  double *tmp_data = dup (data (), len);
+  for (int i = 0; i < len; i++)
+    {
+      if (elem (i, i) == 0.0)
+	{
+	  info = -1;
+	  copy (tmp_data, data (), len); // Restore contents.
+	  break;
+	}
+      else
+	{
+	  tmp_data[i] = 1.0 / elem (i, i);
+	}
+    }
+
+  return DiagMatrix (tmp_data, nr, nc);
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+DiagMatrix&
+DiagMatrix::operator += (const DiagMatrix& 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 (nc == 0 || nr == 0)
+    return *this;
+
+  double *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), length ());
+  return *this;
+}
+
+DiagMatrix&
+DiagMatrix::operator -= (const DiagMatrix& 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;
+}
+
 // diagonal matrix by scalar -> matrix operations
 
 Matrix
-DiagMatrix::operator + (double s) const
+operator + (const DiagMatrix& a, double s)
 {
-  Matrix tmp (nr, nc, s);
-  return *this + tmp;
+  Matrix tmp (a.rows (), a.cols (), s);
+  return a + tmp;
 }
 
 Matrix
-DiagMatrix::operator - (double s) const
+operator - (const DiagMatrix& a, double s)
 {
-  Matrix tmp (nr, nc, -s);
-  return *this + tmp;
+  Matrix tmp (a.rows (), a.cols (), -s);
+  return a + tmp;
 }
 
 ComplexMatrix
-DiagMatrix::operator + (const Complex& s) const
+operator + (const DiagMatrix& a, const Complex& s)
 {
-  ComplexMatrix tmp (nr, nc, s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return a + tmp;
 }
 
 ComplexMatrix
-DiagMatrix::operator - (const Complex& s) const
+operator - (const DiagMatrix& a, const Complex& s)
 {
-  ComplexMatrix tmp (nr, nc, -s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), -s);
+  return a + tmp;
 }
 
 // diagonal matrix by scalar -> diagonal matrix operations
 
-DiagMatrix
-DiagMatrix::operator * (double s) const
+ComplexDiagMatrix
+operator * (const DiagMatrix& a, const Complex& s)
 {
-  return DiagMatrix (multiply (data, len, s), nr, nc);
-}
-
-DiagMatrix
-DiagMatrix::operator / (double s) const
-{
-  return DiagMatrix (divide (data, len, s), nr, nc);
+  return ComplexDiagMatrix (multiply (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 ComplexDiagMatrix
-DiagMatrix::operator * (const Complex& s) const
+operator / (const DiagMatrix& a, const Complex& s)
 {
-  return ComplexDiagMatrix (multiply (data, len, s), nr, nc);
-}
-
-ComplexDiagMatrix
-DiagMatrix::operator / (const Complex& s) const
-{
-  return ComplexDiagMatrix (divide (data, len, s), nr, nc);
+  return ComplexDiagMatrix (divide (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 // scalar by diagonal matrix -> matrix operations
@@ -582,35 +441,49 @@
 Matrix
 operator + (double s, const DiagMatrix& a)
 {
-  return a + s;
+  Matrix tmp (a.rows (), a.cols (), s);
+  return tmp + a;
 }
 
 Matrix
 operator - (double s, const DiagMatrix& a)
 {
-  return -a + s;
+  Matrix tmp (a.rows (), a.cols (), s);
+  return tmp - a;
+}
+
+ComplexMatrix
+operator + (const Complex& s, const DiagMatrix& a)
+{
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp + a;
+}
+
+ComplexMatrix
+operator - (const Complex& s, const DiagMatrix& a)
+{
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp - a;
 }
 
 // scalar by diagonal matrix -> diagonal matrix operations
 
-DiagMatrix
-operator * (double s, const DiagMatrix& a)
+ComplexDiagMatrix
+operator * (const Complex& s, const DiagMatrix& a)
 {
-  return DiagMatrix (multiply (a.data, a.len, s), a.nr, a.nc);
-}
-
-DiagMatrix
-operator / (double s, const DiagMatrix& a)
-{
-  return DiagMatrix (divide (s, a.data, a.len), a.nr, a.nc);
+  return ComplexDiagMatrix (multiply (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 // diagonal matrix by column vector -> column vector operations
 
 ColumnVector
-DiagMatrix::operator * (const ColumnVector& a) const
+operator * (const DiagMatrix& m, const ColumnVector& a)
 {
-  if (nc != a.len)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  int a_len = a.length ();
+  if (nc != a_len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix multiplication attempted");
@@ -622,19 +495,22 @@
 
   ColumnVector result (nr);
 
-  for (int i = 0; i < a.len; i++)
-    result.data[i] = a.data[i] * data[i];
+  for (int i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
 
-  for (i = a.len; i < nr; i++)
-    result.data[i] = 0.0;
+  for (i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
 
   return result;
 }
 
 ComplexColumnVector
-DiagMatrix::operator * (const ComplexColumnVector& a) const
+operator * (const DiagMatrix& m, const ComplexColumnVector& a)
 {
-  if (nc != a.len)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  int a_len = a.length ();
+  if (nc != a_len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix multiplication attempted");
@@ -646,69 +522,23 @@
 
   ComplexColumnVector result (nr);
 
-  for (int i = 0; i < a.len; i++)
-    result.data[i] = a.data[i] * data[i];
+  for (int i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
 
-  for (i = a.len; i < nr; i++)
-    result.data[i] = 0.0;
+  for (i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
 
   return result;
 }
 
 // diagonal matrix by diagonal matrix -> diagonal matrix operations
 
-DiagMatrix
-DiagMatrix::operator + (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix addition attempted");
-      return DiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return DiagMatrix (nr, nc);
-
-  return DiagMatrix (add (data, a.data, len), nr , nc);
-}
-
-DiagMatrix
-DiagMatrix::operator - (const DiagMatrix& a) const
+ComplexDiagMatrix
+operator + (const DiagMatrix& m, const ComplexDiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix subtraction attempted");
-      return DiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return DiagMatrix (nr, nc);
-
-  return DiagMatrix (subtract (data, a.data, len), nr, nc);
-}
-
-DiagMatrix
-DiagMatrix::operator * (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix multiplication attempted");
-      return DiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return DiagMatrix (nr, nc);
-
-  return DiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-DiagMatrix::operator + (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -718,13 +548,15 @@
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (add (data, a.data, len), nr , nc);
+  return ComplexDiagMatrix (add (m.data (), a.data (), m.length ()),  nr, nc);
 }
 
 ComplexDiagMatrix
-DiagMatrix::operator - (const ComplexDiagMatrix& a) const
+operator - (const DiagMatrix& m, const ComplexDiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -734,61 +566,16 @@
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (subtract (data, a.data, len), nr, nc);
+  return ComplexDiagMatrix (subtract (m.data (), a.data (), m.length ()),
+			    nr, nc);
 }
 
 ComplexDiagMatrix
-DiagMatrix::operator * (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix multiplication attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-DiagMatrix
-DiagMatrix::product (const DiagMatrix& a) const
+product (const DiagMatrix& m, const ComplexDiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix product attempted");
-      return DiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return DiagMatrix (nr, nc);
-
-  return DiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-DiagMatrix
-DiagMatrix::quotient (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return DiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return DiagMatrix (nr, nc);
-
-  return DiagMatrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-DiagMatrix::product (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix product attempted");
@@ -798,64 +585,18 @@
   if (nc == 0 || nr == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-DiagMatrix::quotient (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (divide (data, a.data, len), nr, nc);
-}
-
-DiagMatrix&
-DiagMatrix::operator += (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nc == 0 || nr == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-DiagMatrix&
-DiagMatrix::operator -= (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-
-  subtract2 (data, a.data, len);
-  return *this;
+  return ComplexDiagMatrix (multiply (m.data (), a.data (), m.length ()),
+			    nr, nc);
 }
 
 // diagonal matrix by matrix -> matrix operations
 
 Matrix
-DiagMatrix::operator + (const Matrix& a) const
+operator + (const DiagMatrix& m, const Matrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -866,16 +607,18 @@
     return Matrix (nr, nc);
 
   Matrix result (a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 Matrix
-DiagMatrix::operator - (const Matrix& a) const
+operator - (const DiagMatrix& m, const Matrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -886,50 +629,54 @@
     return Matrix (nr, nc);
 
   Matrix result (-a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 Matrix
-DiagMatrix::operator * (const Matrix& a) const
+operator * (const DiagMatrix& m, const Matrix& a)
 {
-  if (nc != a.nr)
+  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);
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return Matrix (nr, a_nc, 0.0);
 
-  Matrix c (nr, a.nc);
+  Matrix c (nr, a_nc);
 
-  for (int i = 0; i < len; i++)
+  for (int i = 0; i < m.length (); i++)
     {
-      if (data[i] == 1.0)
+      if (m.elem (i, i) == 1.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  for (int j = 0; j < a_nc; j++)
 	    c.elem (i, j) = a.elem (i, j);
 	}
-      else if (data[i] == 0.0)
+      else if (m.elem (i, i) == 0.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  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) = data[i] * a.elem (i, j);
+	  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++)
+      for (int j = 0; j < a_nc; j++)
+	for (int i = a_nr; i < nr; i++)
 	  c.elem (i, j) = 0.0;
     }
 
@@ -937,9 +684,11 @@
 }
 
 ComplexMatrix
-DiagMatrix::operator + (const ComplexMatrix& a) const
+operator + (const DiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -950,16 +699,18 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-DiagMatrix::operator - (const ComplexMatrix& a) const
+operator - (const DiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -970,63 +721,61 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (-a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-DiagMatrix::operator * (const ComplexMatrix& a) const
+operator * (const DiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nc != a.nr)
+  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 ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
+  if (nr == 0 || nc == 0 || a_nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
 
-  ComplexMatrix c (nr, a.nc);
+  ComplexMatrix c (nr, a_nc);
 
-  for (int i = 0; i < len; i++)
+  for (int i = 0; i < m.length (); i++)
     {
-      if (data[i] == 1.0)
+      if (m.elem (i, i) == 1.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  for (int j = 0; j < a_nc; j++)
 	    c.elem (i, j) = a.elem (i, j);
 	}
-      else if (data[i] == 0.0)
+      else if (m.elem (i, i) == 0.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  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) = data[i] * a.elem (i, j);
+	  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++)
+      for (int j = 0; j < a_nc; j++)
+	for (int i = a_nr; i < nr; i++)
 	  c.elem (i, j) = 0.0;
     }
 
   return c;
 }
 
-// unary operations
-
-DiagMatrix
-DiagMatrix::operator - (void) const
-{
-  return DiagMatrix (negate (data, len), nr, nc);
-}
+// other operations
 
 ColumnVector
 DiagMatrix::diag (void) const
@@ -1039,8 +788,8 @@
 ColumnVector
 DiagMatrix::diag (int k) const
 {
-  int nnr = nr;
-  int nnc = nc;
+  int nnr = rows ();
+  int nnc = cols ();
   if (k > 0)
     nnc -= k;
   else if (k < 0)
@@ -1079,16 +828,15 @@
 ostream&
 operator << (ostream& os, const DiagMatrix& a)
 {
-  double ZERO = 0.0;
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.nr; i++)
+  for (int i = 0; i < a.rows (); i++)
     {
-      for (int j = 0; j < a.nc; j++)
+      for (int j = 0; j < a.cols (); j++)
 	{
 	  if (i == j)
-	    os << " " /* setw (field_width) */ << a.data[i];
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
 	  else
-	    os << " " /* setw (field_width) */ << ZERO;
+	    os << " " /* setw (field_width) */ << 0.0;
 	}
       os << "\n";
     }
@@ -1099,319 +847,28 @@
  * Complex Diagonal Matrix class
  */
 
-ComplexDiagMatrix::ComplexDiagMatrix (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = n;
-  nc = n;
-  len = n;
-  if (len > 0)
-    data = new Complex [len];
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (int n, double val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = n;
-  nc = n;
-  len = n;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (int n, const Complex& val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = n;
-  nc = n;
-  len = n;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (int r, int c)
+ComplexDiagMatrix::ComplexDiagMatrix (const RowVector& a)
+  : DiagArray<Complex> (a.length ())
 {
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = r < c ? r : c;
-  if (len > 0)
-    data = new Complex [len];
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (int r, int c, double val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = r < c ? r : c;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (int r, int c, const Complex& val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = r < c ? r : c;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (const RowVector& a)
-{
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (const ComplexRowVector& a)
-{
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = a.elem (i);
 }
 
 ComplexDiagMatrix::ComplexDiagMatrix (const ColumnVector& a)
+  : DiagArray<Complex> (a.length ())
 {
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (const ComplexColumnVector& a)
-{
-  nr = a.len;
-  nc = nr;
-  len = nr;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = a.elem (i);
 }
 
 ComplexDiagMatrix::ComplexDiagMatrix (const DiagMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (const ComplexDiagMatrix& a)
+  : DiagArray<Complex> (a.rows (), a.cols ())
 {
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (double a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new Complex [1];
-  data[0] = a;
-}
-
-ComplexDiagMatrix::ComplexDiagMatrix (const Complex& a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new Complex [1];
-  data[0] = Complex (a);
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = a.elem (i, i);
 }
 
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator = (const DiagMatrix& a)
-{
-  delete [] data;
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-
-  return *this;
-}
-
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator = (const ComplexDiagMatrix& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      nr = a.nr;
-      nc = a.nc;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new Complex [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (Complex *) NULL;
-    }
-  return *this;
-}
-
-Complex&
-ComplexDiagMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static Complex foo (0.0);
-      return foo;
-    }
-#endif
-
-  return elem (r, c);
-}
-
-Complex
-ComplexDiagMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return Complex (0.0);
-    }
-#endif
-
-  return elem (r, c);
-}
-
+#if 0
 ComplexDiagMatrix&
 ComplexDiagMatrix::resize (int r, int c)
 {
@@ -1510,189 +967,217 @@
 
   return *this;
 }
+#endif
 
 int
 ComplexDiagMatrix::operator == (const ComplexDiagMatrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
+  if (rows () != a.rows () || cols () != a.cols ())
     return 0;
 
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), length ());
 }
 
 int
 ComplexDiagMatrix::operator != (const ComplexDiagMatrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
-    return 1;
-
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 ComplexDiagMatrix
 ComplexDiagMatrix::hermitian (void) const
 {
-  return ComplexDiagMatrix (conj_dup (data, len), nc, nr);
+  return ComplexDiagMatrix (conj_dup (data (), length ()), cols (), rows ());
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (double val)
 {
-  copy (data, len, val);
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = val;
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const Complex& val)
 {
-  copy (data, len, val);
+  for (int i = 0; i < length (); i++)
+    elem (i, i) = val;
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (double val, int beg, int end)
 {
-  if (beg < 0 || end >= len || end < beg)
+  if (beg < 0 || end >= length () || end < beg)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  if (end > beg)
-    copy (data+beg, beg-end, val);
+  for (int i = beg; i < end; i++)
+    elem (i, i) = val;
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const Complex& val, int beg, int end)
 {
-  if (beg < 0 || end >= len || end < beg)
+  if (beg < 0 || end >= length () || end < beg)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  if (end > beg)
-    copy (data+beg, beg-end, val);
+  for (int i = beg; i < end; i++)
+    elem (i, i) = val;
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ColumnVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ComplexColumnVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const RowVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ComplexRowVector& a)
 {
-  if (a.len != len)
+  int len = length ();
+  if (a.length () != len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data, a.data, len);
+  for (int i = 0; i < len; i++)
+    elem (i, i) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ColumnVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ComplexColumnVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const RowVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix&
 ComplexDiagMatrix::fill (const ComplexRowVector& a, int beg)
 {
-  if (beg < 0 || beg + a.len >= len)
+  int a_len = a.length ();
+  if (beg < 0 || beg + a_len >= length ())
     {
       (*current_liboctave_error_handler) ("range error for fill");
       return *this;
     }
 
-  copy (data+beg, a.data, a.len);
+  for (int i = 0; i < a_len; i++)
+    elem (i+beg, i+beg) = a.elem (i);
+
   return *this;
 }
 
 ComplexDiagMatrix
 ComplexDiagMatrix::transpose (void) const
 {
-  return ComplexDiagMatrix (dup (data, len), nc, nr);
+  return ComplexDiagMatrix (dup (data (), length ()), cols (), rows ());
 }
 
 DiagMatrix
 real (const ComplexDiagMatrix& a)
 {
   DiagMatrix retval;
-  if (a.len > 0)
-    retval = DiagMatrix (real_dup (a.data, a.len), a.nr, a.nc);
+  int a_len = a.length ();
+  if (a_len > 0)
+    retval = DiagMatrix (real_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
   return retval;
 }
 
@@ -1700,8 +1185,10 @@
 imag (const ComplexDiagMatrix& a)
 {
   DiagMatrix retval;
-  if (a.len > 0)
-    retval = DiagMatrix (imag_dup (a.data, a.len), a.nr, a.nc);
+  int a_len = a.length ();
+  if (a_len > 0)
+    retval = DiagMatrix (imag_dup (a.data (), a_len), a.rows (),
+			 a.cols ());
   return retval;
 }
 
@@ -1709,8 +1196,10 @@
 conj (const ComplexDiagMatrix& a)
 {
   ComplexDiagMatrix retval;
-  if (a.len > 0)
-    retval = ComplexDiagMatrix (conj_dup (a.data, a.len), a.nr, a.nc);
+  int a_len = a.length ();
+  if (a_len > 0)
+    retval = ComplexDiagMatrix (conj_dup (a.data (), a_len),
+				a.rows (), a.cols ());
   return retval;
 }
 
@@ -1729,7 +1218,7 @@
 
   for (int j = 0; j < new_c; j++)
     for (int i = 0; i < new_r; i++)
-      result.data[new_r*j+i] = elem (r1+i, c1+j);
+      result.elem (i, j) = elem (r1+i, c1+j);
 
   return result;
 }
@@ -1739,6 +1228,8 @@
 ComplexRowVector
 ComplexDiagMatrix::row (int i) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (i < 0 || i >= nr)
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -1747,7 +1238,7 @@
 
   ComplexRowVector retval (nc, 0.0);
   if (nr <= nc || (nr > nc && i < nc))
-    retval.data [i] = data[i];
+    retval.elem (i) = elem (i, i);
 
   return retval;
 }
@@ -1765,7 +1256,7 @@
   if (c == 'f' || c == 'F')
     return row (0);
   else if (c == 'l' || c == 'L')
-    return row (nr - 1);
+    return row (rows () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -1776,6 +1267,8 @@
 ComplexColumnVector
 ComplexDiagMatrix::column (int i) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (i < 0 || i >= nc)
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -1784,7 +1277,7 @@
 
   ComplexColumnVector retval (nr, 0.0);
   if (nr >= nc || (nr < nc && i < nr))
-    retval.data [i] = data[i];
+    retval.elem (i) = elem (i, i);
 
   return retval;
 }
@@ -1802,7 +1295,7 @@
   if (c == 'f' || c == 'F')
     return column (0);
   else if (c == 'l' || c == 'L')
-    return column (nc - 1);
+    return column (cols () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -1811,90 +1304,170 @@
 }
 
 ComplexDiagMatrix
-ComplexDiagMatrix::inverse (int& info) const
-{
-  if (nr != nc)
-    {
-      (*current_liboctave_error_handler) ("inverse requires square matrix");
-      return DiagMatrix ();
-    }
-
-  info = 0;
-  for (int i = 0; i < len; i++)
-    {
-      if (data[i] == 0.0)
-	{
-	  info = -1;
-	  return *this;
-	}
-      else
-	data[i] = 1.0 / data[i];
-    }
-
-  return *this;
-}
-
-ComplexDiagMatrix
 ComplexDiagMatrix::inverse (void) const
 {
   int info;
   return inverse (info);
 }
 
+ComplexDiagMatrix
+ComplexDiagMatrix::inverse (int& info) const
+{
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != nc)
+    {
+      (*current_liboctave_error_handler) ("inverse requires square matrix");
+      return DiagMatrix ();
+    }
+
+  ComplexDiagMatrix retval (nr, nc);
+
+  info = 0;
+  for (int i = 0; i < length (); i++)
+    {
+      if (elem (i, i) == 0.0)
+	{
+	  info = -1;
+	  return *this;
+	}
+      else
+	retval.elem (i, i) = 1.0 / elem (i, i);
+    }
+
+  return *this;
+}
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::operator += (const DiagMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::operator -= (const DiagMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::operator += (const ComplexDiagMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexDiagMatrix&
+ComplexDiagMatrix::operator -= (const ComplexDiagMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), length ());
+  return *this;
+}
+
 // diagonal matrix by scalar -> matrix operations
 
 ComplexMatrix
-ComplexDiagMatrix::operator + (double s) const
+operator + (const ComplexDiagMatrix& a, double s)
 {
-  ComplexMatrix tmp (nr, nc, s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return a + tmp;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator - (double s) const
+operator - (const ComplexDiagMatrix& a, double s)
 {
-  ComplexMatrix tmp (nr, nc, -s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), -s);
+  return a + tmp;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator + (const Complex& s) const
+operator + (const ComplexDiagMatrix& a, const Complex& s)
 {
-  ComplexMatrix tmp (nr, nc, s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return a + tmp;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator - (const Complex& s) const
+operator - (const ComplexDiagMatrix& a, const Complex& s)
 {
-  ComplexMatrix tmp (nr, nc, -s);
-  return *this + tmp;
+  ComplexMatrix tmp (a.rows (), a.cols (), -s);
+  return a + tmp;
 }
 
 // diagonal matrix by scalar -> diagonal matrix operations
 
 ComplexDiagMatrix
-ComplexDiagMatrix::operator * (double s) const
+operator * (const ComplexDiagMatrix& a, double s)
 {
-  return ComplexDiagMatrix (multiply (data, len, s), nr, nc);
+  return ComplexDiagMatrix (multiply (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 ComplexDiagMatrix
-ComplexDiagMatrix::operator / (double s) const
-{
-  return ComplexDiagMatrix (divide (data, len, s), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator * (const Complex& s) const
+operator / (const ComplexDiagMatrix& a, double s)
 {
-  return ComplexDiagMatrix (multiply (data, len, s), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator / (const Complex& s) const
-{
-  return ComplexDiagMatrix (divide (data, len, s), nr, nc);
+  return ComplexDiagMatrix (divide (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 // scalar by diagonal matrix -> matrix operations
@@ -1902,25 +1475,29 @@
 ComplexMatrix
 operator + (double s, const ComplexDiagMatrix& a)
 {
-  return a + s;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp + a;
 }
 
 ComplexMatrix
 operator - (double s, const ComplexDiagMatrix& a)
 {
-  return -a + s;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp - a;
 }
 
 ComplexMatrix
 operator + (const Complex& s, const ComplexDiagMatrix& a)
 {
-  return a + s;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp + a;
 }
 
 ComplexMatrix
 operator - (const Complex& s, const ComplexDiagMatrix& a)
 {
-  return -a + s;
+  ComplexMatrix tmp (a.rows (), a.cols (), s);
+  return tmp - a;
 }
 
 // scalar by diagonal matrix -> diagonal matrix operations
@@ -1928,57 +1505,19 @@
 ComplexDiagMatrix
 operator * (double s, const ComplexDiagMatrix& a)
 {
-  return ComplexDiagMatrix (multiply (a.data, a.len, s), a.nr, a.nc);
-}
-
-ComplexDiagMatrix
- operator / (double s, const ComplexDiagMatrix& a)
-{
-  return ComplexDiagMatrix (divide (s, a.data, a.len), a.nr, a.nc);
-}
-
-ComplexDiagMatrix
- operator * (const Complex& s, const ComplexDiagMatrix& a)
-{
-  return ComplexDiagMatrix (multiply (a.data, a.len, s), a.nr, a.nc);
-}
-
-ComplexDiagMatrix
-operator / (const Complex& s, const ComplexDiagMatrix& a)
-{
-  return ComplexDiagMatrix (divide (s, a.data, a.len), a.nr, a.nc);
+  return ComplexDiagMatrix (multiply (a.data (), a.length (), s),
+			    a.rows (), a.cols ());
 }
 
 // diagonal matrix by column vector -> column vector operations
 
 ComplexColumnVector
-ComplexDiagMatrix::operator * (const ColumnVector& a) const
+operator * (const ComplexDiagMatrix& m, const ColumnVector& a)
 {
-  if (nc != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix muliplication attempted");
-      return ComplexColumnVector ();
-    }
-
-  if (nc == 0 || nr == 0)
-    return ComplexColumnVector (0);
-
-  ComplexColumnVector result (nr);
-
-  for (int i = 0; i < a.len; i++)
-    result.data[i] = a.data[i] * data[i];
-
-  for (i = a.len; i < nr; i++)
-    result.data[i] = 0.0;
-
-  return result;
-}
-
-ComplexColumnVector
-ComplexDiagMatrix::operator * (const ComplexColumnVector& a) const
-{
-  if (nc != a.len)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  int a_len = a.length ();
+  if (nc != a_len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix muliplication attempted");
@@ -1990,11 +1529,38 @@
 
   ComplexColumnVector result (nr);
 
-  for (int i = 0; i < a.len; i++)
-    result.data[i] = a.data[i] * data[i];
+  for (int i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
+
+  return result;
+}
 
-  for (i = a.len; i < nr; i++)
-    result.data[i] = 0.0;
+ComplexColumnVector
+operator * (const ComplexDiagMatrix& m, const ComplexColumnVector& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  int a_len = a.length ();
+  if (nc != a_len)
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix muliplication attempted");
+      return ComplexColumnVector ();
+    }
+
+  if (nc == 0 || nr == 0)
+    return ComplexColumnVector (0);
+
+  ComplexColumnVector result (nr);
+
+  for (int i = 0; i < a_len; i++)
+    result.elem (i) = a.elem (i) * m.elem (i, i);
+
+  for (i = a_len; i < nr; i++)
+    result.elem (i) = 0.0;
 
   return result;
 }
@@ -2002,9 +1568,11 @@
 // diagonal matrix by diagonal matrix -> diagonal matrix operations
 
 ComplexDiagMatrix
-ComplexDiagMatrix::operator + (const DiagMatrix& a) const
+operator + (const ComplexDiagMatrix& m, const DiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -2014,13 +1582,15 @@
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (add (data, a.data, len), nr , nc);
+  return ComplexDiagMatrix (add (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexDiagMatrix
-ComplexDiagMatrix::operator - (const DiagMatrix& a) const
+operator - (const ComplexDiagMatrix& m, const DiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -2030,77 +1600,16 @@
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (subtract (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator * (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix multiplication attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator + (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix addition attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (add (data, a.data, len), nr , nc);
+  return ComplexDiagMatrix (subtract (m.data (), a.data (), m.length ()),
+			    nr, nc);
 }
 
 ComplexDiagMatrix
-ComplexDiagMatrix::operator - (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix subtraction attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (subtract (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator * (const ComplexDiagMatrix& a) const
+product (const ComplexDiagMatrix& m, const DiagMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix multiplication attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::product (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix product attempted");
@@ -2110,131 +1619,18 @@
   if (nr == 0 || nc == 0)
     return ComplexDiagMatrix (nr, nc);
 
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::quotient (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::product (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix product attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix
-ComplexDiagMatrix::quotient (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return ComplexDiagMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexDiagMatrix (nr, nc);
-
-  return ComplexDiagMatrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator += (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator -= (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator += (const ComplexDiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexDiagMatrix&
-ComplexDiagMatrix::operator -= (const ComplexDiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
+  return ComplexDiagMatrix (multiply (m.data (), a.data (), m.length ()),
+			    nr, nc);
 }
 
 // diagonal matrix by matrix -> matrix operations
 
 ComplexMatrix
-ComplexDiagMatrix::operator + (const Matrix& a) const
+operator + (const ComplexDiagMatrix& m, const Matrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -2245,16 +1641,18 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator - (const Matrix& a) const
+operator - (const ComplexDiagMatrix& m, const Matrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -2265,50 +1663,54 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (-a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator * (const Matrix& a) const
+operator * (const ComplexDiagMatrix& m, const Matrix& a)
 {
-  if (nc != a.nr)
+  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 ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
-    return ComplexMatrix (nr, a.nc, 0.0);
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return ComplexMatrix (nr, a_nc, 0.0);
 
-  ComplexMatrix c (nr, a.nc);
+  ComplexMatrix c (nr, a_nc);
 
-  for (int i = 0; i < len; i++)
+  for (int i = 0; i < m.length (); i++)
     {
-      if (data[i] == 1.0)
+      if (m.elem (i, i) == 1.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  for (int j = 0; j < a_nc; j++)
 	    c.elem (i, j) = a.elem (i, j);
 	}
-      else if (data[i] == 0.0)
+      else if (m.elem (i, i) == 0.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  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) = data[i] * a.elem (i, j);
+	  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++)
+      for (int j = 0; j < a_nc; j++)
+	for (int i = a_nr; i < nr; i++)
 	  c.elem (i, j) = 0.0;
     }
 
@@ -2316,9 +1718,11 @@
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator + (const ComplexMatrix& a) const
+operator + (const ComplexDiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -2329,16 +1733,18 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator - (const ComplexMatrix& a) const
+operator - (const ComplexDiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nr != a.nr || nc != a.nc)
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -2349,63 +1755,61 @@
     return ComplexMatrix (nr, nc);
 
   ComplexMatrix result (-a);
-  for (int i = 0; i < len; i++)
-    result.elem (i, i) += data[i];
+  for (int i = 0; i < m.length (); i++)
+    result.elem (i, i) += m.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexDiagMatrix::operator * (const ComplexMatrix& a) const
+operator * (const ComplexDiagMatrix& m, const ComplexMatrix& a)
 {
-  if (nc != a.nr)
+  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 ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
-    return ComplexMatrix (nr, a.nc, 0.0);
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return ComplexMatrix (nr, a_nc, 0.0);
 
-  ComplexMatrix c (nr, a.nc);
+  ComplexMatrix c (nr, a_nc);
 
-  for (int i = 0; i < len; i++)
+  for (int i = 0; i < m.length (); i++)
     {
-      if (data[i] == 1.0)
+      if (m.elem (i, i) == 1.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  for (int j = 0; j < a_nc; j++)
 	    c.elem (i, j) = a.elem (i, j);
 	}
-      else if (data[i] == 0.0)
+      else if (m.elem (i, i) == 0.0)
 	{
-	  for (int j = 0; j < a.nc; j++)
+	  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) = data[i] * a.elem (i, j);
+	  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++)
+      for (int j = 0; j < a_nc; j++)
+	for (int i = a_nr; i < nr; i++)
 	  c.elem (i, j) = 0.0;
     }
 
   return c;
 }
 
-// unary operations
-
-ComplexDiagMatrix
-ComplexDiagMatrix::operator - (void) const
-{
-  return ComplexDiagMatrix (negate (data, len), nr, nc);
-}
+// other operations
 
 ComplexColumnVector
 ComplexDiagMatrix::diag (void) const
@@ -2418,8 +1822,8 @@
 ComplexColumnVector
 ComplexDiagMatrix::diag (int k) const
 {
-  int nnr = nr;
-  int nnc = nc;
+  int nnr = rows ();
+  int nnc = cols ();
   if (k > 0)
     nnc -= k;
   else if (k < 0)
@@ -2462,12 +1866,12 @@
 {
   Complex ZERO (0.0);
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.nr; i++)
+  for (int i = 0; i < a.rows (); i++)
     {
-      for (int j = 0; j < a.nc; j++)
+      for (int j = 0; j < a.cols (); j++)
 	{
 	  if (i == j)
-	    os << " " /* setw (field_width) */ << a.data[i];
+	    os << " " /* setw (field_width) */ << a.elem (i, i);
 	  else
 	    os << " " /* setw (field_width) */ << ZERO;
 	}
--- a/liboctave/FEGrid.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/FEGrid.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,10 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
+#include <iostream.h>
+
 #include "FEGrid.h"
 #include "lo-error.h"
 
--- a/liboctave/FEGrid.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/FEGrid.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,9 +24,7 @@
 #if !defined (_FEGrid_h)
 #define _FEGrid_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+class ostream;
 
 #include "Matrix.h"
 
--- a/liboctave/FSQP.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/FSQP.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,14 +21,12 @@
 
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifndef FSQP_MISSING
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include <iostream.h>
-#include <math.h>
 #include "FSQP.h"
 #include "f77-uscore.h"
 
--- a/liboctave/FSQP.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/FSQP.h	Tue Nov 30 20:23:04 1993 +0000
@@ -21,15 +21,12 @@
 
 */
 
-#ifndef FSQP_MISSING
-
 #if !defined (_FSQP_h)
 #define _FSQP_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+#ifndef FSQP_MISSING
 
+#include "Matrix.h"
 #include "NLP.h"
 
 #ifndef Vector
@@ -42,9 +39,9 @@
  private:
 };
 
-#endif
+#endif /* FSQP_MISSING */
 
-#endif /* FSQP_MISSING */
+#endif
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/LP.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LP.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include "LP.h"
--- a/liboctave/LP.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LP.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,13 +24,9 @@
 #if !defined (_LP_h)
 #define _LP_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
+#include "Matrix.h"
 #include "Bounds.h"
 #include "LinConst.h"
-#include "Matrix.h"
 
 #ifndef Vector
 #define Vector ColumnVector
--- a/liboctave/LPsolve.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LPsolve.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,14 +21,11 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
-#include <math.h>
 #include "LPsolve.h"
-#include "f77-uscore.h"
 
 Vector
 LPsolve::minimize (double& objf, int& inform, Vector& lambda)
--- a/liboctave/LPsolve.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LPsolve.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,7 @@
 #if !defined (_LPsolve_h)
 #define _LPsolve_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
+#include "Matrix.h"
 #include "LP.h"
 
 #ifndef Vector
--- a/liboctave/LSODE.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LSODE.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "ODE.h"
 #include "f77-uscore.h"
 #include "lo-error.h"
--- a/liboctave/LinConst.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LinConst.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <iostream.h>
+
 #include "LinConst.h"
 #include "lo-error.h"
 
--- a/liboctave/LinConst.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/LinConst.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,10 @@
 #if !defined (_LinConst_h)
 #define _LinConst_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+#include <float.h>
 
-#include <float.h>
+class ostream;
+
 #include "Matrix.h"
 #include "Bounds.h"
 
--- a/liboctave/Makefile.in	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Makefile.in	Tue Nov 30 20:23:04 1993 +0000
@@ -28,18 +28,19 @@
 	fi
 
 INCLUDES = Array.h Bounds.h CollocWt.h DAE.h DAEFunc.h FEGrid.h \
-	FSQP.h LinConst.h LP.h LPsolve.h Matrix.h NLConst.h NLEqn.h \
-	NLFunc.h NLP.h NPSOL.h ODE.h ODEFunc.h Objective.h QLD.h \
-	QP.h QPSOL.h Quad.h Range.h f77-uscore.h sun-utils.h \
-	lo-error.h
+	FSQP.h LinConst.h LP.h LPsolve.h MArray.h Matrix.h NLConst.h \
+	NLEqn.h NLFunc.h NLP.h NPSOL.h ODE.h ODEFunc.h Objective.h \
+	QLD.h QP.h QPSOL.h Quad.h Range.h mx-kludge.h lo-error.h \
+	f77-uscore.h sun-utils.h
 
-SOURCES = Bounds.cc ColVector.cc CollocWt.cc DAE.cc DAEFunc.cc \
-	DiagMatrix.cc FEGrid.cc FSQP.cc LinConst.cc LP.cc LPsolve.cc \
-	Matrix-ext.cc Matrix.cc NLConst.cc NLEqn.cc NLFunc.cc NPSOL.cc \
-	Objective.cc ODE.cc ODEFunc.cc QLD.cc QP.cc QPSOL.cc Quad.cc \
-	Range.cc RowVector.cc sun-utils.cc lo-error.cc
+SOURCES = Array.cc Bounds.cc ColVector.cc CollocWt.cc DAE.cc \
+	DAEFunc.cc DiagMatrix.cc FEGrid.cc FSQP.cc LinConst.cc LP.cc \
+	LPsolve.cc Matrix-ext.cc Matrix.cc NLConst.cc NLEqn.cc \
+	NLFunc.cc NPSOL.cc Objective.cc ODE.cc ODEFunc.cc QLD.cc \
+	QP.cc QPSOL.cc Quad.cc Range.cc RowVector.cc lo-error.cc \
+	sun-utils.cc
 
-EXTRAS = mx-inlines.cc Array.cc
+EXTRAS = MArray.cc mx-kludge.cc mx-inlines.cc
 
 DISTFILES = Makefile.in $(SOURCES) $(INCLUDES) $(EXTRAS)
 
--- a/liboctave/Matrix-ext.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Matrix-ext.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,10 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
+#include <iostream.h>
+
 #include "Matrix.h"
 #include "mx-inlines.cc"
 #include "lo-error.h"
@@ -159,13 +161,14 @@
 int
 AEPBALANCE::init (const Matrix& a, const char *balance_job)
 {
-  if (a.nr != a.nc)
+  int a_nc = a.cols ();
+  if (a.rows () != a_nc)
     {
       (*current_liboctave_error_handler) ("AEPBALANCE requires square matrix");
       return -1;
     }
 
-  int n = a.nc;
+  int n = a_nc;
 
 // Parameters for balance call.
 
@@ -199,7 +202,7 @@
 ComplexAEPBALANCE::init (const ComplexMatrix& a, const char *balance_job)
 {
 
-  int n = a.nc;
+  int n = a.cols ();
 
 // Parameters for balance call.
 
@@ -222,7 +225,7 @@
     balancing_mat (i, i) = 1.0;
 
   F77_FCN (zgebak) (balance_job, "R", &n, &ilo, &ihi, scale, &n, 
-		    balancing_mat.fortran_vec(), &n, &info, 1L, 1L);
+		    balancing_mat.fortran_vec (), &n, &info, 1L, 1L);
 
   delete [] scale;
 
@@ -236,14 +239,17 @@
 int
 GEPBALANCE::init (const Matrix& a, const Matrix& b, const char *balance_job)
 {
-  if (a.nr != a.nc || a.nr != b.nr || b.nr != b.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  int b_nr = b.rows ();
+  if (a_nr != a_nc || a_nr != b_nr || b_nr != b.cols ())
     {
       (*current_liboctave_error_handler)
 	("GEPBALANCE requires square matrices of the same size");
       return -1;
     }
 
-  int n = a.nc;
+  int n = a_nc;
 
 // Parameters for balance call.
 
@@ -276,7 +282,7 @@
 
 // Initialize balancing matrices to identity.
 
-  left_balancing_mat = Matrix(n,n,0.0);
+  left_balancing_mat = Matrix (n, n, 0.0);
   for (int i = 0; i < n; i++)
     left_balancing_mat (i, i) = 1.0;
 
@@ -315,7 +321,7 @@
       for (int tmp = ilo-1; tmp < ihi; tmp++)
 	{
 	  cscale[tmp] = 0.0;
-	  wk.elem(tmp,0) = 0.0;
+	  wk.elem (tmp, 0) = 0.0;
 	}
     }
 
@@ -323,8 +329,8 @@
 
   for (int tmp = ilo-1; tmp < ihi; tmp++)
     {
-      cscale[tmp] = pow(2.0,cscale[tmp]);
-      wk.elem(tmp,0) = pow(2.0,-wk.elem(tmp,0));
+      cscale[tmp] = pow (2.0, cscale[tmp]);
+      wk.elem (tmp, 0) = pow (2.0, -wk.elem (tmp, 0));
     }
 
 // Column permutations/scaling.
@@ -366,7 +372,9 @@
 int
 CHOL::init (const Matrix& a)
 {
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr != a_nc)
     {
       (*current_liboctave_error_handler) ("CHOL requires square matrix");
       return -1;
@@ -374,10 +382,10 @@
 
   char uplo = 'U';
 
-  int n = a.nc;
+  int n = a_nc;
   int info;
 
-  double *h = dup (a.data, a.len);
+  double *h = dup (a.data (), a.length ());
 
   F77_FCN (dpotrf) (&uplo, &n, h, &n, &info, 1L);
 
@@ -387,19 +395,19 @@
 // that matter :-)), please let me know!
 
   if (n > 1)
-    for (int j = 0; j < a.nc; j++)
-      for (int i = j+1; i < a.nr; i++)
+    for (int j = 0; j < a_nc; j++)
+      for (int i = j+1; i < a_nr; i++)
         chol_mat.elem (i, j) = 0.0;
 
-
   return info;
 }
 
-
 int
 ComplexCHOL::init (const ComplexMatrix& a)
 {
-   if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+   if (a_nr != a_nc)
      {
        (*current_liboctave_error_handler)
 	 ("ComplexCHOL requires square matrix");
@@ -408,10 +416,10 @@
 
    char uplo = 'U';
 
-   int n = a.nc;
+   int n = a_nc;
    int info;
 
-   Complex *h = dup (a.data, a.len);
+   Complex *h = dup (a.data (), a.length ());
 
    F77_FCN (zpotrf) (&uplo, &n, h, &n, &info, 1L);
 
@@ -421,14 +429,13 @@
 // that matter :-)), please let me know!
 
   if (n > 1)
-    for (int j = 0; j < a.nc; j++)
-      for (int i = j+1; i < a.nr; i++)
+    for (int j = 0; j < a_nc; j++)
+      for (int i = j+1; i < a_nr; i++)
         chol_mat.elem (i, j) = 0.0;
 
    return info;
 }
 
-
 /*
  * HESS stuff
  */
@@ -436,7 +443,9 @@
 int
 HESS::init (const Matrix& a)
 {
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr != a_nc)
     {
       (*current_liboctave_error_handler) ("HESS requires square matrix");
       return -1;
@@ -445,13 +454,13 @@
   char jobbal = 'N';
   char side = 'R';
 
-  int n = a.nc;
+  int n = a_nc;
   int lwork = 32 * n;
   int info;
   int ilo;
   int ihi;
 
-  double *h = dup(a.data, a.len);
+  double *h = dup (a.data (), a.length ());
 
   double *tau = new double [n+1];
   double *scale = new double [n];
@@ -464,7 +473,7 @@
   F77_FCN (dgehrd) (&n, &ilo, &ihi, h, &n, tau, work, &lwork, &info,
 		    1L, 1L);
 
-  copy(z,h,n*n);
+  copy (z, h, n*n);
 
   F77_FCN (dorghr) (&n, &ilo, &ihi, z, &n, tau, work, &lwork, &info,
 		    1L, 1L);
@@ -475,16 +484,16 @@
 // We need to clear out all of the area below the sub-diagonal which was used
 // to store the unitary matrix.
 
-  hess_mat = Matrix(h,n,n);
-  unitary_hess_mat = Matrix(z,n,n);
+  hess_mat = Matrix (h, n, n);
+  unitary_hess_mat = Matrix (z, n, n);
 
 // If someone thinks of a more graceful way of doing this (or faster for 
 // that matter :-)), please let me know! 
 
   if (n > 2)
-    for (int j = 0; j < a.nc; j++)
-      for (int i = j+2; i < a.nr; i++)
-        hess_mat.elem(i,j) = 0;
+    for (int j = 0; j < a_nc; j++)
+      for (int i = j+2; i < a_nr; i++)
+        hess_mat.elem (i, j) = 0;
 
   delete [] tau;
   delete [] work;
@@ -493,11 +502,12 @@
   return info;
 }
 
-
 int
 ComplexHESS::init (const ComplexMatrix& a)
 {
-   if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+   if (a_nr != a_nc)
      {
        (*current_liboctave_error_handler)
 	 ("ComplexHESS requires square matrix");
@@ -507,13 +517,13 @@
    char job = 'N';
    char side = 'R';
 
-   int n = a.nc;
+   int n = a_nc;
    int lwork = 32 * n;
    int info;
    int ilo;
    int ihi;
 
-   Complex *h = dup(a.data,a.len);
+   Complex *h = dup (a.data (), a.length ());
 
    double *scale = new double [n];
    Complex *tau = new Complex [n-1];
@@ -525,7 +535,7 @@
    F77_FCN (zgehrd) (&n, &ilo, &ihi, h, &n, tau, work, &lwork, &info, 1L,
 		     1L);
 
-   copy(z,h,n*n);
+   copy (z, h, n*n);
 
    F77_FCN (zunghr) (&n, &ilo, &ihi, z, &n, tau, work, &lwork, &info, 1L,
 		     1L);
@@ -540,9 +550,9 @@
 // that matter :-)), please let me know!
 
    if (n > 2)
-     for (int j = 0; j < a.nc; j++)
-       for (int i = j+2; i < a.nr; i++)
-         hess_mat.elem(i,j) = 0;
+     for (int j = 0; j < a_nc; j++)
+       for (int i = j+2; i < a_nr; i++)
+         hess_mat.elem (i, j) = 0;
 
    delete [] work;
    delete [] tau;
@@ -573,7 +583,9 @@
 int
 SCHUR::init (const Matrix& a, const char *ord)
 {
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr != a_nc)
     {
       (*current_liboctave_error_handler) ("SCHUR requires square matrix");
       return -1;
@@ -589,7 +601,7 @@
 
   char sense = 'N';
 
-  int n = a.nc;
+  int n = a_nc;
   int lwork = 8 * n;
   int liwork = 1;
   int info;
@@ -597,7 +609,7 @@
   double rconde;
   double rcondv;
 
-  double *s = dup(a.data,a.len);
+  double *s = dup (a.data (), a.length ());
 
   double *wr = new double [n];
   double *wi = new double [n];
@@ -635,7 +647,6 @@
 			1L, 1L);
     }
 
-
   schur_mat = Matrix (s, n, n);
   unitary_mat = Matrix (q, n, n);
 
@@ -651,7 +662,7 @@
 static int
 complex_select_ana (Complex *a)
 {
-  return (real (*a) < 0.0);
+  return a->real () < 0.0;
 }
 
 static int
@@ -663,7 +674,9 @@
 int
 ComplexSCHUR::init (const ComplexMatrix& a, const char *ord)
 {
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr != a_nc)
     {
       (*current_liboctave_error_handler)
 	("ComplexSCHUR requires square matrix");
@@ -679,7 +692,7 @@
 
   char sense = 'N';
 
-  int n = a.nc;
+  int n = a_nc;
   int lwork = 8 * n;
   int info;
   int sdim;
@@ -694,7 +707,7 @@
   if (*ord == 'A' || *ord == 'D' || *ord == 'a' || *ord == 'd')
     bwork = new int [n];
 
-  Complex *s = dup(a.data,a.len);
+  Complex *s = dup (a.data (), a.length ());
 
   Complex *work = new Complex [lwork];
   Complex *q = new Complex [n*n];
@@ -748,13 +761,13 @@
 {
   int info;
 
-  int m = a.nr;
-  int n = a.nc;
+  int m = a.rows ();
+  int n = a.cols ();
 
   char jobu = 'A';
   char jobv = 'A';
 
-  double *tmp_data = dup (a.data, a.len);
+  double *tmp_data = dup (a.data (), a.length ());
 
   int min_mn = m < n ? m : n;
   int max_mn = m > n ? m : n;
@@ -797,13 +810,13 @@
 {
   int info;
 
-  int m = a.nr;
-  int n = a.nc;
+  int m = a.rows ();
+  int n = a.cols ();
 
   char jobu = 'A';
   char jobv = 'A';
 
-  Complex *tmp_data = dup (a.data, a.len);
+  Complex *tmp_data = dup (a.data (), a.length ());
 
   int min_mn = m < n ? m : n;
   int max_mn = m > n ? m : n;
@@ -833,26 +846,91 @@
 }
 
 /*
+ * DET stuff.
+ */
+
+int
+DET::value_will_overflow (void) const
+{
+  return det[2] + 1 > log10 (MAXDOUBLE) ? 1 : 0;
+}
+
+int
+DET::value_will_underflow (void) const
+{
+  return det[2] - 1 < log10 (MINDOUBLE) ? 1 : 0;
+}
+
+double
+DET::coefficient (void) const
+{
+  return det[0];
+}
+
+int
+DET::exponent (void) const
+{
+  return (int) det[1];
+}
+
+double
+DET::value (void) const
+{
+  return det[0] * pow (10.0, det[1]);
+}
+
+int
+ComplexDET::value_will_overflow (void) const
+{
+  return det[2].real () + 1 > log10 (MAXDOUBLE) ? 1 : 0;
+}
+
+int
+ComplexDET::value_will_underflow (void) const
+{
+  return det[2].real () - 1 < log10 (MINDOUBLE) ? 1 : 0;
+}
+
+Complex
+ComplexDET::coefficient (void) const
+{
+  return det[0];
+}
+
+int
+ComplexDET::exponent (void) const
+{
+  return (int) (det[1].real ());
+}
+
+Complex
+ComplexDET::value (void) const
+{
+  return det[0] * pow (10.0, det[1].real ());
+}
+
+/*
  * EIG stuff.
  */
 
 int
 EIG::init (const Matrix& a)
 {
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  if (a_nr != a.cols ())
     {
       (*current_liboctave_error_handler) ("EIG requires square matrix");
       return -1;
     }
 
-  int n = a.nr;
+  int n = a_nr;
 
   int info;
 
   char jobvl = 'N';
   char jobvr = 'V';
 
-  double *tmp_data = dup (a.data, a.len);
+  double *tmp_data = dup (a.data (), a.length ());
   double *wr = new double[n];
   double *wi = new double[n];
   Matrix vr (n, n);
@@ -909,14 +987,14 @@
 int
 EIG::init (const ComplexMatrix& a)
 {
-
-  if (a.nr != a.nc)
+  int a_nr = a.rows ();
+  if (a_nr != a.cols ())
     {
       (*current_liboctave_error_handler) ("EIG requires square matrix");
       return -1;
     }
 
-  int n = a.nr;
+  int n = a_nr;
 
   int info;
 
@@ -929,7 +1007,7 @@
   Complex *pw = lambda.fortran_vec ();
   Complex *pvr = v.fortran_vec ();
 
-  Complex *tmp_data = dup (a.data, a.len);
+  Complex *tmp_data = dup (a.data (), a.length ());
 
   int lwork = 8*n;
   Complex *work = new Complex[lwork];
@@ -955,17 +1033,19 @@
 
 LU::LU (const Matrix& a)
 {
-  if (a.nr == 0 || a.nc == 0 || a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr == 0 || a_nc == 0 || a_nr != a_nc)
     {
       (*current_liboctave_error_handler) ("LU requires square matrix");
       return;
     }
 
-  int n = a.nr;
+  int n = a_nr;
 
   int *ipvt = new int [n];
   int *pvt = new int [n];
-  double *tmp_data = dup (a.data, a.len);
+  double *tmp_data = dup (a.data (), a.length ());
   int info = 0;
   int zero = 0;
   double b;
@@ -1017,17 +1097,19 @@
 
 ComplexLU::ComplexLU (const ComplexMatrix& a)
 {
-  if (a.nr == 0 || a.nc == 0 || a.nr != a.nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (a_nr == 0 || a_nc == 0 || a_nr != a_nc)
     {
       (*current_liboctave_error_handler) ("ComplexLU requires square matrix");
       return;
     }
 
-  int n = a.nr;
+  int n = a_nr;
 
   int *ipvt = new int [n];
   int *pvt = new int [n];
-  Complex *tmp_data = dup (a.data, a.len);
+  Complex *tmp_data = dup (a.data (), a.length ());
   int info = 0;
   int zero = 0;
   Complex b;
@@ -1083,8 +1165,8 @@
 
 QR::QR (const Matrix& a)
 {
-  int m = a.nr;
-  int n = a.nc;
+  int m = a.rows ();
+  int n = a.cols ();
 
   if (m == 0 || n == 0)
     {
@@ -1102,10 +1184,10 @@
   if (m > n)
     {
       tmp_data = new double [m*m];
-      copy (tmp_data, a.data, a.len);
+      copy (tmp_data, a.data (), a.length ());
     }
   else
-   tmp_data = dup (a.data, a.len);
+    tmp_data = dup (a.data (), a.length ());
 
   F77_FCN (dgeqrf) (&m, &n, tmp_data, &m, tau, work, &lwork, &info);
 
@@ -1132,8 +1214,8 @@
 
 ComplexQR::ComplexQR (const ComplexMatrix& a)
 {
-  int m = a.nr;
-  int n = a.nc;
+  int m = a.rows ();
+  int n = a.cols ();
 
   if (m == 0 || n == 0)
     {
@@ -1152,10 +1234,10 @@
   if (m > n)
     {
       tmp_data = new Complex [m*m];
-      copy (tmp_data, a.data, a.len);
+      copy (tmp_data, a.data (), a.length ());
     }
   else
-   tmp_data = dup (a.data, a.len);
+    tmp_data = dup (a.data (), a.length ());
 
   F77_FCN (zgeqrf) (&m, &n, tmp_data, &m, tau, work, &lwork, &info);
 
--- a/liboctave/Matrix.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Matrix.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,11 @@
 
 */
 
-// I\'m not sure how this is supposed to work if the .h file declares
-// several classes, each of which is defined in a separate file...
-//
-// #ifdef __GNUG__
-// #pragma implementation
-// #endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream.h>
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
@@ -114,145 +113,85 @@
   int F77_FCN (cfftb) (const int*, Complex*, Complex*);
 }
 
+// Since this is only temporary, put all of this here, rather than
+// putting each type where it logically belongs.  This way, it will be
+// easier to delete.
+
+#define KLUDGE_MATRICES
+#define TYPE double
+#define KL_MAT_TYPE Matrix
+#include "mx-kludge.cc"
+#undef KLUDGE_MATRICES
+#undef TYPE
+#undef KL_MAT_TYPE
+
+#define KLUDGE_VECTORS
+#define TYPE double
+#define KL_VEC_TYPE ColumnVector
+#include "mx-kludge.cc"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
+
+#define KLUDGE_VECTORS
+#define TYPE double
+#define KL_VEC_TYPE RowVector
+#include "mx-kludge.cc"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
+
+#define KLUDGE_DIAG_MATRICES
+#define TYPE double
+#define KL_DMAT_TYPE DiagMatrix
+#include "mx-kludge.cc"
+#undef KLUDGE_DIAG_MATRICES
+#undef TYPE
+#undef KL_DMAT_TYPE
+
+#define KLUDGE_MATRICES
+#define TYPE Complex
+#define KL_MAT_TYPE ComplexMatrix
+#include "mx-kludge.cc"
+#undef KLUDGE_MATRICES
+#undef TYPE
+#undef KL_MAT_TYPE
+
+#define KLUDGE_VECTORS
+#define TYPE Complex
+#define KL_VEC_TYPE ComplexColumnVector
+#include "mx-kludge.cc"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
+
+#define KLUDGE_VECTORS
+#define TYPE Complex
+#define KL_VEC_TYPE ComplexRowVector
+#include "mx-kludge.cc"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
+
+#define KLUDGE_DIAG_MATRICES
+#define TYPE Complex
+#define KL_DMAT_TYPE ComplexDiagMatrix
+#include "mx-kludge.cc"
+#undef KLUDGE_DIAG_MATRICES
+#undef TYPE
+#undef KL_DMAT_TYPE
+
 /*
  * Matrix class.
  */
 
-Matrix::Matrix (int r, int c)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't construct matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = nr * nc;
-  if (len > 0)
-    data = new double [len];
-  else
-    data = (double *) NULL;
-}
-
-Matrix::Matrix (int r, int c, double val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't construct matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, len, val);
-    }
-  else
-    data = (double *) NULL;
-}
-
-Matrix::Matrix (const Matrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-Matrix::Matrix (const DiagMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, len, 0.0);
-      for (int i = 0; i < a.len; i++)
-	data[nr*i+i] = a.data[i];
-    }
-  else
-    data = (double *) NULL;
-}
-
-Matrix::Matrix (double a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new double [1];
-  data[0] = a;
-}
-
-Matrix&
-Matrix::operator = (const Matrix& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      nr = a.nr;
-      nc = a.nc;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new double [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (double *) NULL;
-    }
-  return *this;
-}
-
-double&
-Matrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static double foo = 0.0;
-      return foo;
-    }
-#endif
-
-  return elem (r, c);
-}
-
-double
-Matrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return 0.0;
-    }
-#endif
-
-  return elem (r, c);
-}
-
+Matrix::Matrix (const DiagMatrix& a) : Array2<double> (a.rows (), a.cols ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+#if 0
 Matrix&
 Matrix::resize (int r, int c)
 {
@@ -323,14 +262,15 @@
 
   return *this;
 }
+#endif
 
 int
 Matrix::operator == (const Matrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
+  if (rows () != a.rows () || cols () != a.cols ())
     return 0;
 
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), length ());
 }
 
 int
@@ -342,14 +282,17 @@
 Matrix&
 Matrix::insert (const Matrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  int a_rows = a.rows ();
+  int a_cols = a.cols ();
+  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 j = 0; j < a.nc; j++)
-    for (int i = 0; i < a.nr; i++)
+  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;
@@ -358,14 +301,15 @@
 Matrix&
 Matrix::insert (const RowVector& a, int r, int c)
 {
-  if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r, c+i) = a.elem (i);
 
   return *this;
 }
@@ -373,14 +317,15 @@
 Matrix&
 Matrix::insert (const ColumnVector& a, int r, int c)
 {
-  if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i, c) = a.elem (i);
 
   return *this;
 }
@@ -388,14 +333,15 @@
 Matrix&
 Matrix::insert (const DiagMatrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  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.len; i++)
-    elem (r+i, c+i) = a.data[i];
+  for (int i = 0; i < a.length (); i++)
+    elem (r+i, c+i) = a.elem (i, i);
 
   return *this;
 }
@@ -403,14 +349,21 @@
 Matrix&
 Matrix::fill (double val)
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nr > 0 && nc > 0)
-    copy (data, len, val);
+    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 = rows ();
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
     {
@@ -431,14 +384,16 @@
 Matrix
 Matrix::append (const Matrix& a) const
 {
-  if (nr != a.nr)
+  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.nc);
+  Matrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -447,6 +402,8 @@
 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");
@@ -454,7 +411,7 @@
     }
 
   int nc_insert = nc;
-  Matrix retval (nr, nc + a.len);
+  Matrix retval (nr, nc + a.length ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -463,7 +420,9 @@
 Matrix
 Matrix::append (const ColumnVector& a) const
 {
-  if (nr != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.length ())
     {
       (*current_liboctave_error_handler) ("row dimension mismatch for append");
       return Matrix ();
@@ -479,14 +438,16 @@
 Matrix
 Matrix::append (const DiagMatrix& a) const
 {
-  if (nr != a.nr)
+  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.nc);
+  Matrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -495,7 +456,9 @@
 Matrix
 Matrix::stack (const Matrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -503,7 +466,7 @@
     }
 
   int nr_insert = nr;
-  Matrix retval (nr + a.nr, nc);
+  Matrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -512,7 +475,9 @@
 Matrix
 Matrix::stack (const RowVector& a) const
 {
-  if (nc != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.length ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -529,6 +494,8 @@
 Matrix
 Matrix::stack (const ColumnVector& a) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nc != 1)
     {
       (*current_liboctave_error_handler)
@@ -537,7 +504,7 @@
     }
 
   int nr_insert = nr;
-  Matrix retval (nr + a.len, nc);
+  Matrix retval (nr + a.length (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -546,7 +513,9 @@
 Matrix
 Matrix::stack (const DiagMatrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -554,7 +523,7 @@
     }
 
   int nr_insert = nr;
-  Matrix retval (nr + a.nr, nc);
+  Matrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -563,12 +532,14 @@
 Matrix
 Matrix::transpose (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   Matrix result (nc, nr);
-  if (len > 0)
+  if (length () > 0)
     {
       for (int j = 0; j < nc; j++)
 	for (int i = 0; i < nr; i++)
-	  result.data[nc*i+j] = data[nr*j+i];
+	  result.elem (j, i) = elem (i, j);
     }
   return result;
 }
@@ -586,7 +557,7 @@
 
   for (int j = 0; j < new_c; j++)
     for (int i = 0; i < new_r; i++)
-      result.data[new_r*j+i] = elem (r1+i, c1+j);
+      result.elem (i, j) = elem (r1+i, c1+j);
 
   return result;
 }
@@ -596,7 +567,8 @@
 RowVector
 Matrix::row (int i) const
 {
-  if (i < 0 || i >= nr)
+  int nc = cols ();
+  if (i < 0 || i >= rows ())
     {
       (*current_liboctave_error_handler) ("invalid row selection");
       return RowVector ();
@@ -622,7 +594,7 @@
   if (c == 'f' || c == 'F')
     return row (0);
   else if (c == 'l' || c == 'L')
-    return row (nr - 1);
+    return row (rows () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -633,7 +605,8 @@
 ColumnVector
 Matrix::column (int i) const
 {
-  if (i < 0 || i >= nc)
+  int nr = rows ();
+  if (i < 0 || i >= cols ())
     {
       (*current_liboctave_error_handler) ("invalid column selection");
       return ColumnVector ();
@@ -659,7 +632,7 @@
   if (c == 'f' || c == 'F')
     return column (0);
   else if (c == 'l' || c == 'L')
-    return column (nc - 1);
+    return column (cols () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -668,8 +641,26 @@
 }
 
 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");
@@ -680,14 +671,14 @@
 
   int *ipvt = new int [nr];
   double *z = new double [nr];
-  double *tmp_data = dup (data, len);
+  double *tmp_data = dup (data (), len);
 
   F77_FCN (dgeco) (tmp_data, &nr, &nc, ipvt, &rcond, z);
 
   if (rcond + 1.0 == 1.0)
     {
       info = -1;
-      copy (tmp_data, data, len);  // Restore matrix contents.
+      copy (tmp_data, data (), len);  // Restore matrix contents.
     }
   else
     {
@@ -703,24 +694,11 @@
   return Matrix (tmp_data, nr, nc);
 }
 
-Matrix
-Matrix::inverse (int& info) const
-{
-  double rcond;
-  return inverse (info, rcond);
-}
-
-Matrix
-Matrix::inverse (void) const
-{
-  int info;
-  double rcond;
-  return inverse (info, rcond);
-}
-
 ComplexMatrix
 Matrix::fourier (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   int npts, nsamples;
   if (nr == 1 || nc == 1)
     {
@@ -735,7 +713,7 @@
 
   int nn = 4*npts+15;
   Complex *wsave = new Complex [nn];
-  Complex *tmp_data = make_complex (data, len);
+  Complex *tmp_data = make_complex (data (), length ());
 
   F77_FCN (cffti) (&npts, wsave);
 
@@ -750,6 +728,8 @@
 ComplexMatrix
 Matrix::ifourier (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   int npts, nsamples;
   if (nr == 1 || nc == 1)
     {
@@ -764,7 +744,7 @@
 
   int nn = 4*npts+15;
   Complex *wsave = new Complex [nn];
-  Complex *tmp_data = make_complex (data, len);
+  Complex *tmp_data = make_complex (data (), length ());
 
   F77_FCN (cffti) (&npts, wsave);
 
@@ -799,6 +779,8 @@
 {
   DET retval;
 
+  int nr = rows ();
+  int nc = cols ();
   if (nr == 0 || nc == 0)
     {
       double d[2];
@@ -811,7 +793,7 @@
   int *ipvt = new int [nr];
 
   double *z = new double [nr];
-  double *tmp_data = dup (data, len);
+  double *tmp_data = dup (data (), length ());
 
   F77_FCN (dgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -854,7 +836,9 @@
 {
   Matrix retval;
 
-  if (nr == 0 || nc == 0 || nr != nc || nr != b.nr)
+  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");
@@ -865,7 +849,7 @@
   int *ipvt = new int [nr];
 
   double *z = new double [nr];
-  double *tmp_data = dup (data, len);
+  double *tmp_data = dup (data (), length ());
 
   F77_FCN (dgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -877,12 +861,13 @@
     {
       int job = 0;
 
-      double *result = dup (b.data, b.len);
-
-      for (int j = 0; j < b.nc; j++)
+      double *result = dup (b.data (), b.length ());
+
+      int b_nc = b.cols ();
+      for (int j = 0; j < b_nc; j++)
 	F77_FCN (dgesl) (tmp_data, &nr, &nr, ipvt, &result[nr*j], &job);
 
-      retval = Matrix (result, b.nr, b.nc);
+      retval = Matrix (result, b.rows (), b_nc);
     }
 
   delete [] tmp_data;
@@ -916,8 +901,7 @@
 ColumnVector
 Matrix::solve (const ColumnVector& b) const
 {
-  int info;
-  double rcond;
+  int info; double rcond;
   return solve (b, info, rcond);
 }
 
@@ -933,7 +917,9 @@
 {
   ColumnVector retval;
 
-  if (nr == 0 || nc == 0 || nr != nc || nr != b.len)
+  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");
@@ -944,7 +930,7 @@
   int *ipvt = new int [nr];
 
   double *z = new double [nr];
-  double *tmp_data = dup (data, len);
+  double *tmp_data = dup (data (), length ());
 
   F77_FCN (dgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -956,11 +942,13 @@
     {
       int job = 0;
 
-      double *result = dup (b.data, b.len);
+      int b_len = b.length ();
+
+      double *result = dup (b.data (), b_len);
 
       F77_FCN (dgesl) (tmp_data, &nr, &nr, ipvt, result, &job);
 
-      retval = ColumnVector (result, b.len);
+      retval = ColumnVector (result, b_len);
     }
 
   delete [] tmp_data;
@@ -1009,19 +997,19 @@
 Matrix
 Matrix::lssolve (const Matrix& b, int& info, int& rank) const
 {
-  int nrhs = b.nc;
-
-  int m = nr;
-  int n = nc;
-
-  if (m == 0 || n == 0 || m != b.nr)
+  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, len);
+  double *tmp_data = dup (data (), length ());
 
   int nrr = m > n ? m : n;
   Matrix result (nrr, nrhs);
@@ -1070,22 +1058,21 @@
 Matrix::lssolve (const ComplexMatrix& b, int& info) const
 {
   ComplexMatrix tmp (*this);
-  return tmp.lssolve (b, info);
+  return tmp.lssolve (b);
 }
 
 ComplexMatrix
 Matrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const
 {
   ComplexMatrix tmp (*this);
-  return tmp.lssolve (b, info, rank);
+  return tmp.lssolve (b);
 }
 
 ColumnVector
 Matrix::lssolve (const ColumnVector& b) const
 {
   int info;
-  int rank;
-  return lssolve (b, info, rank);
+  int rank; return lssolve (b, info, rank);
 }
 
 ColumnVector
@@ -1100,17 +1087,17 @@
 {
   int nrhs = 1;
 
-  int m = nr;
-  int n = nc;
-
-  if (m == 0 || n == 0 || m != b.len)
+  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, len);
+  double *tmp_data = dup (data (), length ());
 
   int nrr = m > n ? m : n;
   ColumnVector result (nrr);
@@ -1167,88 +1154,167 @@
   return tmp.lssolve (b, info, rank);
 }
 
-// matrix by scalar -> matrix operations.
-
-Matrix
-Matrix::operator + (double s) const
-{
-  return Matrix (add (data, len, s), nr, nc);
-}
-
-Matrix
-Matrix::operator - (double s) const
-{
-  return Matrix (subtract (data, len, s), nr, nc);
-}
+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 * (double s) const
-{
-  return Matrix (multiply (data, len, s), nr, nc);
-}
-
-Matrix
-Matrix::operator / (double s) const
-{
-  return Matrix (divide (data, len, s), nr, nc);
-}
+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;
+}
+
+// matrix by scalar -> matrix operations.
 
 ComplexMatrix
-Matrix::operator + (const Complex& s) const
-{
-  return ComplexMatrix (add (data, len, s), nr, nc);
+operator + (const Matrix& a, const Complex& s)
+{
+  return ComplexMatrix (add (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-Matrix::operator - (const Complex& s) const
-{
-  return ComplexMatrix (subtract (data, len, s), nr, nc);
+operator - (const Matrix& a, const Complex& s)
+{
+  return ComplexMatrix (subtract (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-Matrix::operator * (const Complex& s) const
-{
-  return ComplexMatrix (multiply (data, len, s), nr, nc);
+operator * (const Matrix& a, const Complex& s)
+{
+  return ComplexMatrix (multiply (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-Matrix::operator / (const Complex& s) const
-{
-  return ComplexMatrix (divide (data, len, s), nr, nc);
-}
-
-// scalar by matrix -> matrix operations
-
-Matrix
-operator + (double s, const Matrix& a)
-{
-  return Matrix (add (a.data, a.len, s), a.nr, a.nc);
-}
-
-Matrix
-operator - (double s, const Matrix& a)
-{
-  return Matrix (subtract (s, a.data, a.len), a.nr, a.nc);
-}
-
-Matrix
-operator * (double s, const Matrix& a)
-{
-  return Matrix (multiply (a.data, a.len, s), a.nr, a.nc);
-}
-
-Matrix
-operator / (double s, const Matrix& a)
-{
-  return Matrix (divide (s, a.data, a.len), a.nr, a.nc);
+operator / (const Matrix& a, const Complex& s)
+{
+  return ComplexMatrix (divide (a.data (), a.length (), s),
+			a.rows (), a.cols ());
+}
+
+// scalar by matrix -> matrix operations.
+
+ComplexMatrix
+operator + (const Complex& s, const Matrix& a)
+{
+  assert (0);
+  return ComplexMatrix ();
+}
+
+ComplexMatrix
+operator - (const Complex& s, const Matrix& a)
+{
+  assert (0);
+  return ComplexMatrix ();
+}
+
+ComplexMatrix
+operator * (const Complex& s, const Matrix& a)
+{
+  assert (0);
+  return ComplexMatrix ();
+}
+
+ComplexMatrix
+operator / (const Complex& s, const Matrix& a)
+{
+  assert (0);
+  return ComplexMatrix ();
 }
 
 // matrix by column vector -> column vector operations
 
 ColumnVector
-Matrix::operator * (const ColumnVector& a) const
-{
-  if (nc != a.len)
+operator * (const Matrix& m, const ColumnVector& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nc != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix multiplication attempted");
@@ -1266,25 +1332,27 @@
 
   double *y = new double [nr];
 
-  F77_FCN (dgemv) (&trans, &nr, &nc, &alpha, data, &ld, a.data,
+  F77_FCN (dgemv) (&trans, &nr, &nc, &alpha, m.data (), &ld, a.data (),
 		   &i_one, &beta, y, &i_one, 1L); 
 
   return ColumnVector (y, nr);
 }
 
 ComplexColumnVector
-Matrix::operator * (const ComplexColumnVector& a) const
-{
-  ComplexMatrix tmp (*this);
+operator * (const Matrix& m, const ComplexColumnVector& a)
+{
+  ComplexMatrix tmp (m);
   return tmp * a;
 }
 
 // matrix by diagonal matrix -> matrix operations
 
 Matrix
-Matrix::operator + (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+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");
@@ -1294,17 +1362,20 @@
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
 
-  Matrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) += a.data[i];
+  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
-Matrix::operator - (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+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");
@@ -1314,39 +1385,45 @@
   if (nr == 0 || nc == 0)
     return Matrix (nr, nc);
 
-  Matrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) -= a.data[i];
+  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
-Matrix::operator * (const DiagMatrix& a) const
-{
-  if (nc != a.nr)
+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];
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return Matrix (nr, a_nc, 0.0);
+
+  double *c = new double [nr*a_nc];
   double *ctmp = (double *) NULL;
 
-  for (int j = 0; j < a.len; j++)
+  int a_len = a.length ();
+  for (int j = 0; j < a_len; j++)
     {
       int idx = j * nr;
       ctmp = c + idx;
-      if (a.data[j] == 1.0)
+      if (a.elem (j, j) == 1.0)
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = elem (i, j);
+	    ctmp[i] = m.elem (i, j);
 	}
-      else if (a.data[j] == 0.0)
+      else if (a.elem (j, j) == 0.0)
 	{
 	  for (int i = 0; i < nr; i++)
 	    ctmp[i] = 0.0;
@@ -1354,23 +1431,25 @@
       else
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = a.data[j] * elem (i, j);
+	    ctmp[i] = a.elem (j, j) * m.elem (i, j);
 	}
     }
 
-  if (a.nr < a.nc)
+  if (a_nr < a_nc)
     {
-      for (int i = nr * nc; i < nr * a.nc; i++)
+      for (int i = nr * nc; i < nr * a_nc; i++)
 	ctmp[i] = 0.0;
     }
 
-  return Matrix (c, nr, a.nc);
+  return Matrix (c, nr, a_nc);
 }
 
 ComplexMatrix
-Matrix::operator + (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator + (const Matrix& m, const ComplexDiagMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -1380,17 +1459,19 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) += a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) += a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-Matrix::operator - (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator - (const Matrix& m, const ComplexDiagMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -1400,39 +1481,43 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) -= a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) -= a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-Matrix::operator * (const ComplexDiagMatrix& a) const
-{
-  if (nc != a.nr)
+operator * (const Matrix& m, const ComplexDiagMatrix& 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 ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
-    return ComplexMatrix (nr, a.nc, 0.0);
-
-  Complex *c = new Complex [nr*a.nc];
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return ComplexMatrix (nr, a_nc, 0.0);
+
+  Complex *c = new Complex [nr*a_nc];
   Complex *ctmp = (Complex *) NULL;
 
-  for (int j = 0; j < a.len; j++)
+  for (int j = 0; j < a.length (); j++)
     {
       int idx = j * nr;
       ctmp = c + idx;
-      if (a.data[j] == 1.0)
+      if (a.elem (j, j) == 1.0)
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = elem (i, j);
+	    ctmp[i] = m.elem (i, j);
 	}
-      else if (a.data[j] == 0.0)
+      else if (a.elem (j, j) == 0.0)
 	{
 	  for (int i = 0; i < nr; i++)
 	    ctmp[i] = 0.0;
@@ -1440,133 +1525,83 @@
       else
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = a.data[j] * elem (i, j);
+	    ctmp[i] = a.elem (j, j) * m.elem (i, j);
 	}
     }
 
-  if (a.nr < a.nc)
+  if (a_nr < a_nc)
     {
-      for (int i = nr * nc; i < nr * a.nc; i++)
+      for (int i = nr * nc; i < nr * a_nc; i++)
 	ctmp[i] = 0.0;
     }
 
-  return ComplexMatrix (c, nr, a.nc);
-}
-
-Matrix&
-Matrix::operator += (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) += a.data[i];
-
-  return *this;
-}
-
-Matrix&
-Matrix::operator -= (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) -= a.data[i];
-
-  return *this;
+  return ComplexMatrix (c, nr, a_nc);
 }
 
 // matrix by matrix -> matrix operations
 
 Matrix
-Matrix::operator + (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix addition attempted");
-      return Matrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return Matrix (nr, nc);
-
-  return Matrix (add (data, a.data, len), nr, nc);
-}
-
-Matrix
-Matrix::operator - (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix subtraction attempted");
-      return Matrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return Matrix (nr, nc);
-
-  return Matrix (subtract (data, a.data, len), nr, nc);
-}
-
-Matrix
-Matrix::operator * (const Matrix& a) const
-{
-  if (nc != a.nr)
+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);
+  if (nr == 0 || nc == 0 || a_nc == 0)
+    return Matrix (nr, a_nc, 0.0);
 
   char trans  = 'N';
   char transa = 'N';
 
   int ld  = nr;
-  int lda = a.nr;
+  int lda = a_nr;
 
   double alpha = 1.0;
   double beta  = 0.0;
-  int anc = a.nc;
-
-  double *c = new double [nr*a.nc];
-
-  F77_FCN (dgemm) (&trans, &transa, &nr, &anc, &nc, &alpha, data, &ld,
-		   a.data, &lda, &beta, c, &nr, 1L, 1L);
-
-  return Matrix (c, nr, a.nc);
+
+  double *c = new double [nr*a_nc];
+
+  F77_FCN (dgemm) (&trans, &transa, &nr, &a_nc, &nc, &alpha, m.data (),
+		   &ld, a.data (), &lda, &beta, c, &nr, 1L, 1L);
+
+  return Matrix (c, nr, a_nc);
 }
 
 ComplexMatrix
-Matrix::operator + (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator * (const Matrix& m, const ComplexMatrix& a)
+{
+  ComplexMatrix tmp (m);
+  return tmp * a;
+}
+
+ComplexMatrix
+operator + (const Matrix& m, const ComplexMatrix& 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 ComplexMatrix ();
     }
 
-  return ComplexMatrix (add (data, a.data, len), nr, nc);
+  return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-Matrix::operator - (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator - (const Matrix& m, const ComplexMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -1576,52 +1611,15 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (subtract (data, a.data, len), nr, nc);
+  return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-Matrix::operator * (const ComplexMatrix& a) const
-{
-  ComplexMatrix tmp (*this);
-  return tmp * a;
-}
-
-Matrix
-Matrix::product (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix product attempted");
-      return Matrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return Matrix (nr, nc);
-
-  return Matrix (multiply (data, a.data, len), nr, nc);
-}
-
-Matrix
-Matrix::quotient (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return Matrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return Matrix (nr, nc);
-
-  return Matrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix
-Matrix::product (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+product (const Matrix& m, const ComplexMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix product attempted");
@@ -1631,13 +1629,15 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (multiply (data, a.data, len), nr, nc);
+  return ComplexMatrix (multiply (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-Matrix::quotient (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+quotient (const Matrix& m, const ComplexMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix quotient attempted");
@@ -1647,41 +1647,7 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (divide (data, a.data, len), nr, nc);
-}
-
-Matrix&
-Matrix::operator += (const Matrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-Matrix&
-Matrix::operator -= (const Matrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
+  return ComplexMatrix (divide (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 // other operations.
@@ -1697,8 +1663,10 @@
 void
 Matrix::map (d_d_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  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
@@ -1708,6 +1676,8 @@
 Matrix
 Matrix::all (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   Matrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -1760,6 +1730,8 @@
 Matrix
 Matrix::any (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   Matrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -1813,6 +1785,10 @@
 Matrix::cumprod (void) const
 {
   Matrix retval;
+
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr == 1)
     {
       retval.resize (1, nc);
@@ -1865,6 +1841,10 @@
 Matrix::cumsum (void) const
 {
   Matrix retval;
+
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr == 1)
     {
       retval.resize (1, nc);
@@ -1917,6 +1897,10 @@
 Matrix::prod (void) const
 {
   Matrix retval;
+
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr == 1)
     {
       retval.resize (1, 1);
@@ -1955,6 +1939,10 @@
 Matrix::sum (void) const
 {
   Matrix retval;
+
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr == 1)
     {
       retval.resize (1, 1);
@@ -1993,6 +1981,10 @@
 Matrix::sumsq (void) const
 {
   Matrix retval;
+
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr == 1)
     {
       retval.resize (1, 1);
@@ -2038,8 +2030,8 @@
 ColumnVector
 Matrix::diag (int k) const
 {
-  int nnr = nr;
-  int nnc = nc;
+  int nnr = rows ();
+  int nnc = cols ();
   if (k > 0)
     nnc -= k;
   else if (k < 0)
@@ -2075,31 +2067,14 @@
   return d;
 }
 
-// unary operations
-
-Matrix
-Matrix::operator - (void) const
-{
-  return Matrix (negate (data, len), nr, nc);
-}
-
-Matrix
-Matrix::operator ! (void) const
-{
-  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;
-}
-
 ColumnVector
 Matrix::row_min (void) const
 {
   ColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -2122,6 +2097,9 @@
 {
   ColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -2144,6 +2122,9 @@
 {
   ColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -2166,6 +2147,9 @@
 {
   ColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -2188,6 +2172,9 @@
 {
   RowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -2209,6 +2196,9 @@
 {
   RowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -2232,6 +2222,9 @@
 {
   RowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -2254,6 +2247,9 @@
 {
   RowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -2275,9 +2271,9 @@
 operator << (ostream& os, const Matrix& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.nr; i++)
+  for (int i = 0; i < a.rows (); i++)
     {
-      for (int j = 0; j < a.nc; j++)
+      for (int j = 0; j < a.cols (); j++)
 	os << " " /* setw (field_width) */ << a.elem (i, j);
       os << "\n";
     }
@@ -2288,7 +2284,7 @@
 operator >> (istream& is, Matrix& a)
 {
   int nr = a.rows ();
-  int nc = a.columns ();
+  int nc = a.cols ();
 
   if (nr < 1 || nc < 1)
     is.clear (ios::badbit);
@@ -2313,222 +2309,29 @@
  * Complex Matrix class
  */
 
-ComplexMatrix::ComplexMatrix (int r, int c)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't construct matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = nr * nc;
-  if (len > 0)
-    data = new Complex [len];
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexMatrix::ComplexMatrix (int r, int c, double val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't construct matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexMatrix::ComplexMatrix (int r, int c, const Complex& val)
-{
-  if (r < 0 || c < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't construct matrix with negative dimensions");
-      nr = 0;
-      nc = 0;
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  nr = r;
-  nc = c;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
 ComplexMatrix::ComplexMatrix (const Matrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexMatrix::ComplexMatrix (const ComplexMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
+  : Array2<Complex> (a.rows (), a.cols ())
+{
+  for (int j = 0; j < cols (); j++)
+    for (int i = 0; i < rows (); i++)
+      elem (i, j) = a.elem (i, j);
 }
 
 ComplexMatrix::ComplexMatrix (const DiagMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, 0.0);
-      for (int i = 0; i < a.len; i++)
-	data[nr*i+i] = a.data[i];
-    }
-  else
-    data = (Complex *) NULL;
+  : Array2<Complex> (a.rows (), a.cols ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
 }
 
 ComplexMatrix::ComplexMatrix (const ComplexDiagMatrix& a)
-{
-  nr = a.nr;
-  nc = a.nc;
-  len = nr * nc;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, 0.0);
-      for (int i = 0; i < a.len; i++)
-	data[nr*i+i] = a.data[i];
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexMatrix::ComplexMatrix (double a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new Complex [1];
-  data[0] = a;
-}
-
-ComplexMatrix::ComplexMatrix (const Complex& a)
-{
-  nr = 1;
-  nc = 1;
-  len = 1;
-  data = new Complex [1];
-  data[0] = Complex (a);
-}
-
-ComplexMatrix&
-ComplexMatrix::operator = (const Matrix& a)
-{
-  delete [] data;
-  nr = a.nr;
-  nc = a.nc;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator = (const ComplexMatrix& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      nr = a.nr;
-      nc = a.nc;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new Complex [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (Complex *) NULL;
-    }
-  return *this;
-}
-
-Complex&
-ComplexMatrix::checkelem (int r, int c)
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static Complex foo (0.0);
-      return foo;
-    }
-#endif
-
-  return elem (r, c);
-}
-
-Complex
-ComplexMatrix::checkelem (int r, int c) const
-{
-#ifndef NO_RANGE_CHECK
-  if (r < 0 || r >= nr || c < 0 || c >= nc)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return Complex (0.0);
-    }
-#endif
-
-  return elem (r, c);
-}
-
+  : Array2<Complex> (a.rows (), a.cols ())
+{
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+#if 0
 ComplexMatrix&
 ComplexMatrix::resize (int r, int c)
 {
@@ -2637,14 +2440,15 @@
 
   return *this;
 }
+#endif
 
 int
 ComplexMatrix::operator == (const ComplexMatrix& a) const
 {
-  if (nr != a.nr || nc != a.nc)
+  if (rows () != a.rows () || cols () != a.cols ())
     return 0;
 
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), length ());
 }
 
 int
@@ -2658,14 +2462,16 @@
 ComplexMatrix&
 ComplexMatrix::insert (const Matrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (r < 0 || r + a_nr - 1 > rows () || c < 0 || c + a_nc - 1 > cols ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int j = 0; j < a.nc; j++)
-    for (int i = 0; i < a.nr; i++)
+  for (int j = 0; j < a_nc; j++)
+    for (int i = 0; i < a_nr; i++)
       elem (r+i, c+j) = a.elem (i, j);
 
   return *this;
@@ -2674,14 +2480,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const RowVector& a, int r, int c)
 {
-  if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r, c+i) = a.elem (i);
 
   return *this;
 }
@@ -2689,14 +2496,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const ColumnVector& a, int r, int c)
 {
-  if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i, c) = a.elem (i);
 
   return *this;
 }
@@ -2704,14 +2512,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const DiagMatrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  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.len; i++)
-    elem (r+i, c+i) = a.data[i];
+  for (int i = 0; i < a.length (); i++)
+    elem (r+i, c+i) = a.elem (i, i);
 
   return *this;
 }
@@ -2719,14 +2528,16 @@
 ComplexMatrix&
 ComplexMatrix::insert (const ComplexMatrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
+  if (r < 0 || r + a_nr - 1 > rows () || c < 0 || c + a_nc - 1 > cols ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int j = 0; j < a.nc; j++)
-    for (int i = 0; i < a.nr; i++)
+  for (int j = 0; j < a_nc; j++)
+    for (int i = 0; i < a_nr; i++)
       elem (r+i, c+j) = a.elem (i, j);
 
   return *this;
@@ -2735,14 +2546,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const ComplexRowVector& a, int r, int c)
 {
-  if (r < 0 || r >= nr || c < 0 || c + a.len - 1 > nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r, c+i) = a.elem (i);
 
   return *this;
 }
@@ -2750,14 +2562,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const ComplexColumnVector& a, int r, int c)
 {
-  if (r < 0 || r + a.len - 1 > nr || c < 0 || c >= nc)
+  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.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (r+i, c) = a.elem (i);
 
   return *this;
 }
@@ -2765,14 +2578,15 @@
 ComplexMatrix&
 ComplexMatrix::insert (const ComplexDiagMatrix& a, int r, int c)
 {
-  if (r < 0 || r + a.nr - 1 > nr || c < 0 || c + a.nc - 1 > nc)
+  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.len; i++)
-    elem (r+i, c+i) = a.data[i];
+  for (int i = 0; i < a.length (); i++)
+    elem (r+i, c+i) = a.elem (i, i);
 
   return *this;
 }
@@ -2780,22 +2594,34 @@
 ComplexMatrix&
 ComplexMatrix::fill (double val)
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nr > 0 && nc > 0)
-    copy (data, len, val);
+    for (int j = 0; j < nc; j++)
+      for (int i = 0; i < nr; i++)
+	elem (i, j) = val;
+
   return *this;
 }
 
 ComplexMatrix&
 ComplexMatrix::fill (const Complex& val)
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nr > 0 && nc > 0)
-    copy (data, len, val);
+    for (int j = 0; j < nc; j++)
+      for (int i = 0; i < nr; i++)
+	elem (i, j) = val;
+
   return *this;
 }
 
 ComplexMatrix&
 ComplexMatrix::fill (double val, int r1, int c1, int r2, int c2)
 {
+  int nr = rows ();
+  int nc = rows ();
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
     {
@@ -2816,6 +2642,8 @@
 ComplexMatrix&
 ComplexMatrix::fill (const Complex& val, int r1, int c1, int r2, int c2)
 {
+  int nr = rows ();
+  int nc = rows ();
   if (r1 < 0 || r2 < 0 || c1 < 0 || c2 < 0
       || r1 >= nr || r2 >= nr || c1 >= nc || c2 >= nc)
     {
@@ -2836,14 +2664,16 @@
 ComplexMatrix
 ComplexMatrix::append (const Matrix& a) const
 {
-  if (nr != a.nr)
+  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;
-  ComplexMatrix retval (nr, nc + a.nc);
+  ComplexMatrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2852,6 +2682,8 @@
 ComplexMatrix
 ComplexMatrix::append (const RowVector& a) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nr != 1)
     {
       (*current_liboctave_error_handler) ("row dimension mismatch for append");
@@ -2859,7 +2691,7 @@
     }
 
   int nc_insert = nc;
-  ComplexMatrix retval (nr, nc + a.len);
+  ComplexMatrix retval (nr, nc + a.length ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2868,7 +2700,9 @@
 ComplexMatrix
 ComplexMatrix::append (const ColumnVector& a) const
 {
-  if (nr != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.length ())
     {
       (*current_liboctave_error_handler) ("row dimension mismatch for append");
       return *this;
@@ -2884,14 +2718,16 @@
 ComplexMatrix
 ComplexMatrix::append (const DiagMatrix& a) const
 {
-  if (nr != a.nr)
+  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;
-  ComplexMatrix retval (nr, nc + a.nc);
+  ComplexMatrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2900,14 +2736,16 @@
 ComplexMatrix
 ComplexMatrix::append (const ComplexMatrix& a) const
 {
-  if (nr != a.nr)
+  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;
-  ComplexMatrix retval (nr, nc + a.nc);
+  ComplexMatrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2916,6 +2754,8 @@
 ComplexMatrix
 ComplexMatrix::append (const ComplexRowVector& a) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nr != 1)
     {
       (*current_liboctave_error_handler) ("row dimension mismatch for append");
@@ -2923,7 +2763,7 @@
     }
 
   int nc_insert = nc;
-  ComplexMatrix retval (nr, nc + a.len);
+  ComplexMatrix retval (nr, nc + a.length ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2932,7 +2772,9 @@
 ComplexMatrix
 ComplexMatrix::append (const ComplexColumnVector& a) const
 {
-  if (nr != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.length ())
     {
       (*current_liboctave_error_handler) ("row dimension mismatch for append");
       return *this;
@@ -2948,14 +2790,16 @@
 ComplexMatrix
 ComplexMatrix::append (const ComplexDiagMatrix& a) const
 {
-  if (nr != a.nr)
+  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;
-  ComplexMatrix retval (nr, nc + a.nc);
+  ComplexMatrix retval (nr, nc + a.cols ());
   retval.insert (*this, 0, 0);
   retval.insert (a, 0, nc_insert);
   return retval;
@@ -2964,7 +2808,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const Matrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -2972,7 +2818,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.nr, nc);
+  ComplexMatrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -2981,7 +2827,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const RowVector& a) const
 {
-  if (nc != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.length ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -2998,6 +2846,8 @@
 ComplexMatrix
 ComplexMatrix::stack (const ColumnVector& a) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nc != 1)
     {
       (*current_liboctave_error_handler)
@@ -3006,7 +2856,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.len, nc);
+  ComplexMatrix retval (nr + a.length (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -3015,7 +2865,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const DiagMatrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -3023,7 +2875,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.nr, nc);
+  ComplexMatrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -3032,7 +2884,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const ComplexMatrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -3040,7 +2894,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.nr, nc);
+  ComplexMatrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -3049,7 +2903,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const ComplexRowVector& a) const
 {
-  if (nc != a.len)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.length ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -3066,6 +2922,8 @@
 ComplexMatrix
 ComplexMatrix::stack (const ComplexColumnVector& a) const
 {
+  int nr = rows ();
+  int nc = cols ();
   if (nc != 1)
     {
       (*current_liboctave_error_handler)
@@ -3074,7 +2932,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.len, nc);
+  ComplexMatrix retval (nr + a.length (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -3083,7 +2941,9 @@
 ComplexMatrix
 ComplexMatrix::stack (const ComplexDiagMatrix& a) const
 {
-  if (nc != a.nc)
+  int nr = rows ();
+  int nc = cols ();
+  if (nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("column dimension mismatch for stack");
@@ -3091,7 +2951,7 @@
     }
 
   int nr_insert = nr;
-  ComplexMatrix retval (nr + a.nr, nc);
+  ComplexMatrix retval (nr + a.rows (), nc);
   retval.insert (*this, 0, 0);
   retval.insert (a, nr_insert, 0);
   return retval;
@@ -3100,13 +2960,15 @@
 ComplexMatrix
 ComplexMatrix::hermitian (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix result;
-  if (len > 0)
+  if (length () > 0)
     {
       result.resize (nc, nr);
       for (int j = 0; j < nc; j++)
 	for (int i = 0; i < nr; i++)
-	  result.data[nc*i+j] = conj (data[nr*j+i]);
+	  result.elem (j, i) = conj (elem (i, j));
     }
   return result;
 }
@@ -3114,12 +2976,14 @@
 ComplexMatrix
 ComplexMatrix::transpose (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix result (nc, nr);
-  if (len > 0)
+  if (length () > 0)
     {
       for (int j = 0; j < nc; j++)
 	for (int i = 0; i < nr; i++)
-	  result.data[nc*i+j] = data[nr*j+i];
+	  result.elem (j, i) = elem (i, j);
     }
   return result;
 }
@@ -3127,27 +2991,31 @@
 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.nr, a.nc);
+  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.nr, a.nc);
+  if (a_len > 0)
+    retval = Matrix (imag_dup (a.data (), a_len), a.rows (), a.cols ());
   return retval;
 }
 
 ComplexMatrix
 conj (const ComplexMatrix& a)
 {
+  int a_len = a.length ();
   ComplexMatrix retval;
-  if (a.len > 0)
-    retval = ComplexMatrix (conj_dup (a.data, a.len), a.nr, a.nc);
+  if (a_len > 0)
+    retval = ComplexMatrix (conj_dup (a.data (), a_len), a.rows (),
+			    a.cols ());
   return retval;
 }
 
@@ -3166,7 +3034,7 @@
 
   for (int j = 0; j < new_c; j++)
     for (int i = 0; i < new_r; i++)
-      result.data[new_r*j+i] = elem (r1+i, c1+j);
+      result.elem (i, j) = elem (r1+i, c1+j);
 
   return result;
 }
@@ -3176,14 +3044,15 @@
 ComplexRowVector
 ComplexMatrix::row (int i) const
 {
-  if (i < 0 || i >= nr)
+  int nc = cols ();
+  if (i < 0 || i >= rows ())
     {
       (*current_liboctave_error_handler) ("invalid row selection");
       return ComplexRowVector ();
     }
 
   ComplexRowVector retval (nc);
-  for (int j = 0; j < nc; j++)
+  for (int j = 0; j < cols (); j++)
     retval.elem (j) = elem (i, j);
 
   return retval;
@@ -3202,7 +3071,7 @@
   if (c == 'f' || c == 'F')
     return row (0);
   else if (c == 'l' || c == 'L')
-    return row (nr - 1);
+    return row (rows () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid row selection");
@@ -3213,7 +3082,8 @@
 ComplexColumnVector
 ComplexMatrix::column (int i) const
 {
-  if (i < 0 || i >= nc)
+  int nr = rows ();
+  if (i < 0 || i >= cols ())
     {
       (*current_liboctave_error_handler) ("invalid column selection");
       return ComplexColumnVector ();
@@ -3239,7 +3109,7 @@
   if (c == 'f' || c == 'F')
     return column (0);
   else if (c == 'l' || c == 'L')
-    return column (nc - 1);
+    return column (cols () - 1);
   else
     {
       (*current_liboctave_error_handler) ("invalid column selection");
@@ -3248,8 +3118,25 @@
 }
 
 ComplexMatrix
+ComplexMatrix::inverse (void) const
+{
+  int info;
+  double rcond; return inverse (info, rcond);
+}
+
+ComplexMatrix
+ComplexMatrix::inverse (int& info) const
+{
+  double rcond;
+  return inverse (info, rcond);
+}
+
+ComplexMatrix
 ComplexMatrix::inverse (int& info, double& rcond) const
 {
+  int nr = rows ();
+  int nc = cols ();
+  int len = length ();
   if (nr != nc)
     {
       (*current_liboctave_error_handler) ("inverse requires square matrix");
@@ -3260,14 +3147,14 @@
 
   int *ipvt = new int [nr];
   Complex *z = new Complex [nr];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), len);
 
   F77_FCN (zgeco) (tmp_data, &nr, &nc, ipvt, &rcond, z);
 
   if (rcond + 1.0 == 1.0)
     {
       info = -1;
-      copy (tmp_data, data, len);  // Restore contents.
+      copy (tmp_data, data (), len);  // Restore contents.
     }
   else
     {
@@ -3284,23 +3171,10 @@
 }
 
 ComplexMatrix
-ComplexMatrix::inverse (int& info) const
-{
-  double rcond;
-  return inverse (info, rcond);
-}
-
-ComplexMatrix
-ComplexMatrix::inverse (void) const
-{
-  int info;
-  double rcond;
-  return inverse (info, rcond);
-}
-
-ComplexMatrix
 ComplexMatrix::fourier (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   int npts, nsamples;
   if (nr == 1 || nc == 1)
     {
@@ -3315,7 +3189,7 @@
 
   int nn = 4*npts+15;
   Complex *wsave = new Complex [nn];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   F77_FCN (cffti) (&npts, wsave);
 
@@ -3330,6 +3204,8 @@
 ComplexMatrix
 ComplexMatrix::ifourier (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   int npts, nsamples;
   if (nr == 1 || nc == 1)
     {
@@ -3344,7 +3220,7 @@
 
   int nn = 4*npts+15;
   Complex *wsave = new Complex [nn];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   F77_FCN (cffti) (&npts, wsave);
 
@@ -3379,6 +3255,8 @@
 {
   ComplexDET retval;
 
+  int nr = rows ();
+  int nc = cols ();
   if (nr == 0 || nc == 0)
     {
       Complex d[2];
@@ -3391,7 +3269,7 @@
   int *ipvt = new int [nr];
 
   Complex *z = new Complex [nr];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   F77_FCN (zgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -3450,13 +3328,16 @@
   double rcond;
   return solve (b, info, rcond);
 }
-
 ComplexMatrix
 ComplexMatrix::solve (const ComplexMatrix& b, int& info, double& rcond) const
 {
   ComplexMatrix retval;
 
-  if (nr == 0 || nc == 0 || nr != nc || nr != b.nr)
+  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");
@@ -3467,7 +3348,7 @@
   int *ipvt = new int [nr];
 
   Complex *z = new Complex [nr];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   F77_FCN (zgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -3479,12 +3360,12 @@
     {
       int job = 0;
 
-      Complex *result = dup (b.data, b.len);
-
-      for (int j = 0; j < b.nc; j++)
+      Complex *result = dup (b.data (), b.length ());
+
+      for (int j = 0; j < b_nc; j++)
 	F77_FCN (zgesl) (tmp_data, &nr, &nr, ipvt, &result[nr*j], &job);
 
-      retval = ComplexMatrix (result, b.nr, b.nc);
+      retval = ComplexMatrix (result, b_nr, b_nc);
     }
 
   delete [] tmp_data;
@@ -3495,28 +3376,6 @@
 }
 
 ComplexColumnVector
-ComplexMatrix::solve (const ColumnVector& b) const
-{
-  int info;
-  double rcond;
-  return solve (b, info, rcond);
-}
-
-ComplexColumnVector
-ComplexMatrix::solve (const ColumnVector& b, int& info) const
-{
-  double rcond;
-  return solve (b, info, rcond);
-}
-
-ComplexColumnVector
-ComplexMatrix::solve (const ColumnVector& b, int& info, double& rcond) const
-{
-  ComplexColumnVector tmp (b);
-  return solve (tmp, info, rcond);
-}
-
-ComplexColumnVector
 ComplexMatrix::solve (const ComplexColumnVector& b) const
 {
   int info;
@@ -3537,7 +3396,10 @@
 {
   ComplexColumnVector retval;
 
-  if (nr == 0 || nc == 0 || nr != nc || nr != b.len)
+  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");
@@ -3548,7 +3410,7 @@
   int *ipvt = new int [nr];
 
   Complex *z = new Complex [nr];
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   F77_FCN (zgeco) (tmp_data, &nr, &nr, ipvt, &rcond, z);
 
@@ -3560,11 +3422,11 @@
     {
       int job = 0;
 
-      Complex *result = dup (b.data, b.len);
+      Complex *result = dup (b.data (), b_len);
 
       F77_FCN (zgesl) (tmp_data, &nr, &nr, ipvt, result, &job);
 
-      retval = ComplexColumnVector (result, b.len);
+      retval = ComplexColumnVector (result, b_len);
     }
 
   delete [] tmp_data;
@@ -3575,28 +3437,6 @@
 }
 
 ComplexMatrix
-ComplexMatrix::lssolve (const Matrix& b) const
-{
-  int info;
-  int rank;
-  return lssolve (b, info, rank);
-}
-
-ComplexMatrix
-ComplexMatrix::lssolve (const Matrix& b, int& info) const
-{
-  int rank;
-  return lssolve (b, info, rank);
-}
-
-ComplexMatrix
-ComplexMatrix::lssolve (const Matrix& b, int& info, int& rank) const
-{
-  ComplexMatrix tmp (b);
-  return lssolve (tmp, info, rank);
-}
-
-ComplexMatrix
 ComplexMatrix::lssolve (const ComplexMatrix& b) const
 {
   int info;
@@ -3614,19 +3454,19 @@
 ComplexMatrix
 ComplexMatrix::lssolve (const ComplexMatrix& b, int& info, int& rank) const
 {
-  int nrhs = b.nc;
-
-  int m = nr;
-  int n = nc;
-
-  if (m == 0 || n == 0 || m != b.nr)
+  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");
       return Matrix ();
     }
 
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   int nrr = m > n ? m : n;
   ComplexMatrix result (nrr, nrhs);
@@ -3670,28 +3510,6 @@
 }
 
 ComplexColumnVector
-ComplexMatrix::lssolve (const ColumnVector& b) const
-{
-  int info;
-  int rank;
-  return lssolve (b, info, rank);
-}
-
-ComplexColumnVector
-ComplexMatrix::lssolve (const ColumnVector& b, int& info) const
-{
-  int rank;
-  return lssolve (b, info, rank);
-}
-
-ComplexColumnVector
-ComplexMatrix::lssolve (const ColumnVector& b, int& info, int& rank) const
-{
-  ComplexColumnVector tmp (b);
-  return lssolve (tmp, info, rank);
-}
-
-ComplexColumnVector
 ComplexMatrix::lssolve (const ComplexColumnVector& b) const
 {
   int info;
@@ -3712,17 +3530,17 @@
 {
   int nrhs = 1;
 
-  int m = nr;
-  int n = nc;
-
-  if (m == 0 || n == 0 || m != b.len)
+  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");
       return ComplexColumnVector ();
     }
 
-  Complex *tmp_data = dup (data, len);
+  Complex *tmp_data = dup (data (), length ());
 
   int nrr = m > n ? m : n;
   ComplexColumnVector result (nrr);
@@ -3763,54 +3581,202 @@
   return retval;
 }
 
+// matrix by diagonal matrix -> matrix operations
+
+ComplexMatrix&
+ComplexMatrix::operator += (const DiagMatrix& a)
+{
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.rows () || nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return ComplexMatrix ();
+    }
+
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const DiagMatrix& a)
+{
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.rows () || nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return ComplexMatrix ();
+    }
+
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator += (const ComplexDiagMatrix& a)
+{
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.rows () || nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix += operation attempted");
+      return ComplexMatrix ();
+    }
+
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) += a.elem (i, i);
+
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const ComplexDiagMatrix& a)
+{
+  int nr = rows ();
+  int nc = cols ();
+  if (nr != a.rows () || nc != a.cols ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant matrix -= operation attempted");
+      return ComplexMatrix ();
+    }
+
+  for (int i = 0; i < a.length (); i++)
+    elem (i, i) -= a.elem (i, i);
+
+  return *this;
+}
+
+// matrix by matrix -> matrix operations
+
+ComplexMatrix&
+ComplexMatrix::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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator += (const ComplexMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), length ());
+  return *this;
+}
+
+ComplexMatrix&
+ComplexMatrix::operator -= (const ComplexMatrix& 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;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), length ());
+  return *this;
+}
+
+// unary operations
+
+Matrix
+ComplexMatrix::operator ! (void) const
+{
+  return Matrix (not (data (), length ()), rows (), cols ());
+}
+
 // matrix by scalar -> matrix operations
 
 ComplexMatrix
-ComplexMatrix::operator + (double s) const
-{
-  return ComplexMatrix (add (data, len, s), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator - (double s) const
-{
-  return ComplexMatrix (subtract (data, len, s), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator * (double s) const
-{
-  return ComplexMatrix (multiply (data, len, s), nr, nc);
+operator + (const ComplexMatrix& a, double s)
+{
+  return ComplexMatrix (add (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-ComplexMatrix::operator / (double s) const
-{
-  return ComplexMatrix (divide (data, len, s), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator + (const Complex& s) const
-{
-  return ComplexMatrix (add (data, len, s), nr, nc);
+operator - (const ComplexMatrix& a, double s)
+{
+  return ComplexMatrix (subtract (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-ComplexMatrix::operator - (const Complex& s) const
-{
-  return ComplexMatrix (subtract (data, len, s), nr, nc);
+operator * (const ComplexMatrix& a, double s)
+{
+  return ComplexMatrix (multiply (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
-ComplexMatrix::operator * (const Complex& s) const
-{
-  return ComplexMatrix (multiply (data, len, s), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator / (const Complex& s) const
-{
-  return ComplexMatrix (divide (data, len, s), nr, nc);
+operator / (const ComplexMatrix& a, double s)
+{
+  return ComplexMatrix (divide (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 // scalar by matrix -> matrix operations
@@ -3818,64 +3784,46 @@
 ComplexMatrix
 operator + (double s, const ComplexMatrix& a)
 {
-  return ComplexMatrix (add (a.data, a.len, s), a.nr, a.nc);
+  return ComplexMatrix (add (a.data (), a.length (), s), a.rows (),
+			a.cols ());
 }
 
 ComplexMatrix
 operator - (double s, const ComplexMatrix& a)
 {
-  return ComplexMatrix (subtract (s, a.data, a.len), a.nr, a.nc);
+  return ComplexMatrix (subtract (s, a.data (), a.length ()),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
 operator * (double s, const ComplexMatrix& a)
 {
-  return ComplexMatrix (multiply (a.data, a.len, s), a.nr, a.nc);
+  return ComplexMatrix (multiply (a.data (), a.length (), s),
+			a.rows (), a.cols ());
 }
 
 ComplexMatrix
 operator / (double s, const ComplexMatrix& a)
 {
-  return ComplexMatrix (divide (s, a.data, a.len), a.nr, a.nc);
-}
-
-ComplexMatrix
-operator + (const Complex& s, const ComplexMatrix& a)
-{
-  return ComplexMatrix (add (s, a.data, a.len), a.nr, a.nc);
-}
-
-ComplexMatrix
-operator - (const Complex& s, const ComplexMatrix& a)
-{
-  return ComplexMatrix (subtract (s, a.data, a.len), a.nr, a.nc);
-}
-
-ComplexMatrix
-operator * (const Complex& s, const ComplexMatrix& a)
-{
-  return ComplexMatrix (multiply (s, a.data, a.len), a.nr, a.nc);
-}
-
-ComplexMatrix
-operator / (const Complex& s, const ComplexMatrix& a)
-{
-  return ComplexMatrix (divide (s, a.data, a.len), a.nr, a.nc);
+  return ComplexMatrix (divide (s, a.data (), a.length ()),
+			a.rows (), a.cols ());
 }
 
 // matrix by column vector -> column vector operations
 
 ComplexColumnVector
-ComplexMatrix::operator * (const ColumnVector& a) const
+operator * (const ComplexMatrix& m, const ColumnVector& a)
 {
   ComplexColumnVector tmp (a);
-  return *this * tmp;
+  return m * tmp;
 }
 
 ComplexColumnVector
-ComplexMatrix::operator * (const ComplexColumnVector& a) const
-{
-  if (nc != a.len)
+operator * (const ComplexMatrix& m, const ComplexColumnVector& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nc != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix multiplication attempted");
@@ -3893,7 +3841,7 @@
 
   Complex *y = new Complex [nr];
 
-  F77_FCN (zgemv) (&trans, &nr, &nc, &alpha, data, &ld, a.data,
+  F77_FCN (zgemv) (&trans, &nr, &nc, &alpha, m.data (), &ld, a.data (),
 		   &i_one, &beta, y, &i_one, 1L); 
 
   return ComplexColumnVector (y, nr);
@@ -3902,9 +3850,11 @@
 // matrix by diagonal matrix -> matrix operations
 
 ComplexMatrix
-ComplexMatrix::operator + (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator + (const ComplexMatrix& 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");
@@ -3914,17 +3864,19 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) += a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) += a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexMatrix::operator - (const DiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator - (const ComplexMatrix& 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");
@@ -3934,39 +3886,42 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) -= a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) -= a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexMatrix::operator * (const DiagMatrix& a) const
-{
-  if (nc != a.nr)
+operator * (const ComplexMatrix& m, const DiagMatrix& a)
+{
+  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");
       return ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
+  if (nr == 0 || nc == 0 || a_nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
 
-  Complex *c = new Complex [nr*a.nc];
+  Complex *c = new Complex [nr*a_nc];
   Complex *ctmp = (Complex *) NULL;
 
-  for (int j = 0; j < a.len; j++)
+  for (int j = 0; j < a.length (); j++)
     {
       int idx = j * nr;
       ctmp = c + idx;
-      if (a.data[j] == 1.0)
+      if (a.elem (j, j) == 1.0)
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = elem (i, j);
+	    ctmp[i] = m.elem (i, j);
 	}
-      else if (a.data[j] == 0.0)
+      else if (a.elem (j, j) == 0.0)
 	{
 	  for (int i = 0; i < nr; i++)
 	    ctmp[i] = 0.0;
@@ -3974,23 +3929,25 @@
       else
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = a.data[j] * elem (i, j);
+	    ctmp[i] = a.elem (j, j) * m.elem (i, j);
 	}
     }
 
-  if (a.nr < a.nc)
+  if (a.rows () < a_nc)
     {
-      for (int i = nr * nc; i < nr * a.nc; i++)
+      for (int i = nr * nc; i < nr * a_nc; i++)
 	ctmp[i] = 0.0;
     }
 
-  return ComplexMatrix (c, nr, a.nc);
+  return ComplexMatrix (c, nr, a_nc);
 }
 
 ComplexMatrix
-ComplexMatrix::operator + (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator + (const ComplexMatrix& m, const ComplexDiagMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix addition attempted");
@@ -4000,17 +3957,19 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) += a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) += a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexMatrix::operator - (const ComplexDiagMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator - (const ComplexMatrix& m, const ComplexDiagMatrix& a)
+{
+  int nr = m.rows ();
+  int nc = m.cols ();
+  if (nr != a.rows () || nc != a.cols ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant matrix subtraction attempted");
@@ -4020,39 +3979,42 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  ComplexMatrix result (*this);
-  for (int i = 0; i < a.len; i++)
-    result.elem (i, i) -= a.data[i];
+  ComplexMatrix result (m);
+  for (int i = 0; i < a.length (); i++)
+    result.elem (i, i) -= a.elem (i, i);
 
   return result;
 }
 
 ComplexMatrix
-ComplexMatrix::operator * (const ComplexDiagMatrix& a) const
-{
-  if (nc != a.nr)
+operator * (const ComplexMatrix& m, const ComplexDiagMatrix& a)
+{
+  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");
       return ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
+  if (nr == 0 || nc == 0 || a_nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
 
-  Complex *c = new Complex [nr*a.nc];
+  Complex *c = new Complex [nr*a_nc];
   Complex *ctmp = (Complex *) NULL;
 
-  for (int j = 0; j < a.len; j++)
+  for (int j = 0; j < a.length (); j++)
     {
       int idx = j * nr;
       ctmp = c + idx;
-      if (a.data[j] == 1.0)
+      if (a.elem (j, j) == 1.0)
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = elem (i, j);
+	    ctmp[i] = m.elem (i, j);
 	}
-      else if (a.data[j] == 0.0)
+      else if (a.elem (j, j) == 0.0)
 	{
 	  for (int i = 0; i < nr; i++)
 	    ctmp[i] = 0.0;
@@ -4060,128 +4022,27 @@
       else
 	{
 	  for (int i = 0; i < nr; i++)
-	    ctmp[i] = a.data[j] * elem (i, j);
+	    ctmp[i] = a.elem (j, j) * m.elem (i, j);
 	}
     }
 
-  if (a.nr < a.nc)
+  if (a.rows () < a_nc)
     {
-      for (int i = nr * nc; i < nr * a.nc; i++)
+      for (int i = nr * nc; i < nr * a_nc; i++)
 	ctmp[i] = 0.0;
     }
 
-  return ComplexMatrix (c, nr, a.nc);
-}
-
-ComplexMatrix&
-ComplexMatrix::operator += (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return ComplexMatrix ();
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) += a.data[i];
-
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator -= (const DiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return ComplexMatrix ();
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) -= a.data[i];
-
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator += (const ComplexDiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return ComplexMatrix ();
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) += a.data[i];
-
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator -= (const ComplexDiagMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return ComplexMatrix ();
-    }
-
-  for (int i = 0; i < a.len; i++)
-    elem (i, i) -= a.data[i];
-
-  return *this;
+  return ComplexMatrix (c, nr, a_nc);
 }
 
 // matrix by matrix -> matrix operations
 
 ComplexMatrix
-ComplexMatrix::operator + (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix addition attempted");
-      return ComplexMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexMatrix (nr, nc);
-
-  return ComplexMatrix (add (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator - (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix subtraction attempted");
-      return ComplexMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexMatrix (nr, nc);
-
-  return ComplexMatrix (subtract (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::operator * (const Matrix& a) const
-{
-  ComplexMatrix tmp (a);
-  return *this * tmp;
-}
-
-ComplexMatrix
-ComplexMatrix::operator + (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator + (const ComplexMatrix& 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");
@@ -4191,13 +4052,15 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (add (data, a.data, len), nr, nc);
+  return ComplexMatrix (add (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-ComplexMatrix::operator - (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+operator - (const ComplexMatrix& 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");
@@ -4207,76 +4070,55 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (subtract (data, a.data, len), nr, nc);
+  return ComplexMatrix (subtract (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-ComplexMatrix::operator * (const ComplexMatrix& a) const
-{
-  if (nc != a.nr)
+operator * (const ComplexMatrix& m, const Matrix& a)
+{
+  ComplexMatrix tmp (a);
+  return m * tmp;
+}
+
+ComplexMatrix
+operator * (const ComplexMatrix& m, const ComplexMatrix& a)
+{
+  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");
       return ComplexMatrix ();
     }
 
-  if (nr == 0 || nc == 0 || a.nc == 0)
+  if (nr == 0 || nc == 0 || a_nc == 0)
     return ComplexMatrix (nr, nc, 0.0);
 
   char trans  = 'N';
   char transa = 'N';
 
   int ld  = nr;
-  int lda = a.nr;
+  int lda = a.rows ();
 
   Complex alpha (1.0);
   Complex beta (0.0);
-  int anc = a.nc;
-
-  Complex *c = new Complex [nr*a.nc];
-
-  F77_FCN (zgemm) (&trans, &transa, &nr, &anc, &nc, &alpha, data, &ld,
-		   a.data, &lda, &beta, c, &nr, 1L, 1L);
-
-  return ComplexMatrix (c, nr, a.nc);
+
+  Complex *c = new Complex [nr*a_nc];
+
+  F77_FCN (zgemm) (&trans, &transa, &nr, &a_nc, &nc, &alpha, m.data (),
+		   &ld, a.data (), &lda, &beta, c, &nr, 1L, 1L);
+
+  return ComplexMatrix (c, nr, a_nc);
 }
 
 ComplexMatrix
-ComplexMatrix::product (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix product attempted");
-      return ComplexMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexMatrix (nr, nc);
-
-  return ComplexMatrix (multiply (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::quotient (const Matrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix quotient attempted");
-      return ComplexMatrix ();
-    }
-
-  if (nr == 0 || nc == 0)
-    return ComplexMatrix (nr, nc);
-
-  return ComplexMatrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix
-ComplexMatrix::product (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+product (const ComplexMatrix& 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 product attempted");
@@ -4286,13 +4128,15 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (multiply (data, a.data, len), nr, nc);
+  return ComplexMatrix (multiply (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 ComplexMatrix
-ComplexMatrix::quotient (const ComplexMatrix& a) const
-{
-  if (nr != a.nr || nc != a.nc)
+quotient (const ComplexMatrix& 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 quotient attempted");
@@ -4302,89 +4146,7 @@
   if (nr == 0 || nc == 0)
     return ComplexMatrix (nr, nc);
 
-  return ComplexMatrix (divide (data, a.data, len), nr, nc);
-}
-
-ComplexMatrix&
-ComplexMatrix::operator += (const Matrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator -= (const Matrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator += (const ComplexMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix += operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexMatrix&
-ComplexMatrix::operator -= (const ComplexMatrix& a)
-{
-  if (nr != a.nr || nc != a.nc)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant matrix -= operation attempted");
-      return *this;
-    }
-
-  if (nr == 0 || nc == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-// unary operations
-
-ComplexMatrix
-ComplexMatrix::operator - (void) const
-{
-  return ComplexMatrix (negate (data, len), nr, nc);
-}
-
-Matrix
-ComplexMatrix::operator ! (void) const
-{
-  return Matrix (not (data, len), nr, nc);
+  return ComplexMatrix (divide (m.data (), a.data (), m.length ()), nr, nc);
 }
 
 // other operations
@@ -4400,9 +4162,11 @@
 Matrix
 map (d_c_Mapper f, const ComplexMatrix& a)
 {
-  Matrix b (a.nr, a.nc);
-  for (int j = 0; j < a.nc; j++)
-    for (int i = 0; i < a.nr; i++)
+  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;
 }
@@ -4410,13 +4174,16 @@
 void
 ComplexMatrix::map (c_c_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  for (int j = 0; j < cols (); j++)
+    for (int i = 0; i < rows (); i++)
+      elem (i, j) = f (elem (i, j));
 }
 
 Matrix
 ComplexMatrix::all (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   Matrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4469,6 +4236,8 @@
 Matrix
 ComplexMatrix::any (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   Matrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4521,6 +4290,8 @@
 ComplexMatrix
 ComplexMatrix::cumprod (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4567,6 +4338,8 @@
 ComplexMatrix
 ComplexMatrix::cumsum (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4613,6 +4386,8 @@
 ComplexMatrix
 ComplexMatrix::prod (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4647,6 +4422,8 @@
 ComplexMatrix
 ComplexMatrix::sum (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4681,6 +4458,8 @@
 ComplexMatrix
 ComplexMatrix::sumsq (void) const
 {
+  int nr = rows ();
+  int nc = cols ();
   ComplexMatrix retval;
   if (nr > 0 && nc > 0)
     {
@@ -4730,8 +4509,8 @@
 ComplexColumnVector
 ComplexMatrix::diag (int k) const
 {
-  int nnr = nr;
-  int nnc = nc;
+  int nnr = rows ();
+  int nnc = cols ();
   if (k > 0)
     nnc -= k;
   else if (k < 0)
@@ -4772,6 +4551,8 @@
 {
   ComplexColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -4798,6 +4579,9 @@
 {
   ComplexColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -4824,6 +4608,9 @@
 {
   ComplexColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -4850,6 +4637,9 @@
 {
   ComplexColumnVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nr);
@@ -4876,6 +4666,9 @@
 {
   ComplexRowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -4902,6 +4695,9 @@
 {
   ComplexRowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -4928,6 +4724,9 @@
 {
   ComplexRowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -4954,6 +4753,9 @@
 {
   ComplexRowVector result;
 
+  int nr = rows ();
+  int nc = cols ();
+
   if (nr > 0 && nc > 0)
     {
       result.resize (nc);
@@ -4981,9 +4783,9 @@
 operator << (ostream& os, const ComplexMatrix& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.nr; i++)
+  for (int i = 0; i < a.rows (); i++)
     {
-      for (int j = 0; j < a.nc; j++)
+      for (int j = 0; j < a.cols (); j++)
 	os << " " /* setw (field_width) */ << a.elem (i, j);
       os << "\n";
     }
@@ -4994,7 +4796,7 @@
 operator >> (istream& is, ComplexMatrix& a)
 {
   int nr = a.rows ();
-  int nc = a.columns ();
+  int nc = a.cols ();
 
   if (nr < 1 || nc < 1)
     is.clear (ios::badbit);
--- a/liboctave/Matrix.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Matrix.h	Tue Nov 30 20:23:04 1993 +0000
@@ -31,13 +31,6 @@
 #if !defined (_Matrix_h)
 #define _Matrix_h 1
 
-// I\'m not sure how this is supposed to work if the .h file declares
-// several classes, each of which is defined in a separate file...
-//
-// #ifdef __GNUG__
-// #pragma interface
-// #endif
-
 #include <stdlib.h>
 #include <stddef.h>
 #include <math.h>
@@ -47,6 +40,9 @@
 // #include <iomanip.h>  // We don\'t use this yet.
 #include <Complex.h>
 
+class ostream;
+class istream;
+
 #ifndef MAPPER_FCN_TYPEDEFS
 #define MAPPER_FCN_TYPEDEFS 1
 
@@ -56,6 +52,8 @@
 
 #endif
 
+#include "Array.h"
+
 // Classes we declare.
 
 class Matrix;
@@ -89,62 +87,24 @@
  * Matrix class
  */
 
-class Matrix
+class Matrix : public Array2<double>
 {
-friend class RowVector;
-friend class DiagMatrix;
-friend class ComplexMatrix;
-friend class ComplexDiagMatrix;
-friend class AEPBALANCE;
-friend class CHOL;
-friend class EIG;
-friend class GEPBALANCE;
-friend class HESS;
-friend class SCHUR;
+friend class LU;
 friend class SVD;
-friend class LU;
-friend class QR;
 
 public:
-  Matrix (void);
-  Matrix (int r, int c);
-  Matrix (int r, int c, double val);
-  Matrix (const Matrix& a);
+
+  Matrix (void) : Array2<double> () { }
+  Matrix (int r, int c) : Array2<double> (r, c) { }
+  Matrix (int r, int c, double val) : Array2<double> (r, c, val) { }
+  Matrix (const Array2<double>& a) : Array2<double> (a) { }
+  Matrix (const Matrix& a) : Array2<double> (a) { }
+  Matrix (const DiagArray<double>& a) : Array2<double> (a) { }
   Matrix (const DiagMatrix& a);
-  Matrix (double a);
- ~Matrix (void);
-
-#if defined (MDEBUG)
-  void *operator new (size_t size)
-    {
-      Matrix *p = ::new Matrix;
-      cerr << "Matrix::new(): " << p << "\n";
-      return p;
-    }
-
-  void operator delete (void *p, size_t size)
-    {
-      cerr << "Matrix::delete(): " << p << "\n";
-      ::delete p;
-    }
-#endif
-
-  Matrix& operator = (const Matrix& a);
-
-  int rows (void) const;
-  int cols (void) const;
-  int columns (void) const;
-
-  double& elem (int r, int c);
-  double& checkelem (int r, int c);
-  double& operator () (int r, int c);
-
-  double elem (int r, int c) const; // const access
-  double checkelem (int r, int c) const;
-  double operator () (int r, int c) const;
-
-  Matrix& resize (int r, int c);
-  Matrix& resize (int r, int c, double val);
+//  Matrix (double a) : Array2<double> (1, 1, a) { }
+
+  Matrix& operator = (const Matrix& a)
+    { return Array2<double>::operator = (a); }
 
   int operator == (const Matrix& a) const;
   int operator != (const Matrix& a) const;
@@ -183,9 +143,9 @@
   ColumnVector column (int i) const;
   ColumnVector column (char *s) const;
 
-  Matrix inverse (int& info, double& rcond) const;
+  Matrix inverse (void) const;
   Matrix inverse (int& info) const;
-  Matrix inverse (void) const;
+  Matrix inverse (int& info, double& rcond) const;
 
   ComplexMatrix fourier (void) const;
   ComplexMatrix ifourier (void) const;
@@ -229,67 +189,59 @@
   ComplexColumnVector lssolve (const ComplexColumnVector& b, int& info,
 			       int& rank) const;
 
-// matrix by scalar -> matrix operations
-
-  Matrix operator + (double s) const;
-  Matrix operator - (double s) const;
-  Matrix operator * (double s) const;
-  Matrix operator / (double s) const;
-
-  ComplexMatrix operator + (const Complex& s) const;
-  ComplexMatrix operator - (const Complex& s) const;
-  ComplexMatrix operator * (const Complex& s) const;
-  ComplexMatrix operator / (const Complex& s) const;
-
-// scalar by matrix -> matrix operations
-
-  friend Matrix operator + (double s, const Matrix& a);
-  friend Matrix operator - (double s, const Matrix& a);
-  friend Matrix operator * (double s, const Matrix& a);
-  friend Matrix operator / (double s, const Matrix& a);
-
-// matrix by column vector -> column vector operations
-
-  ColumnVector operator * (const ColumnVector& a) const;
-
-  ComplexColumnVector operator * (const ComplexColumnVector& a) const;
-
-// matrix by diagonal matrix -> matrix operations
-
-  Matrix operator + (const DiagMatrix& a) const;
-  Matrix operator - (const DiagMatrix& a) const;
-  Matrix operator * (const DiagMatrix& a) const;
-
-  ComplexMatrix operator + (const ComplexDiagMatrix& a) const;
-  ComplexMatrix operator - (const ComplexDiagMatrix& a) const;
-  ComplexMatrix operator * (const ComplexDiagMatrix& a) const;
+  Matrix& operator += (const Matrix& a);
+  Matrix& operator -= (const Matrix& a);
 
   Matrix& operator += (const DiagMatrix& a);
   Matrix& operator -= (const DiagMatrix& a);
 
+// unary operations
+
+  Matrix operator ! (void) const;
+
+// matrix by scalar -> matrix operations
+
+  friend ComplexMatrix operator + (const Matrix& a, const Complex& s);
+  friend ComplexMatrix operator - (const Matrix& a, const Complex& s);
+  friend ComplexMatrix operator * (const Matrix& a, const Complex& s);
+  friend ComplexMatrix operator / (const Matrix& a, const Complex& s);
+
+// scalar by matrix -> matrix operations
+
+  friend ComplexMatrix operator + (const Complex& s, const Matrix& a);
+  friend ComplexMatrix operator - (const Complex& s, const Matrix& a);
+  friend ComplexMatrix operator * (const Complex& s, const Matrix& a);
+  friend ComplexMatrix operator / (const Complex& s, const Matrix& a);
+
+// matrix by column vector -> column vector operations
+
+  friend ColumnVector operator * (const Matrix& a, const ColumnVector& b);
+  friend ComplexColumnVector operator * (const Matrix& a,
+					 const ComplexColumnVector& b);
+
+// matrix by diagonal matrix -> matrix operations
+
+  friend Matrix operator + (const Matrix& a, const DiagMatrix& b);
+  friend Matrix operator - (const Matrix& a, const DiagMatrix& b);
+  friend Matrix operator * (const Matrix& a, const DiagMatrix& b);
+
+  friend ComplexMatrix operator + (const Matrix& a,
+				   const ComplexDiagMatrix& b); 
+  friend ComplexMatrix operator - (const Matrix& a,
+				   const ComplexDiagMatrix& b);
+  friend ComplexMatrix operator * (const Matrix& a,
+				   const ComplexDiagMatrix& b);
+
 // matrix by matrix -> matrix operations
 
-  Matrix operator + (const Matrix& a) const;
-  Matrix operator - (const Matrix& a) const;
-  Matrix operator * (const Matrix& a) const;
-
-  ComplexMatrix operator + (const ComplexMatrix& a) const;
-  ComplexMatrix operator - (const ComplexMatrix& a) const;
-  ComplexMatrix operator * (const ComplexMatrix& a) const;
-
-  Matrix product (const Matrix& a) const;    // element by element
-  Matrix quotient (const Matrix& a) const;   // element by element
-
-  ComplexMatrix product (const ComplexMatrix& a) const;  // element by element
-  ComplexMatrix quotient (const ComplexMatrix& a) const; // element by element
-
-  Matrix& operator += (const Matrix& a);
-  Matrix& operator -= (const Matrix& a);
-
-// unary operations
-
-  Matrix operator - (void) const;
-  Matrix operator ! (void) const;
+  friend Matrix operator * (const Matrix& a, const Matrix& b);
+  friend ComplexMatrix operator * (const Matrix& a, const ComplexMatrix& b);
+
+  friend ComplexMatrix operator + (const Matrix& a, const ComplexMatrix& b);
+  friend ComplexMatrix operator - (const Matrix& a, const ComplexMatrix& b);
+
+  friend ComplexMatrix product (const Matrix& a, const ComplexMatrix& b);
+  friend ComplexMatrix quotient (const Matrix& a, const ComplexMatrix& b);
 
 // other operations
 
@@ -325,78 +277,40 @@
   friend ostream& operator << (ostream& os, const Matrix& a);
   friend istream& operator >> (istream& is, Matrix& a);
 
-// conversions
-
-  double *fortran_vec (void) const;
+// Until templates really work with g++:
+
+#define KLUDGE_MATRICES
+#define TYPE double
+#define KL_MAT_TYPE Matrix
+#include "mx-kludge.h"
+#undef KLUDGE_MATRICES
+#undef TYPE
+#undef KL_MAT_TYPE
 
 private:
-  int nr;
-  int nc;
-  int len;
-  double *data;
-
-  Matrix (double *d, int r, int c);
+
+  Matrix (double *d, int r, int c) : Array2<double> (d, r, c) { }
 };
 
-inline Matrix::Matrix (void) { nr = 0; nc = 0; len = 0; data = 0; }
-
-inline Matrix::Matrix (double *d, int r, int c)
-  { nr = r; nc = c; len = nr*nc; data = d; }
-
-inline Matrix::~Matrix (void) { delete [] data; data = 0; }
-
-inline int Matrix::rows (void) const { return nr; }
-inline int Matrix::cols (void) const { return nc; }
-inline int Matrix::columns (void) const { return nc; } 
-
-inline double& Matrix::elem (int r, int c) { return data[nr*c+r]; }
-
-inline double& Matrix::operator () (int r, int c)
-  { return checkelem (r, c); }
-
-inline double Matrix::elem (int r, int c) const { return data[nr*c+r]; }
-
-inline double Matrix::operator () (int r, int c) const
-  { return checkelem (r, c); }
-
-inline double *Matrix::fortran_vec (void) const { return data; }
-
 /*
  * Column Vector class
  */
 
-class ColumnVector
+class ColumnVector : public Array<double>
 {
-friend class Matrix;
-friend class RowVector;
-friend class DiagMatrix;
-friend class ComplexMatrix;
-friend class ComplexColumnVector;
-friend class ComplexDiagMatrix;
-
 public:
-  ColumnVector (void);
-  ColumnVector (int n);
-  ColumnVector (int n, double val);
-  ColumnVector (const ColumnVector& a);
-  ColumnVector (double a);
- ~ColumnVector (void);
-
-  ColumnVector& operator = (const ColumnVector& a);
-
-  int capacity (void) const;
-  int length (void) const;
-
-  double& elem (int n);
-  double& checkelem (int n);
-  double& operator () (int n);
-
-  double elem (int n) const; // const access
-  double checkelem (int n) const;
-  double operator () (int n) const;
-
-  ColumnVector& resize (int n);
-  ColumnVector& resize (int n, double val);
+
+  ColumnVector (void) : Array<double> () { }
+  ColumnVector (int n) : Array<double> (n) { }
+  ColumnVector (int n, double val) : Array<double> (n, val) { }
+  ColumnVector (const Array<double>& a) : Array<double> (a) { }
+  ColumnVector (const ColumnVector& a) : Array<double> (a) { }
+//  ColumnVector (double a) : Array<double> (1, a) { }
+
+  ColumnVector& operator = (const ColumnVector& a)
+    { return Array<double>::operator = (a); }
+
+//  operator Array<double>& () const { return *this; }
 
   int operator == (const ColumnVector& a) const;
   int operator != (const ColumnVector& a) const;
@@ -416,51 +330,55 @@
 
   ColumnVector extract (int r1, int r2) const;
 
-// column vector by scalar -> column vector operations
-
-  ColumnVector operator + (double s) const;
-  ColumnVector operator - (double s) const;
-  ColumnVector operator * (double s) const;
-  ColumnVector operator / (double s) const;
-
-  ComplexColumnVector operator + (const Complex& s) const;
-  ComplexColumnVector operator - (const Complex& s) const;
-  ComplexColumnVector operator * (const Complex& s) const;
-  ComplexColumnVector operator / (const Complex& s) const;
-
-// scalar by column vector -> column vector operations
-
-  friend ColumnVector operator + (double s, const ColumnVector& a);
-  friend ColumnVector operator - (double s, const ColumnVector& a);
-  friend ColumnVector operator * (double s, const ColumnVector& a);
-  friend ColumnVector operator / (double s, const ColumnVector& a);
-
-// column vector by row vector -> matrix operations
-
-  Matrix operator * (const RowVector& a) const;
-
-  ComplexMatrix operator * (const ComplexRowVector& a) const;
-
 // column vector by column vector -> column vector operations
 
-  ColumnVector operator + (const ColumnVector& a) const;
-  ColumnVector operator - (const ColumnVector& a) const;
-
-  ComplexColumnVector operator + (const ComplexColumnVector& a) const;
-  ComplexColumnVector operator - (const ComplexColumnVector& a) const;
-
-  ColumnVector product (const ColumnVector& a) const;  // element by element
-  ColumnVector quotient (const ColumnVector& a) const; // element by element
-
-  ComplexColumnVector product (const ComplexColumnVector& a) const;
-  ComplexColumnVector quotient (const ComplexColumnVector& a) const;
-
   ColumnVector& operator += (const ColumnVector& a);
   ColumnVector& operator -= (const ColumnVector& a);
 
-// unary operations
-
-  ColumnVector operator - (void) const;
+// column vector by scalar -> column vector operations
+
+  friend ComplexColumnVector operator + (const ColumnVector& a,
+					 const Complex& s);  
+  friend ComplexColumnVector operator - (const ColumnVector& a,
+					 const Complex& s);
+  friend ComplexColumnVector operator * (const ColumnVector& a,
+					 const Complex& s);
+  friend ComplexColumnVector operator / (const ColumnVector& a,
+					 const Complex& s);
+
+// scalar by column vector -> column vector operations
+
+  friend ComplexColumnVector operator + (const Complex& s,
+					 const ColumnVector& a); 
+  friend ComplexColumnVector operator - (const Complex& s,
+					 const ColumnVector& a);
+  friend ComplexColumnVector operator * (const Complex& s,
+					 const ColumnVector& a);
+  friend ComplexColumnVector operator / (const Complex& s,
+					 const ColumnVector& a);
+
+// column vector by row vector -> matrix operations
+
+  friend Matrix operator * (const ColumnVector& a, const RowVector& a);
+
+  friend ComplexMatrix operator * (const ColumnVector& a,
+				   const ComplexRowVector& b);
+
+// column vector by column vector -> column vector operations
+
+  friend ComplexColumnVector operator + (const ComplexColumnVector& a,
+					 const ComplexColumnVector& b);
+
+  friend ComplexColumnVector operator - (const ComplexColumnVector& a,
+					 const ComplexColumnVector& b); 
+
+  friend ComplexColumnVector product (const ComplexColumnVector& a,
+				      const ComplexColumnVector& b); 
+
+  friend ComplexColumnVector quotient (const ComplexColumnVector& a,
+				       const ComplexColumnVector& b); 
+
+// other operations
 
   friend ColumnVector map (d_d_Mapper f, const ColumnVector& a);
   void map (d_d_Mapper f);
@@ -472,70 +390,38 @@
 
   friend ostream& operator << (ostream& os, const ColumnVector& a);
 
-// conversions
-
-  double *fortran_vec (void) const;
+#define KLUDGE_VECTORS
+#define TYPE double
+#define KL_VEC_TYPE ColumnVector
+#include "mx-kludge.h"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
 
 private:
-  int len;
-  double *data;
-
-  ColumnVector (double *d, int l);
+
+  ColumnVector (double *d, int l) : Array<double> (d, l) { }
 };
 
-inline ColumnVector::ColumnVector (void) { len = 0; data = 0; }
-inline ColumnVector::ColumnVector (double *d, int l) { len = l; data = d; }
-inline ColumnVector::~ColumnVector (void) { delete [] data; data = 0; }
-
-inline int ColumnVector::capacity (void) const { return len; }
-inline int ColumnVector::length (void) const { return len; }
-
-inline double& ColumnVector::elem (int n) { return data[n]; }
-
-inline double& ColumnVector::operator () (int n) { return checkelem (n); }
-
-inline double ColumnVector::elem (int n) const { return data[n]; }
-
-inline double ColumnVector::operator () (int n) const { return checkelem (n); }
-
-inline double *ColumnVector::fortran_vec (void) const { return data; }
-
 /*
  * Row Vector class
  */
 
-class RowVector
+class RowVector : public Array<double>
 {
-friend class Matrix;
-friend class DiagMatrix;
-friend class ColumnVector;
-friend class ComplexMatrix;
-friend class ComplexRowVector;
-friend class ComplexDiagMatrix;
-
 public:
-  RowVector (void);
-  RowVector (int n);
-  RowVector (int n, double val);
-  RowVector (const RowVector& a);
-  RowVector (double a);
- ~RowVector (void);
-
-  RowVector& operator = (const RowVector& a);
-
-  int capacity (void) const;
-  int length (void) const;
-
-  double& elem (int n);
-  double& checkelem (int n);
-  double& operator () (int n);
-
-  double elem (int n) const; // const access
-  double checkelem (int n) const;
-  double operator () (int n) const;
-
-  RowVector& resize (int n);
-  RowVector& resize (int n, double val);
+
+  RowVector (void) : Array<double> () { }
+  RowVector (int n) : Array<double> (n) { }
+  RowVector (int n, double val) : Array<double> (n, val) { }
+  RowVector (const Array<double>& a) : Array<double> (a) { }
+  RowVector (const RowVector& a) : Array<double> (a) { }
+//  RowVector (double a) : Array<double> (1, a) { }
+
+  RowVector& operator = (const RowVector& a)
+    { return Array<double>::operator = (a); }
+
+//  operator Array<double>& () const { return *this; }
 
   int operator == (const RowVector& a) const;
   int operator != (const RowVector& a) const;
@@ -555,57 +441,51 @@
 
   RowVector extract (int c1, int c2) const;
 
-// row vector by scalar -> row vector operations
-
-  RowVector operator + (double s) const;
-  RowVector operator - (double s) const;
-  RowVector operator * (double s) const;
-  RowVector operator / (double s) const;
-
-  ComplexRowVector operator + (const Complex& s) const;
-  ComplexRowVector operator - (const Complex& s) const;
-  ComplexRowVector operator * (const Complex& s) const;
-  ComplexRowVector operator / (const Complex& s) const;
-
-// scalar by row vector -> row vector operations
-
-  friend RowVector operator + (double s, const RowVector& a);
-  friend RowVector operator - (double s, const RowVector& a);
-  friend RowVector operator * (double s, const RowVector& a);
-  friend RowVector operator / (double s, const RowVector& a);
-
-// row vector by column vector -> scalar
-
-  double operator * (const ColumnVector& a) const;
-
-  Complex operator * (const ComplexColumnVector& a) const;
-
-// row vector by matrix -> row vector
-
-  RowVector operator * (const Matrix& a) const;
-
-  ComplexRowVector operator * (const ComplexMatrix& a) const;
-
 // row vector by row vector -> row vector operations
 
-  RowVector operator + (const RowVector& a) const;
-  RowVector operator - (const RowVector& a) const;
-
-  ComplexRowVector operator + (const ComplexRowVector& a) const;
-  ComplexRowVector operator - (const ComplexRowVector& a) const;
-
-  RowVector product (const RowVector& a) const;  // element by element
-  RowVector quotient (const RowVector& a) const; // element by element
-
-  ComplexRowVector product (const ComplexRowVector& a) const;  // el by el
-  ComplexRowVector quotient (const ComplexRowVector& a) const; // el by el
-
   RowVector& operator += (const RowVector& a);
   RowVector& operator -= (const RowVector& a);
 
-// unary operations
-
-  RowVector operator - (void) const;
+// row vector by scalar -> row vector operations
+
+  friend ComplexRowVector operator + (const RowVector& a, const Complex& s);
+  friend ComplexRowVector operator - (const RowVector& a, const Complex& s);
+  friend ComplexRowVector operator * (const RowVector& a, const Complex& s);
+  friend ComplexRowVector operator / (const RowVector& a, const Complex& s);
+
+// scalar by row vector -> row vector operations
+
+  friend ComplexRowVector operator + (const Complex& s, const RowVector& a);
+  friend ComplexRowVector operator - (const Complex& s, const RowVector& a);
+  friend ComplexRowVector operator * (const Complex& s, const RowVector& a);
+  friend ComplexRowVector operator / (const Complex& s, const RowVector& a);
+
+// row vector by column vector -> scalar
+
+  friend double operator * (const RowVector& a, ColumnVector& b);
+
+  friend Complex operator * (const RowVector& a, const ComplexColumnVector& b);
+
+// row vector by matrix -> row vector
+
+  friend RowVector operator * (const RowVector& a, const Matrix& b);
+
+  friend ComplexRowVector operator * (const RowVector& a,
+				      const ComplexMatrix& b);
+
+// row vector by row vector -> row vector operations
+
+  friend ComplexRowVector operator + (const RowVector& a,
+				      const ComplexRowVector& b);
+  friend ComplexRowVector operator - (const RowVector& a,
+				      const ComplexRowVector& b);
+
+  friend ComplexRowVector product (const RowVector& a,
+				   const ComplexRowVector& b);
+  friend ComplexRowVector quotient (const RowVector& a,
+				    const ComplexRowVector& b);
+
+// other operations
 
   friend RowVector map (d_d_Mapper f, const RowVector& a);
   void map (d_d_Mapper f);
@@ -617,72 +497,45 @@
 
   friend ostream& operator << (ostream& os, const RowVector& a);
 
-// conversions
-
-  double *fortran_vec (void) const;
+#define KLUDGE_VECTORS
+#define TYPE double
+#define KL_VEC_TYPE RowVector
+#include "mx-kludge.h"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
 
 private:
-  int len;
-  double *data;
-
-  RowVector (double *d, int l);
+
+  RowVector (double *d, int l) : Array<double> (d, l) { }
 };
 
-inline RowVector::RowVector (void) { len = 0; data = 0; }
-inline RowVector::RowVector (double *d, int l) { len = l; data = d; }
-inline RowVector::~RowVector (void) { delete [] data; data = 0; }
-
-inline int RowVector::capacity (void) const { return len; }
-inline int RowVector::length (void) const { return len; }
-
-inline double& RowVector::elem (int n) { return data[n]; }
-
-inline double& RowVector::operator () (int n) { return checkelem (n); }
-
-inline double RowVector::elem (int n) const { return data[n]; }
-
-inline double RowVector::operator () (int n) const { return checkelem (n); }
-
-inline double *RowVector::fortran_vec (void) const { return data; }
-
 /*
  * Diagonal Matrix class
  */
 
-class DiagMatrix
+class DiagMatrix : public DiagArray<double>
 {
-friend class Matrix;
-friend class ComplexMatrix;
-friend class ComplexDiagMatrix;
+friend class SVD;
+friend class ComplexSVD;
 
 public:
-  DiagMatrix (void);
-  DiagMatrix (int n);
-  DiagMatrix (int n, double val);
-  DiagMatrix (int r, int c);
-  DiagMatrix (int r, int c, double val);
-  DiagMatrix (const RowVector& a);
-  DiagMatrix (const ColumnVector& a);
-  DiagMatrix (const DiagMatrix& a);
-  DiagMatrix (double a);
- ~DiagMatrix (void);
-
-  DiagMatrix& operator = (const DiagMatrix& a);
-
-  int rows (void) const;
-  int cols (void) const;
-  int columns (void) const;
-
-  double& elem (int r, int c);
-  double& checkelem (int r, int c);
-  double& operator () (int r, int c);
-
-  double elem (int r, int c) const; // const access
-  double checkelem (int r, int c) const;
-  double operator () (int r, int c) const;
-
-  DiagMatrix& resize (int r, int c);
-  DiagMatrix& resize (int r, int c, double val);
+
+  DiagMatrix (void) : DiagArray<double> () { }
+  DiagMatrix (int n) : DiagArray<double> (n) { }
+  DiagMatrix (int n, double val) : DiagArray<double> (n, val) { }
+  DiagMatrix (int r, int c) : DiagArray<double> (r, c) { }
+  DiagMatrix (int r, int c, double val) : DiagArray<double> (r, c, val) { }
+  DiagMatrix (const RowVector& a) : DiagArray<double> (a) { }
+  DiagMatrix (const ColumnVector& a) : DiagArray<double> (a) { }
+  DiagMatrix (const DiagArray<double>& a) : DiagArray<double> (a) { }
+  DiagMatrix (const DiagMatrix& a) : DiagArray<double> (a) { }
+//  DiagMatrix (double a) : DiagArray<double> (1, a) { }
+
+  DiagMatrix& operator = (const DiagMatrix& a)
+    { return DiagArray<double>::operator = (a); }
+
+//  operator DiagArray<double>& () const { return *this; }
 
   int operator == (const DiagMatrix& a) const;
   int operator != (const DiagMatrix& a) const;
@@ -708,73 +561,70 @@
   ColumnVector column (int i) const;
   ColumnVector column (char *s) const;
 
+  DiagMatrix inverse (void) const;
   DiagMatrix inverse (int& info) const;
-  DiagMatrix inverse (void) const;
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+  DiagMatrix& operator += (const DiagMatrix& a);
+  DiagMatrix& operator -= (const DiagMatrix& a);
 
 // diagonal matrix by scalar -> matrix operations
 
-  Matrix operator + (double s) const;
-  Matrix operator - (double s) const;
-
-  ComplexMatrix operator + (const Complex& s) const;
-  ComplexMatrix operator - (const Complex& s) const;
+  friend Matrix operator + (const DiagMatrix& a, double s);
+  friend Matrix operator - (const DiagMatrix& a, double s);
+
+  friend ComplexMatrix operator + (const DiagMatrix& a, const Complex& s);
+  friend ComplexMatrix operator - (const DiagMatrix& a, const Complex& s);
 
 // diagonal matrix by scalar -> diagonal matrix operations
 
-  DiagMatrix operator * (double s) const;
-  DiagMatrix operator / (double s) const;
-
-  ComplexDiagMatrix operator * (const Complex& s) const;
-  ComplexDiagMatrix operator / (const Complex& s) const;
+  friend ComplexDiagMatrix operator * (const DiagMatrix& a, const Complex& s);
+  friend ComplexDiagMatrix operator / (const DiagMatrix& a, const Complex& s);
 
 // scalar by diagonal matrix -> matrix operations
 
   friend Matrix operator + (double s, const DiagMatrix& a);
   friend Matrix operator - (double s, const DiagMatrix& a);
 
+  friend ComplexMatrix operator + (const Complex& s, const DiagMatrix& a);
+  friend ComplexMatrix operator - (const Complex& s, const DiagMatrix& a);
+
 // scalar by diagonal matrix -> diagonal matrix operations
 
-  friend DiagMatrix operator * (double s, const DiagMatrix& a);
-  friend DiagMatrix operator / (double s, const DiagMatrix& a);
+  friend ComplexDiagMatrix operator * (const Complex& s, const DiagMatrix& a);
 
 // diagonal matrix by column vector -> column vector operations
 
-  ColumnVector operator * (const ColumnVector& a) const;
-
-  ComplexColumnVector operator * (const ComplexColumnVector& a) const;
+  friend ColumnVector operator * (const DiagMatrix& a, const ColumnVector& b);
+
+  friend ComplexColumnVector operator * (const DiagMatrix& a, const
+					 ComplexColumnVector& b);
 
 // diagonal matrix by diagonal matrix -> diagonal matrix operations
 
-  DiagMatrix operator + (const DiagMatrix& a) const;
-  DiagMatrix operator - (const DiagMatrix& a) const;
-  DiagMatrix operator * (const DiagMatrix& a) const;
-
-  ComplexDiagMatrix operator + (const ComplexDiagMatrix& a) const;
-  ComplexDiagMatrix operator - (const ComplexDiagMatrix& a) const;
-  ComplexDiagMatrix operator * (const ComplexDiagMatrix& a) const;
-
-  DiagMatrix product (const DiagMatrix& a) const;    // element by element
-  DiagMatrix quotient (const DiagMatrix& a) const;   // element by element
-
-  ComplexDiagMatrix product (const ComplexDiagMatrix& a) const;  // el by el
-  ComplexDiagMatrix quotient (const ComplexDiagMatrix& a) const; // el by el
-
-  DiagMatrix& operator += (const DiagMatrix& a);
-  DiagMatrix& operator -= (const DiagMatrix& a);
+  friend ComplexDiagMatrix operator + (const DiagMatrix& a,
+				       const ComplexDiagMatrix& b);
+  friend ComplexDiagMatrix operator - (const DiagMatrix& a,
+				       const ComplexDiagMatrix& b);
+
+  friend ComplexDiagMatrix product (const DiagMatrix& a,
+				    const ComplexDiagMatrix& b);
 
 // diagonal matrix by matrix -> matrix operations
 
-  Matrix operator + (const Matrix& a) const;
-  Matrix operator - (const Matrix& a) const;
-  Matrix operator * (const Matrix& a) const;
-
-  ComplexMatrix operator + (const ComplexMatrix& a) const;
-  ComplexMatrix operator - (const ComplexMatrix& a) const;
-  ComplexMatrix operator * (const ComplexMatrix& a) const;
-
-// unary operations
-
-  DiagMatrix operator - (void) const;
+  friend Matrix operator + (const DiagMatrix& a, const Matrix& b);
+  friend Matrix operator - (const DiagMatrix& a, const Matrix& b);
+  friend Matrix operator * (const DiagMatrix& a, const Matrix& b);
+
+  friend ComplexMatrix operator + (const DiagMatrix& a,
+				   const ComplexMatrix& b);
+  friend ComplexMatrix operator - (const DiagMatrix& a,
+				   const ComplexMatrix& b);
+  friend ComplexMatrix operator * (const DiagMatrix& a,
+				   const ComplexMatrix& b);
+
+// other operations
 
   ColumnVector diag (void) const;
   ColumnVector diag (int k) const;
@@ -783,91 +633,47 @@
 
   friend ostream& operator << (ostream& os, const DiagMatrix& a);
 
+#define KLUDGE_DIAG_MATRICES
+#define TYPE double
+#define KL_DMAT_TYPE DiagMatrix
+#include "mx-kludge.h"
+#undef KLUDGE_DIAG_MATRICES
+#undef TYPE
+#undef KL_DMAT_TYPE
+
 private:
-  int nr;
-  int nc;
-  int len;
-  double *data;
-
-  DiagMatrix (double *d, int nr, int nc);
+
+  DiagMatrix (double *d, int nr, int nc) : DiagArray<double> (d, nr, nc) { }
 };
 
-inline DiagMatrix::DiagMatrix (void)
-  { nr = 0; nc = 0; len = 0; data = 0; }
-
-inline DiagMatrix::DiagMatrix (double *d, int r, int c)
-  { nr = r; nc = c; len = nr < nc ? nr : nc; data = d; }
-
-inline DiagMatrix::~DiagMatrix (void) { delete [] data; data = 0; }
-
-inline int DiagMatrix::rows (void) const { return nr; }
-inline int DiagMatrix::cols (void) const { return nc; }
-inline int DiagMatrix::columns (void) const { return nc; } 
-
-// Would be nice to be able to avoid compiler warning and make this
-// fail on assignment.
-inline double& DiagMatrix::elem (int r, int c)
-  { return (r == c) ? data[r] : 0; }
-
-inline double& DiagMatrix::operator () (int r, int c)
-  { return checkelem (r, c); }
-
-inline double DiagMatrix::elem (int r, int c) const
-  { return (r == c) ? data[r] : 0; }
-
-inline double DiagMatrix::operator () (int r, int c) const
-  { return checkelem (r, c); }
-
 /*
  * Complex Matrix class
  */
 
-class ComplexMatrix
+class ComplexMatrix : public Array2<Complex>
 {
-friend class Matrix;
-friend class DiagMatrix;
-friend class ComplexRowVector;
-friend class ComplexDiagMatrix;
-friend class ComplexAEPBALANCE;
-friend class ComplexCHOL;
-friend class EIG;
-friend class ComplexHESS;
+friend class ComplexLU;
 friend class ComplexSVD;
-friend class ComplexSCHUR;
-friend class ComplexLU;
-friend class ComplexQR;
 
 public:
-  ComplexMatrix (void);
-  ComplexMatrix (int r, int c);
-  ComplexMatrix (int r, int c, double val);
-  ComplexMatrix (int r, int c, const Complex& val);
+ 
+  ComplexMatrix (void) : Array2<Complex> () { }
+  ComplexMatrix (int r, int c) : Array2<Complex> (r, c) { }
+  ComplexMatrix (int r, int c, const Complex& val)
+    : Array2<Complex> (r, c, val) { }
   ComplexMatrix (const Matrix& a);
-  ComplexMatrix (const ComplexMatrix& a);
+  ComplexMatrix (const Array2<Complex>& a) : Array2<Complex> (a) { }
+  ComplexMatrix (const ComplexMatrix& a) : Array2<Complex> (a) { }
   ComplexMatrix (const DiagMatrix& a);
+  ComplexMatrix (const DiagArray<Complex>& a) : Array2<Complex> (a) { }
   ComplexMatrix (const ComplexDiagMatrix& a);
-  ComplexMatrix (double a);
-  ComplexMatrix (const Complex& a);
- ~ComplexMatrix (void);
-
-  ComplexMatrix& operator = (const Matrix& a);
-  ComplexMatrix& operator = (const ComplexMatrix& a);
-
-  int rows (void) const;
-  int cols (void) const;
-  int columns (void) const;
-
-  Complex& elem (int r, int c);
-  Complex& checkelem (int r, int c);
-  Complex& operator () (int r, int c);
-
-  Complex elem (int r, int c) const; // const access
-  Complex checkelem (int r, int c) const;
-  Complex operator () (int r, int c) const;
-
-  ComplexMatrix& resize (int r, int c);
-  ComplexMatrix& resize (int r, int c, double val);
-  ComplexMatrix& resize (int r, int c, const Complex& val);
+//  ComplexMatrix (double a) : Array2<Complex> (1, 1, a) { }
+//  ComplexMatrix (const Complex& a) : Array2<Complex> (1, 1, a) { }
+
+  ComplexMatrix& operator = (const ComplexMatrix& a)
+    { return Array2<Complex>::operator = (a); }
+
+//  operator Array2<Complex>& () const { return *this; }
 
   int operator == (const ComplexMatrix& a) const;
   int operator != (const ComplexMatrix& a) const;
@@ -928,9 +734,9 @@
   ComplexColumnVector column (int i) const;
   ComplexColumnVector column (char *s) const;
 
-  ComplexMatrix inverse (int& info, double& rcond) const;
+  ComplexMatrix inverse (void) const;
   ComplexMatrix inverse (int& info) const;
-  ComplexMatrix inverse (void) const;
+  ComplexMatrix inverse (int& info, double& rcond) const;
 
   ComplexMatrix fourier (void) const;
   ComplexMatrix ifourier (void) const;
@@ -947,75 +753,23 @@
   ComplexMatrix solve (const ComplexMatrix& b, int& info) const;
   ComplexMatrix solve (const ComplexMatrix& b, int& info, double& rcond) const;
 
-  ComplexColumnVector solve (const ColumnVector& b) const;
-  ComplexColumnVector solve (const ColumnVector& b, int& info) const;
-  ComplexColumnVector solve (const ColumnVector& b, int& info,
-			     double& rcond) const;
-
   ComplexColumnVector solve (const ComplexColumnVector& b) const;
   ComplexColumnVector solve (const ComplexColumnVector& b, int& info) const;
   ComplexColumnVector solve (const ComplexColumnVector& b, int& info,
 			     double& rcond) const;
 
-  ComplexMatrix lssolve (const Matrix& b) const;
-  ComplexMatrix lssolve (const Matrix& b, int& info) const;
-  ComplexMatrix lssolve (const Matrix& b, int& info, int& rank) const;
-
   ComplexMatrix lssolve (const ComplexMatrix& b) const;
   ComplexMatrix lssolve (const ComplexMatrix& b, int& info) const;
   ComplexMatrix lssolve (const ComplexMatrix& b, int& info,
 			 int& rank) const;
 
-  ComplexColumnVector lssolve (const ColumnVector& b) const;
-  ComplexColumnVector lssolve (const ColumnVector& b, int& info) const;
-  ComplexColumnVector lssolve (const ColumnVector& b, int& info,
-			       int& rank) const;
-
   ComplexColumnVector lssolve (const ComplexColumnVector& b) const;
   ComplexColumnVector lssolve (const ComplexColumnVector& b, int& info) const;
   ComplexColumnVector lssolve (const ComplexColumnVector& b, int& info,
 			       int& rank) const;
 
-// matrix by scalar -> matrix operations
-
-  ComplexMatrix operator + (double s) const;
-  ComplexMatrix operator - (double s) const;
-  ComplexMatrix operator * (double s) const;
-  ComplexMatrix operator / (double s) const;
-
-  ComplexMatrix operator + (const Complex& s) const;
-  ComplexMatrix operator - (const Complex& s) const;
-  ComplexMatrix operator * (const Complex& s) const;
-  ComplexMatrix operator / (const Complex& s) const;
-
-// scalar by matrix -> matrix operations
-
-  friend ComplexMatrix operator + (double s, const ComplexMatrix& a);
-  friend ComplexMatrix operator - (double s, const ComplexMatrix& a);
-  friend ComplexMatrix operator * (double s, const ComplexMatrix& a);
-  friend ComplexMatrix operator / (double s, const ComplexMatrix& a);
-
-  friend ComplexMatrix operator + (const Complex& s, const ComplexMatrix& a);
-  friend ComplexMatrix operator - (const Complex& s, const ComplexMatrix& a);
-  friend ComplexMatrix operator * (const Complex& s, const ComplexMatrix& a);
-  friend ComplexMatrix operator / (const Complex& s, const ComplexMatrix& a);
-
-// matrix by column vector -> column vector operations
-
-  ComplexColumnVector operator * (const ColumnVector& a) const;
-
-  ComplexColumnVector operator * (const ComplexColumnVector& a) const;
-
 // matrix by diagonal matrix -> matrix operations
 
-  ComplexMatrix operator + (const DiagMatrix& a) const;
-  ComplexMatrix operator - (const DiagMatrix& a) const;
-  ComplexMatrix operator * (const DiagMatrix& a) const;
-
-  ComplexMatrix operator + (const ComplexDiagMatrix& a) const;
-  ComplexMatrix operator - (const ComplexDiagMatrix& a) const;
-  ComplexMatrix operator * (const ComplexDiagMatrix& a) const;
-
   ComplexMatrix& operator += (const DiagMatrix& a);
   ComplexMatrix& operator -= (const DiagMatrix& a);
 
@@ -1024,20 +778,6 @@
 
 // matrix by matrix -> matrix operations
 
-  ComplexMatrix operator + (const Matrix& a) const;
-  ComplexMatrix operator - (const Matrix& a) const;
-  ComplexMatrix operator * (const Matrix& a) const;
-
-  ComplexMatrix operator + (const ComplexMatrix& a) const;
-  ComplexMatrix operator - (const ComplexMatrix& a) const;
-  ComplexMatrix operator * (const ComplexMatrix& a) const;
-
-  ComplexMatrix product (const Matrix& a) const;    // element by element
-  ComplexMatrix quotient (const Matrix& a) const;   // element by element
-
-  ComplexMatrix product (const ComplexMatrix& a) const;  // element by element
-  ComplexMatrix quotient (const ComplexMatrix& a) const; // element by element
-
   ComplexMatrix& operator += (const Matrix& a);
   ComplexMatrix& operator -= (const Matrix& a);
 
@@ -1046,9 +786,58 @@
 
 // unary operations
 
-  ComplexMatrix operator - (void) const;
   Matrix operator ! (void) const;
 
+// matrix by scalar -> matrix operations
+
+  friend ComplexMatrix operator + (const ComplexMatrix& a, double s);
+  friend ComplexMatrix operator - (const ComplexMatrix& a, double s);
+  friend ComplexMatrix operator * (const ComplexMatrix& a, double s);
+  friend ComplexMatrix operator / (const ComplexMatrix& a, double s);
+
+// scalar by matrix -> matrix operations
+
+  friend ComplexMatrix operator + (double s, const ComplexMatrix& a);
+  friend ComplexMatrix operator - (double s, const ComplexMatrix& a);
+  friend ComplexMatrix operator * (double s, const ComplexMatrix& a);
+  friend ComplexMatrix operator / (double s, const ComplexMatrix& a);
+
+// matrix by column vector -> column vector operations
+
+  friend ComplexColumnVector operator * (const ComplexMatrix& a,
+					 const ColumnVector& b);
+
+  friend ComplexColumnVector operator * (const ComplexMatrix& a,
+					 const ComplexColumnVector& b);
+
+// matrix by diagonal matrix -> matrix operations
+
+  friend ComplexMatrix operator + (const ComplexMatrix& a,
+				   const DiagMatrix& b);
+  friend ComplexMatrix operator - (const ComplexMatrix& a,
+				   const DiagMatrix& b);
+  friend ComplexMatrix operator * (const ComplexMatrix& a,
+				   const DiagMatrix& b);
+
+  friend ComplexMatrix operator + (const ComplexMatrix& a,
+				   const ComplexDiagMatrix& b);
+  friend ComplexMatrix operator - (const ComplexMatrix& a,
+				   const ComplexDiagMatrix& b);
+  friend ComplexMatrix operator * (const ComplexMatrix& a,
+				   const ComplexDiagMatrix& b);
+
+// matrix by matrix -> matrix operations
+
+  friend ComplexMatrix operator + (const ComplexMatrix& a, const Matrix& b);
+  friend ComplexMatrix operator - (const ComplexMatrix& a, const Matrix& b);
+
+  friend ComplexMatrix operator * (const ComplexMatrix& a, const Matrix& b);
+  friend ComplexMatrix operator * (const ComplexMatrix& a,
+				   const ComplexMatrix& b);
+
+  friend ComplexMatrix product (const ComplexMatrix& a, const Matrix& b);
+  friend ComplexMatrix quotient (const ComplexMatrix& a, const Matrix& b);
+
 // other operations
 
   friend ComplexMatrix map (c_c_Mapper f, const ComplexMatrix& a);
@@ -1084,83 +873,41 @@
   friend ostream& operator << (ostream& os, const ComplexMatrix& a);
   friend istream& operator >> (istream& is, ComplexMatrix& a);
 
-// conversions
-
-  Complex *fortran_vec (void) const;
+#define KLUDGE_MATRICES
+#define TYPE Complex
+#define KL_MAT_TYPE ComplexMatrix
+#include "mx-kludge.h"
+#undef KLUDGE_MATRICES
+#undef TYPE
+#undef KL_MAT_TYPE
 
 private:
-  int nr;
-  int nc;
-  int len;
-  Complex *data;
-
-  ComplexMatrix (Complex *d, int r, int c);
+
+  ComplexMatrix (Complex *d, int r, int c) : Array2<Complex> (d, r, c) { }
 };
 
-inline ComplexMatrix::ComplexMatrix (void)
-   { nr = 0; nc = 0; len = 0; data = 0; }
-
-inline ComplexMatrix::ComplexMatrix (Complex *d, int r, int c)
-  { nr = r; nc = c; len = nr*nc; data = d; }
-
-inline ComplexMatrix::~ComplexMatrix (void) { delete [] data; data = 0; }
-
-inline int ComplexMatrix::rows (void) const { return nr; }
-inline int ComplexMatrix::cols (void) const { return nc; }
-inline int ComplexMatrix::columns (void) const { return nc; } 
-
-inline Complex& ComplexMatrix::elem (int r, int c) { return data[nr*c+r]; }
-
-inline Complex& ComplexMatrix::operator () (int r, int c)
-  { return checkelem (r, c); }
-
-inline Complex ComplexMatrix::elem (int r, int c) const
-  { return data[nr*c+r]; }
-
-inline Complex ComplexMatrix::operator () (int r, int c) const
-  { return checkelem (r, c); }
-
-inline Complex *ComplexMatrix::fortran_vec (void) const { return data; }
-
 /*
  * Complex Column Vector class
  */
 
-class ComplexColumnVector
+class ComplexColumnVector : public Array<Complex>
 {
-friend class DiagMatrix;
-friend class ComplexMatrix;
-friend class ColumnVector;
-friend class ComplexDiagMatrix;
-
 public:
-  ComplexColumnVector (void);
-  ComplexColumnVector (int n);
-  ComplexColumnVector (int n, double val);
-  ComplexColumnVector (int n, const Complex& val);
+
+  ComplexColumnVector (void) : Array<Complex> () { }
+  ComplexColumnVector (int n) : Array<Complex> (n) { }
+  ComplexColumnVector (int n, const Complex& val)
+    : Array<Complex> (n, val) { }
   ComplexColumnVector (const ColumnVector& a);
-  ComplexColumnVector (const ComplexColumnVector& a);
-  ComplexColumnVector (double a);
-  ComplexColumnVector (const Complex& a);
- ~ComplexColumnVector (void);
-
-  ComplexColumnVector& operator = (const ColumnVector& a);
-  ComplexColumnVector& operator = (const ComplexColumnVector& a);
-
-  int capacity (void) const;
-  int length (void) const;
-
-  Complex& elem (int n);
-  Complex& checkelem (int n);
-  Complex& operator () (int n);
-
-  Complex elem (int n) const; // const access
-  Complex checkelem (int n) const;
-  Complex operator () (int n) const;
-
-  ComplexColumnVector& resize (int n);
-  ComplexColumnVector& resize (int n, double val);
-  ComplexColumnVector& resize (int n, const Complex& val);
+  ComplexColumnVector (const Array<Complex>& a) : Array<Complex> (a) { }
+  ComplexColumnVector (const ComplexColumnVector& a) : Array<Complex> (a) { }
+//  ComplexColumnVector (double a) : Array<Complex> (1, a) { }
+//  ComplexColumnVector (const Complex& a) : Array<Complex> (1, a) { }
+
+  ComplexColumnVector& operator = (const ComplexColumnVector& a)
+    { return Array<Complex>::operator = (a); }
+
+//  operator Array<Complex>& () const { return *this; }
 
   int operator == (const ComplexColumnVector& a) const;
   int operator != (const ComplexColumnVector& a) const;
@@ -1189,17 +936,24 @@
 
   ComplexColumnVector extract (int r1, int r2) const;
 
+// column vector by column vector -> column vector operations
+
+  ComplexColumnVector& operator += (const ColumnVector& a);
+  ComplexColumnVector& operator -= (const ColumnVector& a);
+
+  ComplexColumnVector& operator += (const ComplexColumnVector& a);
+  ComplexColumnVector& operator -= (const ComplexColumnVector& a);
+
 // column vector by scalar -> column vector operations
 
-  ComplexColumnVector operator + (double s) const;
-  ComplexColumnVector operator - (double s) const;
-  ComplexColumnVector operator * (double s) const;
-  ComplexColumnVector operator / (double s) const;
-
-  ComplexColumnVector operator + (const Complex& s) const;
-  ComplexColumnVector operator - (const Complex& s) const;
-  ComplexColumnVector operator * (const Complex& s) const;
-  ComplexColumnVector operator / (const Complex& s) const;
+  friend ComplexColumnVector operator + (const ComplexColumnVector& a,
+					 double s);
+  friend ComplexColumnVector operator - (const ComplexColumnVector& a,
+					 double s);
+  friend ComplexColumnVector operator * (const ComplexColumnVector& a,
+					 double s);
+  friend ComplexColumnVector operator / (const ComplexColumnVector& a,
+					 double s);
 
 // scalar by column vector -> column vector operations
 
@@ -1212,44 +966,24 @@
   friend ComplexColumnVector operator / (double s,
 					 const ComplexColumnVector& a);
 
-  friend ComplexColumnVector operator + (const Complex& s,
-					 const ComplexColumnVector& a);
-  friend ComplexColumnVector operator - (const Complex& s,
-					 const ComplexColumnVector& a);
-  friend ComplexColumnVector operator * (const Complex& s,
-					 const ComplexColumnVector& a);
-  friend ComplexColumnVector operator / (const Complex& s,
-					 const ComplexColumnVector& a);
-
 // column vector by row vector -> matrix operations
 
-  ComplexMatrix operator * (const RowVector& a) const;
-
-  ComplexMatrix operator * (const ComplexRowVector& a) const;
+  friend ComplexMatrix operator * (const ComplexColumnVector& a,
+				   const ComplexRowVector& b);
 
 // column vector by column vector -> column vector operations
 
-  ComplexColumnVector operator + (const ColumnVector& a) const;
-  ComplexColumnVector operator - (const ColumnVector& a) const;
-
-  ComplexColumnVector operator + (const ComplexColumnVector& a) const;
-  ComplexColumnVector operator - (const ComplexColumnVector& a) const;
-
-  ComplexColumnVector product (const ColumnVector& a) const;  // el by el
-  ComplexColumnVector quotient (const ColumnVector& a) const; // el by el
-
-  ComplexColumnVector product (const ComplexColumnVector& a) const;
-  ComplexColumnVector quotient (const ComplexColumnVector& a) const;
-
-  ComplexColumnVector& operator += (const ColumnVector& a);
-  ComplexColumnVector& operator -= (const ColumnVector& a);
-
-  ComplexColumnVector& operator += (const ComplexColumnVector& a);
-  ComplexColumnVector& operator -= (const ComplexColumnVector& a);
-
-// unary operations
-
-  ComplexColumnVector operator - (void) const;
+  friend ComplexColumnVector operator + (const ComplexColumnVector& a,
+					 const ColumnVector& b);
+  friend ComplexColumnVector operator - (const ComplexColumnVector& a,
+					 const ColumnVector& b);
+
+  friend ComplexColumnVector product (const ComplexColumnVector& a,
+				      const ColumnVector& b);
+  friend ComplexColumnVector quotient (const ComplexColumnVector& a,
+				       const ColumnVector& b);
+
+// other operations
 
   friend ComplexColumnVector map (c_c_Mapper f, const ComplexColumnVector& a);
   friend ColumnVector map (d_c_Mapper f, const ComplexColumnVector& a);
@@ -1262,77 +996,40 @@
 
   friend ostream& operator << (ostream& os, const ComplexColumnVector& a);
 
-// conversions
-
-  Complex *fortran_vec (void) const;
+#define KLUDGE_VECTORS
+#define TYPE Complex
+#define KL_VEC_TYPE ComplexColumnVector
+#include "mx-kludge.h"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
 
 private:
-  int len;
-  Complex *data;
-
-  ComplexColumnVector (Complex *d, int l);
+
+  ComplexColumnVector (Complex *d, int l) : Array<Complex> (d, l) { }
 };
 
-inline ComplexColumnVector::ComplexColumnVector (void) { len = 0; data = 0; }
-inline ComplexColumnVector::ComplexColumnVector (Complex *d, int l)
-  { len = l; data = d; }
-inline ComplexColumnVector::~ComplexColumnVector (void)
-  { delete [] data; data = 0; }
-
-inline int ComplexColumnVector::capacity (void) const { return len; }
-inline int ComplexColumnVector::length (void) const { return len; }
-
-inline Complex& ComplexColumnVector::elem (int n) { return data[n]; }
-
-inline Complex& ComplexColumnVector::operator () (int n)
-  { return checkelem (n); }
-
-inline Complex ComplexColumnVector::elem (int n) const { return data[n]; }
-
-inline Complex ComplexColumnVector::operator () (int n) const
-  { return checkelem (n); }
-
-inline Complex *ComplexColumnVector::fortran_vec (void) const { return data; }
-
 /*
  * Complex Row Vector class
  */
 
-class ComplexRowVector
+class ComplexRowVector : public Array<Complex>
 {
-friend class RowVector;
-friend class ComplexMatrix;
-friend class ComplexColumnVector;
-friend class ComplexDiagMatrix;
-
 public:
-  ComplexRowVector (void);
-  ComplexRowVector (int n);
-  ComplexRowVector (int n, double val);
-  ComplexRowVector (int n, const Complex& val);
+
+  ComplexRowVector (void) : Array<Complex> () { }
+  ComplexRowVector (int n) : Array<Complex> (n) { }
+  ComplexRowVector (int n, const Complex& val) : Array<Complex> (n, val) { }
   ComplexRowVector (const RowVector& a);
-  ComplexRowVector (const ComplexRowVector& a);
-  ComplexRowVector (double a);
-  ComplexRowVector (const Complex& a);
- ~ComplexRowVector (void);
-
-  ComplexRowVector& operator = (const RowVector& a);
-  ComplexRowVector& operator = (const ComplexRowVector& a);
-
-  int capacity (void) const;
-  int length (void) const;
-
-  Complex& checkelem (int n);
-  Complex& elem (int n);
-  Complex& operator () (int n);
-
-  Complex checkelem (int n) const; // const access
-  Complex elem (int n) const;
-  Complex operator () (int n) const;
-
-  ComplexRowVector& resize (int n);
-  ComplexRowVector& resize (int n, double val);
-  ComplexRowVector& resize (int n, const Complex& val);
+  ComplexRowVector (const Array<Complex>& a) : Array<Complex> (a) { }
+  ComplexRowVector (const ComplexRowVector& a) : Array<Complex> (a) { }
+//  ComplexRowVector (double a) : Array<Complex> (1, a) { }
+//  ComplexRowVector (const Complex& a) : Array<Complex> (1, a) { }
+
+  ComplexRowVector& operator = (const ComplexRowVector& a)
+    { return Array<Complex>::operator = (a); }
+
+//  operator Array<Complex>& () const { return *this; }
 
   int operator == (const ComplexRowVector& a) const;
   int operator != (const ComplexRowVector& a) const;
@@ -1361,17 +1058,20 @@
 
   ComplexRowVector extract (int c1, int c2) const;
 
+// row vector by row vector -> row vector operations
+
+  ComplexRowVector& operator += (const RowVector& a);
+  ComplexRowVector& operator -= (const RowVector& a);
+
+  ComplexRowVector& operator += (const ComplexRowVector& a);
+  ComplexRowVector& operator -= (const ComplexRowVector& a);
+
 // row vector by scalar -> row vector operations
 
-  ComplexRowVector operator + (double s) const;
-  ComplexRowVector operator - (double s) const;
-  ComplexRowVector operator * (double s) const;
-  ComplexRowVector operator / (double s) const;
-
-  ComplexRowVector operator + (const Complex& s) const;
-  ComplexRowVector operator - (const Complex& s) const;
-  ComplexRowVector operator * (const Complex& s) const;
-  ComplexRowVector operator / (const Complex& s) const;
+  friend ComplexRowVector operator + (const ComplexRowVector& a, double s);
+  friend ComplexRowVector operator - (const ComplexRowVector& a, double s);
+  friend ComplexRowVector operator * (const ComplexRowVector& a, double s);
+  friend ComplexRowVector operator / (const ComplexRowVector& a, double s);
 
 // scalar by row vector -> row vector operations
 
@@ -1380,50 +1080,31 @@
   friend ComplexRowVector operator * (double s, const ComplexRowVector& a);
   friend ComplexRowVector operator / (double s, const ComplexRowVector& a);
 
-  friend ComplexRowVector operator + (const Complex& s, const
-				      ComplexRowVector& a);
-  friend ComplexRowVector operator - (const Complex& s, const
-				      ComplexRowVector& a);
-  friend ComplexRowVector operator * (const Complex& s, const
-				      ComplexRowVector& a);
-  friend ComplexRowVector operator / (const Complex& s, const
-				      ComplexRowVector& a);
-
 // row vector by column vector -> scalar
 
-  Complex operator * (const ColumnVector& a) const;
-
-  Complex operator * (const ComplexColumnVector& a) const;
+  friend Complex operator * (const ComplexRowVector& a, const ColumnVector& b);
+
+  friend Complex operator * (const ComplexRowVector& a,
+			     const ComplexColumnVector& b);
 
 // row vector by matrix -> row vector
 
-  ComplexRowVector operator * (const Matrix& a) const;
-
-  ComplexRowVector operator * (const ComplexMatrix& a) const;
+  friend ComplexRowVector operator * (const ComplexRowVector& a,
+				      const ComplexMatrix& b);
 
 // row vector by row vector -> row vector operations
 
-  ComplexRowVector operator + (const RowVector& a) const;
-  ComplexRowVector operator - (const RowVector& a) const;
-
-  ComplexRowVector operator + (const ComplexRowVector& a) const;
-  ComplexRowVector operator - (const ComplexRowVector& a) const;
-
-  ComplexRowVector product (const RowVector& a) const;  // element by element
-  ComplexRowVector quotient (const RowVector& a) const; // element by element
-
-  ComplexRowVector product (const ComplexRowVector& a) const;  // el by el
-  ComplexRowVector quotient (const ComplexRowVector& a) const; // el by el
-
-  ComplexRowVector& operator += (const RowVector& a);
-  ComplexRowVector& operator -= (const RowVector& a);
-
-  ComplexRowVector& operator += (const ComplexRowVector& a);
-  ComplexRowVector& operator -= (const ComplexRowVector& a);
-
-// unary operations
-
-  ComplexRowVector operator - (void) const;
+  friend ComplexRowVector operator + (const ComplexRowVector& a,
+				      const RowVector& b);
+  friend ComplexRowVector operator - (const ComplexRowVector& a,
+				      const RowVector& b);
+
+  friend ComplexRowVector product (const ComplexRowVector& a,
+				   const RowVector& b);
+  friend ComplexRowVector quotient (const ComplexRowVector& a,
+				    const RowVector& b);
+
+// other operations
 
   friend ComplexRowVector map (c_c_Mapper f, const ComplexRowVector& a);
   friend RowVector map (d_c_Mapper f, const ComplexRowVector& a);
@@ -1436,82 +1117,49 @@
 
   friend ostream& operator << (ostream& os, const ComplexRowVector& a);
 
-// conversions
-
-  Complex *fortran_vec (void) const;
+#define KLUDGE_VECTORS
+#define TYPE Complex
+#define KL_VEC_TYPE ComplexRowVector
+#include "mx-kludge.h"
+#undef KLUDGE_VECTORS
+#undef TYPE
+#undef KL_VEC_TYPE
 
 private:
-  int len;
-  Complex *data;
-
-  ComplexRowVector (Complex *d, int l);
+
+  ComplexRowVector (Complex *d, int l) : Array<Complex> (d, l) { }
 };
 
-inline ComplexRowVector::ComplexRowVector (void) { len = 0; data = 0; }
-inline ComplexRowVector::ComplexRowVector (Complex *d, int l)
-  { len = l; data = d; }
-inline ComplexRowVector::~ComplexRowVector (void) { delete [] data; data = 0; }
-
-inline int ComplexRowVector::capacity (void) const { return len; }
-inline int ComplexRowVector::length (void) const { return len; }
-
-inline Complex& ComplexRowVector::elem (int n) { return data[n]; }
-
-inline Complex& ComplexRowVector::operator () (int n) { return checkelem (n); }
-
-inline Complex ComplexRowVector::elem (int n) const { return data[n]; }
-
-inline Complex ComplexRowVector::operator () (int n) const
-  { return checkelem (n); }
-
-inline Complex *ComplexRowVector::fortran_vec (void) const { return data; }
-
 /*
  * Complex Diagonal Matrix class
  */
 
-class ComplexDiagMatrix
+class ComplexDiagMatrix : public DiagArray<Complex>
 {
-friend class Matrix;
-friend class DiagMatrix;
-friend class ComplexMatrix;
-
 public:
-  ComplexDiagMatrix (void);
-  ComplexDiagMatrix (int n);
-  ComplexDiagMatrix (int n, double val);
-  ComplexDiagMatrix (int n, const Complex& val);
-  ComplexDiagMatrix (int r, int c);
-  ComplexDiagMatrix (int r, int c, double val);
-  ComplexDiagMatrix (int r, int c, const Complex& val);
+
+  ComplexDiagMatrix (void) : DiagArray<Complex> () { }
+  ComplexDiagMatrix (int n) : DiagArray<Complex> (n) { }
+  ComplexDiagMatrix (int n, const Complex& val)
+    : DiagArray<Complex> (n, val) { }
+  ComplexDiagMatrix (int r, int c) : DiagArray<Complex> (r, c) { }
+  ComplexDiagMatrix (int r, int c, const Complex& val)
+    : DiagArray<Complex> (r, c, val) { }
   ComplexDiagMatrix (const RowVector& a);
-  ComplexDiagMatrix (const ComplexRowVector& a);
+  ComplexDiagMatrix (const ComplexRowVector& a) : DiagArray<Complex> (a) { }
   ComplexDiagMatrix (const ColumnVector& a);
-  ComplexDiagMatrix (const ComplexColumnVector& a);
+  ComplexDiagMatrix (const ComplexColumnVector& a)
+    : DiagArray<Complex> (a) { }
   ComplexDiagMatrix (const DiagMatrix& a);
-  ComplexDiagMatrix (const ComplexDiagMatrix& a);
-  ComplexDiagMatrix (double a);
-  ComplexDiagMatrix (const Complex& a);
- ~ComplexDiagMatrix (void);
-
-  ComplexDiagMatrix& operator = (const DiagMatrix& a);
-  ComplexDiagMatrix& operator = (const ComplexDiagMatrix& a);
-
-  int rows (void) const;
-  int cols (void) const;
-  int columns (void) const;
-
-  Complex& checkelem (int r, int c);
-  Complex& elem (int r, int c);
-  Complex& operator () (int r, int c);
-
-  Complex checkelem (int r, int c) const; // const access
-  Complex elem (int r, int c) const;
-  Complex operator () (int r, int c) const;
-
-  ComplexDiagMatrix& resize (int r, int c);
-  ComplexDiagMatrix& resize (int r, int c, double val);
-  ComplexDiagMatrix& resize (int r, int c, const Complex& val);
+  ComplexDiagMatrix (const DiagArray<Complex>& a)
+    : DiagArray<Complex> (a) { }
+  ComplexDiagMatrix (const ComplexDiagMatrix& a) : DiagArray<Complex> (a) { }
+//  ComplexDiagMatrix (const Complex& a) : DiagArray<Complex> (1, a) { }
+
+  ComplexDiagMatrix& operator = (const ComplexDiagMatrix& a)
+    { return DiagArray<Complex>::operator = (a); }
+
+//  operator DiagArray<Complex>& () const { return *this; }
 
   int operator == (const ComplexDiagMatrix& a) const;
   int operator != (const ComplexDiagMatrix& a) const;
@@ -1551,83 +1199,78 @@
   ComplexDiagMatrix inverse (int& info) const;
   ComplexDiagMatrix inverse (void) const;
 
-// diagonal matrix by scalar -> matrix operations
-
-  ComplexMatrix operator + (double s) const;
-  ComplexMatrix operator - (double s) const;
-
-  ComplexMatrix operator + (const Complex& s) const;
-  ComplexMatrix operator - (const Complex& s) const;
-
-// diagonal matrix by scalar -> diagonal matrix operations
-
-  ComplexDiagMatrix operator * (double s) const;
-  ComplexDiagMatrix operator / (double s) const;
-
-  ComplexDiagMatrix operator * (const Complex& s) const;
-  ComplexDiagMatrix operator / (const Complex& s) const;
-
-// scalar by diagonal matrix -> matrix operations
-
-  friend ComplexMatrix operator + (double s, const ComplexDiagMatrix& a);
-  friend ComplexMatrix operator - (double s, const ComplexDiagMatrix& a);
-
-  friend ComplexMatrix operator + (const Complex& s, const
-				   ComplexDiagMatrix& a);
-  friend ComplexMatrix operator - (const Complex& s, const
-				   ComplexDiagMatrix& a);
-
-// scalar by diagonal matrix -> diagonal matrix operations
-
-  friend ComplexDiagMatrix operator * (double s, const ComplexDiagMatrix& a);
-  friend ComplexDiagMatrix operator / (double s, const ComplexDiagMatrix& a);
-
-  friend ComplexDiagMatrix operator * (const Complex& s, const
-				       ComplexDiagMatrix& a);
-  friend ComplexDiagMatrix operator / (const Complex& s, const
-				       ComplexDiagMatrix& a);
-
-// diagonal matrix by column vector -> column vector operations
-
-  ComplexColumnVector operator * (const ColumnVector& a) const;
-
-  ComplexColumnVector operator * (const ComplexColumnVector& a) const;
-
 // diagonal matrix by diagonal matrix -> diagonal matrix operations
 
-  ComplexDiagMatrix operator + (const DiagMatrix& a) const;
-  ComplexDiagMatrix operator - (const DiagMatrix& a) const;
-  ComplexDiagMatrix operator * (const DiagMatrix& a) const;
-
-  ComplexDiagMatrix operator + (const ComplexDiagMatrix& a) const;
-  ComplexDiagMatrix operator - (const ComplexDiagMatrix& a) const;
-  ComplexDiagMatrix operator * (const ComplexDiagMatrix& a) const;
-
-  ComplexDiagMatrix product (const DiagMatrix& a) const;  // element by element
-  ComplexDiagMatrix quotient (const DiagMatrix& a) const; // element by element
-
-  ComplexDiagMatrix product (const ComplexDiagMatrix& a) const;  // el by el
-  ComplexDiagMatrix quotient (const ComplexDiagMatrix& a) const; // el by el
-
   ComplexDiagMatrix& operator += (const DiagMatrix& a);
   ComplexDiagMatrix& operator -= (const DiagMatrix& a);
 
   ComplexDiagMatrix& operator += (const ComplexDiagMatrix& a);
   ComplexDiagMatrix& operator -= (const ComplexDiagMatrix& a);
 
+// diagonal matrix by scalar -> matrix operations
+
+  friend ComplexMatrix operator + (const ComplexDiagMatrix& a, double s);
+  friend ComplexMatrix operator - (const ComplexDiagMatrix& a, double s);
+
+  friend ComplexMatrix operator + (const ComplexDiagMatrix& a,
+				   const Complex& s);
+  friend ComplexMatrix operator - (const ComplexDiagMatrix& a,
+				   const Complex& s);
+
+// diagonal matrix by scalar -> diagonal matrix operations
+
+  friend ComplexDiagMatrix operator * (const ComplexDiagMatrix& a, double s);
+  friend ComplexDiagMatrix operator / (const ComplexDiagMatrix& a, double s);
+
+// scalar by diagonal matrix -> matrix operations
+
+  friend ComplexMatrix operator + (double s, const ComplexDiagMatrix& a);
+  friend ComplexMatrix operator - (double s, const ComplexDiagMatrix& a);
+
+  friend ComplexMatrix operator + (const Complex& s,
+				   const ComplexDiagMatrix& a);
+  friend ComplexMatrix operator - (const Complex& s,
+				   const ComplexDiagMatrix& a);
+
+// scalar by diagonal matrix -> diagonal matrix operations
+
+  friend ComplexDiagMatrix operator * (double s, const ComplexDiagMatrix& a);
+
+// diagonal matrix by column vector -> column vector operations
+
+  friend ComplexColumnVector operator * (const ComplexDiagMatrix& a,
+					 const ColumnVector& b);
+
+  friend ComplexColumnVector operator * (const ComplexDiagMatrix& a,
+					 const ComplexColumnVector& b);
+
+// diagonal matrix by diagonal matrix -> diagonal matrix operations
+
+  friend ComplexDiagMatrix operator + (const ComplexDiagMatrix& a,
+				       const DiagMatrix& b);
+  friend ComplexDiagMatrix operator - (const ComplexDiagMatrix& a,
+				       const DiagMatrix& b);
+
+  friend ComplexDiagMatrix product (const ComplexDiagMatrix& a,
+				    const DiagMatrix& b); 
+
 // diagonal matrix by matrix -> matrix operations
 
-  ComplexMatrix operator + (const Matrix& a) const;
-  ComplexMatrix operator - (const Matrix& a) const;
-  ComplexMatrix operator * (const Matrix& a) const;
-
-  ComplexMatrix operator + (const ComplexMatrix& a) const;
-  ComplexMatrix operator - (const ComplexMatrix& a) const;
-  ComplexMatrix operator * (const ComplexMatrix& a) const;
-
-// unary operations
-
-  ComplexDiagMatrix operator - (void) const;
+  friend ComplexMatrix operator + (const ComplexDiagMatrix& a,
+				   const Matrix& b); 
+  friend ComplexMatrix operator - (const ComplexDiagMatrix& a,
+				   const Matrix& b);
+  friend ComplexMatrix operator * (const ComplexDiagMatrix& a,
+				   const Matrix& b);
+
+  friend ComplexMatrix operator + (const ComplexDiagMatrix& a,
+				   const ComplexMatrix& b);
+  friend ComplexMatrix operator - (const ComplexDiagMatrix& a,
+				   const ComplexMatrix& b);
+  friend ComplexMatrix operator * (const ComplexDiagMatrix& a,
+				   const ComplexMatrix& b);
+
+// other operations
 
   ComplexColumnVector diag (void) const;
   ComplexColumnVector diag (int k) const;
@@ -1636,42 +1279,20 @@
 
   friend ostream& operator << (ostream& os, const ComplexDiagMatrix& a);
 
+#define KLUDGE_DIAG_MATRICES
+#define TYPE Complex
+#define KL_DMAT_TYPE ComplexDiagMatrix
+#include "mx-kludge.h"
+#undef KLUDGE_DIAG_MATRICES
+#undef TYPE
+#undef KL_DMAT_TYPE
+
 private:
-  int nr;
-  int nc;
-  int len;
-  Complex *data;
-
-  ComplexDiagMatrix (Complex *d, int nr, int nc);
+
+  ComplexDiagMatrix (Complex *d, int nr, int nc)
+    : DiagArray<Complex> (d, nr, nc) { }
 };
 
-inline ComplexDiagMatrix::ComplexDiagMatrix (void)
-  { nr = 0; nc = 0; len = 0; data = 0; }
-
-inline ComplexDiagMatrix::ComplexDiagMatrix (Complex *d, int r, int c)
-  { nr = r; nc = c; len = nr < nc ? nr : nc; data = d; }
-
-inline ComplexDiagMatrix::~ComplexDiagMatrix (void)
-  { delete [] data; data = 0; }
-
-inline int ComplexDiagMatrix::rows (void) const { return nr; }
-inline int ComplexDiagMatrix::cols (void) const { return nc; }
-inline int ComplexDiagMatrix::columns (void) const { return nc; } 
-
-// Would be nice to be able to avoid compiler warning and make this
-// fail on assignment.
-inline Complex& ComplexDiagMatrix::elem (int r, int c)
-  { Complex czero (0.0, 0.0); return (r == c) ? data[r] : czero; }
-
-inline Complex& ComplexDiagMatrix::operator () (int r, int c)
-  { return checkelem (r, c); }
-
-inline Complex ComplexDiagMatrix::elem (int r, int c) const
-  { Complex czero (0.0, 0.0); return (r == c) ? data[r] : czero; }
-
-inline Complex ComplexDiagMatrix::operator () (int r, int c) const
-  { return checkelem (r, c); }
-
 /*
  * Result of a AEP Balance operation
  */
@@ -1681,6 +1302,7 @@
 friend class Matrix;
 
 public:
+
   AEPBALANCE (void) {}
 
   AEPBALANCE (const Matrix& a, const char *balance_job);
@@ -1693,6 +1315,7 @@
   friend ostream& operator << (ostream& os, const AEPBALANCE& a);
 
 private:
+
   int init (const Matrix& a, const char * balance_job);
 
   Matrix balanced_mat;
@@ -1733,6 +1356,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexAEPBALANCE (void) {}
   ComplexAEPBALANCE (const ComplexMatrix& a, const char *balance_job);
   ComplexAEPBALANCE (const ComplexAEPBALANCE& a);
@@ -1743,6 +1367,7 @@
   friend ostream& operator << (ostream& os, const ComplexAEPBALANCE& a);
 
 private:
+
   int init (const ComplexMatrix& a, const char * balance_job);
 
   ComplexMatrix balanced_mat;
@@ -1783,6 +1408,7 @@
 class DET
 {
 public:
+
   DET (void) {}
 
   DET (const DET& a);
@@ -1798,6 +1424,7 @@
   friend ostream&  operator << (ostream& os, const DET& a);
 
 private:
+
   DET (const double *d);
 
   double det [2];
@@ -1808,16 +1435,6 @@
 inline DET& DET::operator = (const DET& a)
   { det[0] = a.det[0]; det[1] = a.det[1]; return *this; }
 
-inline int DET::value_will_overflow (void) const
-  { return det[2] + 1 > log10 (MAXDOUBLE) ? 1 : 0; }
-
-inline int DET::value_will_underflow (void) const
-  { return det[2] - 1 < log10 (MINDOUBLE) ? 1 : 0; }
-
-inline double DET::coefficient (void) const { return det[0]; }
-inline int DET::exponent (void) const { return (int) det[1]; }
-inline double DET::value (void) const { return det[0] * pow (10.0, det[1]); }
-
 inline DET::DET (const double *d) { det[0] = d[0]; det[1] = d[1]; }
 
 /*
@@ -1827,6 +1444,7 @@
 class ComplexDET
 {
 public:
+
   ComplexDET (void) {}
 
   ComplexDET (const ComplexDET& a);
@@ -1842,6 +1460,7 @@
   friend ostream&  operator << (ostream& os, const ComplexDET& a);
 
 private:
+
   ComplexDET (const Complex *d);
 
   Complex det [2];
@@ -1853,19 +1472,6 @@
 inline ComplexDET& ComplexDET::operator = (const ComplexDET& a)
   { det[0] = a.det[0]; det[1] = a.det[1]; return *this; }
 
-inline int ComplexDET::value_will_overflow (void) const
-  { return real (det[2]) + 1 > log10 (MAXDOUBLE) ? 1 : 0; }
-
-inline int ComplexDET::value_will_underflow (void) const
-  { return real (det[2]) - 1 < log10 (MINDOUBLE) ? 1 : 0; }
-
-inline Complex ComplexDET::coefficient (void) const { return det[0]; }
-
-inline int ComplexDET::exponent (void) const { return (int) real (det[1]); }
-
-inline Complex ComplexDET::value (void) const
-  { return det[0] * pow (10.0, real (det[1])); }
-
 inline ComplexDET::ComplexDET (const Complex *d)
   { det[0] = d[0]; det[1] = d[1]; }
 
@@ -1880,6 +1486,7 @@
 friend class Matrix;
 
 public:
+
   GEPBALANCE (void) {}
 
   GEPBALANCE (const Matrix& a, const Matrix &, const char *balance_job);
@@ -1894,6 +1501,7 @@
   friend ostream& operator << (ostream& os, const GEPBALANCE& a);
 
 private:
+
   int init (const Matrix& a, const Matrix& b, const char * balance_job);
 
   Matrix balanced_a_mat;
@@ -1948,6 +1556,7 @@
 friend class Matrix;
 
 public:
+
   CHOL (void) {}
 
   CHOL (const Matrix& a);
@@ -1960,6 +1569,7 @@
   friend ostream& operator << (ostream& os, const CHOL& a);
 
 private:
+
   int init (const Matrix& a);
 
   Matrix chol_mat;
@@ -1988,6 +1598,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexCHOL (void) {}
   ComplexCHOL (const ComplexMatrix& a);
   ComplexCHOL (const ComplexMatrix& a, int& info);
@@ -1998,6 +1609,7 @@
   friend ostream& operator << (ostream& os, const ComplexCHOL& a);
 
 private:
+
   int init (const ComplexMatrix& a);
 
   ComplexMatrix chol_mat;
@@ -2031,6 +1643,7 @@
 friend class Matrix;
 
 public:
+
   HESS (void) {}
 
   HESS (const Matrix& a);
@@ -2044,6 +1657,7 @@
   friend ostream& operator << (ostream& os, const HESS& a);
 
 private:
+
   int init (const Matrix& a);
 
   Matrix hess_mat;
@@ -2080,6 +1694,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexHESS (void) {}
   ComplexHESS (const ComplexMatrix& a);
   ComplexHESS (const ComplexMatrix& a, int& info);
@@ -2091,6 +1706,7 @@
   friend ostream& operator << (ostream& os, const ComplexHESS& a);
 
 private:
+
   int init (const ComplexMatrix& a);
 
   ComplexMatrix hess_mat;
@@ -2131,6 +1747,7 @@
 friend class Matrix;
 
 public:
+
   SCHUR (void) {}
 
   SCHUR (const Matrix& a, const char *ord);
@@ -2138,7 +1755,7 @@
 
   SCHUR (const SCHUR& a, const char *ord);
 
-  SCHUR& operator = (const SCHUR& a, const char *ord);
+  SCHUR& operator = (const SCHUR& a);
 
   Matrix schur_matrix (void) const;
   Matrix unitary_matrix (void) const;
@@ -2146,6 +1763,7 @@
   friend ostream& operator << (ostream& os, const SCHUR& a);
 
 private:
+
   int init (const Matrix& a, const char *ord);
 
   Matrix schur_mat;
@@ -2163,7 +1781,7 @@
 }
 
 inline SCHUR&
-SCHUR::operator = (const SCHUR& a, const char *ord)
+SCHUR::operator = (const SCHUR& a)
 {
   schur_mat = a.schur_mat;
   unitary_mat = a.unitary_mat;
@@ -2183,6 +1801,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexSCHUR (void) {}
 
   ComplexSCHUR (const ComplexMatrix& a, const char *ord);
@@ -2190,7 +1809,7 @@
 
   ComplexSCHUR (const ComplexSCHUR& a, const char *ord);
 
-  ComplexSCHUR& operator = (const ComplexSCHUR& a, const char *ord);
+  ComplexSCHUR& operator = (const ComplexSCHUR& a);
 
   ComplexMatrix schur_matrix (void) const;
   ComplexMatrix unitary_matrix (void) const;
@@ -2198,6 +1817,7 @@
   friend ostream& operator << (ostream& os, const ComplexSCHUR& a);
 
 private:
+
   int init (const ComplexMatrix& a, const char *ord);
 
   ComplexMatrix schur_mat;
@@ -2218,7 +1838,7 @@
 }
 
 inline ComplexSCHUR&
-ComplexSCHUR::operator = (const ComplexSCHUR& a, const char *ord)
+ComplexSCHUR::operator = (const ComplexSCHUR& a)
 {
   schur_mat = a.schur_mat;
   unitary_mat = a.unitary_mat;
@@ -2242,6 +1862,7 @@
 friend class Matrix;
 
 public:
+
   SVD (void) {}
 
   SVD (const Matrix& a);
@@ -2258,6 +1879,7 @@
   friend ostream&  operator << (ostream& os, const SVD& a);
 
 private:
+
   int init (const Matrix& a);
 
   DiagMatrix sigma;
@@ -2298,6 +1920,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexSVD (void) {}
 
   ComplexSVD (const ComplexMatrix& a);
@@ -2314,6 +1937,7 @@
   friend ostream&  operator << (ostream& os, const ComplexSVD& a);
 
 private:
+
   int init (const ComplexMatrix& a);
 
   DiagMatrix sigma;
@@ -2361,6 +1985,7 @@
 friend class ComplexMatrix;
 
 public:
+
   EIG (void) {}
 
   EIG (const Matrix& a);
@@ -2379,6 +2004,7 @@
   friend ostream&  operator << (ostream& os, const EIG& a);
 
 private:
+
   int init (const Matrix& a);
   int init (const ComplexMatrix& a);
 
@@ -2410,6 +2036,7 @@
 friend class Matrix;
 
 public:
+
   LU (void) {}
 
   LU (const Matrix& a);
@@ -2445,6 +2072,7 @@
 friend class ComplexMatrix;
 
 public:
+
   ComplexLU (void) {}
 
   ComplexLU (const ComplexMatrix& a);
@@ -2482,6 +2110,7 @@
 class QR
 {
 public:
+
   QR (void) {}
 
   QR (const Matrix& A);
@@ -2496,6 +2125,7 @@
   friend ostream&  operator << (ostream& os, const QR& a);
 
 private:
+
   Matrix q;
   Matrix r;
 };
@@ -2510,6 +2140,7 @@
 class ComplexQR
 {
 public:
+
   ComplexQR (void) {}
 
   ComplexQR (const ComplexMatrix& A);
@@ -2524,6 +2155,7 @@
   friend ostream&  operator << (ostream& os, const ComplexQR& a);
 
 private:
+
   ComplexMatrix q;
   ComplexMatrix r;
 };
--- a/liboctave/NLConst.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLConst.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include "NLConst.h"
--- a/liboctave/NLConst.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLConst.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,12 +24,8 @@
 #if !defined (_NLConst_h)
 #define _NLConst_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <Bounds.h>
 #include "Matrix.h"
+#include "Bounds.h"
 #include "NLFunc.h"
 
 #ifndef Vector
--- a/liboctave/NLEqn.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLEqn.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include <float.h>
+
 #include "NLEqn.h"
 #include "f77-uscore.h"
 #include "lo-error.h"
--- a/liboctave/NLEqn.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLEqn.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,12 +24,8 @@
 #if !defined (_NLEqn_h)
 #define _NLEqn_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <NLFunc.h>
 #include "Matrix.h"
+#include "NLFunc.h"
 
 #ifndef Vector
 #define Vector ColumnVector
--- a/liboctave/NLFunc.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLFunc.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "NLFunc.h"
 
 NLFunc::NLFunc (void)
--- a/liboctave/NLFunc.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLFunc.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,6 @@
 #if !defined (_NLFunc_h)
 #define _NLFunc_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/NLP.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NLP.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,11 @@
 #if !defined (_NLP_h)
 #define _NLP_h 1
 
+#include "Matrix.h"
 #include "Objective.h"
 #include "Bounds.h"
 #include "LinConst.h"
 #include "NLConst.h"
-#include "Matrix.h"
 
 #ifndef Vector
 #define Vector ColumnVector
--- a/liboctave/NPSOL.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NPSOL.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,14 +21,14 @@
 
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+
 #ifndef NPSOL_MISSING
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
-#include <iostream.h>
-#include <math.h>
 #include "NPSOL.h"
 #include "f77-uscore.h"
 #include "sun-utils.h"
--- a/liboctave/NPSOL.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/NPSOL.h	Tue Nov 30 20:23:04 1993 +0000
@@ -21,15 +21,12 @@
 
 */
 
-#ifndef NPSOL_MISSING
-
 #if !defined (_NPSOL_h)
 #define _NPSOL_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+#ifndef NPSOL_MISSING
 
+#include "Matrix.h"
 #include "NLP.h"
 
 #ifndef Vector
@@ -114,9 +111,9 @@
   return *this;
 }
 
-#endif
+#endif /* NPSOL_MISSING */
 
-#endif /* NPSOL_MISSING */
+#endif
 
 /*
 ;;; Local Variables: ***
--- a/liboctave/ODE.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/ODE.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,13 +24,10 @@
 #if !defined (_ODE_h)
 #define _ODE_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+class ostream;
 
-#include <iostream.h>
+#include "Matrix.h"
 #include "ODEFunc.h"
-#include "Matrix.h"
 
 class ODE : public ODEFunc
 {
--- a/liboctave/ODEFunc.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/ODEFunc.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "ODEFunc.h"
 
 ODEFunc::ODEFunc (void)
--- a/liboctave/ODEFunc.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/ODEFunc.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,6 @@
 #if !defined (_ODEFunc_h)
 #define _ODEFunc_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/Objective.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Objective.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include "Objective.h"
--- a/liboctave/Objective.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Objective.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,6 @@
 #if !defined (_Objective_h)
 #define _Objective_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/QLD.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QLD.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,12 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include <math.h>
+
 #include "QLD.h"
 #include "f77-uscore.h"
 
--- a/liboctave/QLD.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QLD.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,7 @@
 #if !defined (_QLD_h)
 #define _QLD_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
+#include "Matrix.h"
 #include "QP.h"
 
 #ifndef Vector
--- a/liboctave/QP.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QP.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,8 +21,8 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include "QP.h"
--- a/liboctave/QP.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QP.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,13 +24,9 @@
 #if !defined (_QP_h)
 #define _QP_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
+#include "Matrix.h"
 #include "Bounds.h"
 #include "LinConst.h"
-#include "Matrix.h"
 
 #ifndef Vector
 #define Vector ColumnVector
--- a/liboctave/QPSOL.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QPSOL.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,14 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include <math.h>
+
+#ifndef QPSOL_MISSING
+
 #include "QPSOL.h"
 #include "f77-uscore.h"
 
@@ -173,6 +175,8 @@
   iprint = 0;
 }
 
+#endif /* QPSOL_MISSING */
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/QPSOL.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/QPSOL.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,9 @@
 #if !defined (_QPSOL_h)
 #define _QPSOL_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
+#ifndef QPSOL_MISSING
 
+#include "Matrix.h"
 #include "QP.h"
 
 #ifndef Vector
@@ -92,6 +91,8 @@
   return *this;
 }
 
+#endif /* QPSOL_MISSING */
+
 #endif
 
 /*
--- a/liboctave/Quad.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Quad.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,11 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
-#include <iostream.h>
 #include "Quad.h"
 #include "f77-uscore.h"
 #include "sun-utils.h"
--- a/liboctave/Quad.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Quad.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,6 @@
 #if !defined (_Quad_h)
 #define _Quad_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
 #include "Matrix.h"
 
 #ifndef Vector
--- a/liboctave/Range.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Range.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,10 +21,11 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
+#include <iostream.h>
 #include <limits.h>
 
 #include "Range.h"
--- a/liboctave/Range.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/Range.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,11 +24,8 @@
 #if !defined (_Range_h)
 #define _Range_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include <iostream.h>
+class istream;
+class ostream;
 
 class Range
 {
--- a/liboctave/RowVector.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/RowVector.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,12 +21,9 @@
 
 */
 
-// I\'m not sure how this is supposed to work if the .h file declares
-// several classes, each of which is defined in a separate file...
-//
-// #ifdef __GNUG__
-// #pragma implementation "Matrix.h"
-// #endif
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include "Matrix.h"
 #include "mx-inlines.cc"
@@ -70,111 +67,7 @@
  * Row Vector class.
  */
 
-RowVector::RowVector (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create vector with negative dimension");
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  len = n;
-  if (len > 0)
-    data = new double [len];
-  else
-    data = (double *) NULL;
-}
-
-RowVector::RowVector (int n, double val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create vector with negative dimension");
-      len = 0;
-      data = (double *) NULL;
-      return;
-    }
-
-  len = n;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, len, val);
-    }
-  else
-    data = (double *) NULL;
-}
-
-RowVector::RowVector (const RowVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new double [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (double *) NULL;
-}
-
-RowVector::RowVector (double a)
-{
-  len = 1;
-  data = new double [1];
-  data[0] = a;
-}
-
-RowVector&
-RowVector::operator = (const RowVector& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new double [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (double *) NULL;
-    }
-  return *this;
-}
-
-double&
-RowVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static double foo = 0.0;
-      return foo;
-    }
-#endif
-
-  return elem (n);
-}
-
-double
-RowVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return 0.0;
-    }
-#endif
-
-  return elem (n);
-}
-
+#if 0
 RowVector&
 RowVector::resize (int n)
 {
@@ -212,34 +105,35 @@
 
   return *this;
 }
+#endif
 
 int
 RowVector::operator == (const RowVector& a) const
 {
-  if (len != a.len)
+  int len = length ();
+  if (len != a.length ())
     return 0;
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), len);
 }
 
 int
 RowVector::operator != (const RowVector& a) const
 {
-  if (len != a.len)
-    return 1;
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 RowVector&
 RowVector::insert (const RowVector& a, int c)
 {
-  if (c < 0 || c + a.len - 1 > len)
+  int a_len = a.length ();
+  if (c < 0 || c + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[c+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (c+i) = a.elem (i);
 
   return *this;
 }
@@ -247,14 +141,17 @@
 RowVector&
 RowVector::fill (double val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 RowVector&
 RowVector::fill (double val, int c1, int c2)
 {
+  int len = length ();
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -264,7 +161,7 @@
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
   for (int i = c1; i <= c2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -272,8 +169,9 @@
 RowVector
 RowVector::append (const RowVector& a) const
 {
+  int len = length ();
   int nc_insert = len;
-  RowVector retval (len + a.len);
+  RowVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nc_insert);
   return retval;
@@ -282,7 +180,8 @@
 ColumnVector
 RowVector::transpose (void) const
 {
-  return ColumnVector (dup (data, len), len);
+  int len = length ();
+  return ColumnVector (dup (data (), len), len);
 }
 
 RowVector
@@ -295,93 +194,116 @@
   RowVector result (new_c);
 
   for (int i = 0; i < new_c; i++)
-    result.data[i] = elem (c1+i);
+    result.elem (i) = elem (c1+i);
 
   return result;
 }
 
+// row vector by row vector -> row vector operations
+
+RowVector&
+RowVector::operator += (const RowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  double *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
+}
+
+RowVector&
+RowVector::operator -= (const RowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  double *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
+}
+
 // row vector by scalar -> row vector operations
 
-RowVector
-RowVector::operator + (double s) const
-{
-  return RowVector (add (data, len, s), len);
-}
-
-RowVector
-RowVector::operator - (double s) const
+ComplexRowVector
+operator + (const RowVector& v, const Complex& s)
 {
-  return RowVector (subtract (data, len, s), len);
-}
-
-RowVector
-RowVector::operator * (double s) const
-{
-  return RowVector (multiply (data, len, s), len);
-}
-
-RowVector
-RowVector::operator / (double s) const
-{
-  return RowVector (divide (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (add (v.data (), len, s), len);
 }
 
 ComplexRowVector
-RowVector::operator + (const Complex& s) const
+operator - (const RowVector& v, const Complex& s)
 {
-  return ComplexRowVector (add (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (subtract (v.data (), len, s), len);
 }
 
 ComplexRowVector
-RowVector::operator - (const Complex& s) const
+operator * (const RowVector& v, const Complex& s)
 {
-  return ComplexRowVector (subtract (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (multiply (v.data (), len, s), len);
 }
 
 ComplexRowVector
-RowVector::operator * (const Complex& s) const
+operator / (const RowVector& v, const Complex& s)
 {
-  return ComplexRowVector (multiply (data, len, s), len);
-}
-
-ComplexRowVector
-RowVector::operator / (const Complex& s) const
-{
-  return ComplexRowVector (divide (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (divide (v.data (), len, s), len);
 }
 
 // scalar by row vector -> row vector operations
 
-RowVector
-operator + (double s, const RowVector& a)
+ComplexRowVector
+operator + (const Complex& s, const RowVector& a)
 {
-  return RowVector (add (a.data, a.len, s), a.len);
+  return ComplexRowVector ();
 }
 
-RowVector
-operator - (double s, const RowVector& a)
+ComplexRowVector
+operator - (const Complex& s, const RowVector& a)
 {
-  return RowVector (subtract (s, a.data, a.len), a.len);
+  return ComplexRowVector ();
 }
 
-RowVector
-operator * (double s, const RowVector& a)
+ComplexRowVector
+operator * (const Complex& s, const RowVector& a)
 {
-  return RowVector (multiply (a.data, a.len, s), a.len);
+  return ComplexRowVector ();
 }
 
-RowVector
-operator / (double s, const RowVector& a)
+ComplexRowVector
+operator / (const Complex& s, const RowVector& a)
 {
-  return RowVector (divide (s, a.data, a.len), a.len);
+  return ComplexRowVector ();
 }
 
 // row vector by column vector -> scalar
 
 double
-RowVector::operator * (const ColumnVector& a) const
+operator * (const RowVector& v, const ColumnVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector multiplication attempted");
@@ -389,95 +311,65 @@
     }
 
   int i_one = 1;
-  return F77_FCN (ddot) (&len, data, &i_one, a.data, &i_one);
+  return F77_FCN (ddot) (&len, v.data (), &i_one, a.data (), &i_one);
 }
 
 Complex
-RowVector::operator * (const ComplexColumnVector& a) const
+operator * (const RowVector& v, const ComplexColumnVector& a)
 {
-  ComplexRowVector tmp (*this);
+  ComplexRowVector tmp (v);
   return tmp * a;
 }
 
 // row vector by matrix -> row vector
 
 RowVector
-RowVector::operator * (const Matrix& a) const
+operator * (const RowVector& v, const Matrix& a)
 {
-  if (a.nr != len)
+  int len = v.length ();
+  if (a.rows () != len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector multiplication attempted");
       return RowVector ();
     }
 
-  if (len == 0 || a.nc == 0)
+  if (len == 0 || a.cols () == 0)
     return RowVector (0);
 
 // Transpose A to form A'*x == (x'*A)'
 
-  int anr = a.nr;
-  int anc = a.nc;
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
 
   char trans = 'T';
-  int ld = anr;
+  int ld = a_nr;
   double alpha = 1.0;
   double beta  = 0.0;
   int i_one = 1;
 
   double *y = new double [len];
 
-  F77_FCN (dgemv) (&trans, &anc, &anr, &alpha, a.data, &ld, data,
-		   &i_one, &beta, y, &i_one, 1L); 
+  F77_FCN (dgemv) (&trans, &a_nc, &a_nr, &alpha, a.data (), &ld,
+		   v.data (), &i_one, &beta, y, &i_one, 1L); 
 
   return RowVector (y, len);
 }
 
 ComplexRowVector
-RowVector::operator * (const ComplexMatrix& a) const
+operator * (const RowVector& v, const ComplexMatrix& a)
 {
-  ComplexRowVector tmp (*this);
+  ComplexRowVector tmp (v);
   return tmp * a;
 }
 
 // row vector by row vector -> row vector operations
 
-RowVector
-RowVector::operator + (const RowVector& a) const
+ComplexRowVector
+operator + (const RowVector& v, const ComplexRowVector& a)
 {
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector addition attempted");
-      return RowVector ();
-    }
-
-  if (len == 0)
-    return RowVector (0);
-
-  return RowVector (add (data, a.data, len), len);
-}
-
-RowVector
-RowVector::operator - (const RowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector subtraction attempted");
-      return RowVector ();
-    }
-
-  if (len == 0)
-    return RowVector (0);
-
-  return RowVector (subtract (data, a.data, len), len);
-}
-
-ComplexRowVector
-RowVector::operator + (const ComplexRowVector& a) const
-{
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector addition attempted");
@@ -487,13 +379,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (add (data, a.data, len), len);
+  return ComplexRowVector (add (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-RowVector::operator - (const ComplexRowVector& a) const
+operator - (const RowVector& v, const ComplexRowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector subtraction attempted");
@@ -503,45 +396,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (subtract (data, a.data, len), len);
-}
-
-RowVector
-RowVector::product (const RowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector product attempted");
-      return RowVector ();
-    }
-
-  if (len == 0)
-    return RowVector (0);
-
-  return RowVector (multiply (data, a.data, len), len);
-}
-
-RowVector
-RowVector::quotient (const RowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector quotient attempted");
-      return RowVector ();
-    }
-
-  if (len == 0)
-    return RowVector (0);
-
-  return RowVector (divide (data, a.data, len), len);
+  return ComplexRowVector (subtract (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-RowVector::product (const ComplexRowVector& a) const
+product (const RowVector& v, const ComplexRowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector product attempted");
@@ -551,13 +413,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (multiply (data, a.data, len), len);
+  return ComplexRowVector (multiply (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-RowVector::quotient (const ComplexRowVector& a) const
+quotient (const RowVector& v, const ComplexRowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector quotient attempted");
@@ -567,53 +430,10 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (divide (data, a.data, len), len);
-}
-
-RowVector&
-RowVector::operator += (const RowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
+  return ComplexRowVector (divide (v.data (), a.data (), len), len);
 }
 
-RowVector&
-RowVector::operator -= (const RowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-// unary operations
-
-RowVector
-RowVector::operator - (void) const
-{
-  if (len == 0)
-    return RowVector (0);
-
-  return RowVector (negate (data, len), len);
-}
+// other operations
 
 RowVector
 map (d_d_Mapper f, const RowVector& a)
@@ -626,21 +446,22 @@
 void
 RowVector::map (d_d_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  for (int i = 0; i < length (); i++)
+    elem (i) = f (elem (i));
 }
 
 double
 RowVector::min (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0;
 
-  double res = data[0];
+  double res = elem (0);
 
   for (int i = 1; i < len; i++)
-    if (data[i] < res)
-      res = data[i];
+    if (elem (i) < res)
+      res = elem (i);
 
   return res;
 }
@@ -648,14 +469,15 @@
 double
 RowVector::max (void) const
 {
+  int len = length ();
   if (len == 0)
     return 0;
 
-  double res = data[0];
+  double res = elem (0);
 
   for (int i = 1; i < len; i++)
-    if (data[i] > res)
-      res = data[i];
+    if (elem (i) > res)
+      res = elem (i);
 
   return res;
 }
@@ -664,8 +486,8 @@
 operator << (ostream& os, const RowVector& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.len; i++)
-    os << " " /* setw (field_width) */ << a.data[i];
+  for (int i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
   return os;
 }
 
@@ -673,167 +495,14 @@
  * Complex Row Vector class
  */
 
-ComplexRowVector::ComplexRowVector (int n)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (len > 0)
-    data = new Complex [len];
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexRowVector::ComplexRowVector (int n, double val)
+ComplexRowVector::ComplexRowVector (const RowVector& a)
+  : Array<Complex> (a.length ())
 {
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexRowVector::ComplexRowVector (int n, const Complex& val)
-{
-  if (n < 0)
-    {
-      (*current_liboctave_error_handler)
-	("can't create vector with negative dimension");
-      len = 0;
-      data = (Complex *) NULL;
-      return;
-    }
-
-  len = n;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, len, val);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexRowVector::ComplexRowVector (const RowVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
+  for (int i = 0; i < length (); i++)
+    elem (i) = a.elem (i);
 }
 
-ComplexRowVector::ComplexRowVector (const ComplexRowVector& a)
-{
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-}
-
-ComplexRowVector::ComplexRowVector (double a)
-{
-  len = 1;
-  data = new Complex [1];
-  data[0] = a;
-}
-
-ComplexRowVector::ComplexRowVector (const Complex& a)
-{
-  len = 1;
-  data = new Complex [1];
-  data[0] = Complex (a);
-}
-
-ComplexRowVector&
-ComplexRowVector::operator = (const RowVector& a)
-{
-  delete [] data;
-  len = a.len;
-  if (len > 0)
-    {
-      data = new Complex [len];
-      copy (data, a.data, len);
-    }
-  else
-    data = (Complex *) NULL;
-
-  return *this;
-}
-
-ComplexRowVector&
-ComplexRowVector::operator = (const ComplexRowVector& a)
-{
-  if (this != &a)
-    {
-      delete [] data;
-      len = a.len;
-      if (len > 0)
-	{
-	  data = new Complex [len];
-	  copy (data, a.data, len);
-	}
-      else
-	data = (Complex *) NULL;
-    }
-  return *this;
-}
-
-Complex&
-ComplexRowVector::checkelem (int n)
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      static Complex foo (0.0);
-      return foo;
-    }
-#endif
-
-  return elem (n);
-}
-
-Complex
-ComplexRowVector::checkelem (int n) const
-{
-#ifndef NO_RANGE_CHECK
-  if (n < 0 || n >= len)
-    {
-      (*current_liboctave_error_handler) ("range error");
-      return Complex (0.0);
-    }
-#endif
-
-  return elem (n);
-}
-
+#if 0
 ComplexRowVector&
 ComplexRowVector::resize (int n)
 {
@@ -882,21 +551,21 @@
 
   return *this;
 }
+#endif
 
 int
 ComplexRowVector::operator == (const ComplexRowVector& a) const
 {
-  if (len != a.len)
+  int len = length ();
+  if (len != a.length ())
     return 0;
-  return equal (data, a.data, len);
+  return equal (data (), a.data (), len);
 }
 
 int
 ComplexRowVector::operator != (const ComplexRowVector& a) const
 {
-  if (len != a.len)
-    return 1;
-  return !equal (data, a.data, len);
+  return !(*this == a);
 }
 
 // destructive insert/delete/reorder operations
@@ -904,14 +573,15 @@
 ComplexRowVector&
 ComplexRowVector::insert (const RowVector& a, int c)
 {
-  if (c < 0 || c + a.len - 1 > len)
+  int a_len = a.length ();
+  if (c < 0 || c + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[c+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (c+i) = a.elem (i);
 
   return *this;
 }
@@ -919,14 +589,15 @@
 ComplexRowVector&
 ComplexRowVector::insert (const ComplexRowVector& a, int c)
 {
-  if (c < 0 || c + a.len - 1 > len)
+  int a_len = a.length ();
+  if (c < 0 || c + a_len - 1 > length ())
     {
       (*current_liboctave_error_handler) ("range error for insert");
       return *this;
     }
 
-  for (int i = 0; i < a.len; i++)
-    data[c+i] = a.data[i];
+  for (int i = 0; i < a_len; i++)
+    elem (c+i) = a.elem (i);
 
   return *this;
 }
@@ -934,22 +605,27 @@
 ComplexRowVector&
 ComplexRowVector::fill (double val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 ComplexRowVector&
 ComplexRowVector::fill (const Complex& val)
 {
+  int len = length ();
   if (len > 0)
-    copy (data, len, val);
+    for (int i = 0; i < len; i++)
+      elem (i) = val;
   return *this;
 }
 
 ComplexRowVector&
 ComplexRowVector::fill (double val, int c1, int c2)
 {
+  int len = length ();
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -959,7 +635,7 @@
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
   for (int i = c1; i <= c2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -967,6 +643,7 @@
 ComplexRowVector&
 ComplexRowVector::fill (const Complex& val, int c1, int c2)
 {
+  int len = length ();
   if (c1 < 0 || c2 < 0 || c1 >= len || c2 >= len)
     {
       (*current_liboctave_error_handler) ("range error for fill");
@@ -976,7 +653,7 @@
   if (c1 > c2) { int tmp = c1; c1 = c2; c2 = tmp; }
 
   for (int i = c1; i <= c2; i++)
-    data[i] = val;
+    elem (i) = val;
 
   return *this;
 }
@@ -984,8 +661,9 @@
 ComplexRowVector
 ComplexRowVector::append (const RowVector& a) const
 {
+  int len = length ();
   int nc_insert = len;
-  ComplexRowVector retval (len + a.len);
+  ComplexRowVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nc_insert);
   return retval;
@@ -994,8 +672,9 @@
 ComplexRowVector
 ComplexRowVector::append (const ComplexRowVector& a) const
 {
+  int len = length ();
   int nc_insert = len;
-  ComplexRowVector retval (len + a.len);
+  ComplexRowVector retval (len + a.length ());
   retval.insert (*this, 0);
   retval.insert (a, nc_insert);
   return retval;
@@ -1004,39 +683,44 @@
 ComplexColumnVector
 ComplexRowVector::hermitian (void) const
 {
-  return ComplexColumnVector (conj_dup (data, len), len);
+  int len = length ();
+  return ComplexColumnVector (conj_dup (data (), len), len);
 }
 
 ComplexColumnVector
 ComplexRowVector::transpose (void) const
 {
-  return ComplexColumnVector (dup (data, len), len);
+  int len = length ();
+  return ComplexColumnVector (dup (data (), len), len);
 }
 
 RowVector
 real (const ComplexRowVector& a)
 {
+  int a_len = a.length ();
   RowVector retval;
-  if (a.len > 0)
-    retval = RowVector (real_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = RowVector (real_dup (a.data (), a_len), a_len);
   return retval;
 }
 
 RowVector
 imag (const ComplexRowVector& a)
 {
+  int a_len = a.length ();
   RowVector retval;
-  if (a.len > 0)
-    retval = RowVector (imag_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = RowVector (imag_dup (a.data (), a_len), a_len);
   return retval;
 }
 
 ComplexRowVector
 conj (const ComplexRowVector& a)
 {
+  int a_len = a.length ();
   ComplexRowVector retval;
-  if (a.len > 0)
-    retval = ComplexRowVector (conj_dup (a.data, a.len), a.len);
+  if (a_len > 0)
+    retval = ComplexRowVector (conj_dup (a.data (), a_len), a_len);
   return retval;
 }
 
@@ -1052,59 +736,121 @@
   ComplexRowVector result (new_c);
 
   for (int i = 0; i < new_c; i++)
-    result.data[i] = elem (c1+i);
+    result.elem (i) = elem (c1+i);
 
   return result;
 }
 
+// row vector by row vector -> row vector operations
+
+ComplexRowVector&
+ComplexRowVector::operator += (const RowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::operator -= (const RowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::operator += (const ComplexRowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector += operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  add2 (d, a.data (), len);
+  return *this;
+}
+
+ComplexRowVector&
+ComplexRowVector::operator -= (const ComplexRowVector& a)
+{
+  int len = length ();
+  if (len != a.length ())
+    {
+      (*current_liboctave_error_handler)
+	("nonconformant vector -= operation attempted");
+      return *this;
+    }
+
+  if (len == 0)
+    return *this;
+
+  Complex *d = fortran_vec (); // Ensures only one reference to my privates!
+
+  subtract2 (d, a.data (), len);
+  return *this;
+}
+
 // row vector by scalar -> row vector operations
 
 ComplexRowVector
-ComplexRowVector::operator + (double s) const
-{
-  return ComplexRowVector (add (data, len, s), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator - (double s) const
+operator + (const ComplexRowVector& v, double s)
 {
-  return ComplexRowVector (subtract (data, len, s), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator * (double s) const
-{
-  return ComplexRowVector (multiply (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (add (v.data (), len, s), len);
 }
 
 ComplexRowVector
-ComplexRowVector::operator / (double s) const
+operator - (const ComplexRowVector& v, double s)
 {
-  return ComplexRowVector (divide (data, len, s), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator + (const Complex& s) const
-{
-  return ComplexRowVector (add (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (subtract (v.data (), len, s), len);
 }
 
 ComplexRowVector
-ComplexRowVector::operator - (const Complex& s) const
+operator * (const ComplexRowVector& v, double s)
 {
-  return ComplexRowVector (subtract (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (multiply (v.data (), len, s), len);
 }
 
 ComplexRowVector
-ComplexRowVector::operator * (const Complex& s) const
+operator / (const ComplexRowVector& v, double s)
 {
-  return ComplexRowVector (multiply (data, len, s), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator / (const Complex& s) const
-{
-  return ComplexRowVector (divide (data, len, s), len);
+  int len = v.length ();
+  return ComplexRowVector (divide (v.data (), len, s), len);
 }
 
 // scalar by row vector -> row vector operations
@@ -1112,105 +858,79 @@
 ComplexRowVector
 operator + (double s, const ComplexRowVector& a)
 {
-  return ComplexRowVector (add (a.data, a.len, s), a.len);
+  int a_len = a.length ();
+  return ComplexRowVector (add (a.data (), a_len, s), a_len);
 }
 
 ComplexRowVector
 operator - (double s, const ComplexRowVector& a)
 {
-  return ComplexRowVector (subtract (s, a.data, a.len), a.len);
+  int a_len = a.length ();
+  return ComplexRowVector (subtract (s, a.data (), a_len), a_len);
 }
 
 ComplexRowVector
 operator * (double s, const ComplexRowVector& a)
 {
-  return ComplexRowVector (multiply (a.data, a.len, s), a.len);
+  int a_len = a.length ();
+  return ComplexRowVector (multiply (a.data (), a_len, s), a_len);
 }
 
 ComplexRowVector
 operator / (double s, const ComplexRowVector& a)
 {
-  return ComplexRowVector (divide (s, a.data, a.len), a.len);
-}
-
-ComplexRowVector
-operator + (const Complex& s, const ComplexRowVector& a)
-{
-  return ComplexRowVector (add (a.data, a.len, s), a.len);
-}
-
-ComplexRowVector
-operator - (const Complex& s, const ComplexRowVector& a)
-{
-  return ComplexRowVector (subtract (s, a.data, a.len), a.len);
-}
-
-ComplexRowVector
-operator * (const Complex& s, const ComplexRowVector& a)
-{
-  return ComplexRowVector (multiply (a.data, a.len, s), a.len);
-}
-
-ComplexRowVector
-operator / (const Complex& s, const ComplexRowVector& a)
-{
-  return ComplexRowVector (divide (s, a.data, a.len), a.len);
+  int a_len = a.length ();
+  return ComplexRowVector (divide (s, a.data (), a_len), a_len);
 }
 
 // row vector by column vector -> scalar
 
 Complex
-ComplexRowVector::operator * (const ColumnVector& a) const
+operator * (const ComplexRowVector& v, const ColumnVector& a)
 {
   ComplexColumnVector tmp (a);
-  return *this * tmp;
+  return v * tmp;
 }
 
 Complex
-ComplexRowVector::operator * (const ComplexColumnVector& a) const
+operator * (const ComplexRowVector& v, const ComplexColumnVector& a)
 {
 // XXX FIXME XXX -- need function body
   assert (0);
-  return Complex (0.0, 0.0);
+  return Complex ();
 }
 
 // row vector by matrix -> row vector
 
 ComplexRowVector
-ComplexRowVector::operator * (const Matrix& a) const
+operator * (const ComplexRowVector& v, const ComplexMatrix& a)
 {
-  ComplexMatrix tmp (a);
-  return *this * tmp;
-}
-
-ComplexRowVector
-ComplexRowVector::operator * (const ComplexMatrix& a) const
-{
-  if (a.nr != len)
+  int len = v.length ();
+  if (a.rows () != len)
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector multiplication attempted");
       return ComplexRowVector ();
     }
 
-  if (len == 0 || a.nc == 0)
+  if (len == 0 || a.cols () == 0)
     return ComplexRowVector (0);
 
 // Transpose A to form A'*x == (x'*A)'
 
-  int anr = a.nr;
-  int anc = a.nc;
+  int a_nr = a.rows ();
+  int a_nc = a.cols ();
 
   char trans = 'T';
-  int ld = anr;
+  int ld = a_nr;
   Complex alpha (1.0);
   Complex beta (0.0);
   int i_one = 1;
 
   Complex *y = new Complex [len];
 
-  F77_FCN (zgemv) (&trans, &anc, &anr, &alpha, a.data, &ld, data,
-		   &i_one, &beta, y, &i_one, 1L); 
+  F77_FCN (zgemv) (&trans, &a_nc, &a_nr, &alpha, a.data (), &ld,
+		   v.data (), &i_one, &beta, y, &i_one, 1L); 
 
   return ComplexRowVector (y, len);
 }
@@ -1218,9 +938,10 @@
 // row vector by row vector -> row vector operations
 
 ComplexRowVector
-ComplexRowVector::operator + (const RowVector& a) const
+operator + (const ComplexRowVector& v, const RowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector addition attempted");
@@ -1230,13 +951,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (add (data, a.data, len), len);
+  return ComplexRowVector (add (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-ComplexRowVector::operator - (const RowVector& a) const
+operator - (const ComplexRowVector& v, const RowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector subtraction attempted");
@@ -1246,77 +968,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (subtract (data, a.data, len), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator + (const ComplexRowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector addition attempted");
-      return ComplexRowVector ();
-    }
-
-  if (len == 0)
-    return ComplexRowVector (0);
-
-  return ComplexRowVector (add (data, a.data, len), len);
-}
-
-ComplexRowVector
-ComplexRowVector::operator - (const ComplexRowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector subtraction attempted");
-      return ComplexRowVector ();
-    }
-
-  if (len == 0)
-    return ComplexRowVector (0);
-
-  return ComplexRowVector (subtract (data, a.data, len), len);
+  return ComplexRowVector (subtract (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-ComplexRowVector::product (const RowVector& a) const
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector product attempted");
-      return ComplexRowVector ();
-    }
-
-  if (len == 0)
-    return ComplexRowVector (0);
-
-  return ComplexRowVector (multiply (data, a.data, len), len);
-}
-
-ComplexRowVector
-ComplexRowVector::quotient (const RowVector& a) const
+product (const ComplexRowVector& v, const RowVector& a)
 {
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector quotient attempted");
-      return ComplexRowVector ();
-    }
-
-  if (len == 0)
-    return ComplexRowVector (0);
-
-  return ComplexRowVector (divide (data, a.data, len), len);
-}
-
-ComplexRowVector
-ComplexRowVector::product (const ComplexRowVector& a) const
-{
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector product attempted");
@@ -1326,13 +985,14 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (multiply (data, a.data, len), len);
+  return ComplexRowVector (multiply (v.data (), a.data (), len), len);
 }
 
 ComplexRowVector
-ComplexRowVector::quotient (const ComplexRowVector& a) const
+quotient (const ComplexRowVector& v, const RowVector& a)
 {
-  if (len != a.len)
+  int len = v.length ();
+  if (len != a.length ())
     {
       (*current_liboctave_error_handler)
 	("nonconformant vector quotient attempted");
@@ -1342,87 +1002,10 @@
   if (len == 0)
     return ComplexRowVector (0);
 
-  return ComplexRowVector (divide (data, a.data, len), len);
-}
-
-ComplexRowVector&
-ComplexRowVector::operator += (const RowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexRowVector&
-ComplexRowVector::operator -= (const RowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
+  return ComplexRowVector (divide (v.data (), a.data (), len), len);
 }
 
-ComplexRowVector&
-ComplexRowVector::operator += (const ComplexRowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector += operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  add2 (data, a.data, len);
-  return *this;
-}
-
-ComplexRowVector&
-ComplexRowVector::operator -= (const ComplexRowVector& a)
-{
-  if (len != a.len)
-    {
-      (*current_liboctave_error_handler)
-	("nonconformant vector -= operation attempted");
-      return *this;
-    }
-
-  if (len == 0)
-    return *this;
-
-  subtract2 (data, a.data, len);
-  return *this;
-}
-
-// unary operations
-
-ComplexRowVector
-ComplexRowVector::operator - (void) const
-{
-  if (len == 0)
-    return ComplexRowVector (0);
-
-  return ComplexRowVector (negate (data, len), len);
-}
+// other operations
 
 ComplexRowVector
 map (c_c_Mapper f, const ComplexRowVector& a)
@@ -1435,8 +1018,9 @@
 RowVector
 map (d_c_Mapper f, const ComplexRowVector& a)
 {
-  RowVector b (a.len);
-  for (int i = 0; i < a.len; i++)
+  int a_len = a.length ();
+  RowVector b (a_len);
+  for (int i = 0; i < a_len; i++)
     b.elem (i) = f (a.elem (i));
   return b;
 }
@@ -1444,23 +1028,24 @@
 void
 ComplexRowVector::map (c_c_Mapper f)
 {
-  for (int i = 0; i < len; i++)
-    data[i] = f (data[i]);
+  for (int i = 0; i < length (); i++)
+    elem (i) = f (elem (i));
 }
 
 Complex
 ComplexRowVector::min (void) const
 {
+  int len = length ();
   if (len == 0)
     return Complex (0.0);
 
-  Complex res = data[0];
+  Complex res = elem (0);
   double absres = abs (res);
 
   for (int i = 1; i < len; i++)
-    if (abs (data[i]) < absres)
+    if (abs (elem (i)) < absres)
       {
-	res = data[i];
+	res = elem (i);
 	absres = abs (res);
       }
 
@@ -1470,16 +1055,17 @@
 Complex
 ComplexRowVector::max (void) const
 {
+  int len = length ();
   if (len == 0)
     return Complex (0.0);
 
-  Complex res = data[0];
+  Complex res = elem (0);
   double absres = abs (res);
 
   for (int i = 1; i < len; i++)
-    if (abs (data[i]) > absres)
+    if (abs (elem (i)) > absres)
       {
-	res = data[i];
+	res = elem (i);
 	absres = abs (res);
       }
 
@@ -1492,12 +1078,11 @@
 operator << (ostream& os, const ComplexRowVector& a)
 {
 //  int field_width = os.precision () + 7;
-  for (int i = 0; i < a.len; i++)
-    os << " " /* setw (field_width) */ << a.data[i];
+  for (int i = 0; i < a.length (); i++)
+    os << " " /* setw (field_width) */ << a.elem (i);
   return os;
 }
 
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/liboctave/f77-fcn.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/f77-fcn.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,6 @@
 #if !defined (_f77_uscore_h)
 #define _f77_uscore_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
 #if defined (F77_APPEND_UNDERSCORE)
 #define F77_FCN(f) f##_
 #else
--- a/liboctave/lo-error.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/lo-error.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,6 @@
 #if !defined (_liboctave_error_h)
 #define _liboctave_error_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
 // Tell g++ that fatal doesn't return;
 
 #ifdef __GNUG__
--- a/liboctave/mx-inlines.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/mx-inlines.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,14 +21,10 @@
 
 */
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 // But first, some helper functions...
 
 static inline double *
-add (double *d, int len, double s)
+add (const double *d, int len, double s)
 {
   double *result = 0;
   if (len > 0)
@@ -41,7 +37,7 @@
 }
 
 static inline double *
-subtract (double *d, int len, double s)
+subtract (const double *d, int len, double s)
 {
   double *result = 0;
   if (len > 0)
@@ -54,7 +50,7 @@
 }
 
 static inline double *
-subtract (double s, double *d, int len)
+subtract (double s, const double *d, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -67,7 +63,7 @@
 }
 
 static inline double *
-multiply (double *d, int len, double s)
+multiply (const double *d, int len, double s)
 {
   double *result = 0;
   if (len > 0)
@@ -80,7 +76,7 @@
 }
 
 static inline double *
-divide (double *d, int len, double s)
+divide (const double *d, int len, double s)
 {
   double *result = 0;
   if (len > 0)
@@ -93,7 +89,7 @@
 }
 
 static inline double *
-divide (double s, double *d, int len)
+divide (double s, const double *d, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -106,7 +102,7 @@
 }
 
 static inline double *
-add (double *x, double *y, int len)
+add (const double *x, const double *y, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -119,7 +115,7 @@
 }
 
 static inline double *
-subtract (double *x, double *y, int len)
+subtract (const double *x, const double *y, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -132,7 +128,7 @@
 }
 
 static inline double *
-multiply (double *x, double *y, int len)
+multiply (const double *x, const double *y, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -145,7 +141,7 @@
 }
 
 static inline double *
-divide (double *x, double *y, int len)
+divide (const double *x, const double *y, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -158,7 +154,7 @@
 }
 
 static inline double *
-add2 (double *x, double *y, int len)
+add2 (double *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] += y[i];
@@ -166,7 +162,7 @@
 }
 
 static inline double *
-subtract2 (double *x, double *y, int len)
+subtract2 (double *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] -= y[i];
@@ -174,7 +170,7 @@
 }
 
 static inline double *
-negate (double *d, int len)
+negate (const double *d, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -194,16 +190,16 @@
 }
 
 static inline void
-copy (double *x, double *y, int len)
+copy (double *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] = y[i];
 }
 
 static inline double *
-dup (double *x, int len)
+dup (const double *x, int len)
 {
-  double *retval = (double *) NULL;
+  double *retval = 0;
   if (len > 0)
     {
       retval = new double [len];
@@ -214,7 +210,7 @@
 }
 
 static inline int
-equal (double *x, double *y, int len)
+equal (const double *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     if (x[i] != y[i])
@@ -225,7 +221,7 @@
 // And some for Complex too...
 
 static inline Complex *
-add (Complex *d, int len, Complex s)
+add (const Complex *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -238,7 +234,7 @@
 }
 
 static inline Complex *
-add (Complex s, Complex *d, int len)
+add (Complex s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -251,7 +247,7 @@
 }
 
 static inline Complex *
-subtract (Complex *d, int len, Complex s)
+subtract (const Complex *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -264,7 +260,7 @@
 }
 
 static inline Complex *
-subtract (Complex s, Complex *d, int len)
+subtract (Complex s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -277,7 +273,7 @@
 }
 
 static inline Complex *
-multiply (Complex *d, int len, Complex s)
+multiply (const Complex *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -290,7 +286,7 @@
 }
 
 static inline Complex *
-multiply (Complex s, Complex *d, int len)
+multiply (Complex s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -303,7 +299,7 @@
 }
 
 static inline Complex *
-divide (Complex *d, int len, Complex s)
+divide (const Complex *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -316,7 +312,7 @@
 }
 
 static inline Complex *
-divide (Complex s, Complex *d, int len)
+divide (Complex s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -329,7 +325,7 @@
 }
 
 static inline Complex *
-add (Complex *x, Complex *y, int len)
+add (const Complex *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -342,7 +338,7 @@
 }
 
 static inline Complex *
-subtract (Complex *x, Complex *y, int len)
+subtract (const Complex *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -355,7 +351,7 @@
 }
 
 static inline Complex *
-multiply (Complex *x, Complex *y, int len)
+multiply (const Complex *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -368,7 +364,7 @@
 }
 
 static inline Complex *
-divide (Complex *x, Complex *y, int len)
+divide (const Complex *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -381,7 +377,7 @@
 }
 
 static inline Complex *
-add2 (Complex *x, Complex *y, int len)
+add2 (Complex *x, const Complex *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] += y[i];
@@ -389,7 +385,7 @@
 }
 
 static inline Complex *
-subtract2 (Complex *x, Complex *y, int len)
+subtract2 (Complex *x, const Complex *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] -= y[i];
@@ -397,7 +393,7 @@
 }
 
 static inline Complex *
-negate (Complex *d, int len)
+negate (const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -410,7 +406,7 @@
 }
 
 static inline double *
-not (Complex *d, int len)
+not (const Complex *d, int len)
 {
   double *result = 0;
   if (len > 0)
@@ -430,16 +426,16 @@
 }
 
 static inline void
-copy (Complex *x, Complex *y, int len)
+copy (Complex *x, const Complex *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] = y[i];
 }
 
 static inline Complex *
-dup (Complex *x, int len)
+dup (const Complex *x, int len)
 {
-  Complex *retval = (Complex *) NULL;
+  Complex *retval = 0;
   if (len > 0)
     {
       retval = new Complex [len];
@@ -450,9 +446,9 @@
 }
 
 static inline Complex *
-make_complex (double *x, int len)
+make_complex (const double *x, int len)
 {
-  Complex *retval = (Complex *) NULL;
+  Complex *retval = 0;
   if (len > 0)
     {
       retval = new Complex [len];
@@ -463,9 +459,9 @@
 }
 
 static inline Complex *
-conj_dup (Complex *x, int len)
+conj_dup (const Complex *x, int len)
 {
-  Complex *retval = (Complex *) NULL;
+  Complex *retval = 0;
   if (len > 0)
     {
       retval = new Complex [len];
@@ -476,9 +472,9 @@
 }
 
 static inline double *
-real_dup (Complex *x, int len)
+real_dup (const Complex *x, int len)
 {
-  double *retval = (double *) NULL;
+  double *retval = 0;
   if (len > 0)
     {
       retval = new double [len];
@@ -489,9 +485,9 @@
 }
 
 static inline double *
-imag_dup (Complex *x, int len)
+imag_dup (const Complex *x, int len)
 {
-  double *retval = (double *) NULL;
+  double *retval = 0;
   if (len > 0)
     {
       retval = new double [len];
@@ -502,7 +498,7 @@
 }
 
 static inline int
-equal (Complex *x, Complex *y, int len)
+equal (const Complex *x, const Complex *y, int len)
 {
   for (int i = 0; i < len; i++)
     if (x[i] != y[i])
@@ -513,7 +509,7 @@
 // And still some more for mixed Complex/double operations...
 
 static inline Complex *
-add (Complex *d, int len, double s)
+add (const Complex *d, int len, double s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -526,7 +522,7 @@
 }
 
 static inline Complex *
-add (double *d, int len, Complex s)
+add (const double *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -539,7 +535,7 @@
 }
 
 static inline Complex *
-add (double s, Complex *d, int len)
+add (double s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -552,7 +548,7 @@
 }
 
 static inline Complex *
-add (Complex s, double *d, int len)
+add (Complex s, const double *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -565,7 +561,7 @@
 }
 
 static inline Complex *
-subtract (Complex *d, int len, double s)
+subtract (const Complex *d, int len, double s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -578,7 +574,7 @@
 }
 
 static inline Complex *
-subtract (double *d, int len, Complex s)
+subtract (const double *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -591,7 +587,7 @@
 }
 
 static inline Complex *
-subtract (double s, Complex *d, int len)
+subtract (double s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -604,7 +600,7 @@
 }
 
 static inline Complex *
-subtract (Complex s, double *d, int len)
+subtract (Complex s, const double *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -617,7 +613,7 @@
 }
 
 static inline Complex *
-multiply (Complex *d, int len, double s)
+multiply (const Complex *d, int len, double s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -630,7 +626,7 @@
 }
 
 static inline Complex *
-multiply (double *d, int len, Complex s)
+multiply (const double *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -643,7 +639,7 @@
 }
 
 static inline Complex *
-divide (Complex *d, int len, double s)
+divide (const Complex *d, int len, double s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -656,7 +652,7 @@
 }
 
 static inline Complex *
-divide (double *d, int len, Complex s)
+divide (const double *d, int len, Complex s)
 {
   Complex *result = 0;
   if (len > 0)
@@ -669,7 +665,7 @@
 }
 
 static inline Complex *
-divide (double s, Complex *d, int len)
+divide (double s, const Complex *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -682,7 +678,7 @@
 }
 
 static inline Complex *
-divide (Complex s, double *d, int len)
+divide (Complex s, const double *d, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -695,7 +691,7 @@
 }
 
 static inline Complex *
-add (Complex *x, double *y, int len)
+add (const Complex *x, const double *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -708,7 +704,7 @@
 }
 
 static inline Complex *
-add (double *x, Complex *y, int len)
+add (const double *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -721,7 +717,7 @@
 }
 
 static inline Complex *
-subtract (Complex *x, double *y, int len)
+subtract (const Complex *x, const double *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -734,7 +730,7 @@
 }
 
 static inline Complex *
-subtract (double *x, Complex *y, int len)
+subtract (const double *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -747,7 +743,7 @@
 }
 
 static inline Complex *
-multiply (Complex *x, double *y, int len)
+multiply (const Complex *x, const double *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -760,7 +756,7 @@
 }
 
 static inline Complex *
-multiply (double *x, Complex *y, int len)
+multiply (const double *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -773,7 +769,7 @@
 }
 
 static inline Complex *
-divide (Complex *x, double *y, int len)
+divide (const Complex *x, const double *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -786,7 +782,7 @@
 }
 
 static inline Complex *
-divide (double *x, Complex *y, int len)
+divide (const double *x, const Complex *y, int len)
 {
   Complex *result = 0;
   if (len > 0)
@@ -799,7 +795,7 @@
 }
 
 static inline Complex *
-add2 (Complex *x, double *y, int len)
+add2 (Complex *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] += y[i];
@@ -807,7 +803,7 @@
 }
 
 static inline Complex *
-subtract2 (Complex *x, double *y, int len)
+subtract2 (Complex *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] -= y[i];
@@ -822,7 +818,7 @@
 }
 
 static inline void
-copy (Complex *x, double *y, int len)
+copy (Complex *x, const double *y, int len)
 {
   for (int i = 0; i < len; i++)
     x[i] = y[i];
--- a/liboctave/sun-utils.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/sun-utils.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -23,10 +23,6 @@
 
 #ifdef sun
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include <assert.h>
 
 /*
--- a/liboctave/sun-utils.h	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/sun-utils.h	Tue Nov 30 20:23:04 1993 +0000
@@ -24,10 +24,6 @@
 #if !defined (_sun_utils_h)
 #define _sun_utils_h 1
 
-#ifdef __GNUG__
-#pragma interface
-#endif
-
 #ifdef sun
 
 /*
--- a/liboctave/utils.cc	Tue Nov 30 20:23:04 1993 +0000
+++ b/liboctave/utils.cc	Tue Nov 30 20:23:04 1993 +0000
@@ -21,6 +21,10 @@
 
 */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <sys/types.h>
 #include <unistd.h>
 #include <signal.h>