TooN
mbase.hh
1 // -*- c++ -*-
2 
3 // Copyright (C) 2009 Tom Drummond (twd20@cam.ac.uk),
4 // Ed Rosten (er258@cam.ac.uk)
5 
6 //All rights reserved.
7 //
8 //Redistribution and use in source and binary forms, with or without
9 //modification, are permitted provided that the following conditions
10 //are met:
11 //1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 //POSSIBILITY OF SUCH DAMAGE.
28 
29 namespace TooN {
30 
31 namespace Internal
32 {
33 // As usual, a positive integer means static and -1 means dynamic.
34 // The new case is that for strides, -2 means that the stride is
35 // the same as num_cols/num_rows, which must be dynamically sized.
36 
37 template<int, int, class, int, int, class> struct GenericMBase;
38 
40 //Closure used to acquire strides
41 //-1 means dynamic stride
42 //-2 means dynamic stride is tied to size for a normal matrix
43 template<int RowStride, int ColStride> struct Slice
44 {
45 
46  template<int Rows, int Cols, class Precision> struct MLayout: public GenericMBase<Rows, Cols, Precision, RowStride, ColStride, MatrixSlice<Rows, Cols, Precision> >
47  {
48  MLayout(Precision* p, int rows, int cols, int rowstride, int colstride)
50  {
51  }
52  };
53 };
54 
55 
56 template<int Rows, int Cols, bool D = (Rows == Dynamic || Cols == Dynamic)>
57 struct DiagSize
58 {
59  static const int size = Dynamic;
60 };
61 template<int Rows, int Cols>
62 struct DiagSize<Rows, Cols, 0>
63 {
64  static const int size = (Rows<Cols?Rows:Cols);
65 };
66 
67 template<int Rs, int Cs, bool D = (Rs == Dynamic || Cs == Dynamic)>
68 struct DiagStride
69 {
70  static const int stride = Dynamic;
71 };
72 template<int Rs, int Cs>
73 struct DiagStride<Rs, Cs, 0>
74 {
75  static const int stride = Rs + Cs;
76 };
77 
78 
79 template<int Rows, int Cols, class Precision, int RowStride, int ColStride, class Mem> struct GenericMBase
80  : public Mem,
81  RowStrideHolder<RowStride>,
82  ColStrideHolder<ColStride>
83 {
84  //Slices can never have tied strides
85  static const int SliceRowStride = RowStride == -2?-1: RowStride;
86  static const int SliceColStride = ColStride == -2?-1: ColStride;
87 
88  typedef Slice<SliceRowStride,SliceColStride> SliceBase;
89 
90  int rowstride() const {
91  if(RowStride == -2) { //Normal tied stride
92  return num_cols();
93  } else {
95  }
96  }
97 
98  int colstride() const {
99  if(ColStride == -2) { //Normal tied stride
100  return num_rows();
101  } else {
103  }
104  }
105 
106  //Optional constructors
107  GenericMBase(){}
108 
109  GenericMBase(Precision* p)
110  :Mem(p)
111  {}
112 
113 
114  GenericMBase(Precision* p, int r, int c, int rowstride, int colstride)
115  :Mem(p, r, c),
116  RowStrideHolder<RowStride>(rowstride),
117  ColStrideHolder<ColStride>(colstride)
118  {}
119 
120  GenericMBase(int r, int c)
121  :Mem(r, c) {}
122 
123  template<class Op>
124  GenericMBase(const Operator<Op>& op)
125  : Mem(op),
128  {}
129 
130  using Mem::my_data;
131  using Mem::num_cols;
132  using Mem::num_rows;
133 
134  Precision& operator()(int r, int c){
135  Internal::check_index(num_rows(), r);
136  Internal::check_index(num_cols(), c);
137  return my_data[r*rowstride() + c*colstride()];
138  }
139 
140  const Precision& operator()(int r, int c) const {
141  Internal::check_index(num_rows(), r);
142  Internal::check_index(num_cols(), c);
143  return my_data[r*rowstride() + c*colstride()];
144  }
145 
146  Precision& operator[](const std::pair<int, int>& index) {
147  Internal::check_index(num_rows(), index.first);
148  Internal::check_index(num_cols(), index.second);
149  return (*this)(index.first, index.second);
150  }
151 
152  const Precision& operator[](const std::pair<int, int>& index) const {
153  Internal::check_index(num_rows(), index.first);
154  Internal::check_index(num_cols(), index.second);
155  return (*this)(index.first, index.second);
156  }
157 
158  // this is the type of vector obtained by [ ]
161 
162  Vec operator[](int r) {
163  Internal::check_index(num_rows(), r);
164  return Vec(my_data + rowstride()* r, num_cols(), colstride(), Slicing());
165  }
166 
167  const CVec operator[](int r) const {
168  Internal::check_index(num_rows(), r);
169  return CVec(my_data + rowstride()* r, num_cols(), colstride(), Slicing());
170  }
171 
172 
173  //Generic matrix slicing
174  template<int Rstart, int Cstart, int Rlength, int Clength>
175  Matrix<Rlength, Clength, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl){
178 
179  //Always pass the size and stride as a run-time parameter. It will be ignored
180  //by SliceHolder (above) if it is statically determined.
182  my_data+rowstride()*(Rstart==Dynamic?rs:Rstart) + colstride()*(Cstart==Dynamic?cs:Cstart),
183  Rlength==Dynamic?rl:Rlength,
184  Clength==Dynamic?cl:Clength,
185  rowstride(), colstride(), Slicing());
186  }
187 
188  template<int Rstart, int Cstart, int Rlength, int Clength>
189  const Matrix<Rlength, Clength, const Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl) const{
192 
193  //Always pass the size and stride as a run-time parameter. It will be ignored
194  //by SliceHolder (above) if it is statically determined.
196  my_data+rowstride()*(Rstart==Dynamic?rs:Rstart) + colstride()*(Cstart==Dynamic?cs:Cstart),
197  Rlength==Dynamic?rl:Rlength,
198  Clength==Dynamic?cl:Clength,
199  rowstride(), colstride(), Slicing());
200  }
201 
202  //Special cases of slicing
203  template<int Rstart, int Cstart, int Rlength, int Clength>
205  {
206  //Extra checking in the static case
209  return slice<Rstart, Cstart, Rlength, Clength>(Rstart, Cstart, Rlength, Clength);
210  }
211 
212  template<int Rstart, int Cstart, int Rlength, int Clength>
214  {
217  return slice<Rstart, Cstart, Rlength, Clength>(Rstart, Cstart, Rlength, Clength);
218  }
219 
220  Matrix<-1, -1, Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl){
221  return slice<Dynamic, Dynamic, Dynamic, Dynamic>(rs, cs, rl, cl);
222  }
223 
224  const Matrix<-1, -1, const Precision, Slice<SliceRowStride,SliceColStride> > slice(int rs, int cs, int rl, int cl) const {
225  return slice<Dynamic, Dynamic, Dynamic, Dynamic>(rs, cs, rl, cl);
226  }
227 
228  //Other slice related functions.
230  return Matrix<Cols, Rows, Precision, Slice<SliceColStride,SliceRowStride> >(my_data, num_cols(), num_rows(), colstride(), rowstride(), Slicing());
231  }
232 
234  return Matrix<Cols, Rows, const Precision, Slice<SliceColStride,SliceRowStride> >(my_data, num_cols(), num_rows(), colstride(), rowstride(), Slicing());
235  }
236 
239 
241  {
242  return Vector<DiagSize, Precision, SliceVBase<DiagStride> >(my_data, std::min(num_cols(), num_rows()), rowstride() + colstride(), Slicing());
243  }
244 
246  {
247  return Vector<DiagSize, const Precision, SliceVBase<DiagStride> >(my_data, std::min(num_cols(), num_rows()), rowstride() + colstride(), Slicing());
248  }
249 };
250 
251 }
252 
254 //
255 // Classes for Matrices owning memory
256 //
257 //
258 struct RowMajor
259 {
260  template<int Rows, int Cols, class Precision> struct MLayout: public Internal::GenericMBase<Rows, Cols, Precision, (Cols==-1?-2:Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >
261  {
262  //Optional constructors.
263 
264  MLayout(){}
265 
266  MLayout(int rows, int cols)
267  :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
268  {}
269 
270  template<class Op>
271  MLayout(const Operator<Op>& op)
272  :Internal::GenericMBase<Rows, Cols, Precision, (Cols == -1 ? -2 : Cols), 1, Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
273  {}
274 
275  };
276 };
277 
278 struct ColMajor
279 {
280  template<int Rows, int Cols, class Precision> struct MLayout: public Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows==-1?-2:Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >
281  {
282  //Optional constructors.
283 
284  MLayout(){}
285 
286  MLayout(int rows, int cols)
287  :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(rows, cols)
288  {}
289 
290  template<class Op>
291  MLayout(const Operator<Op>& op)
292  :Internal::GenericMBase<Rows, Cols, Precision, 1, (Rows == -1 ? -2 : Rows), Internal::MatrixAlloc<Rows, Cols, Precision> >(op)
293  {}
294 
295  };
296 };
297 
298 }
299 
Definition: mbase.hh:43
Definition: slice_error.hh:56
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
A vector.
Definition: vector.hh:126
Definition: mbase.hh:258
Definition: allocator.hh:699
A matrix.
Definition: matrix.hh:105
Definition: allocator.hh:715
Definition: mbase.hh:57
Definition: operators.hh:119
Definition: mbase.hh:278
Definition: mbase.hh:46
int num_rows() const
Return the number of rows.
Definition: allocator.hh:520
Definition: mbase.hh:68
int num_cols() const
Return the number of columns.
Definition: allocator.hh:546
int size() const
Simply return the statcally known size.
Definition: allocator.hh:475
Definition: mbase.hh:280
Definition: mbase.hh:37
Definition: mbase.hh:260
Definition: TooN.h:145