/* rmatrix.h */

#ifndef RMATRIX__H
#define RMATRIX__H

#include "matrix.h"

class dc_rect_matrix : public dc_matrix {
protected:
  Matrix val;
  Matrix T;
  Matrix I;
  bool T_valid; 
  bool I_valid; 

  void touch( void ); /* updates validity of all matrices.
			 valid true if both dimensions > 0
			 others become invalid whenever val changes */
public:
  dc_rect_matrix();
  dc_rect_matrix( const int m, const int n, const string &label = "",
		  dc_node *parent = nil );
  dc_rect_matrix( const Matrix &M, const string &label = "",
		  dc_node *parent = nil );
  dc_rect_matrix( const string &label, dc_node *parent = nil );
  ~dc_rect_matrix();

  /* inherited functions */
  const dc_type sub_type( void ) const { return Rect_Matrix_t; }
  string type_string( void ) const { return valid ? string( "matrix (%d,%d)", 
				     val.Nrows(), val.Ncols() )
				   : string( "invalid matrix" ); }
  
  /* input, output, and assignment operators */
  dc_rect_matrix &operator=( const Matrix &M );
  dc_rect_matrix &operator=( dc_data &D );

  ostream &display( ostream &stream = cout ){ return display_c( stream ); }
  ostream &display_c( ostream &stream = cout ) const;
  friend ostream &operator<<( ostream &stream, const dc_rect_matrix &M ) 
    { return M.display_c( stream ); }
  friend istream &operator>>( istream &stream, dc_rect_matrix &M );

  /* indexing start at 1 */
  Real operator()( const int i, const int j ) const;

  /* functions to access val */
  ReturnMatrix get( void );
  ReturnMatrix get_T( void );
  ReturnMatrix get_I( void );
  void get_dim( int &h, int &w ) const;
  void set( const Matrix &M );
  void set( dc_rect_matrix &D );
  void set( double d[] );
  void resize( const int h, const int w );
  int Nrows( void ) const { return val.Nrows(); }
  int Ncols( void ) const { return val.Ncols(); }
  
  /* returns location of vectors array.  do not delete */
  Real *get_store( void ) const { return val.Store(); }
  int get_storage( void ) const { return val.Storage(); }

  dc_label *duplicate( dc_node *parent ) const;
};

bool operator==( Matrix const &, Matrix const & );

#endif
