MADNESS  0.10.1
basetensor.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31 
32  $Id$
33 */
34 
35 
36 #ifndef MADNESS_TENSOR_BASETENSOR_H__INCLUDED
37 #define MADNESS_TENSOR_BASETENSOR_H__INCLUDED
38 
39 /// \file basetensor.h
40 /// \brief Declares BaseTensor
41 
42 #include <complex>
43 
44 typedef std::complex<float> float_complex;
45 typedef std::complex<double> double_complex;
46 
47 // These probably have to be included in this order
50 #include <madness/tensor/slice.h>
52 
53 #include <madness/madness_config.h>
54 #include <madness/tensor/slice.h>
56 
57 #ifdef TENSOR_INSTANCE_COUNT
59 #endif
60 
61 namespace madness {
62  /*!
63  \ingroup tensor
64  \brief The base class for tensors defines generic capabilities.
65 
66  The base class manages the size, dimension and
67  stride information, and provides operations to manipulate
68  them.
69 
70  It also provides methods for type-safe operation on tensors using
71  just the base class pointers. This interface is primarily useful
72  only to the interface to Python, since Python is largely neutral
73  to (and ignorant of) the type. These are still being
74  re-implemented after the big clean up.
75 
76  Since the base tensor class is virtual, you cannot have an
77  instance of it. Thus, in addition to methods that return information
78  or perform checks, there are two types of base tensor
79  operations.
80  - Inplace operations change \c *this , and return \c void .
81  - Operations that must return a new tensor return a pointer to a tensor
82  allocated with \c new on the heap. The caller is responsible for
83  eventually freeing the memory using \c delete .
84  */
85  class BaseTensor {
86  private:
87 #ifdef TENSOR_INSTANCE_COUNT
88  static madness::AtomicInt instance_count; ///< For debug, count total# instances
89 #endif
90 
91  protected:
92 
93  long _size; ///< Number of elements in the tensor
94  long _ndim; ///< Number of dimensions (-1=invalid; 0=no supported; >0=tensor)
95  long _id; ///< Id from TensorTypeData<T> in type_data.h
96  long _dim[TENSOR_MAXDIM]; ///< Size of each dimension
97  long _stride[TENSOR_MAXDIM]; ///< Increment between elements in each dimension
98 
99  void set_dims_and_size(long nd, const long d[]) {
100  _ndim = nd;
101  _size = 1;
102  if (_ndim < 0) _size=0;
103  for (long i=_ndim-1; i>=0; --i) {
104  _dim[i] = d[i];
105  _stride[i] = _size;
106  _size *= d[i];
107  }
108  for (long i=std::max(_ndim,0L); i<TENSOR_MAXDIM; ++i) { // So can iterate over missing dimensions
109  _dim[i] = 1;
110  _stride[i] = 0;
111  }
112  }
113 
114  public:
115 
116  BaseTensor() : _size(0), _ndim(-1) {
117 #ifdef TENSOR_INSTANCE_COUNT
118  instance_count++;
119 #endif
120  }
121 
122  virtual ~BaseTensor() {
123 #ifdef TENSOR_INSTANCE_COUNT
124  instance_count--;
125 #endif
126  }
127 
128  /// Returns the count of all current instances of tensors & slice tensors of all types.
129  static inline int get_instance_count() {
130 #ifdef TENSOR_INSTANCE_COUNT
131  return instance_count;
132 #else
133  return 0;
134 #endif
135  }
136 
137  /// Returns the number of elements in the tensor
138  long size() const {return _size;}
139 
140  /// Returns the typeid of the tensor (c.f., \c TensorTypeData<T> )
141  long id() const {return _id;}
142 
143  /// Returns the number of dimensions in the tensor
144  long ndim() const {return _ndim;}
145 
146  /// Returns the size of dimension \c i
147  long dim(int i) const {return _dim[i];}
148 
149  /// Returns the stride associated with dimension \c i
150  long stride(int i) const {return _stride[i];}
151 
152  /// Returns the array of tensor dimensions
153  const long* dims() const {return _dim;}
154 
155  /// Returns the array of tensor strides
156  const long* strides() const {return _stride;}
157 
158  /// Returns true if this and *t are the same shape and size
159  bool conforms(const BaseTensor *t) const {
160  if (_ndim != t->_ndim) return false;
161  for (long i=0; i<_ndim; ++i) {
162  if (_dim[i] != t->_dim[i]) return false;
163  }
164  return true;
165  }
166 
167  /// Returns true if the tensor refers to contiguous memory locations.
168  bool iscontiguous() const {
169  if (_size <= 0) return true;
170  long sz = 1;
171  for (long i=_ndim-1; i>=0; --i) {
172  if (_stride[i] != sz) return false;
173  sz *= _dim[i];
174  }
175  return true;
176  }
177 
178  protected:
179 
180  /// Reshapes the tensor inplace
181  void reshape_inplace(const std::vector<long>& d);
182 
183  /// Reshapes the tensor inplace
184  void reshape_inplace(int ndimnew, const long* d);
185 
186  /// Reshapes the tensor inplace into 1D
187  void flat_inplace();
188 
189  /// Splits dimension \c i
190  void splitdim_inplace(long i, long dimi0, long dimi1);
191 
192  /// Fuses dimensions \c i and \c i+1
193  void fusedim_inplace(long i);
194 
195  /// Swaps the dimensions
196  void swapdim_inplace(long i, long j);
197 
198  /// Cyclic shift of dimensions
199  void cycledim_inplace(long shift, long start, long end);
200 
201  /// General permutation of dimensions
202  void mapdim_inplace(const std::vector<long>& map);
203  };
204 
205 }
206 
207 #endif // MADNESS_TENSOR_BASETENSOR_H__INCLUDED
Implements AtomicInt.
std::complex< double > double_complex
Definition: basetensor.h:45
std::complex< float > float_complex
Definition: basetensor.h:44
An integer with atomic set, get, read+increment, read+decrement, and decrement+test operations.
Definition: atomicint.h:126
The base class for tensors defines generic capabilities.
Definition: basetensor.h:85
bool conforms(const BaseTensor *t) const
Returns true if this and *t are the same shape and size.
Definition: basetensor.h:159
void flat_inplace()
Reshapes the tensor inplace into 1D.
Definition: basetensor.cc:81
long dim(int i) const
Returns the size of dimension i.
Definition: basetensor.h:147
bool iscontiguous() const
Returns true if the tensor refers to contiguous memory locations.
Definition: basetensor.h:168
static int get_instance_count()
Returns the count of all current instances of tensors & slice tensors of all types.
Definition: basetensor.h:129
void mapdim_inplace(const std::vector< long > &map)
General permutation of dimensions.
Definition: basetensor.cc:156
long _stride[TENSOR_MAXDIM]
Increment between elements in each dimension.
Definition: basetensor.h:97
long stride(int i) const
Returns the stride associated with dimension i.
Definition: basetensor.h:150
long _size
Number of elements in the tensor.
Definition: basetensor.h:93
long id() const
Returns the typeid of the tensor (c.f., TensorTypeData<T> )
Definition: basetensor.h:141
void set_dims_and_size(long nd, const long d[])
Definition: basetensor.h:99
long _id
Id from TensorTypeData<T> in type_data.h.
Definition: basetensor.h:95
const long * dims() const
Returns the array of tensor dimensions.
Definition: basetensor.h:153
void splitdim_inplace(long i, long dimi0, long dimi1)
Splits dimension i.
Definition: basetensor.cc:88
void swapdim_inplace(long i, long j)
Swaps the dimensions.
Definition: basetensor.cc:124
virtual ~BaseTensor()
Definition: basetensor.h:122
BaseTensor()
Definition: basetensor.h:116
void fusedim_inplace(long i)
Fuses dimensions i and i+1.
Definition: basetensor.cc:107
long _dim[TENSOR_MAXDIM]
Size of each dimension.
Definition: basetensor.h:96
long ndim() const
Returns the number of dimensions in the tensor.
Definition: basetensor.h:144
long size() const
Returns the number of elements in the tensor.
Definition: basetensor.h:138
void cycledim_inplace(long shift, long start, long end)
Cyclic shift of dimensions.
Definition: basetensor.cc:134
const long * strides() const
Returns the array of tensor strides.
Definition: basetensor.h:156
long _ndim
Number of dimensions (-1=invalid; 0=no supported; >0=tensor)
Definition: basetensor.h:94
void reshape_inplace(const std::vector< long > &d)
Reshapes the tensor inplace.
Definition: basetensor.cc:76
static double shift
Definition: dirac-hatom.cc:19
#define max(a, b)
Definition: lda.h:51
Macros and tools pertaining to the configuration of MADNESS.
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
static const double L
Definition: rk.cc:46
Declares and implements Slice.
Macros for easy and efficient iteration over tensors.
#define TENSOR_MAXDIM
Definition: tensor_macros.h:194
void d()
Definition: test_sig.cc:79
Defines and implements TensorTypeData, a type traits class.
Declares and implements factories for short vectors.