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

📄 lastreams.h

📁 basic linear algebra classes and applications (SVD,interpolation, multivariate optimization)
💻 H
📖 第 1 页 / 共 2 页
字号:
// This may look like C code, but it is really -*- C++ -*-/* ************************************************************************ * *			  Linear Algebra Package *			   * The following functions support a _sequential_ traversal of a matrix * or its parts (a row, a column, a diagonal, or an arbitrary rectangular * block). As the README file explains, a random access to matrix elements * is often an unnecessary luxury. Many Numerical Math algorithms access * matrices by walking them in regular sequential ways. This _serial_ * access can be implemented far more efficiently than the arbitrary * access. *  * The classes below act as input/ouput "matrix" streams. As with regular * streams, be sure to check for eof() before attempting to get() an * element. * Note, since all the methods of the matrix streams are implemented inline, * the whole iteration would be inline, too. * Note, that if the stream is applied to the entire Matrix or its * rectangular block, it would be traversed in the natural, that is, * COLUMN major order. * * $Id: LAStreams.h,v 1.1 1998/12/06 23:39:12 oleg Exp oleg $ * ************************************************************************ */#ifndef __GNUC__#pragma once#endif#ifndef _LAStreams_h#define _LAStreams_h 1#if !defined(_LinAlg_h)#include "LinAlg.h"#endifclass LAS {			// A "namespace" to define some common constantspublic: enum seek_dir { beg, cur, end};  static inline const REAL * min(const REAL * const p1, const REAL * const p2)  	{ return p1 > p2 ? p2 : p1; }	 static inline const REAL * max(const REAL * const p1, const REAL * const p2)  	{ return p1 > p2 ? p1 : p2; }	};          			// A bookmark in the streamclass AREALMark{  friend class AREALStreamIn;  friend class AREALStreamOut;  friend class AREALStrideStreamIn;  friend class AREALStrideStreamOut;  friend class AREALBlockStreamIn;  friend class AREALBlockStreamOut;  size_t offset;  enum { invalid_offset = (size_t)(-1) };  AREALMark(const size_t _offset) : offset(_offset) {}public:  AREALMark(void) : offset(invalid_offset) {}  operator bool (void) const	{ return offset != invalid_offset; }  bool operator ! (void) const	{ return offset == invalid_offset; }  rowcol get_2dpos(const DimSpec dims) const  	{ assert( (bool)(*this) && dims.q_nrows() > 0 );  	  div_t res = div(offset,dims.q_nrows());  	  return rowcol(res.rem+dims.q_row_lwb(),res.quot+dims.q_col_lwb()); }  friend ostream& operator << (ostream& os, const AREALMark& mark);};    			// The following are the pair of "streams" over 			// the field of REALs 			// These classes are mixins - they provide an 			// "abstract" stream functionality. The classes 			// don't have public constructors, as none of 			// mixin classes do. The classes are supposed to be 			// "blended" with other classes to imbue them with 			// stream properties: the derived class 			// must then properly set the current element 			// pointer and the last element pointer. 			// Since the classes do not declare any virtual 			// functions, they are lightweight (and can be 			// inlined)class AREALStreamIn{  const REAL * curr_el_p;            // curr_el_p <= last_el_p always  const REAL * const first_el_p;     // The first element pointer  const REAL * const last_el_p;      // The == condition means EOF    AREALStreamIn(const AREALStreamIn&);	 // Not implemented and forbidden:  void operator = (const AREALStreamIn&);// no cloning/assignment allowed  				// Apply range:dir to yield a new first_el_p  				// invariant: new_first_el_p >= first_el_p  const REAL * subrange_first(const IRange range, LAS::seek_dir dir) const  {    if( dir == LAS::beg )      return range.lwb <= 0 ? first_el_p : first_el_p + range.lwb;    else if( dir == LAS::end )      return range.lwb == - IRange::INF ? first_el_p :    		LAS::max(first_el_p,last_el_p - range.lwb);    else      return range.lwb == - IRange::INF ? curr_el_p :    		LAS::max(first_el_p,curr_el_p + range.lwb);  }  				// Apply range:dir to yield a new last_el_p  				// invariant: new_last_el_p <= last_el_p  const REAL * subrange_last(const IRange range, LAS::seek_dir dir) const  {    if( dir == LAS::beg )      return range.upb == IRange::INF ? last_el_p :    		LAS::min(last_el_p,first_el_p + range.upb + 1);    else if( dir == LAS::end )      return last_el_p;    else      return range.upb == IRange::INF ? last_el_p :    		LAS::min(last_el_p,curr_el_p + range.upb + 1);  }protected:				// A protected constructor  AREALStreamIn(const REAL * _beg_ptr, const REAL * _end_ptr)        : curr_el_p(_beg_ptr),          first_el_p(_beg_ptr),          last_el_p(_end_ptr)          {}	  			// Subrange the current stream by applying	  			// the range. seek_dir determines if the	  			// range applies to the current state	  			// of the stream or its init position  AREALStreamIn(const AREALStreamIn& proto, const IRange range,		LAS::seek_dir dir)        : first_el_p(proto.subrange_first(range,dir)),          last_el_p(proto.subrange_last(range,dir))          { curr_el_p = first_el_p;	    assert(first_el_p <= last_el_p); }                                // Get the current elem _ref_ and advance                                // in the stream  const REAL& get_ref(void)        { if( curr_el_p >= last_el_p)           _error("Can't get() the AREALStream boundary!");          return *curr_el_p++; }  const REAL& peek_ref(void) const      // Does *not* advance the "stream ptr"        { if( curr_el_p >= last_el_p)           _error("Can't peek() past the AREALStream boundary!");          return *curr_el_p; }public:			// No public constructors!  bool eof(void) const          { return curr_el_p == last_el_p; }  bool bof(void) const          { return curr_el_p == first_el_p; }                                // Get the current elem and advance in the                                // stream  REAL get(void)		{ return get_ref(); }  REAL peek(void) const         // Does *not* advance the "stream ptr"  				{ return peek_ref(); }                    			// Reset the stream at the beginning  void rewind(void)		{ curr_el_p = first_el_p; }   			// Note the current position in the stream  AREALMark tell(void) const  	{ return AREALMark(curr_el_p - first_el_p); }    			// Note the previous (that is, just gotten)  			// position in the stream  AREALMark tell_prev(void) const  	{ if( curr_el_p == first_el_p )  	    _error("The stream is at its beginng, no previous pos exists");  	  return AREALMark(curr_el_p - first_el_p - 1); }  			// Set the current position at the mark  AREALStreamIn& seek(const AREALMark mark)  	{ assert( (bool) mark );  	  curr_el_p = first_el_p + mark.offset;  	  assert( curr_el_p >= first_el_p && curr_el_p < last_el_p );  	  return *this; }	   			// Set the current position according to the	  		// given offset and seek_dir.	  		// Note: the offset can be arbitrarily large:	  		// if it points beyond this stream, no run-time	   		// error is generated but the EOF condition is set	  		// (which can later be checked with eof())  AREALStreamIn& seek(const int offset, LAS::seek_dir dir = LAS::cur)  	{ switch(dir)	  { case LAS::beg: curr_el_p = first_el_p + offset; break;	    case LAS::cur: curr_el_p = curr_el_p + offset; break;	    case LAS::end: curr_el_p = last_el_p - offset; break;	    default: assert(0 /*wrong seek_dir*/); };	  if( curr_el_p > last_el_p ) curr_el_p = last_el_p;  	  else assert( curr_el_p >= first_el_p );  	  return *this; }	    AREALStreamIn& ignore(const int how_many)  	{ return seek(how_many,LAS::cur); }   	  		// Dump the current status of the stream  ostream& dump(ostream& os) const;};			// This is a readable _and_ writable streamclass AREALStreamOut : public AREALStreamIn{  AREALStreamOut(const AREALStreamOut&);  // Not implemented and forbidden:  void operator = (const AREALStreamOut&);// no cloning/assignment allowedprotected:				// A protected constructor  AREALStreamOut(REAL * _beg_ptr, REAL * _end_ptr)        : AREALStreamIn(_beg_ptr,_end_ptr)          {}  AREALStreamOut(const AREALStreamIn& proto, const IRange range,		LAS::seek_dir dir)  	: AREALStreamIn(proto,range,dir) {}public:			// No public constructors!                                // Get the current elem and advance in the                                // stream  REAL& get(void)		{ return const_cast<REAL&>(get_ref()); }  REAL& peek(void) const         // Does *not* advance the "stream ptr"  				{ return const_cast<REAL&>(peek_ref()); }            	  		// Dump the current status of the stream//  ostream& dump(ostream& os) const;};                                 // The following class is an STL-like iterator                                // to access _values_ of Matrix elements                                // one-by-one.                                // Note this is a _read-only_ streamclass LAStreamIn : protected Matrix::ConstReference,		   public AREALStreamIn{  LAStreamIn(const LAStreamIn&);	// Not implemented and forbidden:  void operator = (const LAStreamIn&);	// no cloning/assignment allowedpublic:  LAStreamIn(const Matrix& m)        : Matrix::ConstReference(m),          AREALStreamIn(m.elements,m.elements+m.nelems)          {}  inline LAStreamIn(const ConstMatrixColumn& mc);  LAStreamIn(const LAStreamIn& ls, const IRange range,	    LAS::seek_dir dir = LAS::cur)  	: Matrix::ConstReference(ls.ref()),	  AREALStreamIn(ls,range,dir) {}  inline LAStreamIn(const LAStreamOut& ls, const IRange range,		    LAS::seek_dir dir = LAS::cur);  rowcol get_pos(const AREALMark mark) const  	  { return mark.get_2dpos(operator const Matrix& ()); }};inline LAStreamIn::LAStreamIn(const ConstMatrixColumn& mc)        : Matrix::ConstReference(mc.ref()),          AREALStreamIn(mc.col_ptr,mc.col_ptr+mc.nrows)          {}                                // This class provides read *and* write                                // access to matrix elements, one-by-oneclass LAStreamOut : protected Matrix::Reference,		    public AREALStreamOut{  friend class LAStreamIn;  LAStreamOut(const LAStreamOut&);	// Not implemented and forbidden:  void operator = (const LAStreamOut&);	// no cloning/assignment allowedpublic:  LAStreamOut(Matrix& m)        : Matrix::Reference(m),          AREALStreamOut(m.elements,m.elements+m.nelems)          {}  inline LAStreamOut(const MatrixColumn& mc);  LAStreamOut(const LAStreamOut& ls, const IRange range,	    LAS::seek_dir dir = LAS::cur)  	: Matrix::Reference(ls.ref()),	  AREALStreamOut(ls,range,dir) {}  rowcol get_pos(const AREALMark mark)  	  { return mark.get_2dpos(operator Matrix& ()); }};inline LAStreamOut::LAStreamOut(const MatrixColumn& mc)        : Matrix::Reference(const_cast<Matrix&>(mc.ref())),          AREALStreamOut(const_cast<REAL*>(mc.col_ptr),          		 const_cast<REAL*>(mc.col_ptr)+mc.q_nrows())          {}inline LAStreamIn::LAStreamIn(const LAStreamOut& ls, const IRange range,		    LAS::seek_dir dir)  	: Matrix::ConstReference(ls.ref()),	  AREALStreamIn(ls,range,dir) {}  			// The following pair of streams are similar 			// to the ones above, with an exception they 			// walk a sequence of REALs with a non-unit 			// strideclass AREALStrideStreamIn{  const REAL * curr_el_p;  const REAL * const first_el_p;     // The first element pointer  const REAL * const last_el_p;      // The curr_el_p >= condition means EOF  const int stride;  AREALStrideStreamIn(const AREALStrideStreamIn&); // Not implemented and forbidden:  void operator = (const AREALStrideStreamIn&);// no cloning/assignment allowed  				// Apply range:dir to yield a new first_el_p  				// invariant: new_first_el_p >= first_el_p  const REAL * subrange_first(const IRange range, LAS::seek_dir dir) const  {    if( dir == LAS::beg )      return range.lwb <= 0 ? first_el_p : first_el_p + stride*range.lwb;    else if( dir == LAS::end )     if( range.lwb == - IRange::INF )       return first_el_p;     else     { const int r = (last_el_p - first_el_p) % stride;       return LAS::max(first_el_p,		       (r == 0 ? last_el_p : last_el_p - r + stride)	    				- range.lwb*stride); }    else      return range.lwb == - IRange::INF ? curr_el_p :    		LAS::max(first_el_p,curr_el_p + stride*range.lwb);  }  				// Apply range:dir to yield a new last_el_p  				// invariant: new_last_el_p <= last_el_p  const REAL * subrange_last(const IRange range, LAS::seek_dir dir) const  {    if( dir == LAS::beg )      return range.upb == IRange::INF ? last_el_p :    		LAS::min(last_el_p,first_el_p + stride*(range.upb+1));    else if( dir == LAS::end )      return last_el_p;    else      return range.upb == IRange::INF ? last_el_p :    		LAS::min(last_el_p,curr_el_p + stride*(range.upb+1));  } protected:				// A protected constructor  AREALStrideStreamIn(const REAL * _beg_ptr, const REAL * _end_ptr,  		      const int _stride)        : curr_el_p(_beg_ptr),          first_el_p(_beg_ptr),          last_el_p(_end_ptr),          stride(_stride)          {}	  			// Subrange the current stream by applying	  			// the range. seek_dir determines if the	  			// range applies to the current state	  			// of the stream or its init position  AREALStrideStreamIn(const AREALStrideStreamIn& proto, const IRange range,		LAS::seek_dir dir)        : first_el_p(proto.subrange_first(range,dir)),          last_el_p(proto.subrange_last(range,dir)),	  stride(proto.stride)          { curr_el_p = first_el_p;	    assert(first_el_p <= last_el_p); }                                // Get the current elem _ref_ and advance

⌨️ 快捷键说明

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