MUQ  0.4.3
TemplatedArrayUtilities.h
Go to the documentation of this file.
1 
2 #ifndef TEMPLATEDARRAYUTILITIES_H_
3 #define TEMPLATEDARRAYUTILITIES_H_
4 
5 #include <Eigen/Dense>
6 #include <vector>
7 
8 namespace muq
9 {
10 namespace Approximation
11 {
12 
13 template<typename MatType>
14 class MatrixBlock;
15 
23 template<typename MatrixType>
24 unsigned GetShape(MatrixType const& mat, unsigned dim)
25 {
26  return mat.dimension(dim);
27 }
28 
29 template<typename ScalarType, int rows, int cols>
30 unsigned GetShape(Eigen::Matrix<ScalarType, rows, cols> const& mat, unsigned dim)
31 {
32  assert(dim<2);
33  return dim==0 ? mat.rows() : mat.cols();
34 }
35 
36 template<typename Derived>
37 unsigned GetShape(MatrixBlock<Derived> const& mat, unsigned dim)
38 {
39  assert(dim<2);
40  return dim==0 ? mat.rows() : mat.cols();
41 }
42 
43 
44 template<typename Derived>
45 unsigned GetShape(Eigen::Ref<Derived> const& mat, unsigned dim)
46 {
47  assert(dim<2);
48  return dim==0 ? mat.rows() : mat.cols();
49 }
50 
55 template<typename VectorType1, typename VectorType2>
56 double CalcSquaredDistance(VectorType1 const& v1, VectorType2 const& v2, int startDim=0, int endDim=-1)
57 {
58  if(endDim==-1)
59  {
60  endDim = GetShape(v1,0);
61  }
62 
63  const int dim = endDim-startDim;
64  const int minDim = 10;
65 
66  // If the dimension is small enough, just compute the some with a for loop
67  if(dim<minDim)
68  {
69  double output = 0.0;
70  for(int i=0; i<dim; ++i)
71  {
72  output += std::pow(v1(startDim+i)-v2(startDim+i), 2.0);
73  }
74  return output;
75  }
76  else
77  {
78 
79  int midDim = startDim + std::floor(0.5*dim);
80  return CalcSquaredDistance(v1,v2, startDim, midDim) + CalcSquaredDistance(v1,v2, midDim, endDim);
81  }
82 
83 }
84 
85 
87 template<typename VectorType1, typename VectorType2>
88 double CalcDistance(VectorType1 const& v1, VectorType2 const& v2)
89 {
90  // Make sure the vectors are the same size
91  const int dim = GetShape(v1,0);
92  assert(dim==GetShape(v2,0));
93 
94  return std::sqrt(CalcSquaredDistance(v1,v2));
95 }
96 
104 template<typename MatType>
106 {
107 public:
108  //ColumnSlice(MatType const& matrixIn, unsigned colIn) : col(colIn), matrix(matrixIn){};
109  ColumnSlice(MatType& matrixIn, unsigned colIn) : col(colIn), matrix(matrixIn){};
110 
111  double operator()(unsigned row) const{return matrix(row, col);};
112  double operator()(unsigned row, unsigned col2) const{assert(col2==0); return matrix(row,col);};
113 
114  double& operator()(unsigned row){return matrix(row, col);};
115  double& operator()(unsigned row, unsigned col2){assert(col2==0); return matrix(row,col);};
116 
117  unsigned dimension(unsigned dim) const
118  {
119  if(dim>0)
120  return 1;
121  else
122  return GetShape(matrix,0);
123  };
124 
125  unsigned rows() const
126  {
127  return GetShape(matrix,0);
128  }
129 
130  unsigned cols() const
131  {
132  return 1;
133  }
134 
135  operator Eigen::VectorXd() const
136  {
137  return eval();
138  };
139 
140  Eigen::VectorXd eval() const
141  {
142  Eigen::VectorXd output(rows());
143  for(int i=0; i<rows(); ++i)
144  output(i) = (*this)(i);
145  return output;
146  };
147 private:
148  const unsigned col;
149  MatType& matrix;
150 };
151 
152 template<typename VecType>
154 {
155 public:
156  VectorSlice(VecType const& vectorIn, std::vector<unsigned> const& indsIn) : vector(vectorIn), inds(indsIn){};
157 
158  double operator()(unsigned row) const{return vector(inds.at(row));};
159  double& operator()(unsigned row){return vector(inds.at(row));};
160 
161  unsigned dimension(unsigned dim) const
162  {
163  if(dim>0)
164  return 1;
165  else
166  return inds.size();
167  }
168 
169 private:
170  VecType const& vector;
171  std::vector<unsigned> const& inds;
172 };
173 
174 template<typename MatType>
176 {
177 public:
178  MatrixBlock(MatType & matrixIn,
179  unsigned startRowIn,
180  unsigned startColIn,
181  unsigned numRowsIn,
182  unsigned numColsIn) : startRow(startRowIn), startCol(startColIn), numRows(numRowsIn), numCols(numColsIn), matrix(matrixIn)
183  {
184  assert(GetShape(matrix,0)>=startRow+numRows);
185  assert(GetShape(matrix,1)>=startCol+numCols);
186  };
187 
188  double operator() (unsigned row, unsigned col) const{return matrix(startRow + row, startCol + col);};
189  double &operator()(unsigned row, unsigned col){return matrix(startRow + row, startCol + col);};
190 
191  template<typename Derived>
192  MatrixBlock& operator=(Eigen::DenseBase<Derived> const& otherMat)
193  {
194  assert(otherMat.rows()==numRows);
195  assert(otherMat.cols()==numCols);
196 
197  for(unsigned j=0; j<numCols; ++j)
198  {
199  for(unsigned i=0; i<numRows; ++i)
200  {
201  matrix(startRow + i, startCol + j) = otherMat(i,j);
202  }
203  }
204  return *this;
205  }
206 
207  unsigned rows() const{return numRows;};
208  unsigned cols() const{return numCols;};
209 
210 private:
211 
212  const unsigned startRow, startCol, numRows, numCols;
213  MatType& matrix;
214 };
215 
221 template<typename MatType>
222 ColumnSlice<MatType> GetColumn(MatType& matrix, unsigned col)
223 {
224  return ColumnSlice<MatType>(matrix, col);
225 }
226 
227 template<typename MatType>
228 VectorSlice<MatType> GetSlice(MatType& matrix, std::vector<unsigned> const& inds)
229 {
230  return VectorSlice<MatType>(matrix, inds);
231 }
232 
233 
234 template<typename MatType>
235 MatrixBlock<MatType> GetBlock(MatType & matrix, unsigned rowStart, unsigned colStart, unsigned numRows, unsigned numCols)
236 {
237  return MatrixBlock<MatType>(matrix, rowStart, colStart, numRows, numCols);
238 }
239 
240 
241 } // namespace Approximation
242 
243 } // namespace muq
244 
245 #endif
double operator()(unsigned row) const
ColumnSlice(MatType &matrixIn, unsigned colIn)
unsigned dimension(unsigned dim) const
double & operator()(unsigned row, unsigned col2)
double operator()(unsigned row, unsigned col2) const
double & operator()(unsigned row, unsigned col)
MatrixBlock & operator=(Eigen::DenseBase< Derived > const &otherMat)
double operator()(unsigned row, unsigned col) const
MatrixBlock(MatType &matrixIn, unsigned startRowIn, unsigned startColIn, unsigned numRowsIn, unsigned numColsIn)
double operator()(unsigned row) const
VectorSlice(VecType const &vectorIn, std::vector< unsigned > const &indsIn)
unsigned dimension(unsigned dim) const
std::vector< unsigned > const & inds
double CalcDistance(VectorType1 const &v1, VectorType2 const &v2)
MatrixBlock< MatType > GetBlock(MatType &matrix, unsigned rowStart, unsigned colStart, unsigned numRows, unsigned numCols)
VectorSlice< MatType > GetSlice(MatType &matrix, std::vector< unsigned > const &inds)
double CalcSquaredDistance(VectorType1 const &v1, VectorType2 const &v2, int startDim=0, int endDim=-1)
Calculates the distance squared between two points defined by vectors v1 and v2.
unsigned GetShape(MatrixType const &mat, unsigned dim)
ColumnSlice< MatType > GetColumn(MatType &matrix, unsigned col)