array.hh

来自「用于计算矩阵的特征值,及矩阵的其他运算.可以用与稀疏矩阵」· HH 代码 · 共 858 行 · 第 1/2 页

HH
858
字号
// Copyright (C) 2002 Charless C. Fowlkes <fowlkes@eecs.berkeley.edu>// Copyright (C) 2002 David R. Martin <dmartin@eecs.berkeley.edu>//// This program 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 of the// License, or (at your option) any later version.// // This program 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 this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA// 02111-1307, USA, or see http://www.gnu.org/copyleft/gpl.html.#ifndef ARRAY_HH#define ARRAY_HH#include <assert.h>#include "message.hh"// TODO: // - replace asserts with exceptions?// - add typing to serialization here and in matlab// Arrays that reduce bugs by://  - Being allocatable on the stack, so destructors get called //    automatically.//  - Doing bounds checking.//  - Providing easy initialization.//  - Encapsulating the address calculation.//// The arrays are allocated as single blocks so that all elements are// contiguous in memory.  Latter indices change more quickly than// former indices.  Clients can rely on this ordering.// // slice returns an const array of smaller dimension.  for effeciency, it// doesn't copy the array contents but since it's const you won't accidentaly// resize or delete it...//namespace Util{  template < class Elem > class Array1D;  template < class Elem > class Array2D;  template < class Elem > class Array3D;  template < class Elem > class Array4D;  template < class Elem > class Array1D  {      public:        Array1D ()        {          _alloc (0);        }        Array1D(const Array1D<Elem>& a)        {          _alloc(a._n);          for (unsigned int i = 0; i < _n; i++)          {            _array[i] = a._array[i];          }        }        Array1D (unsigned int n)        {          _alloc (n);        }        ~Array1D ()        {          _delete ();        }        void resize (unsigned int n)        {          if (!issize (n))          {            _delete ();            _alloc (n);            Message::debug(String("Array1D::resized to %d",_n),5);          }        }        void init (const Elem & elem)        {          for (unsigned int i = 0; i < _n; i++)          {            _array[i] = elem;          }        }        bool issize (unsigned int n) const        {          return (_n == n);        }        int size () const        {          return _n;        }        int size (unsigned int d) const        {          assert (d < 1);          return _n;        }        Elem *data ()        {          return _array;        }        Elem & operator()(unsigned int i)        {          assert (i < _n);          return _array[i];        }        const Elem & operator() (unsigned int i) const        {          assert (i < _n);          return _array[i];        }        const Array1D<Elem>& operator=(const Array1D<Elem>& rhs)         {           if (this != &rhs)           {             resize(rhs._n);            for (unsigned int i = 0; i < _n; i++)            {              _array[i] = rhs._array[i];            }          }           return *this;         }#define DEFOP(OP) \    Array1D<Elem>& operator OP (const Elem& a) \    { \        for (unsigned int i = 0; i < _n; i++) { \            _array[i] OP a; \        } \        return *this; \    } \    \    Array1D<Elem>& operator OP (const Array1D<Elem>& that)\    { \        assert(size(0) == that.size(0)); \        for (unsigned int i = 0; i < _n; i++) { \            _array[i] OP that._array[i]; \        } \        return *this; \    }DEFOP(+=)DEFOP(-=)DEFOP(*=)DEFOP(/=)#undef DEFOP        friend std::istream & operator >> (std::istream & in, Array1D<Elem>& a)        {          unsigned int dim = 0;          in.read((char*)&dim,sizeof(int));          assert(dim == 1);          unsigned int d0 = 0;          in.read((char*)&d0,sizeof(int));          a.resize(d0);          in.read((char*)a._array,d0*sizeof(Elem));                   return in;        }        friend std::ostream & operator << (std::ostream & out, const Array1D<Elem>& a)        {          const unsigned int dim = 2;          const unsigned int d0 = a.size(0);           out.write((char*)&dim,sizeof(int));           out.write((char*)&d0,sizeof(int));          out.write((char*)a._array,d0*sizeof(Elem));          return out;        }         private:        friend class Array2D<Elem>;        friend class Array3D<Elem>;        friend class Array4D<Elem>;        Array1D (const Elem* data, unsigned int size)        {          _n = size;          _array = const_cast<Elem*>(data);        }        void _alloc (unsigned int n)        {          _n = n;          _array = new Elem[_n];        }        void _delete ()        {          assert (_array != NULL);          delete[] _array;          _array = NULL;        }        unsigned int _n;        Elem *_array;  };                            // class Array1D  ///////////////////////////////////////////////////////////////////////////////  template < class Elem > class Array2D  {      public:        Array2D ()        {          _alloc (0, 0);        }        Array2D(const Array2D<Elem>& a)        {          _alloc(a._dim[0],a._dim[1]);          for (unsigned int i = 0; i < _n; i++)          {            _array[i] = a._array[i];          }        }        Array2D (unsigned int d0, unsigned int d1)        {          _alloc (d0, d1);        }        ~Array2D ()        {          _delete ();        }        void resize (unsigned int d0, unsigned int d1)        {          if (!issize (d0, d1))          {            _delete ();            _alloc (d0, d1);            Message::debug(String("Array2D::resized to %d %d",d0,d1),5);          }        }        void init (const Elem & elem)        {          for (unsigned int i = 0; i < _n; i++)          {            _array[i] = elem;          }        }        bool issize (unsigned int d0, unsigned int d1) const        {          return (_dim[0] == d0 && _dim[1] == d1);        }        int size (unsigned int d) const        {          assert (d < 2);          return _dim[d];        }        Elem *data ()        {          return _array;        }        // return a slice wrapped in a const array        const Array1D<Elem>* slice(unsigned int i) const        {          return new Array1D<Elem>( &((*this)(i,0)) , _dim[1] );        }        Elem & operator() (unsigned int i, unsigned int j)        {          assert (i < _dim[0]);          assert (j < _dim[1]);          unsigned int index = i * _dim[1] + j;          assert (index < _n);          return _array[index];        }        const Elem & operator() (unsigned int i, unsigned int j) const        {          assert (i < _dim[0]);          assert (j < _dim[1]);          unsigned int index = i * _dim[1] + j;            assert (index < _n);            return _array[index];        }        const Array2D<Elem>& operator=(const Array2D<Elem>& rhs)         {           if (this != &rhs)           {             resize(rhs._dim[0],rhs._dim[1]);            for (unsigned int i = 0; i < _n; i++)            {              _array[i] = rhs._array[i];            }          }           return *this;         }#define DEFOP(OP) \    Array2D<Elem>& operator OP (const Elem& a) \    { \        for (unsigned int i = 0; i < _n; i++) { \            _array[i] OP a; \        } \        return *this; \    } \    \    Array2D<Elem>& operator OP (const Array2D<Elem>& that)\    { \        assert(size(0) == that.size(0)); \        for (unsigned int i = 0; i < _n; i++) { \            _array[i] OP that._array[i]; \        } \        return *this; \    }DEFOP(+=)DEFOP(-=)DEFOP(*=)DEFOP(/=)#undef DEFOP        friend std::istream & operator >> (std::istream & in, Array2D<Elem>& a)        {          unsigned int dim = 0;          in.read((char*)&dim,sizeof(int));          assert(dim == 2);          unsigned int d0 = 0;          unsigned int d1 = 0;          in.read((char*)&d0,sizeof(int));          in.read((char*)&d1,sizeof(int));          a.resize(d0,d1);          in.read((char*)a._array,d0*d1*sizeof(Elem));                   return in;        }        friend std::ostream & operator << (std::ostream & out, const Array2D<Elem>& a)        {          const unsigned int dim = 2;          const unsigned int d0 = a.size(0);           const unsigned int d1 = a.size(1);           out.write((char*)&dim,sizeof(int));           out.write((char*)&d0,sizeof(int));          out.write((char*)&d1,sizeof(int));          out.write((char*)a._array,d0*d1*sizeof(Elem));          return out;        }      private:        friend class Array3D<Elem>;        friend class Array4D<Elem>;        Array2D (const Elem* data, unsigned int d0, unsigned int d1)         {          _array = const_cast<Elem*>(data);          _dim[0] = d0;          _dim[1] = d1;          _n = _dim[0]*_dim[1];        }        void _alloc (unsigned int d0, unsigned int d1)        {          _n = d0 * d1;          _dim[0] = d0;          _dim[1] = d1;          _array = new Elem[_n];        }        void _delete ()        {          assert (_array != NULL);          delete[]_array;          _array = NULL;        }        unsigned int _dim[2];        unsigned int _n;        Elem *_array;  }; // class Array2D  ///////////////////////////////////////////////////////////////////////////////  template < class Elem > class Array3D  {      public:        Array3D ()        {          _alloc (0, 0, 0);        }        Array3D(const Array3D<Elem>& a)        {          _alloc(a._dim[0],a._dim[1],a._dim[2]);          for (unsigned int i = 0; i < _n; i++)          {            _array[i] = a._array[i];          }        }        Array3D (unsigned int d0, unsigned int d1, unsigned int d2)        {          _alloc (d0, d1, d2);

⌨️ 快捷键说明

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