vnl_matrix_fixed.hxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_matrix_fixed.hxx
2 #ifndef vnl_matrix_fixed_hxx_
3 #define vnl_matrix_fixed_hxx_
4 //:
5 // \file
6 #include <cmath>
7 #include <iostream>
8 #include <cstdlib>
9 #include "vnl_matrix_fixed.h"
10 
11 #ifdef _MSC_VER
12 # include <vcl_msvc_warnings.h>
13 #endif
14 #include <cassert>
15 
16 #include <vnl/vnl_error.h>
17 #include <vnl/vnl_math.h>
18 #include <vnl/vnl_complex.h> //vnl_math functions for complex variables
19 #include <vnl/vnl_vector_fixed.h>
20 
21 template<class T, unsigned num_rows, unsigned num_cols>
24 {
25  fill(v); return *this;
26 }
27 
28 template<class T, unsigned num_rows, unsigned num_cols>
31 {
32  assert(rhs.rows() == num_rows && rhs.columns() == num_cols);
33  std::memcpy(data_[0], rhs.data_block(), num_rows*num_cols * sizeof(T));
34  return *this;
35 }
36 
37 template<class T, unsigned nrows, unsigned ncols>
38 T &
40 {
41 #if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
42  assert(r < rows()); // Check the row index is valid
43  assert(c < cols()); // Check the column index is valid
44 #endif
45  return this->data_[r][c];
46 }
47 
48 template<class T, unsigned nrows, unsigned ncols>
49 T const &
51 {
52 #if VNL_CONFIG_CHECK_BOUNDS && (!defined NDEBUG)
53  assert(r < rows()); // Check the row index is valid
54  assert(c < cols()); // Check the column index is valid
55 #endif
56  return this->data_[r][c];
57 }
58 
59 template<class T, unsigned nrows, unsigned ncols>
60 void
61 vnl_matrix_fixed<T,nrows,ncols>::add( const T* a, const T* b, T* r )
62 {
63  unsigned int count = nrows*ncols;
64  while ( count-- )
65  *(r++) = *(a++) + *(b++);
66 }
67 
68 
69 template<class T, unsigned nrows, unsigned ncols>
70 void
71 vnl_matrix_fixed<T,nrows,ncols>::add( const T* a, T b, T* r )
72 {
73  unsigned int count = nrows*ncols;
74  while ( count-- )
75  *(r++) = *(a++) + b;
76 }
77 
78 template<class T, unsigned nrows, unsigned ncols>
79 void
80 vnl_matrix_fixed<T,nrows,ncols>::sub( const T* a, const T* b, T* r )
81 {
82  unsigned int count = nrows*ncols;
83  while ( count-- )
84  *(r++) = *(a++) - *(b++);
85 }
86 
87 template<class T, unsigned nrows, unsigned ncols>
88 void
89 vnl_matrix_fixed<T,nrows,ncols>::sub( const T* a, T b, T* r )
90 {
91  unsigned int count = nrows*ncols;
92  while ( count-- )
93  *(r++) = *(a++) - b;
94 }
95 
96 template<class T, unsigned nrows, unsigned ncols>
97 void
98 vnl_matrix_fixed<T,nrows,ncols>::sub( T a, const T* b, T* r )
99 {
100  unsigned int count = nrows*ncols;
101  while ( count-- )
102  *(r++) = a - *(b++);
103 }
104 
105 template<class T, unsigned nrows, unsigned ncols>
106 void
107 vnl_matrix_fixed<T,nrows,ncols>::mul( const T* a, const T* b, T* r )
108 {
109  unsigned int count = nrows*ncols;
110  while ( count-- )
111  *(r++) = *(a++) * *(b++);
112 }
113 
114 template<class T, unsigned nrows, unsigned ncols>
115 void
116 vnl_matrix_fixed<T,nrows,ncols>::mul( const T* a, T b, T* r )
117 {
118  unsigned int count = nrows*ncols;
119  while ( count-- )
120  *(r++) = *(a++) * b;
121 }
122 
123 template<class T, unsigned nrows, unsigned ncols>
124 void
125 vnl_matrix_fixed<T,nrows,ncols>::div( const T* a, const T* b, T* r )
126 {
127  unsigned int count = nrows*ncols;
128  while ( count-- )
129  *(r++) = *(a++) / *(b++);
130 }
131 
132 template<class T, unsigned nrows, unsigned ncols>
133 void
134 vnl_matrix_fixed<T,nrows,ncols>::div( const T* a, T b, T* r )
135 {
136  unsigned int count = nrows*ncols;
137  while ( count-- )
138  *(r++) = *(a++) / b;
139 }
140 
141 template<class T, unsigned nrows, unsigned ncols>
142 bool
143 vnl_matrix_fixed<T,nrows,ncols>::equal( const T* a, const T* b )
144 {
145  unsigned int count = nrows*ncols;
146  while ( count-- )
147  if ( *(a++) != *(b++) ) return false;
148  return true;
149 }
150 
151 //------------------------------------------------------------
152 
153 
154 template<class T, unsigned nrows, unsigned ncols>
157 {
158  for (unsigned int i = 0; i < nrows; ++i)
159  for (unsigned int j = 0; j < ncols; ++j)
160  this->data_[i][j] = value;
161  return *this;
162 }
163 
164 
165 template<class T, unsigned nrows, unsigned ncols>
168 {
169  for (unsigned int i = 0; i < nrows && i < ncols; ++i)
170  this->data_[i][i] = value;
171  return *this;
172 }
173 
174 
175 template<class T, unsigned nrows, unsigned ncols>
178 {
179  assert(diag.size() >= nrows || diag.size() >= ncols);
180  // The length of the diagonal of a non-square matrix is the minimum of
181  // the matrix's width & height; that explains the "||" in the assert,
182  // and the "&&" in the upper bound for the "for".
183  for (unsigned int i = 0; i < nrows && i < ncols; ++i)
184  this->data_[i][i] = diag[i];
185  return *this;
186 }
187 
188 
189 template<class T, unsigned nrows, unsigned ncols>
190 void
192 {
193  for (unsigned int i = 0; i < nrows; ++i)
194  {
195  os << this->data_[i][0];
196  for (unsigned int j = 1; j < ncols; ++j)
197  os << ' ' << this->data_[i][j];
198  os << '\n';
199  }
200 }
201 
202 
203 template <class T, unsigned nrows, unsigned ncols>
206 ::apply(T (*f)(T const&)) const
207 {
209  vnl_c_vector<T>::apply(this->data_[0], rows()*cols(), f, ret.data_block());
210  return ret;
211 }
212 
213 template <class T, unsigned nrows, unsigned ncols>
216 ::apply(T (*f)(T)) const
217 {
219  vnl_c_vector<T>::apply(this->data_[0], rows()*cols(), f, ret.data_block());
220  return ret;
221 }
222 
223 //: Make a vector by applying a function across rows.
224 template <class T, unsigned nrows, unsigned ncols>
228 {
230  for (unsigned int i = 0; i < nrows; ++i)
231  v.put(i,f(this->get_row(i)));
232  return v;
233 }
234 
235 //: Make a vector by applying a function across columns.
236 template <class T, unsigned nrows, unsigned ncols>
240 {
242  for (unsigned int i = 0; i < ncols; ++i)
243  v.put(i,f(this->get_column(i)));
244  return v;
245 }
246 
247 ////--------------------------- Additions------------------------------------
248 
249 
250 template<class T, unsigned nrows, unsigned ncols>
253 {
255  for (unsigned int i = 0; i < cols(); ++i)
256  for (unsigned int j = 0; j < rows(); ++j)
257  result(i,j) = this->data_[j][i];
258  return result;
259 }
260 
261 template<class T, unsigned nrows, unsigned ncols>
264 {
265  vnl_matrix_fixed<T,ncols,nrows> result(transpose());
266  vnl_c_vector<T>::conjugate(result.begin(), // src
267  result.begin(), // dst
268  result.size()); // size of block
269  return result;
270 }
271 
272 template<class T, unsigned nrows, unsigned ncols>
275  unsigned top, unsigned left)
276 {
277  const unsigned int bottom = top + m.rows();
278  const unsigned int right = left + m.cols();
279 #ifndef NDEBUG
280  if (nrows < bottom || ncols < right)
281  vnl_error_matrix_dimension ("update",
282  bottom, right, m.rows(), m.cols());
283 #endif
284  for (unsigned int i = top; i < bottom; ++i)
285  for (unsigned int j = left; j < right; ++j)
286  this->data_[i][j] = m(i-top,j-left);
287  return *this;
288 }
289 
290 
291 template<class T, unsigned nrows, unsigned ncols>
293 vnl_matrix_fixed<T,nrows,ncols>::extract (unsigned rowz, unsigned colz,
294  unsigned top, unsigned left) const
295 {
296  vnl_matrix<T> result(rowz, colz);
297  this->extract( result, top, left );
298  return result;
299 }
300 
301 
302 template<class T, unsigned nrows, unsigned ncols>
303 void
305  unsigned top, unsigned left) const
306 {
307  unsigned int rowz = sub_matrix.rows();
308  unsigned int colz = sub_matrix.cols();
309 #ifndef NDEBUG
310  unsigned int bottom = top + rowz;
311  unsigned int right = left + colz;
312  if ((nrows < bottom) || (ncols < right))
313  vnl_error_matrix_dimension ("extract",
314  nrows, ncols, bottom, right);
315 #endif
316  for (unsigned int i = 0; i < rowz; ++i) // actual copy of all elements
317  for (unsigned int j = 0; j < colz; ++j) // in submatrix
318  sub_matrix(i,j) = this->data_[top+i][left+j];
319 }
320 
321 
322 template<class T, unsigned nrows, unsigned ncols>
325 {
326  T* dp = this->data_block();
327  std::copy( p, p + nrows * ncols, dp );
328  return *this;
329 }
330 
331 template<class T, unsigned nrows, unsigned ncols>
333 {
334  T const* dp = this->data_block();
335  std::copy( dp, dp + nrows * ncols, p );
336 }
337 
338 template<class T, unsigned nrows, unsigned ncols>
341 {
342  // Two simple loops are generally better than having a branch inside
343  // the loop. Probably worth the O(n) extra writes.
344  for (unsigned int i = 0; i < nrows; ++i)
345  for (unsigned int j = 0; j < ncols; ++j)
346  this->data_[i][j] = T(0);
347  for (unsigned int i = 0; i < nrows && i < ncols; ++i)
348  this->data_[i][i] = T(1);
349  return *this;
350 }
351 
352 //: Make each row of the matrix have unit norm.
353 // All-zero rows are ignored.
354 template<class T, unsigned nrows, unsigned ncols>
357 {
358  for (unsigned int i = 0; i < nrows; ++i)
359  {
360  abs_t norm(0); // double will not do for all types.
361  for (unsigned int j = 0; j < ncols; ++j)
362  norm += vnl_math::squared_magnitude( this->data_[i][j] );
363 
364  if (norm != 0)
365  {
366  typedef typename vnl_numeric_traits<abs_t>::real_t real_t;
367  real_t scale = real_t(1)/std::sqrt((real_t)norm);
368  for (unsigned int j = 0; j < ncols; ++j)
369  {
370  // FIXME need correct rounding here
371  // There is e.g. no *standard* operator*=(complex<float>, double), hence the T() cast.
372  this->data_[i][j] *= T(scale);
373  }
374  }
375  }
376  return *this;
377 }
378 
379 template<class T, unsigned nrows, unsigned ncols>
382 {
383  for (unsigned int j = 0; j < ncols; ++j) { // For each column in the Matrix
384  abs_t norm(0); // double will not do for all types.
385  for (unsigned int i = 0; i < nrows; ++i)
386  norm += vnl_math::squared_magnitude( this->data_[i][j] );
387 
388  if (norm != 0)
389  {
390  typedef typename vnl_numeric_traits<abs_t>::real_t real_t;
391  real_t scale = real_t(1)/std::sqrt((real_t)norm);
392  for (unsigned int i = 0; i < nrows; ++i)
393  {
394  // FIXME need correct rounding here
395  // There is e.g. no *standard* operator*=(complex<float>, double), hence the T() cast.
396  this->data_[i][j] *= T(scale);
397  }
398  }
399  }
400  return *this;
401 }
402 
403 template<class T, unsigned nrows, unsigned ncols>
405 vnl_matrix_fixed<T,nrows,ncols>::scale_row(unsigned row_index, T value)
406 {
407 #ifndef NDEBUG
408  if (row_index >= nrows)
409  vnl_error_matrix_row_index("scale_row", row_index);
410 #endif
411  for (unsigned int j = 0; j < ncols; ++j)
412  this->data_[row_index][j] *= value;
413  return *this;
414 }
415 
416 template<class T, unsigned nrows, unsigned ncols>
418 vnl_matrix_fixed<T,nrows,ncols>::scale_column(unsigned column_index, T value)
419 {
420 #ifndef NDEBUG
421  if (column_index >= ncols)
422  vnl_error_matrix_col_index("scale_column", column_index);
423 #endif
424  for (unsigned int j = 0; j < nrows; ++j)
425  this->data_[j][column_index] *= value;
426  return *this;
427 }
428 
429 template <class T, unsigned int nrows, unsigned int ncols>
430 void
433 {
434  for (unsigned int r = 0; r < nrows; ++r)
435  {
436  for (unsigned int c = 0; c < ncols; ++c)
437  {
438  std::swap(this->data_[r][c], that.data_[r][c]);
439  }
440  }
441 }
442 
443 //: Returns a copy of n rows, starting from "row"
444 template<class T, unsigned nrows, unsigned ncols>
446 vnl_matrix_fixed<T,nrows,ncols>::get_n_rows (unsigned row, unsigned n) const
447 {
448 #ifndef NDEBUG
449  if (row + n > nrows)
450  vnl_error_matrix_row_index ("get_n_rows", row);
451 #endif
452 
453  // Extract data rowwise.
454  return vnl_matrix<T>(data_[row], n, ncols);
455 }
456 
457 template<class T, unsigned nrows, unsigned ncols>
459 vnl_matrix_fixed<T,nrows,ncols>::get_n_columns (unsigned column, unsigned n) const
460 {
461 #ifndef NDEBUG
462  if (column + n > ncols)
463  vnl_error_matrix_col_index ("get_n_columns", column);
464 #endif
465 
466  vnl_matrix<T> result(nrows, n);
467  for (unsigned int c = 0; c < n; ++c)
468  for (unsigned int r = 0; r < nrows; ++r)
469  result(r, c) = this->data_[r][column + c];
470  return result;
471 }
472 
473 //: Create a vector out of row[row_index].
474 template<class T, unsigned nrows, unsigned ncols>
476 {
477 #ifdef ERROR_CHECKING
478  if (row_index >= nrows)
479  vnl_error_matrix_row_index ("get_row", row_index);
480 #endif
481 
483  for (unsigned int j = 0; j < ncols; ++j) // For each element in row
484  v[j] = this->data_[row_index][j];
485  return v;
486 }
487 
488 //: Create a vector out of column[column_index].
489 template<class T, unsigned nrows, unsigned ncols>
491 {
492 #ifdef ERROR_CHECKING
493  if (column_index >= ncols)
494  vnl_error_matrix_col_index ("get_column", column_index);
495 #endif
496 
498  for (unsigned int j = 0; j < nrows; ++j)
499  v[j] = this->data_[j][column_index];
500  return v;
501 }
502 
503 //: Create a vector out of row[row_index].
504 template <class T, unsigned int nrows, unsigned int ncols>
508 {
509  vnl_matrix<T> m(i.size(), this->cols());
510  for (unsigned int j = 0; j < i.size(); ++j)
511  m.set_row(j, this->get_row(i.get(j)));
512  return m;
513 }
514 
515 //: Create a vector out of column[column_index].
516 template <class T, unsigned int nrows, unsigned int ncols>
520 {
521  vnl_matrix<T> m(this->rows(), i.size());
522  for (unsigned int j = 0; j < i.size(); ++j)
523  m.set_column(j, this->get_column(i.get(j)));
524  return m;
525 }
526 
527 //: Return a vector with the content of the (main) diagonal
528 template<class T, unsigned nrows, unsigned ncols>
530 {
531  vnl_vector<T> v(nrows < ncols ? nrows : ncols);
532  for (unsigned int j = 0; j < nrows && j < ncols; ++j)
533  v[j] = this->data_[j][j];
534  return v;
535 }
536 
537 //: Flatten row-major (C-style)
538 template <class T, unsigned nrows, unsigned ncols>
540 {
542  v.copy_in(this->data_block());
543  return v;
544 }
545 
546 //: Flatten column-major (Fortran-style)
547 template <class T, unsigned nrows, unsigned ncols>
549 {
551  for (unsigned int c = 0; c < ncols; ++c)
552  for (unsigned int r = 0; r < nrows; ++r)
553  v[c*nrows+r] = this->data_[r][c];
554  return v;
555 }
556 
557 //--------------------------------------------------------------------------------
558 
559 template<class T, unsigned nrows, unsigned ncols>
561 vnl_matrix_fixed<T,nrows,ncols>::set_row(unsigned row_index, T const *v)
562 {
563  for (unsigned int j = 0; j < ncols; ++j)
564  this->data_[row_index][j] = v[j];
565  return *this;
566 }
567 
568 template<class T, unsigned nrows, unsigned ncols>
571 {
572  if (v.size() >= ncols)
573  set_row(row_index,v.data_block());
574  else
575  for (unsigned int j = 0; j < v.size(); ++j)
576  this->data_[row_index][j] = v[j];
577  return *this;
578 }
579 
580 template<class T, unsigned nrows, unsigned ncols>
583 {
584  set_row(row_index,v.data_block());
585  return *this;
586 }
587 
588 template<class T, unsigned nrows, unsigned ncols>
591 {
592  for (unsigned int j = 0; j < ncols; ++j)
593  this->data_[row_index][j] = v;
594  return *this;
595 }
596 
597 //--------------------------------------------------------------------------------
598 
599 template<class T, unsigned nrows, unsigned ncols>
601 vnl_matrix_fixed<T,nrows,ncols>::set_column(unsigned column_index, T const *v)
602 {
603  for (unsigned int i = 0; i < nrows; ++i)
604  this->data_[i][column_index] = v[i];
605  return *this;
606 }
607 
608 template<class T, unsigned nrows, unsigned ncols>
611 {
612  if (v.size() >= nrows)
613  set_column(column_index,v.data_block());
614  else
615  for (unsigned int i = 0; i < v.size(); ++i)
616  this->data_[i][column_index] = v[i];
617  return *this;
618 }
619 
620 template<class T, unsigned nrows, unsigned ncols>
623 {
624  set_column(column_index,v.data_block());
625  return *this;
626 }
627 
628 template<class T, unsigned nrows, unsigned ncols>
631 {
632  for (unsigned int j = 0; j < nrows; ++j)
633  this->data_[j][column_index] = v;
634  return *this;
635 }
636 
637 
638 template<class T, unsigned nrows, unsigned ncols>
641 {
642  for (unsigned int j = 0; j < m.cols() && starting_column+j < ncols; ++j) // don't go too far right; possibly only use part of m
643  for (unsigned int i = 0; i < nrows && i < m.rows(); ++i) // smallest of the two heights; possibly only use part of m
644  this->data_[i][starting_column + j] = m(i,j);
645  return *this;
646 }
647 
648 
649 template <class T, unsigned nrows, unsigned ncols>
650 bool
652 {
653  T const zero(0);
654  T const one(1);
655  for (unsigned int i = 0; i < nrows; ++i)
656  for (unsigned int j = 0; j < ncols; ++j)
657  {
658  T xm = this->data_[i][j];
659  if ( !((i == j) ? (xm == one) : (xm == zero)) )
660  return false;
661  }
662  return true;
663 }
664 
665 //: Return true if maximum absolute deviation of M from identity is <= tol.
666 template <class T, unsigned nrows, unsigned ncols>
667 bool
669 {
670  T one(1);
671  for (unsigned int i = 0; i < nrows; ++i)
672  for (unsigned int j = 0; j < ncols; ++j)
673  {
674  T xm = this->data_[i][j];
675  abs_t absdev = (i == j) ? vnl_math::abs(xm - one) : vnl_math::abs(xm);
676  if (absdev > tol)
677  return false;
678  }
679  return true;
680 }
681 
682 template <class T, unsigned nrows, unsigned ncols>
683 bool
685 {
686  T const zero(0);
687  for (unsigned int i = 0; i < nrows; ++i)
688  for (unsigned int j = 0; j < ncols; ++j)
689  if ( !( this->data_[i][ j] == zero) )
690  return false;
691 
692  return true;
693 }
694 
695 template <class T, unsigned nrows, unsigned ncols>
697 ::is_equal(vnl_matrix_fixed<T,nrows,ncols> const& rhs, double tol) const
698 {
699  if (this == &rhs) // same object => equal.
700  return true;
701 
702  if (this->rows() != rhs.rows() || this->cols() != rhs.cols())
703  return false; // different sizes => not equal.
704 
705  for (unsigned int i = 0; i < nrows; ++i)
706  for (unsigned int j = 0; j < ncols; ++j)
707  if (vnl_math::abs(this->data_[i][j] - rhs.data_[i][j]) > tol)
708  return false; // difference greater than tol
709 
710  return true;
711 }
712 
713 template <class T, unsigned nrows, unsigned ncols>
714 bool
716 {
717  for (unsigned int i = 0; i < nrows; ++i)
718  for (unsigned int j = 0; j < ncols; ++j)
719  if (vnl_math::abs(this->data_[i][j]) > tol)
720  return false;
721 
722  return true;
723 }
724 
725 template <class T, unsigned nrows, unsigned ncols>
726 bool
728 {
729  for (unsigned int i = 0; i < nrows; ++i)
730  for (unsigned int j = 0; j < ncols; ++j)
731  if (vnl_math::isnan(this->data_[i][j]))
732  return true;
733 
734  return false;
735 }
736 
737 template <class T, unsigned nrows, unsigned ncols>
738 bool
740 {
741  for (unsigned int i = 0; i < nrows; ++i)
742  for (unsigned int j = 0; j < ncols; ++j)
743  if (!vnl_math::isfinite(this->data_[i][j]))
744  return false;
745 
746  return true;
747 }
748 
749 //: Abort if any element of M is inf or nan
750 template <class T, unsigned nrows, unsigned ncols>
751 void
753 {
754  if (is_finite())
755  return;
756 
757  std::cerr << "\n\n" __FILE__ ": " << __LINE__ << ": matrix has non-finite elements\n";
758 
759  if (rows() <= 20 && cols() <= 20)
760  std::cerr << __FILE__ ": here it is:\n" << *this << '\n';
761  else
762  {
763  std::cerr << __FILE__ ": it is quite big (" << rows() << 'x' << cols() << ")\n"
764  << __FILE__ ": in the following picture '-' means finite and '*' means non-finite:\n";
765 
766  for (unsigned int i=0; i<rows(); ++i)
767  {
768  for (unsigned int j=0; j<cols(); ++j)
769  std::cerr << char(vnl_math::isfinite(this->data_[i][ j]) ? '-' : '*');
770  std::cerr << '\n';
771  }
772  }
773  std::cerr << __FILE__ ": calling abort()\n";
774  std::abort();
775 }
776 
777 //: Abort unless M has the given size.
778 template <class T, unsigned nrows, unsigned ncols>
779 void
781 {
782  if (nrows!=rs || ncols!=cs)
783  {
784  std::cerr << __FILE__ ": size is " << nrows << 'x' << ncols
785  << ". should be " << rs << 'x' << cs << std::endl;
786  std::abort();
787  }
788 }
789 
790 template <class T, unsigned nrows, unsigned ncols>
791 bool
793 {
794  if (!s.good())
795  {
796  std::cerr << __FILE__ ": vnl_matrix_fixed<T,nrows,ncols>::read_ascii: Called with bad stream\n";
797  return false;
798  }
799 
800  for (unsigned int i = 0; i < nrows; ++i)
801  for (unsigned int j = 0; j < ncols; ++j)
802  s >> this->data_[i][j];
803 
804  return s.good() || s.eof();
805 }
806 
807 
808 template <class T, unsigned nrows, unsigned ncols>
811 {
812  for (unsigned int r1 = 0; 2*r1+1 < nrows; ++r1)
813  {
814  const unsigned int r2 = nrows - 1 - r1;
815  for (unsigned int c = 0; c < ncols; ++c)
816  {
817  std::swap(this->data_[r1][c], this->data_[r2][c]);
818  }
819  }
820  return *this;
821 }
822 
823 
824 template <class T, unsigned nrows, unsigned ncols>
827 {
828  for (unsigned int c1 = 0; 2*c1+1 < ncols; ++c1)
829  {
830  const unsigned int c2 = ncols - 1 - c1;
831  for (unsigned int r = 0; r < nrows; ++r)
832  {
833  std::swap(this->data_[r][c1], this->data_[r][c2]);
834  }
835  }
836  return *this;
837 }
838 
839 template <class T, unsigned nrows, unsigned ncols>
842 {
843  abs_t m(0);
844  for (unsigned int j=0; j<ncols; ++j)
845  {
846  abs_t t(0);
847  for (unsigned int i=0; i<nrows; ++i)
848  t += vnl_math::abs( this->data_[i][j] );
849  if (t > m)
850  m = t;
851  }
852  return m;
853 }
854 
855 template <class T, unsigned nrows, unsigned ncols>
858 {
859  abs_t m(0);
860  for (unsigned int i=0; i<nrows; ++i)
861  {
862  abs_t t(0);
863  for (unsigned int j=0; j<ncols; ++j)
864  t += vnl_math::abs( this->data_[i][j] );
865  if (t > m)
866  m = t;
867  }
868  return m;
869 }
870 
871 //: Transpose square matrix M in place.
872 template <class T, unsigned nrows, unsigned ncols>
875 {
876  assert(nrows==ncols); // cannot inplace_transpose non-square fixed size matrix
877  for (unsigned i = 0; i < nrows; ++i)
878  for (unsigned j = i+1; j < ncols; ++j)
879  {
880  T t = this->data_[i][j];
881  this->data_[i][j] = this->data_[j][i];
882  this->data_[j][i] = t;
883  }
884  return *this;
885 }
886 
887 template <class T, unsigned m, unsigned n>
888 T const*
890 {
891  return data_[0];
892 }
893 
894 template <class T, unsigned m, unsigned n>
895 T *
897 {
898  return data_[0];
899 }
900 
901 template <class T, unsigned m, unsigned n>
904 {
905  vnl_matrix_fixed<T,m,n> out; // = a.column() * b.row()
906  for (unsigned int i = 0; i < m; ++i)
907  for (unsigned int j = 0; j < n; ++j)
908  out[i][j] = a[i] * b[j];
909  return out;
910 }
911 
912 #define VNL_OUTER_PRODUCT_FIXED_INSTANTIATE( T, M, N ) \
913 template VNL_EXPORT vnl_matrix_fixed<T,M,N > outer_product(vnl_vector_fixed<T,M > const&,\
914  vnl_vector_fixed<T,N > const& )
915 
916 #undef VNL_MATRIX_FIXED_INSTANTIATE
917 #define VNL_MATRIX_FIXED_INSTANTIATE(T, M, N) \
918 template class VNL_EXPORT vnl_matrix_fixed<T,M,N >; \
919 VNL_OUTER_PRODUCT_FIXED_INSTANTIATE( T, M, N )
920 
921 #endif // vnl_matrix_fixed_hxx_
unsigned int cols() const
Return the number of columns.
Definition: vnl_matrix.h:183
vnl_vector_fixed< T, num_rows > apply_rowwise(T(*f)(vnl_vector_fixed< T, num_cols > const &)) const
Make a vector by applying a function across rows.
static void conjugate(T const *, T *, unsigned)
vnl_matrix_fixed & inplace_transpose()
Transposes this matrix efficiently, if it is square, and returns it.
vnl_vector_fixed< T, num_rows > get_column(unsigned col) const
Get a vector equal to the given column.
vnl_matrix_fixed & normalize_columns()
Normalizes each column so it is a unit vector, and returns "*this".
vnl_matrix_fixed & fliplr()
Reverses the order of columns, and returns "*this".
void swap(double &a, double &b)
unsigned int cols() const
Return the number of columns.
Complex additions to vnl_math.
void assert_finite_internal() const
Abort if any element of M is inf or nan.
vnl_vector_fixed< T, num_rows *num_cols > flatten_column_major() const
Flatten column-major (Fortran-style).
vnl_matrix_fixed & set_diagonal(vnl_vector< T > const &)
Sets the diagonal elements of this matrix to the specified list of values.
vnl_matrix< T > get_rows(vnl_vector< unsigned int > i) const
Get a matrix composed of rows from the indices specified in the supplied vector.
bool is_equal(vnl_matrix_fixed< T, num_rows, num_cols > const &rhs, double tol) const
Return true if all elements of both matrices are equal, within given tolerance.
bool is_zero() const
Return true if all elements equal to zero.
T const * data_block() const
Access the contiguous block storing the elements in the matrix row-wise. O(1).
vnl_matrix_fixed & set_row(unsigned i, T const *v)
Set the elements of the i'th row to v[i] (No bounds checking).
#define m
Definition: vnl_vector.h:43
static void mul(const T *a, const T *b, T *r)
size_t size() const
Return the length, number of elements, dimension of this vector.
Definition: vnl_vector.h:126
vnl_matrix_fixed & update(vnl_matrix< T > const &, unsigned top=0, unsigned left=0)
Set values of this matrix to those of M, starting at [top,left].
vnl_matrix< T > get_n_columns(unsigned colstart, unsigned n) const
Get n columns beginning at colstart.
vnl_matrix_fixed & scale_column(unsigned col, T value)
Scales elements in given column by a factor T, and returns "*this".
bool is_identity() const
Return true if all elements equal to identity.
Namespace with standard math functions.
static void sub(const T *a, const T *b, T *r)
void vnl_error_matrix_row_index(char const *fcn, int r)
Raise exception for invalid row index.
Definition: vnl_error.cxx:51
Fixed size, stack-stored, space-efficient matrix.
Definition: vnl_fwd.h:23
vnl_matrix_fixed & scale_row(unsigned row, T value)
Scales elements in given row by a factor T, and returns "*this".
void vnl_error_matrix_col_index(char const *fcn, int c)
Raise exception for invalid col index.
Definition: vnl_error.cxx:61
unsigned int rows() const
Return the number of rows.
bool has_nans() const
Return true if matrix contains NaNs.
vnl_bignum squared_magnitude(vnl_bignum const &x)
Definition: vnl_bignum.h:433
static void apply(T const *, unsigned, T(*f)(T), T *v_out)
void assert_size_internal(unsigned, unsigned) const
Abort unless M has the given size.
vnl_vector< T > get_diagonal() const
Return a vector with the content of the (main) diagonal.
#define v
Definition: vnl_vector.h:42
abs_t operator_inf_norm() const
vnl_matrix_fixed & operator=(const vnl_matrix_fixed &rhs)=default
Copy another vnl_matrix_fixed<T,m,n> into this.
bool isnan(vnl_bignum const &)
Definition: vnl_bignum.h:435
bool is_finite() const
Return true if finite.
T data_[num_rows][num_cols]
bool read_ascii(std::istream &s)
vnl_matrix_fixed & set_identity()
Sets this matrix to an identity matrix, then returns "*this".
void swap(vnl_matrix_fixed< T, num_rows, num_cols > &that)
Swap this matrix with that matrix.
vnl_matrix< T > extract(unsigned r, unsigned c, unsigned top=0, unsigned left=0) const
Extract a sub-matrix of size r x c, starting at (top,left).
An ordinary mathematical matrix.
Definition: vnl_adjugate.h:22
vnl_matrix_fixed< T, num_cols, num_rows > transpose() const
Return transpose.
vnl_matrix< T > get_columns(vnl_vector< unsigned int > i) const
Get a matrix composed of columns from the indices specified in the supplied vector.
void print(std::ostream &os) const
Print matrix to os in some hopefully sensible format.
vnl_matrix_fixed & fill(T)
Sets all elements of matrix to specified value, and returns "*this".
bool isfinite(vnl_bignum const &x)
Definition: vnl_bignum.h:436
static bool equal(const T *a, const T *b)
Mathematical vector class, templated by type of element.
Definition: vnl_fwd.h:16
VNL_EXPORT vnl_matrix_fixed< T, m, n > outer_product(vnl_vector_fixed< T, m > const &a, vnl_vector_fixed< T, n > const &b)
T const * data_block() const
Access the contiguous block storing the elements in the matrix row-wise. O(1).
Definition: vnl_matrix.h:601
Fixed length stack-stored, space-efficient vector.
Definition: vnl_fwd.h:22
vnl_vector_fixed< T, num_rows *num_cols > flatten_row_major() const
Flatten row-major (C-style).
fixed size matrix
T & operator()(unsigned r, unsigned c)
Access an element for reading or writing.
Fixed length stack-stored vector.
abs_t operator_one_norm() const
vnl_matrix_fixed apply(T(*f)(T)) const
Make a new matrix by applying function to each element.
vnl_bignum abs(vnl_bignum const &x)
Definition: vnl_bignum.h:432
vnl_matrix_fixed & copy_in(T const *)
Fills (laminates) this matrix with the given data, then returns it.
void vnl_error_matrix_dimension(char const *fcn, int r1, int c1, int r2, int c2)
Raise exception for invalid dimensions.
Definition: vnl_error.cxx:70
unsigned int rows() const
Return the number of rows.
Definition: vnl_matrix.h:179
vnl_matrix_fixed & fill_diagonal(T)
Sets all diagonal elements of matrix to specified value; returns "*this".
vnl_matrix< T > get_n_rows(unsigned rowstart, unsigned n) const
Get n rows beginning at rowstart.
vnl_matrix_fixed & set_column(unsigned i, T const *v)
Set the elements of the i'th column to v[i] (No bounds checking).
void copy_out(T *) const
Fills the given array with this matrix.
iterator begin()
Iterator pointing to start of data.
unsigned int size() const
Return the total number of elements stored by the matrix.
vnl_matrix_fixed< T, num_cols, num_rows > conjugate_transpose() const
Return conjugate transpose.
static void div(const T *a, const T *b, T *r)
vnl_vector_fixed< T, num_cols > apply_columnwise(T(*f)(vnl_vector_fixed< T, num_rows > const &)) const
Make a vector by applying a function across columns.
T get(size_t i) const
Get value at element i.
Definition: vnl_vector.h:415
vnl_matrix_fixed & normalize_rows()
Normalizes each row so it is a unit vector, and returns "*this".
unsigned int columns() const
Return the number of columns.
Definition: vnl_matrix.h:187
vnl_matrix_fixed & flipud()
Reverses the order of rows, and returns "*this".
vnl_matrix_fixed & set_columns(unsigned starting_column, vnl_matrix< T > const &M)
Set columns to those in M, starting at starting_column, then return *this.
static void add(const T *a, const T *b, T *r)
vnl_vector_fixed< T, num_cols > get_row(unsigned row) const
Get a vector equal to the given row.
vnl_c_vector< T >::abs_t abs_t
Type def for norms.