File: CloneVector.h

package info (click to toggle)
lammps 20220106.git7586adbb6a%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 348,064 kB
  • sloc: cpp: 831,421; python: 24,896; xml: 14,949; f90: 10,845; ansic: 7,967; sh: 4,226; perl: 4,064; fortran: 2,424; makefile: 1,501; objc: 238; lisp: 163; csh: 16; awk: 14; tcl: 6
file content (253 lines) | stat: -rw-r--r-- 10,220 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#ifndef CLONEVECTOR_H
#define CLONEVECTOR_H

#include "Vector.h"
#include <algorithm>

namespace ATC_matrix {

  /**
   *  @class  CloneVector
   *  @brief  Class for creating objects that wrap matrix data for manipulation through vector operations
   */

template<typename T>
class CloneVector : public Vector<T>
{
public:
  CloneVector(); // do not implement
  CloneVector(const Vector<T> &c);
  CloneVector(const Matrix<T> &c, int dim, INDEX idx=0);
  CloneVector(const DiagonalMatrix<T> &c, INDEX idx=0);

  // overloaded virtual functions
  T& operator[](INDEX i);
  T  operator[](INDEX i)              const;
  T  operator()(INDEX i, INDEX j=0)   const;
  T& operator()(INDEX i, INDEX j=0);
  INDEX nRows()                       const;

  CloneVector<T>& operator=(const T &v);
  CloneVector<T>& operator=(const CloneVector<T> &C);
  CloneVector<T>& operator=(const Matrix<T> &C);

  virtual bool memory_contiguous()    const;
  T* ptr()             const;
  void resize(INDEX nRows, INDEX nCols=0, bool copy=false);
  void  reset(INDEX nRows, INDEX nCols=0, bool zero=true);
  void copy(const T * ptr, INDEX nRows, INDEX nCols=0);

private:
  void _resize(INDEX nRows, INDEX nCols, bool copy, bool zero);

  Vector<T> * const _baseV; // ptr to a base vector
  Matrix<T> * const _baseM; // ptr to a base matrix
  int _clone_type;          // what to clone (see enum CLONE_TYPE)
  INDEX _idx;               // index of matrix dimension to clone
};
///////////////////////////////////////////////////////////////////////////////
// Template definitions ///////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Construct from another vector
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>::CloneVector(const Vector<T> &c)
 : Vector<T>(), _baseV(const_cast<Vector<T>*>(&c)), _baseM(nullptr)
{}
//-----------------------------------------------------------------------------
// Construct from a matrix, the const_cast isn't pretty
/* CloneVector(const Matrix<T> &c, int dim, INDEX idx)
/   attaches to a slice of a matrix
/   Arguments: c = pointer to the matrix
/              dim = type of slice CLONE_ROW, CLONE_COL, CLONE_DIAG
/              idx = index of row or column (no effect on diag currently)
*/
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>::CloneVector(const Matrix<T> &c, int dim, INDEX idx)
 : Vector<T>(), _baseV(nullptr), _baseM(const_cast<Matrix<T>*>(&c))
 , _clone_type(dim), _idx(idx)
{}
//-----------------------------------------------------------------------------
// Construct from a DiagonalMatrix
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>::CloneVector(const DiagonalMatrix<T> &c, INDEX /* idx */)
 : Vector<T>(), _baseV(nullptr), _baseM(const_cast<DiagonalMatrix<T>*>(&c))
 , _clone_type(CLONE_DIAG), _idx(0)
{}
//-----------------------------------------------------------------------------
// value (const) indexing operator
//-----------------------------------------------------------------------------
template<typename T>
  T CloneVector<T>::operator()(INDEX i, INDEX /* j */) const
{
  return (*this)[i];
}
//-----------------------------------------------------------------------------
// reference index operator
//-----------------------------------------------------------------------------
template<typename T>
T& CloneVector<T>::operator()(INDEX i, INDEX /* j */)
{
  return (*this)[i];
}
//-----------------------------------------------------------------------------
// Indexes the cloned vector either from another vector or a matrix
//-----------------------------------------------------------------------------
template<typename T>
T CloneVector<T>::operator[](INDEX i)                                     const
{
  if (_baseV)                         return (*_baseV)(i);
  if      (_clone_type == CLONE_ROW)  return (*_baseM)(_idx, i);
  else if (_clone_type == CLONE_COL)  return (*_baseM)(i,_idx);
  else if (_clone_type == CLONE_DIAG) return (*_baseM)(i,i);
  return 0;
}
//-----------------------------------------------------------------------------
// Indexes the cloned vector either from another vector or a matrix
//-----------------------------------------------------------------------------
template<typename T>
T& CloneVector<T>::operator[](INDEX i)
{
  if (_baseV)                    return (*_baseV)(i);
  if (_clone_type == CLONE_ROW)  return (*_baseM)(_idx, i);
  if (_clone_type == CLONE_COL)  return (*_baseM)(i,_idx);
  if (_clone_type == CLONE_DIAG) return (*_baseM)(i,i);
  return (*_baseV)(i);
}
//-----------------------------------------------------------------------------
// Returns the size of the base vector or of the row/col of the base matrix
//-----------------------------------------------------------------------------
template<typename T>
INDEX CloneVector<T>::nRows()                                             const
{
  if (_baseV)                    return _baseV->size();
  if (_clone_type == CLONE_ROW)  return _baseM->nCols();
  if (_clone_type == CLONE_COL)  return _baseM->nRows();
  if (_clone_type == CLONE_DIAG) return std::min(_baseM->nRows(), _baseM->nCols());
  return 0;
}
//-----------------------------------------------------------------------------
// assigns all elements to a constant
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>& CloneVector<T>::operator=(const T &v)
{
  this->set_all_elements_to(v);
  return *this;
}
//-----------------------------------------------------------------------------
// assigns all elements to the corresponding elements in C
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>& CloneVector<T>::operator=(const CloneVector<T> &C)
{
  GCK(*this, C, this->size()!=C.size(), "Error in CloneVector:operator=");
  int sz = this->size();
  for (INDEX i = 0; i < sz; i++) (*this)[i] = C[i];
  return *this;
}
//-----------------------------------------------------------------------------
// assigns all elements to the corresponding elements in C
//-----------------------------------------------------------------------------
template<typename T>
CloneVector<T>& CloneVector<T>::operator=(const Matrix<T> &C)
{
  GCK(*this, C, this->size()!=C.size(), "Error in CloneVector:operator=");
  int sz = this->size();
  for (INDEX i = 0; i < sz; i++) (*this)[i] = C[i];
  return *this;
}
//-----------------------------------------------------------------------------
// returns true only if its guaranteed memory is contiguous
//-----------------------------------------------------------------------------
template<typename T>
bool CloneVector<T>::memory_contiguous()  const
{
  // drill down through clone of clones
  if (_baseV) return _baseV->memory_contiguous();
  // could be okay if DiagonalMatrix, but can't guarantee this
  if (_clone_type == CLONE_DIAG) return false;
#ifdef ROW_STORAGE
  return _clone_type == CLONE_ROW;
#else
  return _clone_type == CLONE_COL;
#endif
}
//-----------------------------------------------------------------------------
// Returns a pointer to the data unless the data is a column of a matrix
//-----------------------------------------------------------------------------
template<typename T>
T* CloneVector<T>::ptr()                                              const
{
  if (_baseV) return _baseV->ptr();
#ifdef ROW_STORAGE
  if (_clone_type == CLONE_ROW)  return  _baseM->ptr() + this->size()*_idx;
  if (_clone_type == CLONE_COL)  return _baseM->ptr() + this->size();
  if (_clone_type == CLONE_DIAG) return _baseM->ptr();
#else
  if (_clone_type == CLONE_COL)  return _baseM->ptr() + this->size()*_idx;
  if (_clone_type == CLONE_ROW)  return _baseM->ptr() + this->size();
  if (_clone_type == CLONE_DIAG) return _baseM->ptr();
#endif
  return 0;
}
//-----------------------------------------------------------------------------
// general resize function, can handle parents that are matrices or vectors
//-----------------------------------------------------------------------------
template<typename T>
void CloneVector<T>::_resize(INDEX nRows, INDEX nCols, bool copy, bool zero)
{
  if (_baseV)
  {
    if (copy) _baseV->resize(nRows, nCols, copy);
    else      _baseV->reset (nRows, nCols, zero);
    return;
  }
  // parent is a matrix, need to decide what the Vector is cloning
  switch (_clone_type)
  {
    case CLONE_ROW:  // now the leading dimension is rows
      nCols = nCols ? nCols : _baseM->nCols();
      break;
    case CLONE_COL:  // now the leading dimension is columns
      nCols = nCols ? nCols : _baseM->nRows();
      ATC_Utility::swap(nRows, nCols);
      break;
    case CLONE_DIAG: // lets just hope you knew what you were doing
      break;
    default:
      return;
  }
  if (zero)  _baseM->reset(nRows, nCols, zero);  // zero overrides copy
  else      _baseM->resize(nRows, nCols, copy);
}
//-----------------------------------------------------------------------------
// resizes the matrix and optionally copies what fits
//-----------------------------------------------------------------------------
template<typename T>
void CloneVector<T>::resize(INDEX nRows, INDEX nCols, bool copy)
{
  _resize(nRows, nCols, copy, false);
}
//-----------------------------------------------------------------------------
// resizes the matrix and optionally zeros it out
//-----------------------------------------------------------------------------
template<typename T>
void CloneVector<T>::reset(INDEX nRows, INDEX nCols, bool zero)
{
  _resize(nRows, nCols, false, zero);
}
//-----------------------------------------------------------------------------
// resizes the matrix and copies data
//-----------------------------------------------------------------------------
template<typename T>
void CloneVector<T>::copy(const T * ptr, INDEX nRows, INDEX nCols)
{
  _resize(nRows, nCols, false, false);
  memcpy(this->ptr(), ptr, this->size()*sizeof(T));
}

} // end namespace
#endif