MyraMath
SparseMatrix.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_SPARSE_SPARSEMATRIX_H
7 #define MYRAMATH_SPARSE_SPARSEMATRIX_H
8 
14 #include <myramath/utility/detail/LIBPUBLIC.h>
16 
18 
19 #include <utility>
20 #include <vector>
21 #include <iosfwd>
22 
23 namespace myra {
24 
25 // Forward declarations.
26 class InputStream;
27 class OutputStream;
28 template<int Arity, class Number> class Expression;
29 template<class Number> class Matrix;
30 template<class Number> class MatrixRange;
31 template<class Number> class SparseMatrix;
32 template<class Number> class SparseMatrixBuilder;
33 class Pattern;
34 class PatternRange;
35 template<class T> class Array1;
36 template<class T> class Array2;
37 
38 namespace detail {
39 
40 // Some of these functions can be implemented more efficiently with access to internal
41 // data structures, they're forward declared here so they can be granted friendship later.
42 class permute_wrapper;
43 class horzcat_wrapper;
44 class vertcat_wrapper;
45 class bothcat_wrapper;
46 class diagcat_wrapper;
47 class transpose_wrapper;
48 class multiply_wrapper;
49 class flip_wrapper;
50 
51 } // namespace detail
52 
54 template<class Number> class LIBPUBLIC SparseMatrix
55  {
56  public:
57 
59  typedef std::pair< CSparseMatrixRange<Number>, CSparseMatrixRange<Number> > CPair;
60  typedef std::pair< SparseMatrixRange<Number>, SparseMatrixRange<Number> > Pair;
61 
62  // ------------------------------------ Construction, serialization, value semantics.
63 
65  SparseMatrix();
66 
68  explicit SparseMatrix(const PatternRange& P);
69 
71  SparseMatrix(const SparseMatrix& that);
72 
74  void swap(SparseMatrix& that);
75  void swap(Pattern& that);
76 
77 #ifdef MYRAMATH_ENABLE_CPP11
78  SparseMatrix(SparseMatrix&& that);
80  SparseMatrix(Pattern&& that);
81 #endif
82 
84  SparseMatrix& operator = (SparseMatrix that);
85 
87  explicit SparseMatrix(const CSparseMatrixRange<Number>& that);
88 
90  explicit SparseMatrix(InputStream& in);
91 
93  void write(OutputStream& out) const;
94 
96  const SparseMatrix<Number>& add_const() const;
97 
99  ~SparseMatrix();
100 
101  // ------------------------------------ Size and pattern queries.
102 
104  std::pair<int,int> size() const;
105 
107  int n_nonzeros() const;
108 
110  int n_nonzeros(int j) const;
111 
113  bool test(int i, int j) const;
114 
116  PatternRange pattern() const;
117 
119  std::vector<int> pattern(int j) const;
120 
121  // ------------------------------------ General slicing.
122 
124  CSparseMatrixRange<Number> range() const;
126  SparseMatrixRange<Number> range() ;
128 
130  operator CSparseMatrixRange<Number> () const;
132  operator SparseMatrixRange<Number> () ;
134 
136  CSparseMatrixRange<Number> window(int i0, int i1, int j0, int j1) const;
138  SparseMatrixRange<Number> window(int i0, int i1, int j0, int j1) ;
140 
142  Array2<CSparseMatrixRange<Number> > windows(const intCRange& i, const intCRange& j) const;
144  Array2< SparseMatrixRange<Number> > windows(const intCRange& i, const intCRange& j) ;
146 
148  const Number* pointer(int i, int j) const;
150  Number* pointer(int i, int j) ;
152 
154  const Number& operator() (int i, int j) const;
156  Number& operator() (int i, int j) ;
158 
160  const Number& at(int i, int j) const;
162  Number& at(int i, int j) ;
164 
165  // ------------------------------------ Iterating.
166 
168  CSparseMatrixIterator<Number> begin() const;
170  CSparseMatrixIterator<Number> end () const;
174 
176  CSparseMatrixIterator<Number> begin(int j) const;
178  CSparseMatrixIterator<Number> end (int j) const;
179  SparseMatrixIterator<Number> begin(int j) ;
180  SparseMatrixIterator<Number> end (int j) ;
182 
183  // ------------------------------------ Row slicing.
184 
186  CSparseMatrixRange<Number> row(int i) const;
188  SparseMatrixRange<Number> row(int i) ;
190 
192  CSparseMatrixRange<Number> rows(int i0, int i1) const;
194  SparseMatrixRange<Number> rows(int i0, int i1) ;
196 
198  CSparseMatrixRange<Number> top(int i) const;
200  SparseMatrixRange<Number> top(int i) ;
202 
204  CSparseMatrixRange<Number> cut_top(int i) const;
206  SparseMatrixRange<Number> cut_top(int i) ;
208 
210  CPair split_top(int i) const;
212  Pair split_top(int i) ;
214 
216  CSparseMatrixRange<Number> bottom(int i) const;
218  SparseMatrixRange<Number> bottom(int i) ;
220 
222  CSparseMatrixRange<Number> cut_bottom(int i) const;
224  SparseMatrixRange<Number> cut_bottom(int i) ;
226 
228  CPair split_bottom(int i) const;
230  Pair split_bottom(int i) ;
232 
234  Array1<CSparseMatrixRange<Number> > rows(const intCRange& i) const;
238 
239  // ------------------------------------ Column slicing.
240 
242  CSparseMatrixRange<Number> column(int j) const;
244  SparseMatrixRange<Number> column(int i) ;
246 
248  CSparseMatrixRange<Number> columns(int j0, int j1) const;
250  SparseMatrixRange<Number> columns(int j0, int j1) ;
252 
254  CSparseMatrixRange<Number> left(int j) const;
256  SparseMatrixRange<Number> left(int j) ;
258 
260  CSparseMatrixRange<Number> cut_left(int j) const;
262  SparseMatrixRange<Number> cut_left(int j) ;
264 
266  CPair split_left(int j) const;
268  Pair split_left(int j) ;
270 
272  CSparseMatrixRange<Number> right(int j) const;
274  SparseMatrixRange<Number> right(int j) ;
276 
278  CSparseMatrixRange<Number> cut_right(int j) const;
280  SparseMatrixRange<Number> cut_right(int j) ;
282 
284  CPair split_right(int j) const;
286  Pair split_right(int j) ;
288 
290  Array1<CSparseMatrixRange<Number> > columns(const intCRange& j) const;
292  Array1< SparseMatrixRange<Number> > columns(const intCRange& j) ;
294 
295  // ------------------------------------ Manipulating numeric contents.
296 
298  // Functor f should be a have an operator(), that takes a Number and returns a Number.
299  template<class Functor> void transform(const Functor& f)
300  { this->range().transform(f); }
301 
303  // Functor f should be a have an operator(), that takes a Number and returns a Number.
304  template<class Functor> void transform_triangle(const Functor& f, char uplo)
305  { this->range().transform_triangle(f,uplo); }
306 
308  // Functor f should be a have an operator(), that takes a Number and returns a Number.
309  template<class Functor> void transform_diagonal(const Functor& f)
310  { this->range().transform_diagonal(f); }
311 
313  SparseMatrix& operator = (const CSparseMatrixRange<Number>& that);
314 
316  void operator *= (Number alpha);
317 
319  void operator /= (Number alpha);
320 
322  SparseMatrix<Number> operator -();
323 
324  // ------------------------------------ Static generators.
325 
327  static SparseMatrix<Number> identity(int IJ);
328 
330  static SparseMatrix<Number> random(int I, int J, int N);
331 
333  static SparseMatrix<Number> random(const PatternRange& P);
334 
336  static SparseMatrix<Number> zeros(int I, int J);
337 
339  static SparseMatrix<Number> zeros(const PatternRange& P);
340 
342  static SparseMatrix<Number> ones(const PatternRange& P);
343 
345  static SparseMatrix<Number> fill(const PatternRange& P, Number c);
346 
348  static SparseMatrix<Number> fill(const intCRange& i, const intCRange& j, const std::vector<Number>& v);
349 
351  static SparseMatrix<Number> swap(int I, int J, std::vector<int>& Ao, std::vector<int>& Ai, std::vector<Number>& Av);
352 
354  static SparseMatrix<Number> evaluate(const PatternRange& P, const Expression<2,Number>& e);
355 
357  Matrix<Number> make_Matrix() const;
359  void make_Matrix(const MatrixRange<Number>& A) const;
361 
363  void debug(std::ostream& out) const;
364 
365  private:
366 
367  // Returns offset to *this A(i,j). Returns -1 if (i,j) is a structural zero. Throws if (i,j) are out of (I,J) bounds.
368  int offset(int i, int j) const;
369 
370  // Stores size.
371  int I;
372  int J;
373 
374  // Stores offsets for each column of A.
375  std::vector<int> Ao;
376 
377  // Holds row indices (i). The sorted i-pattern of column A(:,j) is given by Ai[Ao[j]:Ao[j+1]]
378  std::vector<int> Ai;
379 
380  // Holds numeric values (v). The numeric values of column A(:,j) are given by Av[Ao[j]:Ao[j+1]]
381  std::vector<Number> Av;
382 
383  // Nonmember friend functions that are granted access to internal data structures.
384  friend class SparseMatrixBuilder<Number>;
385  friend class detail::permute_wrapper;
386  friend class detail::horzcat_wrapper;
387  friend class detail::vertcat_wrapper;
388  friend class detail::bothcat_wrapper;
389  friend class detail::diagcat_wrapper;
390  friend class detail::transpose_wrapper;
391  friend class detail::multiply_wrapper;
392  friend class detail::flip_wrapper;
393  };
394 
396 template<class Number> class ReflectNumber< SparseMatrix<Number> >
397  { public: typedef Number type; };
398 
400 LIBPUBLIC SparseMatrix<NumberS> operator + (const CSparseMatrixRange<NumberS>& A, const CSparseMatrixRange<NumberS>& B);
402 LIBPUBLIC SparseMatrix<NumberD> operator + (const CSparseMatrixRange<NumberD>& A, const CSparseMatrixRange<NumberD>& B);
403 LIBPUBLIC SparseMatrix<NumberC> operator + (const CSparseMatrixRange<NumberC>& A, const CSparseMatrixRange<NumberC>& B);
404 LIBPUBLIC SparseMatrix<NumberZ> operator + (const CSparseMatrixRange<NumberZ>& A, const CSparseMatrixRange<NumberZ>& B);
406 
408 LIBPUBLIC SparseMatrix<NumberS> operator - (const CSparseMatrixRange<NumberS>& A, const CSparseMatrixRange<NumberS>& B);
410 LIBPUBLIC SparseMatrix<NumberD> operator - (const CSparseMatrixRange<NumberD>& A, const CSparseMatrixRange<NumberD>& B);
411 LIBPUBLIC SparseMatrix<NumberC> operator - (const CSparseMatrixRange<NumberC>& A, const CSparseMatrixRange<NumberC>& B);
412 LIBPUBLIC SparseMatrix<NumberZ> operator - (const CSparseMatrixRange<NumberZ>& A, const CSparseMatrixRange<NumberZ>& B);
414 
416 LIBPUBLIC SparseMatrix<NumberS> operator * (NumberS alpha, const CSparseMatrixRange<NumberS>& A);
418 LIBPUBLIC SparseMatrix<NumberD> operator * (NumberD alpha, const CSparseMatrixRange<NumberD>& A);
419 LIBPUBLIC SparseMatrix<NumberC> operator * (NumberC alpha, const CSparseMatrixRange<NumberC>& A);
420 LIBPUBLIC SparseMatrix<NumberZ> operator * (NumberZ alpha, const CSparseMatrixRange<NumberZ>& A);
422 
424 LIBPUBLIC SparseMatrix<NumberS> operator * (const CSparseMatrixRange<NumberS>& A, NumberS alpha);
426 LIBPUBLIC SparseMatrix<NumberD> operator * (const CSparseMatrixRange<NumberD>& A, NumberD alpha);
427 LIBPUBLIC SparseMatrix<NumberC> operator * (const CSparseMatrixRange<NumberC>& A, NumberC alpha);
428 LIBPUBLIC SparseMatrix<NumberZ> operator * (const CSparseMatrixRange<NumberZ>& A, NumberZ alpha);
430 
434 LIBPUBLIC SparseMatrix<NumberZ> make_complex(const CSparseMatrixRange<NumberD>& A);
436 
438 LIBPUBLIC SparseMatrix<NumberC> make_complex(const CSparseMatrixRange<NumberS>& R, const CSparseMatrixRange<NumberS>& I);
440 LIBPUBLIC SparseMatrix<NumberZ> make_complex(const CSparseMatrixRange<NumberD>& R, const CSparseMatrixRange<NumberD>& I);
442 
444 LIBPUBLIC SparseMatrix<NumberS> realpart(const CSparseMatrixRange<NumberC>& A);
446 LIBPUBLIC SparseMatrix<NumberD> realpart(const CSparseMatrixRange<NumberZ>& A);
448 
450 LIBPUBLIC SparseMatrix<NumberS> imagpart(const CSparseMatrixRange<NumberC>& A);
452 LIBPUBLIC SparseMatrix<NumberD> imagpart(const CSparseMatrixRange<NumberZ>& A);
454 
455 } // namespace myra
456 
457 #endif
Container of values, allows random (i,j) access.
Definition: Array2.h:30
Number random()
Generate random real/complex Numbers, uniformly distributed over [-1,1].
Reflects Number trait for a Container, containers of Numbers (Matrix&#39;s, Vector&#39;s, etc) should special...
Definition: Number.h:55
Represents a mutable SparseMatrixRange.
Definition: conjugate.h:21
Definition: bothcat.cpp:20
std::pair< CSparseMatrixRange< Number >, CSparseMatrixRange< Number > > CPair
Useful typedefs.
Definition: SparseMatrix.h:59
void transform_triangle(const Functor &f, char uplo)
Overwrites every A(i,j) in the &#39;U&#39;pper or &#39;L&#39;ower triangle of this SparseMatrix with f(A(i...
Definition: SparseMatrix.h:304
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
Definition: multiply.cpp:22
void transform(const Functor &f)
Overwrites every A(i,j) in this SparseMatrix with f(A(i,j)).
Definition: SparseMatrix.h:299
Definition: syntax.dox:1
An iterator over a SparseMatrixRange.
Definition: SparseMatrixRange.h:33
Represents an immutable view of a Pattern.
Definition: PatternRange.h:31
Definition: random.cpp:45
Abstraction layer, serializable objects write themselves to these.
Definition: Streams.h:39
Definition: flip.cpp:18
Various utility functions/classes related to scalar Number types.
Represents a mutable MatrixRange.
Definition: conjugate.h:26
Abstraction layer, deserializable objects read themselves from these.
Definition: Streams.h:47
Definition: diagcat.cpp:20
void transform_diagonal(const Functor &f)
Overwrites every A(ij,ij) on the diagonal of this SparseMatrix with f(A(ij,ij)).
Definition: SparseMatrix.h:309
Represents a const SparseMatrixRange.
Definition: bothcat.h:24
Holds the nonzero pattern of a sparse matrix.
Definition: Pattern.h:55
Like SparseMatrix, but easier to populate via random access (i,j) operator.
Definition: SparseMatrix.h:32
Container of values, allows random (i) access.
Definition: Array1.h:32
An iterator over a CSparseMatrixRange.
Definition: SparseMatrixRange.h:32
Expression< 1, NumberC > make_complex(const Expression< 1, NumberS > &A)
Promotes a real Expression into a complex one.
Definition: functions_complex.cpp:122
Given an index (i,j,etc), returns a value.
Definition: arithmetic.h:19
Definition: horzcat.cpp:20
Stores an IxJ matrix A in compressed sparse column format.
Definition: bothcat.h:23
Definition: permute.cpp:29
Definition: vertcat.cpp:20
Represents a const intRange.
Definition: intRange.h:142
Range/Iterator types associated with SparseMatrix.
Definition: transpose.cpp:23
float NumberS
Useful typedefs.
Definition: Number.h:21