1 /*
2 Copyright 2009 Andreas Biegert
3
4 This file is part of the CS-BLAST package.
5
6 The CS-BLAST package is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 The CS-BLAST package is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef CS_MATRIX_H_
21 #define CS_MATRIX_H_
22
23 #include <numeric>
24 #include <algorithm>
25 #include <iomanip>
26
27
28 template <class T>
29 class Matrix {
30 public:
31 typedef T value_type;
32
33 Matrix();
34 Matrix(size_t n, size_t m);
35 Matrix(size_t n, size_t m, const T &a);
36 Matrix(size_t n, size_t m, const T *a);
37 Matrix(const Matrix &rhs);
38 ~Matrix();
39
40 Matrix & operator=(const Matrix &rhs);
41 T* operator[](const size_t i);
42 const T* operator[](const size_t i) const;
43 size_t nrows() const;
44 size_t ncols() const;
45 void Resize(size_t newn, size_t newm);
46 void Assign(size_t newn, size_t newm, const T &a);
begin()47 T* begin() { return *v; }
begin()48 const T* begin() const { return *v; }
49
50 private:
51 size_t nn;
52 size_t mm;
53 T **v;
54 };
55
56 template <class T>
Matrix()57 Matrix<T>::Matrix() : nn(0), mm(0), v(NULL) {}
58
59 template <class T>
Matrix(size_t n,size_t m)60 Matrix<T>::Matrix(size_t n, size_t m) : nn(n), mm(m), v(n>0 ? new T*[n] : NULL) {
61 size_t i,nel=m*n;
62 if (v) v[0] = nel>0 ? new T[nel] : NULL;
63 for (i=1;i<n;i++) v[i] = v[i-1] + m;
64 }
65
66 template <class T>
Matrix(size_t n,size_t m,const T & a)67 Matrix<T>::Matrix(size_t n, size_t m, const T &a) : nn(n), mm(m), v(n>0 ? new T*[n] : NULL) {
68 size_t i,j,nel=m*n;
69 if (v) v[0] = nel>0 ? new T[nel] : NULL;
70 for (i=1; i< n; i++) v[i] = v[i-1] + m;
71 for (i=0; i< n; i++) for (j=0; j<m; j++) v[i][j] = a;
72 }
73
74 template <class T>
Matrix(size_t n,size_t m,const T * a)75 Matrix<T>::Matrix(size_t n, size_t m, const T *a) : nn(n), mm(m), v(n>0 ? new T*[n] : NULL) {
76 size_t i,j,nel=m*n;
77 if (v) v[0] = nel>0 ? new T[nel] : NULL;
78 for (i=1; i< n; i++) v[i] = v[i-1] + m;
79 for (i=0; i< n; i++) for (j=0; j<m; j++) v[i][j] = *a++;
80 }
81
82 template <class T>
Matrix(const Matrix & rhs)83 Matrix<T>::Matrix(const Matrix &rhs) : nn(rhs.nn), mm(rhs.mm), v(nn>0 ? new T*[nn] : NULL) {
84 size_t i,j,nel=mm*nn;
85 if (v) v[0] = nel>0 ? new T[nel] : NULL;
86 for (i=1; i< nn; i++) v[i] = v[i-1] + mm;
87 for (i=0; i< nn; i++) for (j=0; j<mm; j++) v[i][j] = rhs[i][j];
88 }
89
90 template <class T>
91 Matrix<T> & Matrix<T>::operator=(const Matrix<T> &rhs) {
92 if (this != &rhs) {
93 size_t i,j,nel;
94 if (nn != rhs.nn || mm != rhs.mm) {
95 if (v != NULL) {
96 delete[] (v[0]);
97 delete[] (v);
98 }
99 nn=rhs.nn;
100 mm=rhs.mm;
101 v = nn>0 ? new T*[nn] : NULL;
102 nel = mm*nn;
103 if (v) v[0] = nel>0 ? new T[nel] : NULL;
104 for (i=1; i< nn; i++) v[i] = v[i-1] + mm;
105 }
106 for (i=0; i< nn; i++) for (j=0; j<mm; j++) v[i][j] = rhs[i][j];
107 }
108 return *this;
109 }
110
111 template <class T>
112 inline T* Matrix<T>::operator[](const size_t i) {
113 #ifdef CHECKBOUNDS
114 if (i<0 || i>=nn) {
115 throw Exception("Matrix subscript out of bounds");
116 }
117 #endif
118 return v[i];
119 }
120
121 template <class T>
122 inline const T* Matrix<T>::operator[](const size_t i) const {
123 #ifdef CHECKBOUNDS
124 if (i<0 || i>=nn) {
125 throw Excpetion("Matrix subscript out of bounds");
126 }
127 #endif
128 return v[i];
129 }
130
131 template <class T>
nrows()132 inline size_t Matrix<T>::nrows() const {
133 return nn;
134 }
135
136 template <class T>
ncols()137 inline size_t Matrix<T>::ncols() const {
138 return mm;
139 }
140
141 template <class T>
Resize(size_t newn,size_t newm)142 void Matrix<T>::Resize(size_t newn, size_t newm) {
143 size_t i,nel;
144 if (newn != nn || newm != mm) {
145 if (v != NULL) {
146 delete[] (v[0]);
147 delete[] (v);
148 }
149 nn = newn;
150 mm = newm;
151 v = nn>0 ? new T*[nn] : NULL;
152 nel = mm*nn;
153 if (v) v[0] = nel>0 ? new T[nel] : NULL;
154 for (i=1; i< nn; i++) v[i] = v[i-1] + mm;
155 }
156 }
157
158 template <class T>
Assign(size_t newn,size_t newm,const T & a)159 void Matrix<T>::Assign(size_t newn, size_t newm, const T& a) {
160 size_t i,j,nel;
161 if (newn != nn || newm != mm) {
162 if (v != NULL) {
163 delete[] (v[0]);
164 delete[] (v);
165 }
166 nn = newn;
167 mm = newm;
168 v = nn>0 ? new T*[nn] : NULL;
169 nel = mm*nn;
170 if (v) v[0] = nel>0 ? new T[nel] : NULL;
171 for (i=1; i< nn; i++) v[i] = v[i-1] + mm;
172 }
173 for (i=0; i< nn; i++) for (j=0; j<mm; j++) v[i][j] = a;
174 }
175
176 template <class T>
~Matrix()177 Matrix<T>::~Matrix() {
178 if (v != NULL) {
179 delete[] (v[0]);
180 delete[] (v);
181 }
182 }
183
184 // Assigns given constant value or default to all entries in matrix
185 template<class T>
186 inline void Assign(Matrix<T>& m, T val = T()) {
187 for (size_t i = 0; i < m.nrows(); ++i)
188 for (size_t j = 0; j < m.ncols(); ++j)
189 m[i][j] = val;
190 }
191
192 // Prints profile in human-readable format for debugging.
193 template<class T>
194 std::ostream& operator<< (std::ostream& out, const Matrix<T>& m) {
195 out << "Matrix" << std::endl;
196 for (size_t j = 0; j < m.ncols(); ++j)
197 out << "\t" << j;
198 out << std::endl;
199 for (size_t i = 0; i < m.nrows(); ++i) {
200 out << i;
201 for (size_t j = 0; j < m.ncols(); ++j)
202 out << "\t" << std::setprecision(4) << m[i][j];
203 out << std::endl;
204 }
205 return out;
206 }
207
208 #endif // CS_MATRIX_H_
209