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 + -
显示快捷键?