base_matrix.hpp 5.38 KB
Newer Older
1
// Software License for MTL
2
//
3
4
5
6
7
// Copyright (c) 2007 The Trustees of Indiana University.
//               2008 Dresden University of Technology and the Trustees of Indiana University.
//               2010 SimuNova UG (haftungsbeschränkt), www.simunova.com.
// All rights reserved.
// Authors: Peter Gottschling and Andrew Lumsdaine
8
//
9
// This file is part of the Matrix Template Library
10
//
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// See also license.mtl.txt in the distribution.

#ifndef MTL_BASE_MATRIX_INCLUDE
#define MTL_BASE_MATRIX_INCLUDE

#include <algorithm>
#include <boost/static_assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/numeric/mtl/matrix/dimension.hpp>
#include <boost/numeric/mtl/detail/index.hpp>
#include <boost/numeric/mtl/utility/tag.hpp>
#include <boost/numeric/mtl/utility/exception.hpp>
#include <boost/numeric/mtl/utility/is_static.hpp>

namespace mtl { namespace matrix {
26

27
28
/// Base class for other matrices, contains only very simple functionality that is used in all matrices.
template <class Elt, class Parameters>
29
struct base_matrix
30
31
32
33
34
35
36
37
38
39
40
41
{
    typedef base_matrix                       self;
    typedef Elt                               value_type;
    typedef typename Parameters::orientation  orientation;
    typedef typename Parameters::index        index_type;
    typedef typename Parameters::dimensions   dim_type;
    static bool const                         on_stack= Parameters::on_stack;
    typedef typename Parameters::size_type    size_type;
  protected:
    dim_type                        dim;       ///< # of rows and columns
    size_type                       my_nnz;    ///< # of non-zeros, to be set by derived matrix
    typedef mtl::traits::is_static<dim_type>       static_bool;
42

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  public:
    base_matrix(size_type n= 0) :  my_nnz(n) {}

    /// Setting dimension
    explicit base_matrix(mtl::non_fixed::dimensions d, size_type n= 0) : dim(d), my_nnz(n) {}

	///	Swap base matrix
    friend void swap(self& x, self& y)
    {
	using std::swap;
	swap(x.my_nnz, y.my_nnz);
	swap(x.dim, y.dim);
    }

    /// Either matrix to be changed is uninitialized (i.e. 0x0) or dimensions are equal
    /** The matrices with dimension 0 x 0 are considered like stem cells: they can still
	change into an arbitrary dimension and are compatible with any other matrix.  Once a matrix has a non-trivial dimension
	it can be only changed explicitly and is only compatible with matrices of the same dimensionality. **/
    void check_dim(size_type MTL_DEBUG_ARG(num_rows), size_type MTL_DEBUG_ARG(num_cols)) const
    {
	MTL_DEBUG_THROW_IF(this->num_rows() * this->num_cols() != 0
			   && (this->num_rows() != num_rows || this->num_cols() != num_cols),
			   incompatible_size());
    }

#if 0
    /** Will fail for fixed::dimension **/
    void change_dim(mtl::non_fixed::dimensions d) { dim= d; }

72
    template <std::size_t Rows, std::size_t Cols>
73
74
75
    void change_dim(mtl::fixed::dimensions<Rows, Cols> d) {}
#endif

76
77
    void change_dim(size_type r, size_type c, boost::mpl::false_) { dim= dim_type(r, c); }
    void change_dim(size_type r, size_type c, boost::mpl::true_) { check_dim(r, c); }
78

79
    void change_dim(size_type r, size_type c) {	change_dim(r, c, static_bool()); }
80
81
82

public:
    /// Number of rows
83
    size_type num_rows() const
84
85
86
87
    {
      return dim.num_rows();
    }
    /// First row taking indexing into account
88
    size_type begin_row() const
89
90
91
92
    {
      return index::change_to(index_type(), 0);
    }
    /// Past-end row taking indexing into account
93
    size_type end_row() const
94
95
96
97
98
    {
      return index::change_to(index_type(), num_rows());
    }

    /// number of colums
99
    size_type num_cols() const
100
101
102
103
    {
      return dim.num_cols();
    }
    /// First column taking indexing into account
104
    size_type begin_col() const
105
106
107
108
    {
      return index::change_to(index_type(), 0);
    }
    /// Past-end column taking indexing into account
109
    size_type end_col() const
110
111
112
113
114
115
116
117
118
119
120
121
    {
      return index::change_to(index_type(), num_cols());
    }

    /// Number of non-zeros
    size_type nnz() const
    {
      return my_nnz;
    }

  protected:
    // dispatched functions for major dimension
122
    size_type dim1(row_major) const
123
124
125
    {
      return num_rows();
    }
126
    size_type dim1(col_major) const
127
128
129
130
131
    {
      return num_cols();
    }

    // dispatched functions for minor dimension
132
    size_type dim2(row_major) const
133
134
135
    {
      return num_cols();
    }
136
    size_type dim2(col_major) const
137
138
139
    {
      return num_rows();
    }
140

141
142
143
144
    // Dispatched functions for major
    // Trailing _ due to conflicts with macro major
    size_type major_(size_type r, size_type, row_major) const
    {
145
	return r;
146
147
148
    }
    size_type major_(size_type, size_type c, col_major) const
    {
149
150
	return c;
    }
151
152
153

  public:
    /// Major dimension
154
    size_type dim1() const
155
156
157
158
159
    {
      return dim1(orientation());
    }

    /// Minor dimension
160
    size_type dim2() const
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    {
      return dim2(orientation());
    }

    // Returns the row for row_major otherwise the column
    // Trailing _ due to conflicts with macro major
    size_type major_(size_type r, size_type c) const
    {
	return major_(r, c, orientation());
    }

    // Returns the row for col_major otherwise the column
    // Trailing _ for consistency with major
    size_type minor_(size_type r, size_type c) const
    {
	return major_(c, r, orientation());
    }
178

179
    // returns copy of dim
180
    dim_type get_dimensions() const
181
    {
182
183
      return dim;
    }
184
185
186
187
188
189
190
};



}} // namespace mtl::matrix

#endif // MTL_BASE_MATRIX_INCLUDE