Mercurial > hg > octave-nkf
diff liboctave/Matrix.h @ 3:9a4c07481e61
[project @ 1993-08-08 01:20:23 by jwe]
Initial revision
author | jwe |
---|---|
date | Sun, 08 Aug 1993 01:21:46 +0000 |
parents | |
children | 1b59f5c6c370 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/liboctave/Matrix.h @@ -0,0 +1,2606 @@ +// Matrix manipulations. -*- C++ -*- +/* + +Copyright (C) 1992, 1993 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* + +Should probably say something here about why these classes are not +represented by some sort of inheritance tree... + +*/ + +#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> +#include <values.h> +#include <assert.h> +#include <iostream.h> +// #include <iomanip.h> // We don\'t use this yet. +#include <Complex.h> + +#define FAIL assert(0) /* XXX FIXME XXX */ + +#ifndef MAPPER_FCN_TYPEDEFS +#define MAPPER_FCN_TYPEDEFS 1 + +typedef double (*d_d_Mapper)(double); +typedef double (*d_c_Mapper)(const Complex&); +typedef Complex (*c_c_Mapper)(const Complex&); + +#endif + +#include "f77-uscore.h" + +// Fortran functions we call. + +extern "C" +{ + int F77_FCN (dgemm) (const char*, const char*, const int*, + const int*, const int*, const double*, + const double*, const int*, const double*, + const int*, const double*, double*, const int*, + long, long); + + int F77_FCN (dgemv) (const char*, const int*, const int*, + const double*, const double*, const int*, + const double*, const int*, const double*, + double*, const int*, long); + + int F77_FCN (dgeco) (double*, const int*, const int*, int*, double*, + double*); + + int F77_FCN (dgesv) (const int*, const int*, double*, const int*, + int*, double*, const int*, int*); + + int F77_FCN (dgeqrf) (const int*, const int*, double*, const int*, + double*, double*, const int*, int*); + + int F77_FCN (dorgqr) (const int*, const int*, const int*, double*, + const int*, double*, double*, const int*, int*); + + int F77_FCN (dgesl) (const double*, const int*, const int*, + const int*, double*, const int*); + + int F77_FCN (dgedi) (double*, const int*, const int*, const int*, + double*, double*, const int*); + + double F77_FCN (ddot) (const int*, const double*, const int*, + const double*, const int*); + + int F77_FCN (dgeev) (const char*, const char*, const int*, double*, + const int*, double*, double*, double*, + const int*, double*, const int*, double*, + const int*, int*, long, long); + + int F77_FCN (dgeesx) (const char*, const char*, int (*)(), const char*, + const int*, double*, const int*, int*, double*, + double*, double*, const int*, double*, double*, + double*, const int*, int*, const int*, int*, + int*, long, long); + + int F77_FCN (dhseqr) (const char*, const char*, const int*, + const int*, const int*, double*, + const int*, double*, double*, + double*, const int*, double*, const int*, + int*, long, long); + + int F77_FCN (dgebal) (const char*, const int*, double*, + const int*, int*, int*, double*, + int*, long, long); + + int F77_FCN (dgebak) (const char*, const char*, const int*, const int*, + const int*, double*, const int*, double*, const int*, + int*, long, long); + + int F77_FCN (dgehrd) (const int*, const int*, const int*, + double*, const int*, double*, double*, + const int*, int*, long, long); + + int F77_FCN (dorghr) (const int*, const int*, const int*, + double*, const int*, double*, double*, + const int*, int*, long, long); + + int F77_FCN (dgesvd) (const char*, const char*, const int*, + const int*, double*, const int*, double*, + double*, const int*, double*, const int*, + double*, const int*, int*, long, long); + + int F77_FCN (dgelss) (const int*, const int*, const int*, double*, + const int*, double*, const int*, double*, + const double*, int*, double*, const int*, + int*); + +/* + * f2c translates complex*16 as + * + * typedef struct { doublereal re, im; } doublecomplex; + * + * and Complex.h from libg++ uses + * + * protected: + * double re; + * double im; + * + * as the only data members, so this should work (fingers crossed that + * things don't change). + */ + + int F77_FCN (zgemm) (const char*, const char*, const int*, + const int*, const int*, const Complex*, + const Complex*, const int*, const Complex*, + const int*, const Complex*, Complex*, const int*, + long, long); + + int F77_FCN (zgemv) (const char*, const int*, const int*, + const Complex*, const Complex*, const int*, + const Complex*, const int*, const Complex*, + Complex*, const int*, long); + + int F77_FCN (zgeco) (Complex*, const int*, const int*, int*, + double*, Complex*); + + int F77_FCN (zgesv) (const int*, const int*, Complex*, const int*, + int*, Complex*, const int*, int*); + + int F77_FCN (zgeqrf) (const int*, const int*, Complex*, const int*, + Complex*, Complex*, const int*, int*); + + int F77_FCN (zgeesx) (const char*, const char*, int (*)(), const char*, + const int*, Complex*, const int*, int*, + Complex*, Complex*, const int*, double*, double*, + Complex*, const int*, double*, int*, int*, + long, long); + + int F77_FCN (zhseqr) (const char*, const char*, const int*, + const int*, const int*, Complex*, const int*, + Complex*, Complex*, const int*, Complex*, + const int*, int*, long, long); + + int F77_FCN (zgebal) (const char*, const int*, Complex*, const int*, + int*, int*, double*, int*, long, long); + + int F77_FCN (zgebak) (const char*, const char*, const int*, const int*, + const int*, double*, const int*, Complex*, + const int*, int*, long, long); + + int F77_FCN (zgehrd) (const int*, const int*, const int*, Complex*, + const int*, Complex*, Complex*, const int*, + int*, long, long); + + int F77_FCN (zunghr) (const int*, const int*, const int*, Complex*, + const int*, Complex*, Complex*, const int*, + int*, long, long); + + int F77_FCN (zungqr) (const int*, const int*, const int*, Complex*, + const int*, Complex*, Complex*, const int*, int*); + + int F77_FCN (zgedi) (Complex*, const int*, const int*, int*, + Complex*, Complex*, const int*); + + int F77_FCN (zgesl) (Complex*, const int*, const int*, int*, + Complex*, const int*); + + int F77_FCN (zgeev) (const char*, const char*, const int*, Complex*, + const int*, Complex*, Complex*, const int*, + Complex*, const int*, Complex*, const int*, + double*, int*, long, long); + + int F77_FCN (zgesvd) (const char*, const char*, const int*, + const int*, Complex*, const int*, double*, + Complex*, const int*, Complex*, const int*, + Complex*, const int*, double*, int*, long, long); + + int F77_FCN (zgelss) (const int*, const int*, const int*, Complex*, + const int*, Complex*, const int*, double*, + const double*, int*, Complex*, const int*, + double*, int*); + +// Note that the original complex fft routines were not written for +// double complex arguments. They have been modified by adding an +// implicit double precision (a-h,o-z) statement at the beginning of +// each subroutine. + + int F77_FCN (cffti) (const int*, Complex*); + + int F77_FCN (cfftf) (const int*, Complex*, Complex*); + + int F77_FCN (cfftb) (const int*, Complex*, Complex*); + +} + +// Classes we declare. + +class Matrix; +class ColumnVector; +class RowVector; +class DiagMatrix; +class ComplexMatrix; +class ComplexColumnVector; +class ComplexRowVector; +class ComplexDiagMatrix; +class DET; +class ComplexDET; +class EIG; +class HESS; +class ComplexHESS; +class SCHUR; +class ComplexSCHUR; +class SVD; +class ComplexSVD; +class LU; +class ComplexLU; +class QR; +class ComplexQR; + +/* + * Matrix class + */ + +class Matrix +{ +friend class RowVector; +friend class DiagMatrix; +friend class ComplexMatrix; +friend class ComplexDiagMatrix; +friend class EIG; +friend class HESS; +friend class SCHUR; +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 (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); + + int operator == (const Matrix& a) const; + int operator != (const Matrix& a) const; + +// destructive insert/delete/reorder operations + + Matrix& insert (const Matrix& a, int r, int c); + Matrix& insert (const RowVector& a, int r, int c); + Matrix& insert (const ColumnVector& a, int r, int c); + Matrix& insert (const DiagMatrix& a, int r, int c); + + Matrix& fill (double val); + Matrix& fill (double val, int r1, int c1, int r2, int c2); + + Matrix append (const Matrix& a) const; + Matrix append (const RowVector& a) const; + Matrix append (const ColumnVector& a) const; + Matrix append (const DiagMatrix& a) const; + + Matrix stack (const Matrix& a) const; + Matrix stack (const RowVector& a) const; + Matrix stack (const ColumnVector& a) const; + Matrix stack (const DiagMatrix& a) const; + + Matrix transpose (void) const; + +// resize is the destructive equivalent for this one + + Matrix extract (int r1, int c1, int r2, int c2) const; + +// extract row or column i. + + RowVector row (int i) const; + RowVector row (char *s) const; + + ColumnVector column (int i) const; + ColumnVector column (char *s) const; + + Matrix inverse (int& info, double& rcond) const; + Matrix inverse (int& info) const; + Matrix inverse (void) const; + + ComplexMatrix fourier (void) const; + ComplexMatrix ifourier (void) const; + + DET determinant (void) const; + DET determinant (int& info) const; + DET determinant (int& info, double& rcond) const; + + Matrix solve (const Matrix& b) const; + Matrix solve (const Matrix& b, int& info) const; + Matrix solve (const Matrix& b, int& info, double& rcond) const; + + ComplexMatrix solve (const ComplexMatrix& b) const; + ComplexMatrix solve (const ComplexMatrix& b, int& info) const; + ComplexMatrix solve (const ComplexMatrix& b, int& info, double& rcond) const; + + ColumnVector solve (const ColumnVector& b) const; + ColumnVector solve (const ColumnVector& b, int& info) const; + ColumnVector 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; + + Matrix lssolve (const Matrix& b) const; + Matrix lssolve (const Matrix& b, int& info) const; + Matrix 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; + + ColumnVector lssolve (const ColumnVector& b) const; + ColumnVector lssolve (const ColumnVector& b, int& info) const; + ColumnVector 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 + + Matrix operator + (double s) const; + Matrix operator - (double s) const; + Matrix operator * (double s) const; + Matrix operator / (double s) const; + + ComplexMatrix operator + (Complex s) const; + ComplexMatrix operator - (Complex s) const; + ComplexMatrix operator * (Complex s) const; + ComplexMatrix operator / (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 DiagMatrix& a); + Matrix& operator -= (const DiagMatrix& a); + +// 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; + +// other operations + + friend Matrix map (d_d_Mapper f, const Matrix& a); + void map (d_d_Mapper f); + + Matrix all (void) const; + Matrix any (void) const; + + Matrix cumprod (void) const; + Matrix cumsum (void) const; + Matrix prod (void) const; + Matrix sum (void) const; + Matrix sumsq (void) const; + + ColumnVector diag (void) const; + ColumnVector diag (int k) const; + + ColumnVector row_min (void) const; + ColumnVector row_max (void) const; + + RowVector column_min (void) const; + RowVector column_max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const Matrix& a); + friend istream& operator >> (istream& is, Matrix& a); + +// conversions + + double *fortran_vec (void); + +private: + int nr; + int nc; + int len; + double *data; + + Matrix (double *d, int r, int 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::checkelem (int r, int c) +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +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::checkelem (int r, int c) const +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +inline double Matrix::operator () (int r, int c) const + { return checkelem (r, c); } + +inline double *Matrix::fortran_vec (void) { return data; } + +/* + * Column Vector class + */ + +class ColumnVector +{ +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); + + int operator == (const ColumnVector& a) const; + int operator != (const ColumnVector& a) const; + +// destructive insert/delete/reorder operations + + ColumnVector& insert (const ColumnVector& a, int r); + + ColumnVector& fill (double val); + ColumnVector& fill (double val, int r1, int r2); + + ColumnVector stack (const ColumnVector& a) const; + + RowVector transpose (void) const; + +// resize is the destructive equivalent for this one + + 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 + (Complex s) const; + ComplexColumnVector operator - (Complex s) const; + ComplexColumnVector operator * (Complex s) const; + ComplexColumnVector operator / (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; + + friend ColumnVector map (d_d_Mapper f, const ColumnVector& a); + void map (d_d_Mapper f); + + double min (void) const; + double max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const ColumnVector& a); + +// conversions + + double *fortran_vec (void); + +private: + int len; + double *data; + + ColumnVector (double *d, int 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::checkelem (int n) +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline double& ColumnVector::operator () (int n) { return checkelem (n); } + +inline double ColumnVector::elem (int n) const { return data[n]; } + +inline double +ColumnVector::checkelem (int n) const +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline double ColumnVector::operator () (int n) const { return checkelem (n); } + +inline double *ColumnVector::fortran_vec (void) { return data; } + +/* + * Row Vector class + */ + +class RowVector +{ +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); + + int operator == (const RowVector& a) const; + int operator != (const RowVector& a) const; + +// destructive insert/delete/reorder operations + + RowVector& insert (const RowVector& a, int c); + + RowVector& fill (double val); + RowVector& fill (double val, int c1, int c2); + + RowVector append (const RowVector& a) const; + + ColumnVector transpose (void) const; + +// resize is the destructive equivalent for this one + + 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 + (Complex s) const; + ComplexRowVector operator - (Complex s) const; + ComplexRowVector operator * (Complex s) const; + ComplexRowVector operator / (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; + + friend RowVector map (d_d_Mapper f, const RowVector& a); + void map (d_d_Mapper f); + + double min (void) const; + double max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const RowVector& a); + +// conversions + + double *fortran_vec (void); + +private: + int len; + double *data; + + RowVector (double *d, int 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::checkelem (int n) +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline double& RowVector::operator () (int n) { return checkelem (n); } + +inline double RowVector::elem (int n) const { return data[n]; } + +inline double +RowVector::checkelem (int n) const +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline double RowVector::operator () (int n) const { return checkelem (n); } + +inline double *RowVector::fortran_vec (void) { return data; } + +/* + * Diagonal Matrix class + */ + +class DiagMatrix +{ +friend class Matrix; +friend class ComplexMatrix; +friend class ComplexDiagMatrix; + +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); + + int operator == (const DiagMatrix& a) const; + int operator != (const DiagMatrix& a) const; + + DiagMatrix& fill (double val); + DiagMatrix& fill (double val, int beg, int end); + DiagMatrix& fill (const ColumnVector& a); + DiagMatrix& fill (const RowVector& a); + DiagMatrix& fill (const ColumnVector& a, int beg); + DiagMatrix& fill (const RowVector& a, int beg); + + DiagMatrix transpose (void) const; + +// resize is the destructive analog for this one + + Matrix extract (int r1, int c1, int r2, int c2) const; + +// extract row or column i. + + RowVector row (int i) const; + RowVector row (char *s) const; + + ColumnVector column (int i) const; + ColumnVector column (char *s) const; + + DiagMatrix inverse (int& info) const; + DiagMatrix inverse (void) const; + +// diagonal matrix by scalar -> matrix operations + + Matrix operator + (double s) const; + Matrix operator - (double s) const; + + ComplexMatrix operator + (Complex s) const; + ComplexMatrix operator - (Complex s) const; + +// diagonal matrix by scalar -> diagonal matrix operations + + DiagMatrix operator * (double s) const; + DiagMatrix operator / (double s) const; + + ComplexDiagMatrix operator * (Complex s) const; + ComplexDiagMatrix operator / (Complex s) const; + +// scalar by diagonal matrix -> matrix operations + + friend Matrix operator + (double s, const DiagMatrix& a); + friend Matrix operator - (double 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); + +// diagonal matrix by column vector -> column vector operations + + ColumnVector operator * (const ColumnVector& a) const; + + ComplexColumnVector operator * (const ComplexColumnVector& a) const; + +// 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); + +// 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; + + ColumnVector diag (void) const; + ColumnVector diag (int k) const; + +// i/o + + friend ostream& operator << (ostream& os, const DiagMatrix& a); + +private: + int nr; + int nc; + int len; + double *data; + + DiagMatrix (double *d, int nr, int 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 len; } +inline int DiagMatrix::cols (void) const { return len; } +inline int DiagMatrix::columns (void) const { return len; } + +// 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::checkelem (int r, int c) +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +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::checkelem (int r, int c) const +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +inline double DiagMatrix::operator () (int r, int c) const + { return checkelem (r, c); } + +/* + * Complex Matrix class + */ + +class ComplexMatrix +{ +friend class Matrix; +friend class DiagMatrix; +friend class ComplexRowVector; +friend class ComplexDiagMatrix; +friend class EIG; +friend class ComplexHESS; +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, Complex val); + ComplexMatrix (const Matrix& a); + ComplexMatrix (const ComplexMatrix& a); + ComplexMatrix (const DiagMatrix& a); + ComplexMatrix (const ComplexDiagMatrix& a); + ComplexMatrix (double a); + ComplexMatrix (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, Complex val); + + int operator == (const ComplexMatrix& a) const; + int operator != (const ComplexMatrix& a) const; + +// destructive insert/delete/reorder operations + + ComplexMatrix& insert (const Matrix& a, int r, int c); + ComplexMatrix& insert (const RowVector& a, int r, int c); + ComplexMatrix& insert (const ColumnVector& a, int r, int c); + ComplexMatrix& insert (const DiagMatrix& a, int r, int c); + + ComplexMatrix& insert (const ComplexMatrix& a, int r, int c); + ComplexMatrix& insert (const ComplexRowVector& a, int r, int c); + ComplexMatrix& insert (const ComplexColumnVector& a, int r, int c); + ComplexMatrix& insert (const ComplexDiagMatrix& a, int r, int c); + + ComplexMatrix& fill (double val); + ComplexMatrix& fill (Complex val); + ComplexMatrix& fill (double val, int r1, int c1, int r2, int c2); + ComplexMatrix& fill (Complex val, int r1, int c1, int r2, int c2); + + ComplexMatrix append (const Matrix& a) const; + ComplexMatrix append (const RowVector& a) const; + ComplexMatrix append (const ColumnVector& a) const; + ComplexMatrix append (const DiagMatrix& a) const; + + ComplexMatrix append (const ComplexMatrix& a) const; + ComplexMatrix append (const ComplexRowVector& a) const; + ComplexMatrix append (const ComplexColumnVector& a) const; + ComplexMatrix append (const ComplexDiagMatrix& a) const; + + ComplexMatrix stack (const Matrix& a) const; + ComplexMatrix stack (const RowVector& a) const; + ComplexMatrix stack (const ColumnVector& a) const; + ComplexMatrix stack (const DiagMatrix& a) const; + + ComplexMatrix stack (const ComplexMatrix& a) const; + ComplexMatrix stack (const ComplexRowVector& a) const; + ComplexMatrix stack (const ComplexColumnVector& a) const; + ComplexMatrix stack (const ComplexDiagMatrix& a) const; + + ComplexMatrix hermitian (void) const; // complex conjugate transpose + ComplexMatrix transpose (void) const; + + friend Matrix real (const ComplexMatrix& a); + friend Matrix imag (const ComplexMatrix& a); + friend ComplexMatrix conj (const ComplexMatrix& a); + +// resize is the destructive equivalent for this one + + ComplexMatrix extract (int r1, int c1, int r2, int c2) const; + +// extract row or column i. + + ComplexRowVector row (int i) const; + ComplexRowVector row (char *s) const; + + ComplexColumnVector column (int i) const; + ComplexColumnVector column (char *s) const; + + ComplexMatrix inverse (int& info, double& rcond) const; + ComplexMatrix inverse (int& info) const; + ComplexMatrix inverse (void) const; + + ComplexMatrix fourier (void) const; + ComplexMatrix ifourier (void) const; + + ComplexDET determinant (void) const; + ComplexDET determinant (int& info) const; + ComplexDET determinant (int& info, double& rcond) const; + + ComplexMatrix solve (const Matrix& b) const; + ComplexMatrix solve (const Matrix& b, int& info) const; + ComplexMatrix solve (const Matrix& b, int& info, double& rcond) const; + + ComplexMatrix solve (const ComplexMatrix& b) const; + 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 + (Complex s) const; + ComplexMatrix operator - (Complex s) const; + ComplexMatrix operator * (Complex s) const; + ComplexMatrix operator / (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 + (Complex s, const ComplexMatrix& a); + friend ComplexMatrix operator - (Complex s, const ComplexMatrix& a); + friend ComplexMatrix operator * (Complex s, const ComplexMatrix& a); + friend ComplexMatrix operator / (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); + + ComplexMatrix& operator += (const ComplexDiagMatrix& a); + ComplexMatrix& operator -= (const ComplexDiagMatrix& a); + +// 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); + + ComplexMatrix& operator += (const ComplexMatrix& a); + ComplexMatrix& operator -= (const ComplexMatrix& a); + +// unary operations + + ComplexMatrix operator - (void) const; + Matrix operator ! (void) const; + +// other operations + + friend ComplexMatrix map (c_c_Mapper f, const ComplexMatrix& a); + friend Matrix map (d_c_Mapper f, const ComplexMatrix& a); + void map (c_c_Mapper f); + + Matrix all (void) const; + Matrix any (void) const; + + ComplexMatrix cumprod (void) const; + ComplexMatrix cumsum (void) const; + ComplexMatrix prod (void) const; + ComplexMatrix sum (void) const; + ComplexMatrix sumsq (void) const; + + ComplexColumnVector diag (void) const; + ComplexColumnVector diag (int k) const; + + ComplexColumnVector row_min (void) const; + ComplexColumnVector row_max (void) const; + + ComplexRowVector column_min (void) const; + ComplexRowVector column_max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const ComplexMatrix& a); + friend istream& operator >> (istream& is, ComplexMatrix& a); + +// conversions + + Complex *fortran_vec (void); + +private: + int nr; + int nc; + int len; + Complex *data; + + ComplexMatrix (Complex *d, int r, int 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::checkelem (int r, int c) +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +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::checkelem (int r, int c) const +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +inline Complex ComplexMatrix::operator () (int r, int c) const + { return checkelem (r, c); } + +inline Complex *ComplexMatrix::fortran_vec (void) { return data; } + +/* + * Complex Column Vector class + */ + +class ComplexColumnVector +{ +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, Complex val); + ComplexColumnVector (const ColumnVector& a); + ComplexColumnVector (const ComplexColumnVector& a); + ComplexColumnVector (double a); + ComplexColumnVector (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, Complex val); + + int operator == (const ComplexColumnVector& a) const; + int operator != (const ComplexColumnVector& a) const; + +// destructive insert/delete/reorder operations + + ComplexColumnVector& insert (const ColumnVector& a, int r); + ComplexColumnVector& insert (const ComplexColumnVector& a, int r); + + ComplexColumnVector& fill (double val); + ComplexColumnVector& fill (Complex val); + ComplexColumnVector& fill (double val, int r1, int r2); + ComplexColumnVector& fill (Complex val, int r1, int r2); + + ComplexColumnVector stack (const ColumnVector& a) const; + ComplexColumnVector stack (const ComplexColumnVector& a) const; + + ComplexRowVector hermitian (void) const; // complex conjugate transpose. + ComplexRowVector transpose (void) const; + + friend ColumnVector real (const ComplexColumnVector& a); + friend ColumnVector imag (const ComplexColumnVector& a); + friend ComplexColumnVector conj (const ComplexColumnVector& a); + +// resize is the destructive equivalent for this one + + ComplexColumnVector extract (int r1, int r2) const; + +// 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 + (Complex s) const; + ComplexColumnVector operator - (Complex s) const; + ComplexColumnVector operator * (Complex s) const; + ComplexColumnVector operator / (Complex s) const; + +// scalar by column vector -> column vector operations + + friend ComplexColumnVector operator + (double s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator - (double s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator * (double s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator / (double s, + const ComplexColumnVector& a); + + friend ComplexColumnVector operator + (Complex s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator - (Complex s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator * (Complex s, + const ComplexColumnVector& a); + friend ComplexColumnVector operator / (Complex s, + const ComplexColumnVector& a); + +// column vector by row vector -> matrix operations + + ComplexMatrix operator * (const RowVector& a) const; + + ComplexMatrix operator * (const ComplexRowVector& a) const; + +// 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 map (c_c_Mapper f, const ComplexColumnVector& a); + friend ColumnVector map (d_c_Mapper f, const ComplexColumnVector& a); + void map (c_c_Mapper f); + + Complex min (void) const; + Complex max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const ComplexColumnVector& a); + +// conversions + + Complex *fortran_vec (void); + +private: + int len; + Complex *data; + + ComplexColumnVector (Complex *d, int 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::checkelem (int n) +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline Complex& ComplexColumnVector::operator () (int n) + { return checkelem (n); } + +inline Complex ComplexColumnVector::elem (int n) const { return data[n]; } + +inline Complex +ComplexColumnVector::checkelem (int n) const +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline Complex ComplexColumnVector::operator () (int n) const + { return checkelem (n); } + +inline Complex *ComplexColumnVector::fortran_vec (void) { return data; } + +/* + * Complex Row Vector class + */ + +class ComplexRowVector +{ +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, Complex val); + ComplexRowVector (const RowVector& a); + ComplexRowVector (const ComplexRowVector& a); + ComplexRowVector (double a); + ComplexRowVector (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, Complex val); + + int operator == (const ComplexRowVector& a) const; + int operator != (const ComplexRowVector& a) const; + +// destructive insert/delete/reorder operations + + ComplexRowVector& insert (const RowVector& a, int c); + ComplexRowVector& insert (const ComplexRowVector& a, int c); + + ComplexRowVector& fill (double val); + ComplexRowVector& fill (Complex val); + ComplexRowVector& fill (double val, int c1, int c2); + ComplexRowVector& fill (Complex val, int c1, int c2); + + ComplexRowVector append (const RowVector& a) const; + ComplexRowVector append (const ComplexRowVector& a) const; + + ComplexColumnVector hermitian (void) const; // complex conjugate transpose. + ComplexColumnVector transpose (void) const; + + friend RowVector real (const ComplexRowVector& a); + friend RowVector imag (const ComplexRowVector& a); + friend ComplexRowVector conj (const ComplexRowVector& a); + +// resize is the destructive equivalent for this one + + ComplexRowVector extract (int c1, int c2) const; + +// 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 + (Complex s) const; + ComplexRowVector operator - (Complex s) const; + ComplexRowVector operator * (Complex s) const; + ComplexRowVector operator / (Complex s) const; + +// scalar by row vector -> row vector operations + + friend ComplexRowVector operator + (double s, const ComplexRowVector& a); + friend ComplexRowVector operator - (double s, const ComplexRowVector& a); + friend ComplexRowVector operator * (double s, const ComplexRowVector& a); + friend ComplexRowVector operator / (double s, const ComplexRowVector& a); + + friend ComplexRowVector operator + (Complex s, const ComplexRowVector& a); + friend ComplexRowVector operator - (Complex s, const ComplexRowVector& a); + friend ComplexRowVector operator * (Complex s, const ComplexRowVector& a); + friend ComplexRowVector operator / (Complex s, const ComplexRowVector& a); + +// row vector by column vector -> scalar + + Complex operator * (const ColumnVector& a) const; + + Complex operator * (const ComplexColumnVector& a) const; + +// row vector by matrix -> row vector + + ComplexRowVector operator * (const Matrix& a) const; + + ComplexRowVector operator * (const ComplexMatrix& a) const; + +// 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 map (c_c_Mapper f, const ComplexRowVector& a); + friend RowVector map (d_c_Mapper f, const ComplexRowVector& a); + void map (c_c_Mapper f); + + Complex min (void) const; + Complex max (void) const; + +// i/o + + friend ostream& operator << (ostream& os, const ComplexRowVector& a); + +// conversions + + Complex *fortran_vec (void); + +private: + int len; + Complex *data; + + ComplexRowVector (Complex *d, int 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::checkelem (int n) +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline Complex& ComplexRowVector::operator () (int n) { return checkelem (n); } + +inline Complex ComplexRowVector::elem (int n) const { return data[n]; } + +inline Complex +ComplexRowVector::checkelem (int n) const +{ +#ifndef NO_RANGE_CHECK + if (n < 0 || n >= len) + FAIL; +#endif + + return elem (n); +} + +inline Complex ComplexRowVector::operator () (int n) const + { return checkelem (n); } + +inline Complex *ComplexRowVector::fortran_vec (void) { return data; } + +/* + * Complex Diagonal Matrix class + */ + +class ComplexDiagMatrix +{ +friend class Matrix; +friend class DiagMatrix; +friend class ComplexMatrix; + +public: + ComplexDiagMatrix (void); + ComplexDiagMatrix (int n); + ComplexDiagMatrix (int n, double val); + ComplexDiagMatrix (int n, Complex val); + ComplexDiagMatrix (int r, int c); + ComplexDiagMatrix (int r, int c, double val); + ComplexDiagMatrix (int r, int c, Complex val); + ComplexDiagMatrix (const RowVector& a); + ComplexDiagMatrix (const ComplexRowVector& a); + ComplexDiagMatrix (const ColumnVector& a); + ComplexDiagMatrix (const ComplexColumnVector& a); + ComplexDiagMatrix (const DiagMatrix& a); + ComplexDiagMatrix (const ComplexDiagMatrix& a); + ComplexDiagMatrix (double a); + ComplexDiagMatrix (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, Complex val); + + int operator == (const ComplexDiagMatrix& a) const; + int operator != (const ComplexDiagMatrix& a) const; + + ComplexDiagMatrix& fill (double val); + ComplexDiagMatrix& fill (Complex val); + ComplexDiagMatrix& fill (double val, int beg, int end); + ComplexDiagMatrix& fill (Complex val, int beg, int end); + ComplexDiagMatrix& fill (const ColumnVector& a); + ComplexDiagMatrix& fill (const ComplexColumnVector& a); + ComplexDiagMatrix& fill (const RowVector& a); + ComplexDiagMatrix& fill (const ComplexRowVector& a); + ComplexDiagMatrix& fill (const ColumnVector& a, int beg); + ComplexDiagMatrix& fill (const ComplexColumnVector& a, int beg); + ComplexDiagMatrix& fill (const RowVector& a, int beg); + ComplexDiagMatrix& fill (const ComplexRowVector& a, int beg); + + ComplexDiagMatrix hermitian (void) const; // complex conjugate transpose + ComplexDiagMatrix transpose (void) const; + + friend DiagMatrix real (const ComplexDiagMatrix& a); + friend DiagMatrix imag (const ComplexDiagMatrix& a); + friend ComplexDiagMatrix conj (const ComplexDiagMatrix& a); + +// resize is the destructive analog for this one + + ComplexMatrix extract (int r1, int c1, int r2, int c2) const; + +// extract row or column i. + + ComplexRowVector row (int i) const; + ComplexRowVector row (char *s) const; + + ComplexColumnVector column (int i) const; + ComplexColumnVector column (char *s) const; + + 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 + (Complex s) const; + ComplexMatrix operator - (Complex s) const; + +// diagonal matrix by scalar -> diagonal matrix operations + + ComplexDiagMatrix operator * (double s) const; + ComplexDiagMatrix operator / (double s) const; + + ComplexDiagMatrix operator * (Complex s) const; + ComplexDiagMatrix operator / (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 + (Complex s, const ComplexDiagMatrix& a); + friend ComplexMatrix operator - (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 * (Complex s, const ComplexDiagMatrix& a); + friend ComplexDiagMatrix operator / (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 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; + + ComplexColumnVector diag (void) const; + ComplexColumnVector diag (int k) const; + +// i/o + + friend ostream& operator << (ostream& os, const ComplexDiagMatrix& a); + +private: + int nr; + int nc; + int len; + Complex *data; + + ComplexDiagMatrix (Complex *d, int nr, int 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 len; } +inline int ComplexDiagMatrix::cols (void) const { return len; } +inline int ComplexDiagMatrix::columns (void) const { return len; } + +// 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::checkelem (int r, int c) +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +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::checkelem (int r, int c) const +{ +#ifndef NO_RANGE_CHECK + if (r < 0 || r >= nr || c < 0 || c >= nc) + FAIL; +#endif + + return elem (r, c); +} + +inline Complex ComplexDiagMatrix::operator () (int r, int c) const + { return checkelem (r, c); } + +/* + * Result of a Determinant calculation. + */ + +class DET +{ +public: + DET (void) {} + + DET (const DET& a); + + DET& operator = (const DET& a); + + int value_will_overflow (void) const; + int value_will_underflow (void) const; + double coefficient (void) const; + int exponent (void) const; + double value (void) const; + + friend ostream& operator << (ostream& os, const DET& a); + +private: + DET (const double *d); + + double det [2]; +}; + +inline DET::DET (const DET& a) { det[0] = a.det[0]; det[1] = a.det[1]; } + +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]; } + +/* + * Result of a Determinant calculation. + */ + +class ComplexDET +{ +public: + ComplexDET (void) {} + + ComplexDET (const ComplexDET& a); + + ComplexDET& operator = (const ComplexDET& a); + + int value_will_overflow (void) const; + int value_will_underflow (void) const; + Complex coefficient (void) const; + int exponent (void) const; + Complex value (void) const; + + friend ostream& operator << (ostream& os, const ComplexDET& a); + +private: + ComplexDET (const Complex *d); + + Complex det [2]; +}; + +inline ComplexDET::ComplexDET (const ComplexDET& a) + { det[0] = a.det[0]; det[1] = a.det[1]; } + +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]; } + +/* + * Result of a Hessenbug Decomposition + */ + +class HESS +{ +friend class Matrix; + +public: + HESS (void) {} + + HESS (const Matrix& a); + HESS (const Matrix&a, int& info); + + HESS (const HESS& a); + + HESS& operator = (const HESS& a); + Matrix hess_matrix (void) const; + Matrix unitary_hess_matrix (void) const; + friend ostream& operator << (ostream& os, const HESS& a); + +private: + int init (const Matrix& a); + + Matrix hess_mat; + Matrix unitary_hess_mat; +}; + +inline HESS::HESS (const Matrix& a) {init (a); } +inline HESS::HESS (const Matrix& a, int& info) { info = init(a); } +inline HESS::HESS (const HESS& a) +{ + hess_mat = a.hess_mat; + unitary_hess_mat = a.unitary_hess_mat; +} +inline HESS& +HESS::operator = (const HESS& a) +{ + hess_mat = a.hess_mat; + unitary_hess_mat = a.unitary_hess_mat; + + return *this; +} +inline Matrix HESS::hess_matrix (void) const { return hess_mat; } +inline Matrix HESS::unitary_hess_matrix (void) const {return unitary_hess_mat;} + +/* + * Result of a Hessenburg Decomposition + */ + +class ComplexHESS +{ +friend class ComplexMatrix; + +public: + ComplexHESS (void) {} + ComplexHESS (const ComplexMatrix& a); + ComplexHESS (const ComplexMatrix& a, int& info); + ComplexHESS (const ComplexHESS& a); + ComplexHESS& operator = (const ComplexHESS& a); + ComplexMatrix hess_matrix (void) const; + ComplexMatrix unitary_hess_matrix (void) const; + + friend ostream& operator << (ostream& os, const ComplexHESS& a); + +private: + int init (const ComplexMatrix& a); + + ComplexMatrix hess_mat; + ComplexMatrix unitary_hess_mat; +}; + +inline ComplexHESS::ComplexHESS (const ComplexMatrix& a) { init(a); } +inline ComplexHESS::ComplexHESS (const ComplexMatrix& a, int& info) + { info = init(a); } + +inline ComplexHESS::ComplexHESS (const ComplexHESS& a) +{ + hess_mat = a.hess_mat; + unitary_hess_mat = a.unitary_hess_mat; +} + +inline ComplexHESS& +ComplexHESS::operator = (const ComplexHESS& a) +{ + hess_mat = a.hess_mat; + unitary_hess_mat = a.unitary_hess_mat; + + return *this; +} + +inline ComplexMatrix ComplexHESS::hess_matrix (void) const + { return hess_mat; } + +inline ComplexMatrix ComplexHESS::unitary_hess_matrix (void) const + { return unitary_hess_mat; } + +/* + * Result of a Schur Decomposition + */ + +class SCHUR +{ +friend class Matrix; + +public: + SCHUR (void) {} + + SCHUR (const Matrix& a, const char *ord); + SCHUR (const Matrix& a, const char *ord, int& info); + + SCHUR (const SCHUR& a, const char *ord); + + SCHUR& operator = (const SCHUR& a, const char *ord); + + Matrix schur_matrix (void) const; + Matrix unitary_matrix (void) const; + + friend ostream& operator << (ostream& os, const SCHUR& a); + +private: + int init (const Matrix& a, const char *ord); + + Matrix schur_mat; + Matrix unitary_mat; +}; + +inline SCHUR::SCHUR (const Matrix& a, const char *ord) { init (a, ord); } + +inline SCHUR::SCHUR (const Matrix& a, const char *ord, int& info) + { info = init (a, ord); } + +inline SCHUR::SCHUR (const SCHUR& a, const char *ord) +{ + schur_mat = a.schur_mat; + unitary_mat = a.unitary_mat; +} + +inline SCHUR& +SCHUR::operator = (const SCHUR& a, const char *ord) +{ + schur_mat = a.schur_mat; + unitary_mat = a.unitary_mat; + + return *this; +} + +inline Matrix SCHUR::schur_matrix (void) const { return schur_mat; } +inline Matrix SCHUR::unitary_matrix (void) const { return unitary_mat; } + +/* + * Result of a Schur Decomposition + */ + +class ComplexSCHUR +{ +friend class ComplexMatrix; + +public: + ComplexSCHUR (void) {} + + ComplexSCHUR (const ComplexMatrix& a, const char *ord); + ComplexSCHUR (const ComplexMatrix& a, const char *ord, int& info); + + ComplexSCHUR (const ComplexSCHUR& a, const char *ord); + + ComplexSCHUR& operator = (const ComplexSCHUR& a, const char *ord); + + ComplexMatrix schur_matrix (void) const; + ComplexMatrix unitary_matrix (void) const; + + friend ostream& operator << (ostream& os, const ComplexSCHUR& a); + +private: + int init (const ComplexMatrix& a, const char *ord); + + ComplexMatrix schur_mat; + ComplexMatrix unitary_mat; +}; + +inline ComplexSCHUR::ComplexSCHUR (const ComplexMatrix& a, const char *ord) + { init (a,ord); } + +inline ComplexSCHUR::ComplexSCHUR (const ComplexMatrix& a, const char *ord, + int& info) + { info = init (a,ord); } + +inline ComplexSCHUR::ComplexSCHUR (const ComplexSCHUR& a, const char *ord) +{ + schur_mat = a.schur_mat; + unitary_mat = a.unitary_mat; +} + +inline ComplexSCHUR& +ComplexSCHUR::operator = (const ComplexSCHUR& a, const char *ord) +{ + schur_mat = a.schur_mat; + unitary_mat = a.unitary_mat; + + return *this; +} +inline ComplexMatrix ComplexSCHUR::schur_matrix (void) const + { return schur_mat; } + +inline ComplexMatrix ComplexSCHUR::unitary_matrix (void) const + { return unitary_mat; } + + +/* + * Result of a Singular Value Decomposition. + */ + +class SVD +{ +friend class Matrix; + +public: + SVD (void) {} + + SVD (const Matrix& a); + SVD (const Matrix& a, int& info); + + SVD (const SVD& a); + + SVD& operator = (const SVD& a); + + DiagMatrix singular_values (void) const; + Matrix left_singular_matrix (void) const; + Matrix right_singular_matrix (void) const; + + friend ostream& operator << (ostream& os, const SVD& a); + +private: + int init (const Matrix& a); + + DiagMatrix sigma; + Matrix left_sm; + Matrix right_sm; +}; + +inline SVD::SVD (const Matrix& a) { init (a); } + +inline SVD::SVD (const Matrix& a, int& info) { info = init (a); } + +inline SVD::SVD (const SVD& a) +{ + sigma = a.sigma; + left_sm = a.left_sm; + right_sm = a.right_sm; +} + +inline SVD& +SVD::operator = (const SVD& a) +{ + sigma = a.sigma; + left_sm = a.left_sm; + right_sm = a.right_sm; + + return *this; +} + +inline DiagMatrix SVD::singular_values (void) const { return sigma; } +inline Matrix SVD::left_singular_matrix (void) const { return left_sm; } +inline Matrix SVD::right_singular_matrix (void) const { return right_sm; } + +/* + * Result of a Singular Value Decomposition. + */ + +class ComplexSVD +{ +friend class ComplexMatrix; + +public: + ComplexSVD (void) {} + + ComplexSVD (const ComplexMatrix& a); + ComplexSVD (const ComplexMatrix& a, int& info); + + ComplexSVD (const ComplexSVD& a); + + ComplexSVD& operator = (const ComplexSVD& a); + + DiagMatrix singular_values (void) const; + ComplexMatrix left_singular_matrix (void) const; + ComplexMatrix right_singular_matrix (void) const; + + friend ostream& operator << (ostream& os, const ComplexSVD& a); + +private: + int init (const ComplexMatrix& a); + + DiagMatrix sigma; + ComplexMatrix left_sm; + ComplexMatrix right_sm; +}; + +inline ComplexSVD::ComplexSVD (const ComplexMatrix& a) { init (a); } +inline ComplexSVD::ComplexSVD (const ComplexMatrix& a, int& info) + { info = init (a); } + +inline ComplexSVD::ComplexSVD (const ComplexSVD& a) +{ + sigma = a.sigma; + left_sm = a.left_sm; + right_sm = a.right_sm; +} + +inline ComplexSVD& +ComplexSVD::operator = (const ComplexSVD& a) +{ + sigma = a.sigma; + left_sm = a.left_sm; + right_sm = a.right_sm; + + return *this; +} + +inline DiagMatrix ComplexSVD::singular_values (void) const + { return sigma; } + +inline ComplexMatrix ComplexSVD::left_singular_matrix (void) const + { return left_sm; } + +inline ComplexMatrix ComplexSVD::right_singular_matrix (void) const + { return right_sm; } + +/* + * Result of an Eigenvalue computation. + */ + +class EIG +{ +friend class Matrix; +friend class ComplexMatrix; + +public: + EIG (void) {} + + EIG (const Matrix& a); + EIG (const Matrix& a, int& info); + + EIG (const ComplexMatrix& a); + EIG (const ComplexMatrix& a, int& info); + + EIG (const EIG& a); + + EIG& operator = (const EIG& a); + + ComplexColumnVector eigenvalues (void) const; + ComplexMatrix eigenvectors (void) const; + + friend ostream& operator << (ostream& os, const EIG& a); + +private: + int init (const Matrix& a); + int init (const ComplexMatrix& a); + + ComplexColumnVector lambda; + ComplexMatrix v; +}; + +inline EIG::EIG (const Matrix& a) { init (a); } +inline EIG::EIG (const Matrix& a, int& info) { info = init (a); } + +inline EIG::EIG (const ComplexMatrix& a) { init (a); } +inline EIG::EIG (const ComplexMatrix& a, int& info) { info = init (a); } + +inline EIG::EIG (const EIG& a) { lambda = a.lambda; v = a.v; } + +inline EIG& EIG::operator = (const EIG& a) + { lambda = a.lambda; v = a.v; return *this; } + +inline ComplexColumnVector EIG::eigenvalues (void) const { return lambda; } + +inline ComplexMatrix EIG::eigenvectors (void) const { return v; } + +/* + * Result of an LU decomposition. + */ + +class LU +{ +friend class Matrix; + +public: + LU (void) {} + + LU (const Matrix& a); + + LU (const LU& a); + + LU& operator = (const LU& a); + + Matrix L (void) const; + Matrix U (void) const; + Matrix P (void) const; + + friend ostream& operator << (ostream& os, const LU& a); + +private: + + Matrix l; + Matrix u; + Matrix p; +}; + +inline LU::LU (const LU& a) { l = a.l; u = a.u; p = a.p; } + +inline LU& LU::operator = (const LU& a) + { l = a.l; u = a.u; p = a.p; return *this; } + +inline Matrix LU::L (void) const { return l; } +inline Matrix LU::U (void) const { return u; } +inline Matrix LU::P (void) const { return p; } + +class ComplexLU +{ +friend class ComplexMatrix; + +public: + ComplexLU (void) {} + + ComplexLU (const ComplexMatrix& a); + + ComplexLU (const ComplexLU& a); + + ComplexLU& operator = (const ComplexLU& a); + + ComplexMatrix L (void) const; + ComplexMatrix U (void) const; + Matrix P (void) const; + + friend ostream& operator << (ostream& os, const ComplexLU& a); + +private: + + ComplexMatrix l; + ComplexMatrix u; + Matrix p; +}; + +inline ComplexLU::ComplexLU (const ComplexLU& a) { l = a.l; u = a.u; p = a.p; } + +inline ComplexLU& ComplexLU::operator = (const ComplexLU& a) + { l = a.l; u = a.u; p = a.p; return *this; } + +inline ComplexMatrix ComplexLU::L (void) const { return l; } +inline ComplexMatrix ComplexLU::U (void) const { return u; } +inline Matrix ComplexLU::P (void) const { return p; } + +/* + * Result of a QR decomposition. + */ + +class QR +{ +public: + QR (void) {} + + QR (const Matrix& A); + + QR (const QR& a); + + QR& operator = (const QR& a); + + Matrix Q (void) const; + Matrix R (void) const; + + friend ostream& operator << (ostream& os, const QR& a); + +private: + Matrix q; + Matrix r; +}; + +inline QR::QR (const QR& a) { q = a.q; r = a.r; } + +inline QR& QR::operator = (const QR& a) { q = a.q; r = a.r; return *this; } + +inline Matrix QR::Q (void) const { return q; } +inline Matrix QR::R (void) const { return r; } + +class ComplexQR +{ +public: + ComplexQR (void) {} + + ComplexQR (const ComplexMatrix& A); + + ComplexQR (const ComplexQR& a); + + ComplexQR& operator = (const ComplexQR& a); + + ComplexMatrix Q (void) const; + ComplexMatrix R (void) const; + + friend ostream& operator << (ostream& os, const ComplexQR& a); + +private: + ComplexMatrix q; + ComplexMatrix r; +}; + +inline ComplexQR::ComplexQR (const ComplexQR& a) { q = a.q; r = a.r; } + +inline ComplexQR& ComplexQR::operator = (const ComplexQR& a) + { q = a.q; r = a.r; return *this; } + +inline ComplexMatrix ComplexQR::Q (void) const { return q; } +inline ComplexMatrix ComplexQR::R (void) const { return r; } + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; page-delimiter: "^/\\*" *** +;;; End: *** +*/