forked from chienchi/FaQCs
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmatrix.h
150 lines (116 loc) · 3.02 KB
/
matrix.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#ifndef __MATRIX
#define __MATRIX
#include <vector>
template <class T>
class matrix : private std::vector<T>
{
private:
size_t num_row;
size_t num_col;
public:
matrix()
{
num_row = 0;
num_col = 0;
};
matrix(const size_t &m_num_row, const size_t &m_num_col)
{
matrix::resize(m_num_row, m_num_col);
};
void resize(const size_t &m_num_row, const size_t &m_num_col)
{
num_row = m_num_row;
num_col = m_num_col;
std::vector<T>::resize(num_row*num_col);
};
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
inline iterator begin()
{
return std::vector<T>::begin();
};
inline const_iterator begin() const
{
return std::vector<T>::begin();
};
inline iterator end()
{
return std::vector<T>::end();
};
inline const_iterator end() const
{
return std::vector<T>::end();
};
inline T& operator()(const size_t &m_r, const size_t &m_c)
{
return (*this)[m_r*num_col + m_c];
};
inline const T& operator()(const size_t &m_r, const size_t &m_c) const
{
return (*this)[m_r*num_col + m_c];
};
inline size_t get_num_row() const
{
return num_row;
};
inline size_t get_num_col() const
{
return num_col;
};
// Return the selected row
inline std::vector<T> row(const size_t &m_index) const
{
if(m_index >= num_row){
throw __FILE__ ":matrix::row: index out of bounds";
}
std::vector<T> ret(num_col);
const size_t offset = m_index*num_col;
for(size_t i = 0;i < num_col;++i){
ret[i] = (*this)[offset + i];
}
return ret;
};
inline std::vector<T> column(const size_t &m_index) const
{
if(m_index >= num_col){
throw __FILE__ ":matrix::column: index out of bounds";
}
std::vector<T> ret(num_row);
size_t offset = m_index;
for(size_t i = 0;i < num_row;++i, offset += num_col){
ret[i] = (*this)[offset];
}
return ret;
};
matrix& operator+=(const matrix &m_rhs)
{
// The right hand side can have fewer rows, but it must
// have the same number of *columns* (unless the current
// matrix is empty). The reason for this is that the matricies
// are packed by column. We rely on the vector::resize function
// to correctly preserve the old matrix contents.
if( (num_col == 0) || (num_row == 0) ){ // left hand size is empty
resize(m_rhs.num_row, m_rhs.num_col);
}
else{
// The left hand matrix (i.e. the destination) is allowed to
// dynamically grow to accomodate additional rows).
if(num_row < m_rhs.num_row){
if(num_col != m_rhs.num_col){
throw __FILE__ ":matrix::operator+=: Unequal number of columns!";
}
resize(m_rhs.num_row, num_col);
}
}
const size_t len = m_rhs.size();
for(size_t i = 0;i < len;++i){
(*this)[i] += m_rhs[i];
}
return *this;
};
inline void reserve(const size_t &m_r, const size_t &m_c)
{
std::vector<T>::reserve(m_r*m_c);
};
};
#endif // __MATRIX