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

📄 matrix_bidirectional_iterator.h

📁 使用R语言的马尔科夫链蒙特卡洛模拟(MCMC)源代码程序。
💻 H
字号:
/*  * Scythe Statistical Library Copyright (C) 2000-2002 Andrew D. Martin * and Kevin M. Quinn; 2002-present Andrew D. Martin, Kevin M. Quinn, * and Daniel Pemstein.  All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify under the terms of the GNU General Public License as * published by Free Software Foundation; either version 2 of the * License, or (at your option) any later version.  See the text files * COPYING and LICENSE, distributed with this source code, for further * information. * -------------------------------------------------------------------- *  scythestat/matrix_bidirectional_iterator.h * * Bidirectional iterators for the matrix class. * *//*! \file matrix_bidirectional_iterator.h * \brief Definitions of STL-compliant bidirectional iterators for the * Matrix class. * * Contains definitions of const_matrix_bidirectional_iterator, * matrix_bidirectional_iterator, and related operators.  See a * Standard Template Library reference, such as Josuttis (1999), for a * full description of the capabilities of bidirectional iterators. * * These iterators are templated on the type, order and style of the * Matrix they iterate over and their own order, which need not match * the iterated-over matrix.  Same-order iteration over concrete * matrices is extremely fast.  Cross-grain concrete and/or view * iteration is slower.   */#ifndef SCYTHE_MATRIX_BIDIRECTIONAL_ITERATOR_H#define SCYTHE_MATRIX_BIDIRECTIONAL_ITERATOR_H#include <iterator>#ifdef SCYTHE_COMPILE_DIRECT#include "defs.h"#include "error.h"#include "matrix.h"#else#include "scythestat/defs.h"#include "scythestat/error.h"#include "scythestat/matrix.h"#endifnamespace scythe {	/* convenience typedefs */  namespace { // local to this file	  typedef unsigned int uint;  }  	/* forward declaration of the matrix class */	template <typename T_type, matrix_order ORDER, matrix_style STYLE>	class Matrix;  /*! \brief An STL-compliant const bidirectional iterator for Matrix.   *   * Provides bidirectional iteration over const Matrix objects.  See   * Josuttis (1999), or some other STL reference, for a full   * description of the bidirectional iterator interface.   *   * \see Matrix   * \see matrix_bidirectional_iterator   * \see const_matrix_forward_iterator   * \see matrix_forward_iterator   * \see const_matrix_random_access_iterator   * \see matrix_random_access_iterator   */    template <typename T_type, matrix_order ORDER, matrix_order M_ORDER,            matrix_style M_STYLE>  class const_matrix_bidirectional_iterator    : public std::iterator<std::bidirectional_iterator_tag, T_type>  {		public:			/**** TYPEDEFS ***/			typedef const_matrix_bidirectional_iterator<T_type, ORDER,               M_ORDER, M_STYLE> self;			/* These are a little formal, but useful */			typedef typename std::iterator_traits<self>::value_type				value_type;			typedef typename std::iterator_traits<self>::iterator_category				iterator_category;			typedef typename std::iterator_traits<self>::difference_type				difference_type;			typedef typename std::iterator_traits<self>::pointer pointer;			typedef typename std::iterator_traits<self>::reference reference;					/**** CONSTRUCTORS ****/						/* Default constructor */			const_matrix_bidirectional_iterator ()			{}			/* Standard constructor */			const_matrix_bidirectional_iterator        (const Matrix<value_type, M_ORDER, M_STYLE> &M)        : pos_ (M.getArray()),          matrix_ (&M)      {        SCYTHE_CHECK_30 (pos_ == 0, scythe_null_error,            "Requesting iterator to NULL matrix");        /* The basic story is: when M_STYLE == Concrete and ORDER ==         * M_ORDER, we only need pos_ and iteration will be as fast as         * possible.  All other types of iteration need more variables         * to keep track of things and are slower.         */        if (M_STYLE != Concrete || M_ORDER != ORDER) {          offset_ = 0;          if (ORDER == Col) {            lead_length_ = M.rows();            lead_inc_ = M.rowstride();            trail_inc_ = M.colstride();          } else {            lead_length_ = M.cols();            lead_inc_ = M.colstride();            trail_inc_ = M.rowstride();          }          jump_ = trail_inc_ + (1 - lead_length_) * lead_inc_;          vend_ = pos_ + (lead_length_ - 1) * lead_inc_;          vbegin_ = pos_;        }#if SCYTHE_DEBUG > 2				size_ = M.size();        start_ = pos_;#endif      }      /* Copy constructor */      const_matrix_bidirectional_iterator (const self &mi)        : pos_ (mi.pos_),          matrix_ (mi.matrix_)      {        if (M_STYLE != Concrete || M_ORDER != ORDER) {          offset_ = mi.offset_;          lead_length_ = mi.lead_length_;          lead_inc_ = mi.lead_inc_;          trail_inc_ = mi.trail_inc_;          vend_ = mi.vend_;          vbegin_ = mi.vbegin_;          jump_ = mi.jump_;        }#if SCYTHE_DEBUG > 2			  size_ = mi.size_;        start_ = mi.start_;#endif      }      /**** EXTRA MODIFIER ****/      /* This function lets us grab an end iterator.  It is cheap for       * Concrete matrices but somewhat more costly for views.       */      inline self& set_end ()      {        if (M_STYLE == Concrete && ORDER == M_ORDER) {          pos_ = matrix_->getArray() + matrix_->size();        } else {           if (ORDER == Col) {            vbegin_ += trail_inc_ * matrix_->cols();            vend_ += trail_inc_ * matrix_->cols();          } else { // ORDER == Rows            vbegin_ += trail_inc_ * matrix_->rows();            vend_ += trail_inc_ * matrix_->rows();          }          pos_ = vbegin_;          offset_ = matrix_->size();        }        return *this;      }      /**** FORWARD ITERATOR FACILITIES ****/      inline self& operator= (const self& mi)      {        pos_ = mi.pos_;        matrix_ = mi.matrix_;        if (M_STYLE != Concrete || M_ORDER != ORDER) {          offset_ = mi.offset_;          lead_length_ = mi.lead_length_;          lead_inc_ = mi.lead_inc_;          trail_inc_ = mi.trail_inc_;          vend_ = mi.vend_;          vbegin_ = mi.vbegin_;          jump_ = mi.jump_;        }#if SCYTHE_DEBUG > 2				size_ = mi.size_;        start_ = mi.start_;#endif        return *this;      }      inline const reference operator* () const      {				SCYTHE_ITER_CHECK_BOUNDS();        return *pos_;      }      inline const pointer operator-> () const      {				SCYTHE_ITER_CHECK_BOUNDS();        return pos_;      }      inline self& operator++ ()      {        if (M_STYLE == Concrete && ORDER == M_ORDER)          ++pos_;        else {          if (pos_ == vend_) {            vend_ += trail_inc_;            vbegin_ += trail_inc_;            pos_ += jump_;          } else {            pos_ += lead_inc_;          }          ++offset_;        }        return *this;      }      inline self operator++ (int)      {        self tmp = *this;        ++(*this);        return tmp;      }      /* == is only defined for iterators of the same template type       * that point to the same matrix.  Behavior for any other       * comparison is undefined.       *       * Note that we have to be careful about iterator comparisons       * when working with views and cross-grain iterators.       * Specifically, we always have to rely on the offset value.       * Obviously, with <> checks pos_ can jump all over the place in       * cross-grain iterators, but also end iterators point to the       * value after the last in the matrix.  In some cases, the       * equation in += and -= will actually put pos_ inside the       * matrix (often in an early position) in this case.       */      inline bool operator== (const self& x) const      {        if (M_STYLE == Concrete && ORDER == M_ORDER) {          return pos_ == x.pos_;        } else {          return offset_ == x.offset_;        }      }      /* Again, != is only officially defined for iterators over the       * same matrix although the test will be trivially true for       * matrices that don't view the same data, by implementation.       */      inline bool operator!= (const self &x) const      {        return !(*this == x);      }      /**** BIDIRECTIONAL ITERATOR FACILITES ****/      inline self& operator-- ()      {        if (M_STYLE == Concrete && ORDER == M_ORDER)          --pos_;        else {          if (pos_ == vbegin_) {            vend_ -= trail_inc_;            vbegin_ -= trail_inc_;            pos_ -= jump_;          } else {            pos_ -= lead_inc_;          }          --offset_;        }        return *this;      }      inline self operator-- (int)      {        self tmp = *this;        --(*this);        return tmp;      }    protected:      /**** INSTANCE VARIABLES ****/      T_type* pos_;         // pointer to current position in array      T_type *vend_;        // pointer to end of current vector      T_type *vbegin_;      // pointer to begin of current vector      uint offset_;         // logical offset into matrix      // TODO Some of these can probably be uints      int lead_length_;  // Logical length of leading dimension      int lead_inc_;  // Memory distance between vectors in ldim      int trail_inc_; // Memory distance between vectors in tdim      int jump_; // Memory distance between end of one ldim vector and                 // begin of next      // Pointer used only for set_end.  TODO Cleaner impl.      const Matrix<T_type, M_ORDER, M_STYLE>* matrix_;			// Size variable for range checking#if SCYTHE_DEBUG > 2			uint size_;  // Logical matrix size      T_type* start_;  // only needed for bounds checking#endif  };  /*! \brief An STL-compliant bidirectional iterator for Matrix.   *   * Provides bidirectional iteration over Matrix objects.  See   * Josuttis (1999), or some other STL reference, for a full   * description of the bidirectional iterator interface.   *   * \see Matrix   * \see const_matrix_bidirectional_iterator   * \see const_matrix_forward_iterator   * \see matrix_forward_iterator   * \see const_matrix_random_access_iterator   * \see matrix_random_access_iterator   */	template <typename T_type, matrix_order ORDER, matrix_order M_ORDER,            matrix_style M_STYLE>	class matrix_bidirectional_iterator		: public const_matrix_bidirectional_iterator<T_type, ORDER,                                            M_ORDER, M_STYLE>	{			/**** TYPEDEFS ***/			typedef matrix_bidirectional_iterator<T_type, ORDER, M_ORDER,                                       M_STYLE> self;			typedef const_matrix_bidirectional_iterator<T_type, ORDER,                                             M_ORDER, M_STYLE> Base;				public:			/* These are a little formal, but useful */			typedef typename std::iterator_traits<Base>::value_type				value_type;			typedef typename std::iterator_traits<Base>::iterator_category				iterator_category;			typedef typename std::iterator_traits<Base>::difference_type				difference_type;			typedef typename std::iterator_traits<Base>::pointer pointer;			typedef typename std::iterator_traits<Base>::reference reference;					/**** CONSTRUCTORS ****/						/* Default constructor */			matrix_bidirectional_iterator ()				: Base () 			{}			/* Standard constructor */			matrix_bidirectional_iterator (const Matrix<value_type, M_ORDER,                                                   M_STYLE> &M)				:	Base(M)			{}      /* Copy constructor */			matrix_bidirectional_iterator (const self &mi)				:	Base (mi)			{}      /**** EXTRA MODIFIER ****/      inline self& set_end ()      {        Base::set_end();        return *this;      }			/**** FORWARD ITERATOR FACILITIES ****/			/* We have to override a lot of these to get return values			 * right.*/      inline self& operator= (const self& mi)      {        pos_ = mi.pos_;        matrix_ = mi.matrix_;        if (M_STYLE != Concrete || M_ORDER != ORDER) {          offset_ = mi.offset_;          lead_length_ = mi.lead_length_;          lead_inc_ = mi.lead_inc_;          trail_inc_ = mi.trail_inc_;          vend_ = mi.vend_;          vbegin_ = mi.vbegin_;          jump_ = mi.jump_;        }#if SCYTHE_DEBUG > 2				size_ = mi.size_;        start_ = mi.start_;#endif        return *this;      }			inline reference operator* () const			{				SCYTHE_ITER_CHECK_BOUNDS();				return *pos_;			}			inline pointer operator-> () const			{				SCYTHE_ITER_CHECK_BOUNDS();				return pos_;			}			inline self& operator++ ()			{				Base::operator++();				return *this;			}			inline self operator++ (int)			{				self tmp = *this;				++(*this);				return tmp;			}			inline self& operator-- ()			{				Base::operator--();				return *this;			}			inline self operator-- (int)			{				self tmp = *this;				--(*this);				return tmp;			}		private:			/* Get handles to base members.  It boggles the mind */			using Base::pos_;      using Base::vend_;      using Base::vbegin_;      using Base::offset_;      using Base::lead_length_;      using Base::lead_inc_;      using Base::trail_inc_;      using Base::jump_;      using Base::matrix_;#if SCYTHE_DEBUG > 2			using Base::size_;      using Base::start_;#endif	};} // namespace scythe#endif /* SCYTHE_MATRIX_BIDIRECTIONAL_ITERATOR_H */

⌨️ 快捷键说明

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