KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
m_matrix_d.impl.h
Go to the documentation of this file.
1 /* $Id: m_matrix_d.impl.h 18376 2014-12-09 06:44:38Z ksimek $ */
2 /* {{{=========================================================================== *
3  |
4  | Copyright (c) 1994-2014 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek
18  * =========================================================================== }}}*/
19 
20 // vim: tabstop=4 shiftwidth=4 foldmethod=marker
21 
22 #ifndef KJB_M_MATRIX_D_IMPL_H
23 #define KJB_M_MATRIX_D_IMPL_H
24 
25 #include <numeric>
26 #include <functional>
27 #include <cmath>
28 #include <m_cpp/m_matrix.h>
29 #include <m_cpp/m_vector.h>
30 #include <m_cpp/m_vector_d.h>
31 #include <l_cpp/l_functors.h>
32 #include <l_cpp/l_cxx11.h>
33 
34 namespace kjb {
35 
36 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
38  Base()
39 { }
40 
41 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
43  Base(m)
44 {
45 }
46 
47 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
49  Base()
50 {
51  *this = m;
52 }
53 
54 
55 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
57  Base()
58 {
59  *this = m;
60 }
61 
62 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
64  Base()
65 {
66  typename Base::iterator it;
67  // call row.init(value) on all rows
68  for(it = begin(); it < end(); ++it)
69  {
70  std::fill_n(it->begin(), it->size(), value);
71  }
72 }
73 
74 
75 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
77 {
78  return assignment_dispatch_(other);
79 }
80 
81 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
83 {
84  if (
85  other.get_num_rows() != (Matrix::Size_type) get_num_rows() ||
86  other.get_num_cols() != (Matrix::Size_type) get_num_cols() )
87  {
89  }
90 
91  return assignment_dispatch_(other);
92 }
93 
94 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
96 {
97  if (second.get_num_rows() != (Matrix::Size_type) get_num_rows() ||
98  second.get_num_cols() != (Matrix::Size_type) get_num_cols())
99  {
101  }
102 
103  return minus_equals_dispatch_(second);
104 }
105 
106 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
108 {
109  Matrix_d result;
110  for (size_t row = 0; row < NROWS; row++)
111  {
112  for (size_t col = 0; col < NCOLS; col++)
113  {
114  result[row][col] = -(*this)[row][col];
115  }
116  }
117  return result;
118 }
119 
120 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
122 {
123  if (second.get_num_rows() != (Matrix::Size_type) get_num_rows() ||
124  second.get_num_cols() != (Matrix::Size_type) get_num_cols())
125  {
127  }
128 
129  return plus_equals_dispatch_(second);
130 }
131 
132 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
134 {
135  return Matrix_d(*this) += second;
136 }
137 
138 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
140 {
141  for (size_t i = 0; i < NROWS; i++)
142  {
143  (*this)[i] *= s;
144  }
145 
146  return *this;
147 }
148 
149 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
150 template <size_t D>
152 {
154  for(size_t c = 0; c < num_cols; ++c)
155  {
156  if(!TRANSPOSED)
157  {
158  (*this)[r][c] = row[c];
159  }
160  else
161  {
162  (*this)[c][r] = row[c];
163  }
164  }
165 }
166 
167 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
168 template <size_t D>
170 {
172  for(size_t r = 0; r < num_rows; ++r)
173  {
174  if(!TRANSPOSED)
175  {
176  (*this)[r][c] = col[r];
177  }
178  else
179  {
180  (*this)[c][r] = col[r];
181  }
182  }
183 }
184 
185 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
187 {
188  if ((Matrix::Size_type) get_num_rows() != op2.get_num_rows())
189  {
190  return false;
191  }
192  if ((Matrix::Size_type) get_num_cols() != op2.get_num_cols())
193  {
194  return false;
195  }
196 
197  return matrix_equality_dispatch_(op2);
198 }
199 
200 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
202 {
203  return !(*this == op2);
204 }
205 
206 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
207 template <class Matrix_type>
209 {
210  // assume dimension checks have already occurred
211 
212  // this should still work for if _this_ is transposed.
213  for (size_t row = 0; row < get_num_rows(); ++row)
214  {
215  for (size_t col = 0; col < get_num_cols(); ++col)
216  {
217  (*this)(row, col) = other(row, col);
218  }
219  }
220 
221  return *this;
222 }
223 
224 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
225 template <class Matrix_op>
227 {
228  // assume dimension checks have occurred already
229  for (size_t row = 0; row != get_num_rows(); row++)
230  {
231  for (size_t col = 0; col != get_num_cols(); col++)
232  {
233  (*this)(row, col) += second(row, col);
234  }
235  }
236 
237  return *this;
238 }
239 
240 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
241 template <class Matrix_op>
243 {
244  // assume dimension checks have occurred already
245  for (size_t row = 0; row != get_num_rows(); row++)
246  {
247  for (size_t col = 0; col != get_num_cols(); col++)
248  {
249  (*this)(row, col) -= second(row, col);
250  }
251  }
252 
253  return *this;
254 }
255 
256 template <class Matrix_type_1, class Matrix_type_2>
258 {
259  KJB_STATIC_ASSERT(Matrix_type_1::num_cols == Matrix_type_2::num_rows, "Dimension mismatch");
260 
261  static const size_t OUT_ROWS = Matrix_type_1::num_rows;
262  static const size_t IN_ROWS = Matrix_type_1::num_cols;
263  static const size_t IN_COLS= Matrix_type_2::num_cols;
264 
265  Matrix_d<OUT_ROWS, IN_COLS> result(0.0);
266 
267  for (size_t out_row = 0; out_row < OUT_ROWS; ++out_row)
268  {
269  for (size_t in_row = 0; in_row < IN_ROWS; ++in_row)
270  {
271  for (size_t in_col = 0; in_col < IN_COLS; ++in_col)
272  {
273  result(out_row, in_col) += m1(out_row, in_row) * m2(in_row, in_col);
274  }
275  }
276  }
277 
278  return result;
279 }
280 
281 template <size_t NROWS, size_t NCOLS, bool TRANSPOSED>
282 template <class Matrix2>
283 bool Matrix_d<NROWS,NCOLS,TRANSPOSED>::matrix_equality_dispatch_(const Matrix2& m2) const
284 {
285  // assume dimension checks have been done
286  for (size_t row = 0; row != get_num_rows(); row++)
287  {
288  for (size_t col = 0; col != get_num_cols(); col++)
289  {
290  if ((*this)(row,col) != m2(row, col)) return false;
291  }
292  }
293 
294  return true;
295 }
296 
298 template<class Matrix_1, class Matrix_2>
299 Matrix matrix_multiply_dynamic_dispatch_(const Matrix_1& m1, const Matrix_2& m2)
300 {
301  if ((Matrix::Size_type) m1.get_num_cols() != (Matrix::Size_type) m2.get_num_rows())
302  {
304  }
305 
306  static size_t OUT_ROWS = m1.get_num_rows();
307  static size_t IN_ROWS = m2.get_num_rows();
308  static size_t IN_COLS = m2.get_num_cols();
309 
310  // assume all checks have already occurred
311  Matrix result(OUT_ROWS, IN_COLS, 0);
312 
313  for (size_t out_row = 0; out_row < OUT_ROWS; ++out_row)
314  {
315  for (size_t in_row = 0; in_row < IN_ROWS; ++in_row)
316  {
317  for (size_t in_col = 0; in_col < IN_COLS; ++in_col)
318  {
319  result(out_row, in_col) += m1(out_row, in_row) * m2(in_row, in_col);
320  }
321  }
322  }
323 
324  return result;
325 }
326 
327 
328 template<std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
329 inline Matrix_d<NROWS, NCOLS, TRANSPOSED>
331 {
332  return Matrix_d<NROWS, NCOLS, TRANSPOSED>(mat) *= scalar;
333 }
334 
335 template<std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
337 {
338  return matrix_multiply_dynamic_dispatch_(op1, op2);
339 }
340 
341 template<std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
343 {
344  return matrix_multiply_dynamic_dispatch_(op1, op2);
345 }
346 
347 
348 template <std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
349 inline bool operator==(const Matrix& op2, const Matrix_d<NROWS, NCOLS, TRANSPOSED>& op1)
350 {
351  return op1 == op2;
352 }
353 
354 template <std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
355 inline bool operator!=(const Matrix& op2, const Matrix_d<NROWS, NCOLS, TRANSPOSED>& op1)
356 {
357  return op1 != op2;
358 }
359 
360 template <std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
362 {
363  return -op2 + op1;
364 }
365 
366 template <std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
368 {
369  return Matrix_d<NROWS, NCOLS, TRANSPOSED>(op2) += second;
370 }
371 
372 template <std::size_t NROWS, std::size_t NCOLS, bool TRANSPOSED>
373 std::ostream& operator<<(std::ostream& ost, const Matrix_d<NROWS, NCOLS, TRANSPOSED>& mat)
374 {
375  for (size_t r = 0; r < mat.get_num_rows(); ++r)
376  {
377  for (size_t c = 0; c < mat.get_num_cols(); ++c)
378  {
379  ost << mat(r,c) << '\t';
380  }
381  ost << '\n';
382  }
383  return ost;
384 }
385 
386 template <std::size_t D>
388 {
389  Matrix_d<D,D> result(0.0);
390 
391  for (size_t i = 0; i < D; i++)
392  {
393  result(i,i) = 1.0;
394  }
395 
396  return result;
397 }
398 
399 template <std::size_t D>
401 {
402  // these are copied in as row vectors
403  Matrix_d<1,D> m1(&v1);
404  Matrix_d<1,D> m2(&v2);
405 
406  return m1.transpose() * m2;
407 }
408 
409 template <std::size_t NROWS, std::size_t NCOLS>
411 {
412  Matrix_d<NROWS,NCOLS> result(0.0);
413 
414  for(size_t i = 0; i < result.size(); ++i)
415  result[i] = create_random_vector<NCOLS>();
416 
417  return result;
418 }
419 
420 template <size_t D>
421 double trace(const Matrix_d<D,D>& m)
422 {
423  double out = 0;
424  for(size_t i = 0; i < D; ++i)
425  {
426  out += m(i,i);
427  }
428  return out;
429 }
430 
431 template <std::size_t R, std::size_t C, bool T>
432 double accumulate(const Matrix_d<R,C, T>& mat, double init)
433 {
434  double result = init;
435  for (size_t r = 0; r < R; r++)
436  {
437  for (size_t c = 0; c < C; c++)
438  {
439  result += mat(r,c);
440  }
441  }
442 
443  return result;
444 }
445 
446 template <std::size_t R, std::size_t C>
448 {
449  Matrix_d<R,C,false> diff = op1 - op2;
450 
451  double out = -DBL_MAX;
452  for(size_t r = 0; r < R; ++r)
453  for(size_t c = 0; c < C; ++c)
454  {
455  out = std::max(fabs(diff(r,c)), out);
456  }
457  return out;
458 }
459 
460 template <std::size_t R, std::size_t C, bool T>
461 inline double max(const Matrix_d<R,C, T>& mat)
462 {
463  return accumulate(mat, DBL_MIN, kjb::maximum<double>());
464 }
465 
466 template <std::size_t R, std::size_t C, bool T>
467 inline double min(const Matrix_d<R,C, T>& mat)
468 {
469  return accumulate(mat, DBL_MAX, kjb::minimum<double>());
470 }
471 
472 } // namespace kjb
473 
474 #endif /* KJB_M_MATRIX_D_IMPL_H */
Definition: gr_opengl.h:41
Matrix_d< 2, 2 > Matrix2
Definition: m_matrix_d.h:580
bool operator!=(const Matrix_d &op2) const
Definition: m_matrix_d.h:534
Definition for the Matrix class, a thin wrapper on the KJB Matrix struct and its related functionalit...
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
double trace(const Matrix_d< D, D > &m)
Definition: m_matrix_d.impl.h:421
double accumulate(const Matrix_d< R, C, T > &mat, double init)
Definition: m_matrix_d.impl.h:432
void set_col(size_t c, const Vector_d< D > &col)
Definition: m_matrix_d.impl.h:169
Object thrown when an argument is of the wrong size or dimensions.
Definition: l_exception.h:426
int get_num_rows() const
Return the number of rows in the matrix.
Definition: m_matrix.h:543
int Size_type
size type of the elements
Definition: m_matrix.h:110
Int_matrix::Value_type max_abs_difference(const Int_matrix &op1, const Int_matrix &op2)
Find the largest difference between two matrices.
Definition: l_int_matrix.h:1364
Matrix_d< Matrix_type_1::num_rows, Matrix_type_2::num_cols > matrix_multiply_dispatch_(const Matrix_type_1 &m1, const Matrix_type_2 &m2)
Definition: m_matrix_d.impl.h:257
r
Definition: APPgetLargeConnectedEdges.m:127
Image operator-(const Image &im1, const Image &im2)
Subtract two images.
Definition: i_image.h:843
#define KJB_THROW(ex)
Definition: l_exception.h:46
Matrix outer_product(const Vector &v1, const Vector &v2)
Definition: m_matrix.h:2293
#define KJB_STATIC_ASSERT(x, y)
Definition: l_cxx11.h:55
Matrix_d operator-() const
negation
Definition: m_matrix_d.impl.h:107
Image operator+(const Image &op1, const Image &op2)
Add two images.
Definition: i_image.h:834
Matrix_d & operator+=(const Matrix_d &second)
Definition: m_matrix_d.h:341
int get_num_cols() const
Return the number of columns in the matrix.
Definition: m_matrix.h:554
Matrix_d()
Definition: m_matrix_d.impl.h:37
Matrix_d & operator=(const Matrix_d &other)
assignment
Definition: m_matrix_d.h:296
Matrix_d operator+(const Matrix_d &second) const
Definition: m_matrix_d.h:346
Matrix create_identity_matrix(int rank)
Construct an identity matrix of specified rank.
Definition: m_matrix.h:1795
bool operator!=(const Int_matrix &op1, const Int_matrix::Impl_type &op2)
Test for any difference between two matrices.
Definition: l_int_matrix.h:1274
void set_row(size_t r, const Vector_d< D > &row)
Definition: m_matrix_d.impl.h:151
bool operator==(const Matrix_d &op2) const
Definition: m_matrix_d.h:522
bool operator==(const Int_matrix &op1, const Int_matrix::Impl_type &op2)
Test for exact equality between two matrices.
Definition: l_int_matrix.cpp:218
Int_matrix::Value_type min(const Int_matrix &mat)
Return the minimum value in this matrix.
Definition: l_int_matrix.h:1385
Matrix_d & operator*=(double s)
multiplication by a scalar
Definition: m_matrix_d.impl.h:139
Matrix_d & operator-=(const Matrix_d &second)
Definition: m_matrix_d.h:310
Matrix matrix_multiply_dynamic_dispatch_(const Matrix_1 &m1, const Matrix_2 &m2)
don't call me directly
Definition: m_matrix_d.impl.h:299
Definition: g_quaternion.h:37
Definition: l_functors.h:250
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
Matrix_d< NROWS, NCOLS,!TRANSPOSED > & transpose()
Definition: m_matrix_d.h:281
for m
Definition: APPgetLargeConnectedEdges.m:64
D
Definition: APPgetLargeConnectedEdges.m:106
Definition: l_functors.h:238
Gsl_Vector operator*(double scalar, const Gsl_Vector &vector)
multiply scalar and vector, scalar written on the left side
Definition: gsl_vector.h:661
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...
Matrix create_random_matrix(int num_rows, int num_cols)
Definition: m_matrix.h:1853