⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linalg.h

📁 basic linear algebra classes and applications (SVD,interpolation, multivariate optimization)
💻 H
📖 第 1 页 / 共 4 页
字号:
 *	Data classes: Matrix and (its particular case) Vector * * Note that view classes (below) may "borrow" matrix data area * for a while; to make sure they "return" the data, we use a limited form * of reference counting. That is, the destruction/reallocation of a data * class are only possible when the reference counter is 1 * (that is, there are no oustanding views). Otherwise it is a grave error. * */class Matrix : public DimSpec{public:  friend class ElementWiseConst;  friend class ElementWiseStrideConst;  friend class LAStreamIn;  friend class LAStreamOut;  friend class LAStrideStreamIn;  friend class LAStrideStreamOut;  friend class LABlockStreamIn;  friend class LABlockStreamOut;  friend class MatrixDABase;  class ConstReference;			// Forward decl of nested classes  class Reference;  friend class ConstReference;    friend class Vector;  friend class ConstMatrixColumn;  friend class ConstMatrixRow;  friend class ConstMatrixDiag;private:			// Private part  int valid_code;			// Validation code  enum { MATRIX_val_code = 5757 };	// Matrix validation code value  RWWatchDog ref_counter;protected:			// May be used in derived classes  const char * name;				// Name for the matrix  int nelems;				// Total no of elements, nrows*ncols  REAL * elements;			// Elements themselves  void allocate(void);  friend void haar_matrix::fill_in(Matrix& m) const;  friend void LazyTransposedMatrix::fill_in(Matrix& m) const;public:			// Public interface				// Constructors and destructors					// Make a blank matrix  Matrix(const int nrows, const int ncols);	// Indices start with 1  Matrix(const int row_lwb, const int row_upb,	// Or with low:upper	 const int col_lwb, const int col_upb);	// boundary specif.  Matrix(const DimSpec& dimension_specs);  inline Matrix(const Matrix&  another); // A real copy constructor, expensive					// Construct a matrix applying a spec					// operation to two prototypes					// Example: Matrix A(10,12), B(12,5);					// Matrix C(A,Matrix::Mult,B);//  enum MATRIX_CREATORS_2op { Mult, 		// A*B//			     TransposeMult, 	// A'*B//			     InvMult, 		// A^(-1)*B//			     AtBA }; 		// A'*B*A//  Matrix(const Matrix& A, const MATRIX_CREATORS_2op op, const Matrix& B);//  Matrix(const Vector& x, const Vector& y);	// x'*y (diad) matrix  Matrix(const LazyMatrix& lazy_constructor);//Make a matrix using given recipe  explicit Matrix(const char * file_name);	// Read the matrix from the file					// (not yet implemented!)  ~Matrix(void);			// Destructor  void set_name(const char * name);	// Set a new matrix name					// Erase the old matrix and create a					// new one according to new boundaries  void resize_to(const int nrows, const int ncols);	// Indexation @ 1  void resize_to(const int row_lwb, const int row_upb,	// Or with low:upper		 const int col_lwb, const int col_upb);	// boundary specif.  void resize_to(const DimSpec& dimension_specs);	// Like other matrix m  void is_valid(void) const  { if( valid_code != MATRIX_val_code ) invalid_matrix(); }				// Status inquires  int q_no_elems(void) const		{ return nelems; }  const char * q_name(void) const	{ return name; }  class ConstReference  {    friend class Reference;    Matrix& m;    ConstReference(const ConstReference&);	// Not implemented and forbidden    void operator = (const ConstReference&);	// reference isn't transferable  public:    ConstReference(const Matrix& _m)    	: m(const_cast<Matrix&>(_m))    	{ m.is_valid(); m.ref_counter.get_shared(); }   ~ConstReference(void) { m.is_valid(); m.ref_counter.release_shared(); }    /*explicit*/ operator const Matrix& (void) const { return m; }    const Matrix& ref(void) const { return m; }  };  class Reference : public ConstReference  {    Reference(const Reference&);	// Not implemented and forbidden    void operator = (const Reference&);	// reference isn't transferable  public:    Reference(Matrix& _m) : ConstReference(_m) {}    /*explicit*/ operator Matrix& (void) const { return m; }    Matrix& ref(void) const { return m; }  };					// Apply a user-defined action  Matrix& apply(ElementAction& action);		// to each matrix element  const Matrix& apply(ConstElementAction& action) const; // to each matrix element  					// Although the following method does  					// not need a priviledged access to a  					// Matrix, it is required to be a member  					// of the class  inline Matrix& operator = (const REAL val);					// Invert the matrix returning the					// determinant if desired					// determinant = 0 if the matrix is					// singular					// If determ_ptr=dummy_determinant_ref					// and the matrix *is*					// singular, throw up  static double dummy_determinant_ref;  Matrix& invert(double &determ_ref = dummy_determinant_ref);				// Element-wise operations on two matrices  inline Matrix& operator = (const Matrix& source);	// Assignment  inline Matrix& operator = (const ConstReference& ref)  		{ return *this = ref.ref(); }  Matrix& operator = (const LazyMatrix& source);// Force the promise of a matrix  Matrix& clear(void);			// Clear the matrix (fill out with 0) 					// Comparisons  bool operator == (const Matrix& im2) const;  friend inline void are_compatible(const Matrix& im1, const Matrix& im2);				// True matrix operations				// (on a matrix as a whole)    Matrix& operator *= (const Matrix& source);	// Inplace multiplication						// possible only for square src  inline Matrix& operator *= (const ConstReference& ref)  		{ return *this *= ref.ref(); }    void mult(const Matrix& A, const Matrix& B);  // Compute A*B 				// Compute matrix norms  double row_norm(void) const;		// MAX{ SUM{ |M(i,j)|, over j}, over i}  double norm_inf(void) const		// Alias, shows the norm is induced         { return row_norm(); }		// 	by the vector inf-norm  double col_norm(void) const;		// MAX{ SUM{ |M(i,j)|, over i}, over j}  double norm_1(void) const		// Alias, shows the norm is induced         { return col_norm(); }		// 	by the vector 1-norm  double e2_norm(void) const;		// SUM{ m(i,j)^2 }, Note it's square					// of the Frobenius rather than 2. norm  friend double e2_norm(const Matrix& m1, const Matrix& m2);					// e2_norm(m1-m2)  double determinant(void) const;	// Matrix must be a square one  double asymmetry_index(void) const;	// How far is the matrix from being					// symmetrical (0 means complete symm)					// (not yet implemented)				// Make matrices of a special kind  Matrix& unit_matrix(void);		// Matrix needn't be a square  Matrix& hilbert_matrix(void);		// Hilb[i,j] = 1/(i+j-1); i,j=1..max				// I/O: write, read, print   					// Write to a file					// "| command name" is OK as a file					// name  void write(const char * file_name,const char * title = "") const;  void info(void) const;		// Print the info about the Matrix  void print(const char title []) const;// Print the Matrix as a table  volatile void invalid_matrix(void) const;   // The matrix in question is not valid  					// ==> crash the program};void compare(const Matrix& im1, const Matrix& im2, const char title[]);/* *------------------------------------------------------------------------ *		   Vector as a n*1 matrix (that is, a col-matrix) */class Vector : public Matrix{public:  Vector(const int n);		// Create a blank vector of a given size				// (indexation starts at 1)				// Create a general lwb:upb vector blank vector  Vector(const int lwb, const int upb);//  Vector(const Vector& another);	// a copy constructor (to be inferred)					// Make a vector and assign init vals  Vector(const int lwb, const int upb,  // lower and upper bounds	 double iv1, ...    		// DOUBLE numbers. The last arg of	 ); 				// the list must be string "END"					// E.g: Vector f(1,2,0.0,1.5,"END");  Vector(const LazyMatrix& lazy_constructor);//Make a vector using given recipe				// Resize the vector (keeping as many old				// elements as possible), expand by zeros  void resize_to(const int n);			// Indexation @ 1  void resize_to(const int lwb, const int upb); 	// lwb:upb specif  void resize_to(const Vector& v);			// like other vector  				// Unlike Matrix, Vector permits a direct  				// access to its elements without further ado  				// Still, streams/of_every() are more efficient  				// for uniform access  inline REAL& operator () (const int index);  inline REAL  operator () (const int index) const	{ return (const_cast<Vector&>(*this))(index); }				// Listed below are specific vector operations				// (unlike n*1 matrices)					// Status inquires  int q_lwb(void) const		{ return q_row_lwb(); }  int q_upb(void) const		{ return q_row_upb(); }					// Compute the scalar product  friend double operator * (const Vector& v1, const Vector& v2);					// "Inplace" multiplication					// target = A*target					// A needn't be a square one (the					// target will be resized to fit)  Vector& operator *= (const Matrix& A);					// Vector norms  inline double norm_1(void) const;   		// SUM{ |v[i]| }  inline double norm_2_sqr(void) const;	       	// SUM{ v[i]^2 }  inline double norm_inf(void) const;		// MAX{ |v[i]| }  Vector& operator = (const Vector& v)  	{ Matrix::operator =(v); return *this; }  Vector& operator = (const LazyMatrix& source);// Force the promise of a vector  					// Although the following methods do  					// not need a priviledged access to  					// Vector, they are required to be  					// members of the class  inline Vector& operator = (const ElementWiseConst& stream);  inline Vector& operator = (const ElementWiseStrideConst& stream);  inline Vector& operator = (const REAL val)  	{ Matrix::operator =(val); return *this; }};				// Service functions (useful in the				// verification code). They print some detail				// info if the validation condition failsvoid verify_element_value(const Matrix& m,const REAL val);void verify_matrix_identity(const Matrix& m1, const Matrix& m2);inline void verify_element_value(const Matrix::ConstReference& m,const REAL val)	{ verify_element_value(m.ref(),val); }inline void verify_matrix_identity(const Matrix::ConstReference& m1,				   const Matrix& m2)	{ verify_matrix_identity(m1.ref(),m2); }inline void verify_matrix_identity(const Matrix& m1,				   const Matrix::ConstReference& m2)	{ verify_matrix_identity(m1,m2.ref()); }inline void verify_matrix_identity(const Matrix::ConstReference& m1,				   const Matrix::ConstReference& m2)	{ verify_matrix_identity(m1.ref(),m2.ref()); }				// Multiply by the diagonal				// of another matrixMatrix& operator *= (Matrix& m, const ConstMatrixDiag& diag);				// Compute the product of two matricesclass LazyMatrixProduct : public LazyMatrix{  const Matrix& A;  const Matrix& B;  void fill_in(Matrix& m) const { m.mult(A,B); }  LazyMatrixProduct(const Matrix& _A, const Matrix& _B)	: LazyMatrix(_A.q_row_lwb(),_A.q_row_upb(),		     _B.q_col_lwb(),_B.q_col_upb()),	  A(_A), B(_B) {}  public:  friend const LazyMatrixProduct operator * (const Matrix& A, const Matrix& B)    { return LazyMatrixProduct(A,B); }};				// Make a zero matrixclass LazyZeroMatrix : public LazyMatrix{  void fill_in(Matrix& m) const { __unused(Matrix& m1) = m; }  LazyZeroMatrix(const Matrix& proto)    : LazyMatrix(static_cast<const DimSpec&>(proto)) {}public:  friend const LazyZeroMatrix zero(const Matrix& proto)    { proto.is_valid(); return proto; }};				// Make a unit matrixclass LazyUnitMatrix : public LazyMatrix{  void fill_in(Matrix& m) const { m.unit_matrix(); }  LazyUnitMatrix(const Matrix& proto)    : LazyMatrix(static_cast<const DimSpec&>(proto)) {}public:  friend const LazyUnitMatrix unit(const Matrix& proto)    { proto.is_valid(); return proto; }};				// Make an inverse matrixclass LazyInverseMatrix : public LazyMatrix{  const Matrix& proto;  void fill_in(Matrix& m) const { m = proto; m.invert(); }  LazyInverseMatrix(const Matrix& _proto)    : LazyMatrix(static_cast<const DimSpec&>(_proto)),      proto(_proto) {}public:  friend const LazyInverseMatrix inverse(const Matrix& proto)    { proto.is_valid(); return proto; }};				// Make a transposed matrixinline LazyTransposedMatrix::LazyTransposedMatrix(const Matrix & _proto)  	: LazyMatrix(_proto.q_col_lwb(),_proto.q_col_upb(),  		     _proto.q_row_lwb(),_proto.q_row_upb()),  	  proto(_proto) {}inline const LazyTransposedMatrix transposed(const Matrix & proto)  	{ proto.is_valid(); return proto; }/* *------------------------------------------------------------------------ *	Matrix Views: provide access to elements of a Matrix *	(or groups of elements: rows, columns, diagonals, etc) * Although views can be created and exist for some time, one should * not attempt to pass around views (especially return them as a result * of the function) when the data object itself (a matrix) could be * disposed of. Thanks to the reference counting, this situation would * be detected, and the program would crash. */ /* *------------------------------------------------------------------------ *//* * Functions/procedures (generally grouped together under a ElementWise * class umbrella) that perform a variety of operation on each element * of some structure in turn. * * ElementWiseConst and ElementWise classes are largely a syntactic * sugar; you can't explicitly construct an object of this class, on stack * or on heap. The only way the class can be used is within a pattern *      to_every(matrix) = 1; *	if( of_every(matrix) > 1 ) ... * etc. Besides, this is the only way it makes sense. * * Note that the ElementWise classes are friends of Matrix, so they are * privy of Matrix internals and can use them to make processing faster. */				// A functor describing an operation to apply 				// to every element of a collection in				// turn				// This operation receives only the elements's				// value, and thus it may not modify the				// element under consideration.class ElementWiseConstAction{				// Those aren't implemented; but making them				// private forbids the assignement  ElementWiseConstAction(const ElementWiseConstAction&);  ElementWiseConstAction& operator= (const ElementWiseConstAction&);public:  ElementWiseConstAction(void) {}  virtual void operator () (const REAL element) = 0;};				// The same as above but this functor is given				// a reference to an element, which it can				// modifyclass ElementWiseAction{				// Those aren't implemented; but making them				// private forbids the assignement  ElementWiseAction(const ElementWiseAction&);  ElementWiseAction& operator= (const ElementWiseAction&);public:  ElementWiseAction(void) {}  virtual void operator () (REAL& element) = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -