IT++ Logo
mat.cpp
Go to the documentation of this file.
1
29#include <itpp/base/mat.h>
30
31#ifndef _MSC_VER
32# include <itpp/config.h>
33#else
34# include <itpp/config_msvc.h>
35#endif
36
37#if defined (HAVE_BLAS)
38# include <itpp/base/blas.h>
39#endif
40
42
43namespace itpp
44{
45
46template<>
47cmat cmat::hermitian_transpose() const
48{
49 cmat temp(no_cols, no_rows);
50 for (int i = 0; i < no_rows; i++)
51 for (int j = 0; j < no_cols; j++)
52 temp(j, i) = std::conj(operator()(i,j));
53
54 return temp;
55}
56
57
58// -------- Multiplication operator -------------
59
60#if defined(HAVE_BLAS)
61
62template<>
63mat& mat::operator*=(const mat &m)
64{
65 it_assert_debug(no_cols == m.no_rows, "mat::operator*=(): Wrong sizes");
66 mat r(no_rows, m.no_cols); // unnecessary memory??
67 double alpha = 1.0;
68 double beta = 0.0;
69 char trans = 'n';
70 blas::dgemm_(&trans, &trans, &no_rows, &m.no_cols, &no_cols, &alpha, data,
71 &no_rows, m.data, &m.no_rows, &beta, r.data, &r.no_rows);
72 operator=(r); // time consuming
73 return *this;
74}
75
76template<>
77cmat& cmat::operator*=(const cmat &m)
78{
79 it_assert_debug(no_cols == m.no_rows, "cmat::operator*=(): Wrong sizes");
80 cmat r(no_rows, m.no_cols); // unnecessary memory??
81 std::complex<double> alpha = std::complex<double>(1.0);
82 std::complex<double> beta = std::complex<double>(0.0);
83 char trans = 'n';
84 blas::zgemm_(&trans, &trans, &no_rows, &m.no_cols, &no_cols, &alpha, data,
85 &no_rows, m.data, &m.no_rows, &beta, r.data, &r.no_rows);
86 operator=(r); // time consuming
87 return *this;
88}
89#else
90template<>
91mat& mat::operator*=(const mat &m)
92{
93 it_assert_debug(no_cols == m.no_rows, "Mat<>::operator*=(): Wrong sizes");
94 mat r(no_rows, m.no_cols);
95 int r_pos = 0, pos = 0, m_pos = 0;
96
97 for (int i = 0; i < r.no_cols; i++) {
98 for (int j = 0; j < r.no_rows; j++) {
99 double tmp = 0.0;
100 pos = 0;
101 for (int k = 0; k < no_cols; k++) {
102 tmp += data[pos+j] * m.data[m_pos+k];
103 pos += no_rows;
104 }
105 r.data[r_pos+j] = tmp;
106 }
107 r_pos += r.no_rows;
108 m_pos += m.no_rows;
109 }
110 operator=(r); // time consuming
111 return *this;
112}
113
114template<>
115cmat& cmat::operator*=(const cmat &m)
116{
117 it_assert_debug(no_cols == m.no_rows, "Mat<>::operator*=(): Wrong sizes");
118 cmat r(no_rows, m.no_cols);
119 int r_pos = 0, pos = 0, m_pos = 0;
120
121 for (int i = 0; i < r.no_cols; i++) {
122 for (int j = 0; j < r.no_rows; j++) {
123 std::complex<double> tmp(0.0);
124 pos = 0;
125 for (int k = 0; k < no_cols; k++) {
126 tmp += data[pos+j] * m.data[m_pos+k];
127 pos += no_rows;
128 }
129 r.data[r_pos+j] = tmp;
130 }
131 r_pos += r.no_rows;
132 m_pos += m.no_rows;
133 }
134 operator=(r); // time consuming
135 return *this;
136}
137#endif // HAVE_BLAS
138
139
140#if defined(HAVE_BLAS)
141template<>
142mat operator*(const mat &m1, const mat &m2)
143{
144 it_assert_debug(m1.cols() == m2.rows(), "mat::operator*(): Wrong sizes");
145 int m1_r = m1.rows(); int m1_c = m1.cols();
146 int m2_r = m2.rows(); int m2_c = m2.cols();
147 mat r(m1_r, m2_c);
148 double alpha = 1.0;
149 double beta = 0.0;
150 char trans = 'n';
151 blas::dgemm_(&trans, &trans, &m1_r, &m2_c, &m1_c, &alpha,
152 m1._data(), &m1_r, m2._data(), &m2_r, &beta, r._data(),
153 &m1_r);
154 return r;
155}
156
157template<>
158cmat operator*(const cmat &m1, const cmat &m2)
159{
160 it_assert_debug(m1.cols() == m2.rows(), "cmat::operator*(): Wrong sizes");
161 int m1_r = m1.rows(); int m1_c = m1.cols();
162 int m2_r = m2.rows(); int m2_c = m2.cols();
163 cmat r(m1_r, m2_c);
164 std::complex<double> alpha = std::complex<double>(1.0);
165 std::complex<double> beta = std::complex<double>(0.0);
166 char trans = 'n';
167 blas::zgemm_(&trans, &trans, &m1_r, &m2_c, &m1_c, &alpha,
168 m1._data(), &m1_r, m2._data(), &m2_r, &beta, r._data(),
169 &m1_r);
170 return r;
171}
172#else
173template<>
174mat operator*(const mat &m1, const mat &m2)
175{
176 it_assert_debug(m1.rows() == m2.cols(),
177 "Mat<>::operator*(): Wrong sizes");
178 mat r(m1.rows(), m2.cols());
179 double *tr = r._data();
180 const double *t1;
181 const double *t2 = m2._data();
182 for (int i = 0; i < r.cols(); i++) {
183 for (int j = 0; j < r.rows(); j++) {
184 double tmp = 0.0;
185 t1 = m1._data() + j;
186 for (int k = m1.cols(); k > 0; k--) {
187 tmp += *(t1) * *(t2++);
188 t1 += m1.rows();
189 }
190 *(tr++) = tmp;
191 t2 -= m2.rows();
192 }
193 t2 += m2.rows();
194 }
195 return r;
196}
197
198template<>
199cmat operator*(const cmat &m1, const cmat &m2)
200{
201 it_assert_debug(m1.cols() == m2.rows(),
202 "Mat<>::operator*(): Wrong sizes");
203 cmat r(m1.rows(), m2.cols());
204 std::complex<double> *tr = r._data();
205 const std::complex<double> *t1;
206 const std::complex<double> *t2 = m2._data();
207 for (int i = 0; i < r.cols(); i++) {
208 for (int j = 0; j < r.rows(); j++) {
209 std::complex<double> tmp(0.0);
210 t1 = m1._data() + j;
211 for (int k = m1.cols(); k > 0; k--) {
212 tmp += *(t1) * *(t2++);
213 t1 += m1.rows();
214 }
215 *(tr++) = tmp;
216 t2 -= m2.rows();
217 }
218 t2 += m2.rows();
219 }
220 return r;
221}
222#endif // HAVE_BLAS
223
224
225#if defined(HAVE_BLAS)
226template<>
227vec operator*(const mat &m, const vec &v)
228{
229 it_assert_debug(m.cols() == v.size(), "mat::operator*(): Wrong sizes");
230 int m_r = m.rows(); int m_c = m.cols();
231 vec r(m_r);
232 double alpha = 1.0;
233 double beta = 0.0;
234 char trans = 'n';
235 int incr = 1;
236 blas::dgemv_(&trans, &m_r, &m_c, &alpha, m._data(), &m_r,
237 v._data(), &incr, &beta, r._data(), &incr);
238 return r;
239}
240
241template<>
242cvec operator*(const cmat &m, const cvec &v)
243{
244 it_assert_debug(m.cols() == v.size(), "cmat::operator*(): Wrong sizes");
245 int m_r = m.rows(); int m_c = m.cols();
246 cvec r(m_r);
247 std::complex<double> alpha = std::complex<double>(1.0);
248 std::complex<double> beta = std::complex<double>(0.0);
249 char trans = 'n';
250 int incr = 1;
251 blas::zgemv_(&trans, &m_r, &m_c, &alpha, m._data(), &m_r,
252 v._data(), &incr, &beta, r._data(), &incr);
253 return r;
254}
255#else
256template<>
257vec operator*(const mat &m, const vec &v)
258{
259 it_assert_debug(m.cols() == v.size(),
260 "Mat<>::operator*(): Wrong sizes");
261 vec r(m.rows());
262 for (int i = 0; i < m.rows(); i++) {
263 r(i) = 0.0;
264 int m_pos = 0;
265 for (int k = 0; k < m.cols(); k++) {
266 r(i) += m._data()[m_pos+i] * v(k);
267 m_pos += m.rows();
268 }
269 }
270 return r;
271}
272
273template<>
274cvec operator*(const cmat &m, const cvec &v)
275{
276 it_assert_debug(m.cols() == v.size(),
277 "Mat<>::operator*(): Wrong sizes");
278 cvec r(m.rows());
279 for (int i = 0; i < m.rows(); i++) {
280 r(i) = std::complex<double>(0.0);
281 int m_pos = 0;
282 for (int k = 0; k < m.cols(); k++) {
283 r(i) += m._data()[m_pos+i] * v(k);
284 m_pos += m.rows();
285 }
286 }
287 return r;
288}
289#endif // HAVE_BLAS
290
291
292//---------------------------------------------------------------------
293// Instantiations
294//---------------------------------------------------------------------
295
296// class instantiations
297
298template class ITPP_EXPORT Mat<double>;
299template class ITPP_EXPORT Mat<std::complex<double> >;
300template class ITPP_EXPORT Mat<int>;
301template class ITPP_EXPORT Mat<short int>;
302template class ITPP_EXPORT Mat<bin>;
303
304// addition operators
305
306template ITPP_EXPORT mat operator+(const mat &m1, const mat &m2);
307template ITPP_EXPORT cmat operator+(const cmat &m1, const cmat &m2);
308template ITPP_EXPORT imat operator+(const imat &m1, const imat &m2);
309template ITPP_EXPORT smat operator+(const smat &m1, const smat &m2);
310template ITPP_EXPORT bmat operator+(const bmat &m1, const bmat &m2);
311
312template ITPP_EXPORT mat operator+(const mat &m, double t);
313template ITPP_EXPORT cmat operator+(const cmat &m, std::complex<double> t);
314template ITPP_EXPORT imat operator+(const imat &m, int t);
315template ITPP_EXPORT smat operator+(const smat &m, short t);
316template ITPP_EXPORT bmat operator+(const bmat &m, bin t);
317
318template ITPP_EXPORT mat operator+(double t, const mat &m);
319template ITPP_EXPORT cmat operator+(std::complex<double> t, const cmat &m);
320template ITPP_EXPORT imat operator+(int t, const imat &m);
321template ITPP_EXPORT smat operator+(short t, const smat &m);
322template ITPP_EXPORT bmat operator+(bin t, const bmat &m);
323
324// subraction operators
325
326template ITPP_EXPORT mat operator-(const mat &m1, const mat &m2);
327template ITPP_EXPORT cmat operator-(const cmat &m1, const cmat &m2);
328template ITPP_EXPORT imat operator-(const imat &m1, const imat &m2);
329template ITPP_EXPORT smat operator-(const smat &m1, const smat &m2);
330template ITPP_EXPORT bmat operator-(const bmat &m1, const bmat &m2);
331
332template ITPP_EXPORT mat operator-(const mat &m, double t);
333template ITPP_EXPORT cmat operator-(const cmat &m, std::complex<double> t);
334template ITPP_EXPORT imat operator-(const imat &m, int t);
335template ITPP_EXPORT smat operator-(const smat &m, short t);
336template ITPP_EXPORT bmat operator-(const bmat &m, bin t);
337
338template ITPP_EXPORT mat operator-(double t, const mat &m);
339template ITPP_EXPORT cmat operator-(std::complex<double> t, const cmat &m);
340template ITPP_EXPORT imat operator-(int t, const imat &m);
341template ITPP_EXPORT smat operator-(short t, const smat &m);
342template ITPP_EXPORT bmat operator-(bin t, const bmat &m);
343
344// unary minus
345
346template ITPP_EXPORT mat operator-(const mat &m);
347template ITPP_EXPORT cmat operator-(const cmat &m);
348template ITPP_EXPORT imat operator-(const imat &m);
349template ITPP_EXPORT smat operator-(const smat &m);
350template ITPP_EXPORT bmat operator-(const bmat &m);
351
352// multiplication operators
353
354template ITPP_EXPORT imat operator*(const imat &m1, const imat &m2);
355template ITPP_EXPORT smat operator*(const smat &m1, const smat &m2);
356template ITPP_EXPORT bmat operator*(const bmat &m1, const bmat &m2);
357
358template ITPP_EXPORT ivec operator*(const imat &m, const ivec &v);
359template ITPP_EXPORT svec operator*(const smat &m, const svec &v);
360template ITPP_EXPORT bvec operator*(const bmat &m, const bvec &v);
361
362template ITPP_EXPORT mat operator*(const mat &m, double t);
363template ITPP_EXPORT cmat operator*(const cmat &m, std::complex<double> t);
364template ITPP_EXPORT imat operator*(const imat &m, int t);
365template ITPP_EXPORT smat operator*(const smat &m, short t);
366template ITPP_EXPORT bmat operator*(const bmat &m, bin t);
367
368template ITPP_EXPORT mat operator*(double t, const mat &m);
369template ITPP_EXPORT cmat operator*(std::complex<double> t, const cmat &m);
370template ITPP_EXPORT imat operator*(int t, const imat &m);
371template ITPP_EXPORT smat operator*(short t, const smat &m);
372template ITPP_EXPORT bmat operator*(bin t, const bmat &m);
373
374// elementwise multiplication
375
376template ITPP_EXPORT mat elem_mult(const mat &m1, const mat &m2);
377template ITPP_EXPORT cmat elem_mult(const cmat &m1, const cmat &m2);
378template ITPP_EXPORT imat elem_mult(const imat &m1, const imat &m2);
379template ITPP_EXPORT smat elem_mult(const smat &m1, const smat &m2);
380template ITPP_EXPORT bmat elem_mult(const bmat &m1, const bmat &m2);
381
382template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2, mat &out);
383template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2, cmat &out);
384template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2, imat &out);
385template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2, smat &out);
386template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2, bmat &out);
387
388template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2,
389 const mat &m3, mat &out);
390template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2,
391 const cmat &m3, cmat &out);
392template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2,
393 const imat &m3, imat &out);
394template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2,
395 const smat &m3, smat &out);
396template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2,
397 const bmat &m3, bmat &out);
398
399template ITPP_EXPORT void elem_mult_out(const mat &m1, const mat &m2, const mat &m3,
400 const mat &m4, mat &out);
401template ITPP_EXPORT void elem_mult_out(const cmat &m1, const cmat &m2,
402 const cmat &m3, const cmat &m4, cmat &out);
403template ITPP_EXPORT void elem_mult_out(const imat &m1, const imat &m2,
404 const imat &m3, const imat &m4, imat &out);
405template ITPP_EXPORT void elem_mult_out(const smat &m1, const smat &m2,
406 const smat &m3, const smat &m4, smat &out);
407template ITPP_EXPORT void elem_mult_out(const bmat &m1, const bmat &m2,
408 const bmat &m3, const bmat &m4, bmat &out);
409
410template ITPP_EXPORT void elem_mult_inplace(const mat &m1, mat &m2);
411template ITPP_EXPORT void elem_mult_inplace(const cmat &m1, cmat &m2);
412template ITPP_EXPORT void elem_mult_inplace(const imat &m1, imat &m2);
413template ITPP_EXPORT void elem_mult_inplace(const smat &m1, smat &m2);
414template ITPP_EXPORT void elem_mult_inplace(const bmat &m1, bmat &m2);
415
416template ITPP_EXPORT double elem_mult_sum(const mat &m1, const mat &m2);
417template ITPP_EXPORT std::complex<double> elem_mult_sum(const cmat &m1, const cmat &m2);
418template ITPP_EXPORT int elem_mult_sum(const imat &m1, const imat &m2);
419template ITPP_EXPORT short elem_mult_sum(const smat &m1, const smat &m2);
420template ITPP_EXPORT bin elem_mult_sum(const bmat &m1, const bmat &m2);
421
422// division operator
423
424template ITPP_EXPORT mat operator/(double t, const mat &m);
425template ITPP_EXPORT cmat operator/(std::complex<double> t, const cmat &m);
426template ITPP_EXPORT imat operator/(int t, const imat &m);
427template ITPP_EXPORT smat operator/(short t, const smat &m);
428template ITPP_EXPORT bmat operator/(bin t, const bmat &m);
429
430template ITPP_EXPORT mat operator/(const mat &m, double t);
431template ITPP_EXPORT cmat operator/(const cmat &m, std::complex<double> t);
432template ITPP_EXPORT imat operator/(const imat &m, int t);
433template ITPP_EXPORT smat operator/(const smat &m, short t);
434template ITPP_EXPORT bmat operator/(const bmat &m, bin t);
435
436// elementwise division
437
438template ITPP_EXPORT mat elem_div(const mat &m1, const mat &m2);
439template ITPP_EXPORT cmat elem_div(const cmat &m1, const cmat &m2);
440template ITPP_EXPORT imat elem_div(const imat &m1, const imat &m2);
441template ITPP_EXPORT smat elem_div(const smat &m1, const smat &m2);
442template ITPP_EXPORT bmat elem_div(const bmat &m1, const bmat &m2);
443
444template ITPP_EXPORT void elem_div_out(const mat &m1, const mat &m2, mat &out);
445template ITPP_EXPORT void elem_div_out(const cmat &m1, const cmat &m2, cmat &out);
446template ITPP_EXPORT void elem_div_out(const imat &m1, const imat &m2, imat &out);
447template ITPP_EXPORT void elem_div_out(const smat &m1, const smat &m2, smat &out);
448template ITPP_EXPORT void elem_div_out(const bmat &m1, const bmat &m2, bmat &out);
449
450template ITPP_EXPORT double elem_div_sum(const mat &m1, const mat &m2);
451template ITPP_EXPORT std::complex<double> elem_div_sum(const cmat &m1,
452 const cmat &m2);
453template ITPP_EXPORT int elem_div_sum(const imat &m1, const imat &m2);
454template ITPP_EXPORT short elem_div_sum(const smat &m1, const smat &m2);
455template ITPP_EXPORT bin elem_div_sum(const bmat &m1, const bmat &m2);
456
457// concatenation
458
459template ITPP_EXPORT mat concat_horizontal(const mat &m1, const mat &m2);
460template ITPP_EXPORT cmat concat_horizontal(const cmat &m1, const cmat &m2);
461template ITPP_EXPORT imat concat_horizontal(const imat &m1, const imat &m2);
462template ITPP_EXPORT smat concat_horizontal(const smat &m1, const smat &m2);
463template ITPP_EXPORT bmat concat_horizontal(const bmat &m1, const bmat &m2);
464
465template ITPP_EXPORT mat concat_vertical(const mat &m1, const mat &m2);
466template ITPP_EXPORT cmat concat_vertical(const cmat &m1, const cmat &m2);
467template ITPP_EXPORT imat concat_vertical(const imat &m1, const imat &m2);
468template ITPP_EXPORT smat concat_vertical(const smat &m1, const smat &m2);
469template ITPP_EXPORT bmat concat_vertical(const bmat &m1, const bmat &m2);
470
471// I/O streams
472
473template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const mat &m);
474template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const cmat &m);
475template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const imat &m);
476template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const smat &m);
477template ITPP_EXPORT std::ostream &operator<<(std::ostream &os, const bmat &m);
478
479template ITPP_EXPORT std::istream &operator>>(std::istream &is, mat &m);
480template ITPP_EXPORT std::istream &operator>>(std::istream &is, cmat &m);
481template ITPP_EXPORT std::istream &operator>>(std::istream &is, imat &m);
482template ITPP_EXPORT std::istream &operator>>(std::istream &is, smat &m);
483template ITPP_EXPORT std::istream &operator>>(std::istream &is, bmat &m);
484
485} // namespace itpp
486
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Definition itassert.h:107
Matrix Class Definitions.
Mat< bin > bmat
bin matrix
Definition mat.h:508
itpp namespace
Definition itmex.h:37
void elem_mult_inplace(const Mat< Num_T > &m1, Mat< Num_T > &m2)
In-place element wise multiplication of two matrices. Fast version of B = elem_mult(A,...
Definition mat.h:1630
std::ostream & operator<<(std::ostream &output, const bin &inbin)
Output stream of bin.
Definition binary.cpp:36
Mat< Num_T > concat_horizontal(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Horizontal concatenation of two matrices.
Definition mat.h:1194
Mat< Num_T > operator-(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Subtraction of two matrices.
Definition mat.h:1382
GF2mat operator*(const GF2mat &X, const GF2mat &Y)
GF(2) matrix multiplication.
Definition gf2mat.cpp:847
Mat< Num_T > operator/(const Mat< Num_T > &m, Num_T t)
Element-wise division by a scalar.
Definition mat.h:1670
void elem_div_out(const Mat< Num_T > &m1, const Mat< Num_T > &m2, Mat< Num_T > &out)
Element wise division of two matrices, storing the result in matrix out.
Definition mat.h:1696
std::istream & operator>>(std::istream &input, bin &outbin)
Input stream of bin.
Definition binary.cpp:42
Mat< Num_T > elem_div(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise division of two matrices.
Definition mat.h:1688
Num_T elem_div_sum(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise division of two matrices, followed by summation of the resultant elements....
Definition mat.h:1710
GF2mat operator+(const GF2mat &X, const GF2mat &Y)
GF(2) matrix addition.
Definition gf2mat.cpp:948
Mat< Num_T > elem_mult(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise multiplication of two matrices.
Definition mat.h:1582
Num_T elem_mult_sum(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Element wise multiplication of two matrices, followed by summation of the resultant elements....
Definition mat.h:1639
Mat< Num_T > concat_vertical(const Mat< Num_T > &m1, const Mat< Num_T > &m2)
Vertical concatenation of two matrices.
Definition mat.h:1216
void elem_mult_out(const Mat< Num_T > &m1, const Mat< Num_T > &m2, Mat< Num_T > &out)
Element wise multiplication of two matrices, storing the result in matrix out.
Definition mat.h:1590
SourceForge Logo

Generated on Mon Apr 7 2025 07:53:18 for IT++ by Doxygen 1.11.0