MyraMath
LowerMatrixRange.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_LOWERMATRIXRANGE_H
7 #define MYRAMATH_DENSE_LOWERMATRIXRANGE_H
8 
15 #include <myramath/utility/detail/LIBPUBLIC.h>
16 
17 #include <iosfwd>
18 #include <utility>
19 
20 namespace myra {
21 
22 // Forward declarations.
23 template<int Arity, class Number> class Expression;
24 template<class Number> class Matrix;
25 template<class Number> class MatrixRange;
26 template<class Number> class CMatrixRange;
27 template<class Number> class LowerMatrixRange;
28 template<class Number> class CLowerMatrixRange;
29 class OutputStream;
30 
32 template<class Number> class LIBPUBLIC LowerMatrixRange
33  {
34  public:
35 
37  Number* begin;
39  int N1;
40  int N2;
41  int LD;
43 
44  // ------------------------------------ Construction and range semantics.
45 
48 
50  LowerMatrixRange(Number* in_begin, int N);
51 
53  void write(OutputStream& out) const;
54 
55  // ------------------------------------ Size queries.
56 
58  int size() const;
59 
61  uint64_t n_words() const;
62 
64  std::pair<int,int> blocking() const;
65 
66  // ------------------------------------ General slicing.
67 
69  CLowerMatrixRange<Number> add_const() const;
70 
72  operator CLowerMatrixRange<Number> () const;
73 
75  MatrixRange<Number> rectangle() const;
76 
78  Number& operator() (int i, int j) const;
79 
81  Number& at(int i, int j) const;
82 
84  // Optionally, the 'T'ranspose or 'H'ermitian of *this can be copied into the upper triangle.
86  Matrix<Number> make_Matrix(char op = 'N') const;
87  void make_Matrix(const MatrixRange<Number>& A, char op = 'N') const;
89 
90  // ------------------------------------ Lower triangular slicing.
91 
93  MatrixRange<Number> range11 () const;
95  MatrixRange<Number> range21 () const;
96  MatrixRange<Number> range22t() const;
98 
99  // ------------------------------------ Mutating underlying contents.
100 
102  // Functor f should be a have an operator(), that takes a Number and returns a Number.
103  template<class Functor> void transform(const Functor& f) const
104  {
105  int N = N1+N2;
106  for (int j = 0; j < N; ++j)
107  for (int i = j; i < N; ++i)
108  *pointer(i,j) = f( *pointer(i,j) );
109  }
110 
112  void assign(const CLowerMatrixRange<Number>& that) const;
114  void assign(const Expression<2,Number>& that) const;
115  void assign(const CMatrixRange<Number>& that) const;
117 
119  void operator += (const CLowerMatrixRange<Number>& that) const;
121  void operator += (const Expression<2,Number>& that) const;
123 
125  void operator -= (const CLowerMatrixRange<Number>& that) const;
127  void operator -= (const Expression<2,Number>& that) const;
129 
131  void operator *= (Number alpha) const;
132 
134  void operator /= (Number alpha) const;
135 
137  void zero() const;
138 
139  private:
140 
141  // Returns a pointer to L(i,j)
142  Number* pointer(int i, int j) const;
143 
144  // Throws if that is not the same size as *this.
145  void check_size(const CLowerMatrixRange<Number>& that) const;
146 
147  // Throws if S is not the same size as *this.
148  void check_size(int S) const;
149  };
150 
152 template<class Number> class LIBPUBLIC CLowerMatrixRange
153  {
154  public:
155 
157  const Number* begin;
159  int N1;
160  int N2;
161  int LD;
163 
164  // ------------------------------------ Construction and range semantics.
165 
167  CLowerMatrixRange();
168 
170  CLowerMatrixRange(const Number* in_begin, int N);
171 
173  void write(OutputStream& out) const;
174 
175  // ------------------------------------ Size queries.
176 
178  int size() const;
179 
181  uint64_t n_words() const;
182 
184  std::pair<int,int> blocking() const;
185 
186  // ------------------------------------ General slicing.
187 
189  LowerMatrixRange<Number> remove_const() const;
190 
192  CMatrixRange<Number> rectangle() const;
193 
195  const Number& operator() (int i, int j) const;
196 
198  const Number& at(int i, int j) const;
199 
201  // Optionally, the 'T'ranspose or 'H'ermitian of *this can be copied into the upper triangle.
203  Matrix<Number> make_Matrix(char op = 'N') const;
204  void make_Matrix(const MatrixRange<Number>& A, char op = 'N') const;
206 
207  // ------------------------------------ Lower triangular slicing.
208 
210  CMatrixRange<Number> range11 () const;
212  CMatrixRange<Number> range21 () const;
213  CMatrixRange<Number> range22t() const;
215 
216  private:
217 
218  // Returns a pointer to L(i,j)
219  const Number* pointer(int i, int j) const;
220 
221  };
222 
224 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CLowerMatrixRange<NumberS>& A);
226 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CLowerMatrixRange<NumberD>& A);
227 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CLowerMatrixRange<NumberC>& A);
228 LIBPUBLIC std::ostream& operator << (std::ostream& out, const CLowerMatrixRange<NumberZ>& A);
230 
231 /*
232 
233  Stores a lower triangular matrix in lapack-friendly format, by chopping
234  off the lower right corner, transposing it, and putting it "on top" of
235  the rest. Pictures are worth a thousand words, here's a few to cover it:
236 
237  Examples for even N:
238 
239  N=2
240  C N1 = 1 2
241  A A N2 = 1 0 -> 0
242  B C -> B LD = 3 1 2 1
243 
244 
245  N=4
246  C C 7 8
247  A A C N1 = 2 0 0 9
248  A A -> A A N2 = 2 1 4 -> 1 4
249  B B C B B LD = 5 2 5 7 2 5
250  B B C C B B 3 6 8 9 3 6
251 
252  N=6
253 
254  C C C 15 16 18
255  A A C C N1 = 3 0 0 17 19
256  A A A A C N2 = 3 1 6 1 6 20
257  A A A -> A A A LD = 7 2 7 11 -> 2 7 11
258  B B B C B B B 3 8 12 15 3 8 12
259  B B B C C B B B 4 9 13 16 18 4 9 13
260  B B B C C C B B B 5 10 14 17 19 20 5 10 14
261 
262  Examples for odd N:
263 
264  N=1
265 
266  N1 = 1
267  A -> A N2 = 0 0 -> 0
268  LD = 1
269 
270  N=3
271 
272  A A C N1 = 2 0 0 5
273  A A -> A A N2 = 1 1 3 -> 1 3
274  B B C B B LD = 3 2 4 5 2 4
275 
276  N=5
277 
278  A A C C 1 0 12 13
279  A A A A C N1 = 3 2 6 1 5 14
280  A A A -> A A A N2 = 2 3 7 10 2 6 9
281  B B B C B B B LD = 5 4 8 11 13 -> 3 7 10
282  B B B C C B B B 5 9 12 14 15 4 8 11
283 
284  N=7
285 
286  A A C C C 0 0 22 23 25
287  A A A A C C N1 = 4 1 7 1 7 24 26
288  A A A -> A A A C N2 = 3 2 8 13 2 8 13 27
289  A A A A A A A A LD = 7 3 9 14 18 -> 3 9 14 18
290  B B B B C B B B B 4 10 15 19 22 4 10 15 19
291  B B B B C C B B B B 5 11 16 20 23 25 5 11 16 20
292  B B B B C C C B B B B 6 12 17 21 24 26 27 6 12 17 21
293 
294  MatrixRange's can be obtained over the the various pieces. For example (N=7):
295 
296  [ A C C C ] [ A C C C ]
297  [ A A C C ] [ A A C C ] == .range11()
298  [ A A A C ] [ A A A C ]
299  [ A A A A ] == .rectangle() [ A A A A ]
300  [ B B B B ] B B B B
301  [ B B B B ] B B B B
302  [ B B B B ] B B B B
303 
304  A C C C A [C C C]
305  A A C C A [A C C] == .range22t()
306  A A A C A [A A C]
307  A A A A A A A A
308  [ B B B B ] B B B B
309  [ B B B B ] == .range21() B B B B
310  [ B B B B ] B B B B
311 
312  This storage scheme allows for efficient "column major"/"BLAS3" arithmetic,
313  but maintains the factor of two space advantage that packed formats enjoy
314  compared to just ignoring/wasting the upper triangle of rectangular storage.
315 
316  */
317 
318 } // namespace myra
319 
320 #endif
int N2
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:40
int LD
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:161
Represents a mutable LowerMatrixRange.
Definition: conjugate.h:28
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
int N2
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:160
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 N1
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:39
int LD
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:41
Represents a mutable MatrixRange.
Definition: conjugate.h:26
void transform(const Functor &f) const
Overwrites every A(i,j) in this LowerMatrixRange with f(A(i,j)).
Definition: LowerMatrixRange.h:103
Given an index (i,j,etc), returns a value.
Definition: arithmetic.h:19
Represents a const LowerMatrixRange.
Definition: conjugate.h:34
int N1
---------— Data members, all public ----------------—
Definition: LowerMatrixRange.h:159