MyraMath
MatrixRange.h
Go to the documentation of this file.
1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
6 #ifndef MYRAMATH_DENSE_MATRIXRANGE_H
7 #define MYRAMATH_DENSE_MATRIXRANGE_H
8 
15 #include <myramath/utility/detail/LIBPUBLIC.h>
16 
17 #include <iosfwd>
18 #include <utility>
19 #include <vector>
20 
21 namespace myra {
22 
23 // Forward declarations.
24 template<int Arity, class Number> class Expression;
25 template<class Number> class MatrixRange;
26 template<class Number> class CMatrixRange;
27 template<class Number> class VectorRange;
28 template<class Number> class CVectorRange;
29 template<class T> class Array1;
30 template<class T> class Array2;
31 class OutputStream;
32 class intCRange;
33 
35 template<class Number> class LIBPUBLIC MatrixRange
36  {
37  public:
38 
40  Number* begin; // Pointer to A(0,0)
42  int I; // Number of rows in A
43  int J; // Number of columns in A
44  int LD; // Leading dimension of A
46 
47  // Useful typedef.
48  typedef std::pair<MatrixRange<Number>, MatrixRange<Number> > Pair;
49 
50  // ------------------------------------ Construction and range semantics.
51 
53  MatrixRange();
54 
56  MatrixRange(Number* in_begin, int in_I, int in_J, int in_LD);
57 
59  MatrixRange(Number* in_begin, int in_I, int in_J);
60 
62  void write(OutputStream& out) const;
63 
64  // ------------------------------------ Size queries.
65 
67  std::pair<int,int> size() const;
68 
70  uint64_t n_words() const;
71 
72  // ------------------------------------ General slicing.
73 
75  CMatrixRange<Number> add_const() const;
76 
78  operator CMatrixRange<Number> () const;
79 
81  MatrixRange<Number> window (int i0, int i1, int j0, int j1) const;
82 
84  Array2<MatrixRange<Number> > windows(const intCRange& i, const intCRange& j) const;
85 
87  Number& operator() (int i, int j) const;
88 
90  Number& at(int i, int j) const;
91 
92  // ------------------------------------ Row slicing.
93 
95  MatrixRange<Number> row(int i) const;
96 
98  MatrixRange<Number> rows(int i0, int i1) const;
99 
101  MatrixRange<Number> top(int i) const;
102 
104  MatrixRange<Number> cut_top(int i) const;
105 
107  Pair split_top(int i) const;
108 
110  MatrixRange<Number> bottom(int i) const;
111 
113  MatrixRange<Number> cut_bottom(int i) const;
114 
116  Pair split_bottom(int i) const;
117 
119  Array1<MatrixRange<Number> > rows(const intCRange& i) const;
120 
121  // ------------------------------------ Column slicing.
122 
124  MatrixRange<Number> column(int j) const;
125 
127  MatrixRange<Number> columns(int j0, int j1) const;
128 
130  MatrixRange<Number> left(int j) const;
131 
133  MatrixRange<Number> cut_left(int j) const;
134 
136  Pair split_left(int j) const;
137 
139  MatrixRange<Number> right(int j) const;
140 
142  MatrixRange<Number> cut_right(int j) const;
143 
145  Pair split_right(int j) const;
146 
148  Array1<MatrixRange<Number> > columns(const intCRange& j) const;
149 
151  VectorRange<Number> vector(int j) const;
152 
153  // ------------------------------------ Mutating underlying contents.
154 
156  void swap(const MatrixRange<Number>& that) const;
157 
159  // Functor f should be a have an operator(), that takes a Number and returns a Number.
160  template<class Functor> void transform(const Functor& f) const
161  {
162  for (int j = 0; j < J; ++j)
163  for (int i = 0; i < I; ++i)
164  *pointer(i,j) = f( *pointer(i,j) );
165  }
166 
168  // Functor f should be a have an operator(), that takes a Number and returns a Number.
169  template<class Functor> void transform_triangle(const Functor& f, char uplo) const
170  {
171  if (uplo == 'U')
172  {
173  for (int j = 0; j < J; ++j)
174  for (int i = 0; i <= j && i < I; ++i)
175  *pointer(i,j) = f( *pointer(i,j) );
176  }
177  else if (uplo == 'L')
178  {
179  for (int j = 0; j < J; ++j)
180  for (int i = j; i < I; ++i)
181  *pointer(i,j) = f( *pointer(i,j) );
182  }
183  }
184 
186  // Functor f should be a have an operator(), that takes a Number and returns a Number.
187  template<class Functor> void transform_diagonal(const Functor& f) const
188  {
189  int N = I < J ? I : J;
190  for (int n = 0; n < N; ++n)
191  *pointer(n,n) = f( *pointer(n,n) );
192  }
193 
195  void assign(const CMatrixRange<Number>& that) const;
197  void assign(const CMatrixRange<Number>& that, char op) const;
198  void assign(const Expression<2,Number>& that) const;
200 
202  void operator += (const CMatrixRange<Number>& that) const;
204  void operator += (const Expression<2,Number>& that) const;
206 
208  void operator -= (const CMatrixRange<Number>& that) const;
210  void operator -= (const Expression<2,Number>& that) const;
212 
214  void operator *= (Number alpha) const;
215 
217  void operator /= (Number alpha) const;
218 
220  void zero() const;
221 
222  private:
223 
224  // Returns pointer to (i,j)'th entry.
225  Number* pointer(int i, int j) const;
226 
227  // Throws if IJ is not the same size as *this.
228  void check_size(const std::pair<int,int>& IJ) const;
229 
230  };
231 
233 template<class Number> class LIBPUBLIC CMatrixRange
234  {
235  public:
236 
238  const Number* begin; // Pointer to A(0,0)
240  int I; // Number of rows in A
241  int J; // Number of columns in A
242  int LD; // Leading dimension of A
244 
245  // Useful typedef.
246  typedef std::pair<CMatrixRange<Number>, CMatrixRange<Number> > Pair;
247 
248  // ------------------------------------ Construction and range semantics.
249 
251  CMatrixRange();
252 
254  CMatrixRange(const Number* in_begin, int in_I, int in_J, int in_LD);
255 
257  CMatrixRange(const Number* in_begin, int in_I, int in_J);
258 
260  void write(OutputStream& out) const;
261 
262  // ------------------------------------ Size queries.
263 
265  std::pair<int,int> size() const;
266 
268  uint64_t n_words() const;
269 
270  // ------------------------------------ General slicing.
271 
273  MatrixRange<Number> remove_const() const;
274 
276  CMatrixRange<Number> window (int i0, int i1, int j0, int j1) const;
277 
279  Array2<CMatrixRange<Number> > windows(const intCRange& i, const intCRange& j) const;
280 
282  const Number& operator() (int i, int j) const;
283 
285  const Number& at(int i, int j) const;
286 
287  // ------------------------------------ Row slicing.
288 
290  CMatrixRange<Number> row(int i) const;
291 
293  CMatrixRange<Number> rows(int i0, int i1) const;
294 
296  Array1<CMatrixRange<Number> > rows(const intCRange& i) const;
297 
299  CMatrixRange<Number> top(int i) const;
300 
302  CMatrixRange<Number> cut_top(int i) const;
303 
305  Pair split_top(int i) const;
306 
308  CMatrixRange<Number> bottom(int i) const;
309 
311  CMatrixRange<Number> cut_bottom(int i) const;
312 
314  Pair split_bottom(int i) const;
315 
316  // ------------------------------------ Column slicing.
317 
319  CMatrixRange<Number> column(int j) const;
320 
322  CMatrixRange<Number> columns(int j0, int j1) const;
323 
325  Array1<CMatrixRange<Number> > columns(const intCRange& j) const;
326 
328  CMatrixRange<Number> left(int j) const;
329 
331  CMatrixRange<Number> cut_left(int j) const;
332 
334  Pair split_left(int j) const;
335 
337  CMatrixRange<Number> right(int j) const;
338 
340  CMatrixRange<Number> cut_right(int j) const;
341 
343  Pair split_right(int j) const;
344 
346  CVectorRange<Number> vector(int j) const;
347 
348  private:
349 
350  // Returns pointer to (i,j)'th entry.
351  const Number* pointer(int i, int j) const;
352  };
353 
355 template<class Number> class ReflectNumber< MatrixRange<Number> >
356  { public: typedef Number type; };
357 
359 template<class Number> class ReflectNumber< CMatrixRange<Number> >
360  { public: typedef Number type; };
361 
363 LIBPUBLIC Array1<CMatrixRange<NumberS> > add_const(const Array1<MatrixRange<NumberS> >& ranges);
365 LIBPUBLIC Array1<CMatrixRange<NumberD> > add_const(const Array1<MatrixRange<NumberD> >& ranges);
366 LIBPUBLIC Array1<CMatrixRange<NumberC> > add_const(const Array1<MatrixRange<NumberC> >& ranges);
367 LIBPUBLIC Array1<CMatrixRange<NumberZ> > add_const(const Array1<MatrixRange<NumberZ> >& ranges);
369 
371 LIBPUBLIC Array1<MatrixRange<NumberS> > remove_const(const Array1<CMatrixRange<NumberS> >& ranges);
373 LIBPUBLIC Array1<MatrixRange<NumberD> > remove_const(const Array1<CMatrixRange<NumberD> >& ranges);
374 LIBPUBLIC Array1<MatrixRange<NumberC> > remove_const(const Array1<CMatrixRange<NumberC> >& ranges);
375 LIBPUBLIC Array1<MatrixRange<NumberZ> > remove_const(const Array1<CMatrixRange<NumberZ> >& ranges);
377 
379 LIBPUBLIC Array2<CMatrixRange<NumberS> > add_const(const Array2<MatrixRange<NumberS> >& ranges);
381 LIBPUBLIC Array2<CMatrixRange<NumberD> > add_const(const Array2<MatrixRange<NumberD> >& ranges);
382 LIBPUBLIC Array2<CMatrixRange<NumberC> > add_const(const Array2<MatrixRange<NumberC> >& ranges);
383 LIBPUBLIC Array2<CMatrixRange<NumberZ> > add_const(const Array2<MatrixRange<NumberZ> >& ranges);
385 
387 LIBPUBLIC Array2<MatrixRange<NumberS> > remove_const(const Array2<CMatrixRange<NumberS> >& ranges);
389 LIBPUBLIC Array2<MatrixRange<NumberD> > remove_const(const Array2<CMatrixRange<NumberD> >& ranges);
390 LIBPUBLIC Array2<MatrixRange<NumberC> > remove_const(const Array2<CMatrixRange<NumberC> >& ranges);
391 LIBPUBLIC Array2<MatrixRange<NumberZ> > remove_const(const Array2<CMatrixRange<NumberZ> >& ranges);
393 
395 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CMatrixRange<NumberS>& A);
397 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CMatrixRange<NumberD>& A);
398 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CMatrixRange<NumberC>& A);
399 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CMatrixRange<NumberZ>& A);
401 
402 } // namespace myra
403 
404 #endif
Container of values, allows random (i,j) access.
Definition: Array2.h:30
Reflects Number trait for a Container, containers of Numbers (Matrix&#39;s, Vector&#39;s, etc) should special...
Definition: Number.h:55
int J
---------— Data members, all public ----------------—
Definition: MatrixRange.h:43
void transform_triangle(const Functor &f, char uplo) const
Overwrites every A(i,j) in the &#39;U&#39;pper or &#39;L&#39;ower triangle of this MatrixRange with f(A(i...
Definition: MatrixRange.h:169
Represents a mutable VectorRange.
Definition: axpy.h:21
int I
---------— Data members, all public ----------------—
Definition: MatrixRange.h:42
int LD
---------— Data members, all public ----------------—
Definition: MatrixRange.h:44
Definition: syntax.dox:1
Represents a const MatrixRange.
Definition: bothcat.h:22
Abstraction layer, serializable objects write themselves to these.
Definition: Streams.h:39
Various utility functions/classes related to scalar Number types.
int J
---------— Data members, all public ----------------—
Definition: MatrixRange.h:241
Represents a mutable MatrixRange.
Definition: conjugate.h:26
int I
---------— Data members, all public ----------------—
Definition: MatrixRange.h:240
void transform_diagonal(const Functor &f) const
Overwrites every A(n,n) on the diagonal of this MatrixRange with f(A(n,n)).
Definition: MatrixRange.h:187
int LD
---------— Data members, all public ----------------—
Definition: MatrixRange.h:242
Represents a const VectorRange.
Definition: axpy.h:20
Container of values, allows random (i) access.
Definition: Array1.h:32
Given an index (i,j,etc), returns a value.
Definition: arithmetic.h:19
Represents a const intRange.
Definition: intRange.h:142
void transform(const Functor &f) const
Overwrites every A(i,j) in this MatrixRange with f(A(i,j)).
Definition: MatrixRange.h:160