Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Matrix.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <bias_config.h>
26 #include <Base/Common/W32Compat.hh>
27 #include <math.h>
28 #ifndef BIAS_SKIP_DLL_CONSISTENCY_CHECK
29 // check for consistency between cmake options and current flags
30 // check works only for VS IDE but not for nmake due to missing _WINDLL definition (TODO)
31 # if defined(WIN32)
32 # if defined(BIAS_BUILD_SHARED_LIBS) && !defined(_WINDLL)
33 # error BIAS BIAS_BUILD_SHARED_LIBS is enabled (DLL build consistency check) but _WINDLL is missing!
34 # endif
35 # if !defined(BIAS_BUILD_SHARED_LIBS) && defined(_WINDLL)
36 # error BIAS BIAS_BUILD_SHARED_LIBS is disbaled (static build consistency check) but _WINDLL is set!
37 # endif
38 # endif // WIN32
39 #endif // BIAS_SKIP_DLL_CONSISTENCY_CHECK
40 
41 
42 #include <Base/Debug/Exception.hh>
43 #include <Base/Math/Matrix.hh>
44 #include <Base/Math/Vector.hh>
45 #include <Base/Math/Vector3.hh>
46 #include <Base/Math/Matrix3x3.hh>
47 #include <Base/Math/Polynom.hh>
48 
49 //additional math constants are not used by default in WIN32 - so set usage
50 
51 #include <algorithm>
52 #include <fstream>
53 
54 
55 using namespace BIAS;
56 using namespace std;
57 
58 namespace BIAS {
59 
60 template<class T>
62 {}
63 
64 template <class T>
65 Matrix<T>::Matrix(int rows, int cols, const std::string & s)
66 : TNT::Matrix<T>(rows, cols, s)
67 {}
68 
69 template <class T>
71  : TNT::Matrix<T>(3, 3)
72 {
73  for (int r=0; r<3; r++){
74  for (int c=0; c<3; c++){
75  (*this)[r][c] = mat[r][c];
76  }
77  }
78 }
79 
80 
81 template <class T>
82 void Matrix<T>::Fill(const T & scalar)
83 {
85 }
86 
87 
88 template <class T>
89 void Matrix<T>::NormalizeColsToOne(const int row_to_use)
90 {
91  if (row_to_use >= this->num_rows()) {
92  // Error, index for row is expected to be in [0...num_rows-1]
93  BIASERR("dim of matrix is (" << this->num_rows() << " x " << this->num_cols() <<
94  ").");
95  BIASERR("cannot normalize cols by elements in row " << row_to_use <<
96  ". aborting. ");
97 
98  } else {
99 
100  // value of row index is OK for normalization
101  double divisor;
102  for (int col = 0; col < this->num_cols(); col++) {
103  // get the divisor to normalize with
104  divisor = (*this)[row_to_use][col];
105  if (fabs(divisor) > DOUBLE_EPSILON) {
106 
107  // normalize one column (= all rows of one column)
108  for (int row = 0; row < this->num_cols(); row++) {
109  // normalize element by dividing it by the row_to_use element of
110  //the same column
111  (*this)[row][col] = ((*this)[row][col]) / (T) divisor;
112  };
113  } else {
114  // could not divide by (nearly) zero
115  BIASERR("could not divide by " << divisor <<
116  " because it is too close to zero. DOUBLE_EPSILON= "
117  << DOUBLE_EPSILON);
118  BIASERR("skipping normalization of this column.");
119  };
120  };
121  };
122 }
123 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
124 template <>
125 void Matrix<BIAS::Polynom>::NormalizeColsToOne(const int row_to_use)
126 {
127  BIASERR("Not implemented for BIAS::Polynom");
128  BIASABORT;
129 }
130 #endif
131 
132 
133 
134 template <class T>
135 void Matrix<T>::NormalizeRowsToOne(const int col_to_use)
136 {
137  if (col_to_use >= this->num_cols()) {
138  // Error, index for row is expected to be in [0...num_rows-1]
139  BIASERR("dim of matrix is (" << this->num_rows() << "," << this->num_cols() <<
140  ").");
141  BIASERR("cannot normalize rows by elements in col " << col_to_use
142  << ". aborting. ");
143  } else {
144  // value of col index is OK for normalization
145  double divisor;
146  for (int row = 0; row < this->num_rows(); row++) {
147  // get the divisor to normalize with
148  divisor = (*this)[row][col_to_use];
149  if (fabs(divisor) > DOUBLE_EPSILON) {
150 
151  // normalize one row (= all cols of one row)
152  for (int col = 0; col < this->num_rows(); col++) {
153  // normalize element by dividing it by the col_to_use
154  //element of the same column
155  (*this)[row][col] = ((*this)[row][col]) / (T) divisor;
156  };
157  } else {
158  // could not divide by (nearly) zero
159  BIASERR("could not divide by " << divisor <<
160  " because it is too close to zero. DOUBLE_EPSILON= "
161  << DOUBLE_EPSILON);
162  BIASERR("skipping normalization of this column.");
163  };
164  };
165  };
166 }
167 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
168 template <>
169 void Matrix<BIAS::Polynom>::NormalizeRowsToOne(const int col_to_use)
170 {
171  BIASERR("Not implemented for BIAS::Polynom");
172  BIASABORT;
173 }
174 #endif
175 
176 
177 template <class T>
179 {
180  for (int i = 0; i< this->num_rows() ; i++){
181  double scale = GetRow(i).NormL2();
182  for (int j = 0; j < this->num_cols(); j++)
183  (*this)[i][j]=(T)( (*this)[i][j]/scale);
184  }
185 }
186 
187 
188 template <class T>
190 {
191  for (int j = 0; j< this->num_cols() ; j++){
192  double scale = GetCol(j).NormL2();
193  for (int i = 0; i < this->num_rows(); i++)
194  (*this)[i][j]=(T) ((*this)[i][j]/scale);
195  }
196 }
197 
198 template<class T>
200  for (int i = 0; i < this->num_rows(); i++)
201  for (int j = 0; j < this->num_cols(); j++)
202  ((*this)[i][j]) = T(fabs(float((*this)[i][j])));
203 }
204 
205 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
206 template <>
208 {
209  BIASERR("Not implemented for BIAS::Polynom");
210  BIASABORT;
211 }
212 #endif
213 
214 template<class T>
215 void Matrix<T>::ScaleRow(int NoRow, T scale)
216 {
217  for (int j = 0; j < this->num_cols(); j++)
218  //((*this)[NoRow][j]) *= scale;
219  ((*this)[NoRow][j]) = ((*this)[NoRow][j]) * scale;
220 }
221 
222 
223 template<class T>
224 void Matrix<T>::ScaleCol(int NoCol,T scale)
225 {
226  for (int i = 0; i < this->num_rows(); i++)
227  //((*this)[i][NoCol]) *= scale;
228  (*this)[i][NoCol] = (*this)[i][NoCol] * scale;
229 }
230 
231 
232 template<class T>
233 Vector<T> Matrix<T>::GetRow(const int& row) const
234 {
235  BIASASSERT(row >= 0 && row < this->num_rows());
236  // create a new Vector which will be returned
237  // ? faster: copy elements during constructor
238  const unsigned int numcols = this->num_cols();
239  Vector<T> vec(numcols);
240 
241  // copy the elements into the vector:
242  for (unsigned int col = 0; col < numcols; col++) {
243  vec[col] = (*this)[row][col];
244  };
245 
246  return vec;
247 }
248 
249 
250 
251 template <class T>
252 Vector<T> Matrix<T>::GetCol(const int& col) const
253 {
254  BIASASSERT(col >= 0 && col < this->num_cols());
255  const unsigned int numrows = this->num_rows();
256  Vector<T> vec(numrows);
257  // copy the elements into the vector:
258  for (unsigned int row = 0; row < numrows; row++) {
259  vec[row] = (*this)[row][col];
260  };
261  return vec;
262 }
263 
264 template<class T>
265 void Matrix<T>::SetRow(const int row, const Vector<T>& data)
266 {
267  BIASASSERT(row >= 0 && row < this->num_rows());
268  const int numcols = (int)this->num_cols();
269  BIASASSERT(data.size() == numcols);
270  for (register int col=0; col<numcols; col++)
271  (*this)[row][col] = data[col];
272 }
273 
274 template<class T>
275 void Matrix<T>::SetCol(const int col, const Vector<T>& data)
276 {
277  BIASASSERT(col >= 0 && col < this->num_cols());
278  const int numrows = (int)this->num_rows();
279  BIASASSERT(data.size() == numrows);
280  for (register int row=0; row<numrows; row++)
281  (*this)[row][col] = data[row];
282 }
283 
284 template<class T>
285 void Matrix <T>::GetSubMatrix(const size_t startRow, const size_t startCol,
286  const size_t numRows, const size_t numCols,
287  Matrix<T> &submatrix) const
288 {
289  size_t m = size_t(this->m_);
290  size_t n = size_t(this->n_);
291 
292  BIASASSERT((startRow+numRows <= m)&&(startCol+numCols <= n));
293  BIASASSERT((numRows != 0)&&(numCols != 0));
294 
295  if ((startRow+numRows != m)||(startCol+numCols != n))
296  submatrix.newsize(numRows,numCols);
297 
298  for (size_t i=0; i < numRows; i++) {
299  memcpy(submatrix.GetData() + i*numCols,
300  this->v_+(i+startRow)*n+startCol,sizeof(T)*numCols);
301  }
302 }
303 
304 template<class T>
305 void Matrix <T>::GetSubMatrix(const Vector<int> &rows, const Vector<int> &cols,
306  Matrix<T> &submatrix) const
307 {
308  BIASASSERT((submatrix.num_rows() == rows.size())&&(submatrix.num_cols() == cols.size()));
309  for (int m=0; m<rows.size(); m++) {
310  for (int n=0; n<cols.size(); n++) {
311  submatrix[m][n] = *(this->v_ + this->n_*rows[m] + cols[n]);
312  }
313  }
314 }
315 
316 template<class T>
318  const Vector<int> &cols) const
319 {
320  Matrix<T> submatrix(rows.size(),cols.size());
321  for (int m=0; m<rows.size(); m++) {
322  for (int n=0; n<cols.size(); n++) {
323  submatrix[m][n] = *(this->v_ + this->n_*rows[m] + cols[n]);
324  }
325  }
326  return submatrix;
327 }
328 
329 
330 template<class T>
331 void Matrix <T>::SetSubMatrix(const size_t startRowInThis, const size_t startColInThis,
332  const Matrix<T> &submatrix,
333  const size_t startRowInSub, const size_t startColInSub,
334  const size_t numRows, const size_t numCols)
335 {
336  size_t n = size_t(this->n_);
337  size_t nS = size_t(submatrix.n_);
338 
339  BIASASSERT((startRowInThis+numRows <= size_t(this->m_))&&(startColInThis+numCols <= n));
340  BIASASSERT((startRowInSub+numRows <= (size_t)submatrix.m_)&&(startColInSub+numCols <= nS));
341 
342  if ((numRows == 0)||(numCols == 0)) return;
343 
344  for (size_t i=0; i < numRows; i++) {
345  memcpy(this->v_+(i+startRowInThis)*n+startColInThis,
346  submatrix.GetData() + (i+startRowInSub)*nS + startColInSub,
347  sizeof(T)*numCols);
348  }
349 }
350 
351 
352 template<class T>
353 void Matrix<T>::SetSubMatrix(const size_t startRowInThis, const size_t startColInThis,
354  const Matrix3x3<T> &submatrix)
355 {
356  BIASASSERT((startRowInThis+3 <= size_t(this->m_))
357  &&(startColInThis+3 <= size_t(this->n_)));
358 
359  for (size_t m=0; m < 3; m++) {
360  for (size_t n=0; n < 3; n++) {
361  this->v_[(m+startRowInThis)*this->n_ + startColInThis+n ]
362  = submatrix[m][n];
363  }
364  }
365 }
366 
367 
368 template<class T>
369 void Matrix<T>::SetSubMatrix(const size_t startRowInThis, const size_t startColInThis,
370  const Vector3<T> &subvector)
371 {
372  BIASASSERT((startRowInThis+3 <= size_t(this->m_))
373  &&(startColInThis < size_t(this->n_)));
374 
375  for (size_t m=0; m < 3; m++) {
376  this->v_[(m+startRowInThis)*this->n_ + startColInThis]
377  = subvector[m];
378  }
379 }
380 
381 
382 template<class T>
384 {
385  SetZero();
386  for (int i = 0; i < this->num_cols() && i < this->num_rows(); i++) {
387  //cout << "actual: " << i << endl;
388  (*this)[i][i] = 1;
389  }
390 }
391 
392 
393 /*
394 template<class T>
395 void Matrix<T>::set_diagonal_elements(const Vector<T>& argVec,
396  const bool zero_others)
397 {
398  // Check the dimensions
399  BIASASSERT( argVec.size() == min(num_cols(), num_rows()) );
400  // Are the otther elements to be set to zero?
401  if (zero_others)
402  SetZero();
403  for(int i = 0; i < argVec.size(); i++)
404  (*this)[i][i] = argVec[i];
405 }
406 */
407 
408 template<class T>
410 {
411  // initialize result value with last element
412  register const T* dataP = GetDataLast();
413  T result = *dataP;
414 
415  for(; dataP >= GetData(); dataP--)
416  if (*dataP < result)
417  result = *dataP;
418 
419  return result;
420 }
421 
422 template<class T>
424  Matrix<T> out(this->num_rows(),this->num_cols());
425  for(int i=0; i < this->num_rows(); i++)
426  for(int j=0; j < this->num_cols(); j++)
427  if(((*this)[i][j]) <= m[i][j]){
428  out[i][j] = ((*this)[i][j]);
429  }else{
430  out[i][j] = m[i][j];
431  }
432 
433  return out;
434 }
435 
436 template<class T>
438 {
439  T greatest = 0;
440  for (int i=0; i < this->num_rows(); i++)
441  for (int j=0; j < this->num_cols(); j++)
442  if ( ((*this)[i][j])*((*this)[i][j]) > greatest*greatest )
443  greatest = (*this)[i][j];
444  (*this) /= greatest;
445  return greatest;
446 }
447 
448 template<class T>
450 {
451  // initialize result value with last element
452  register const T* dataP = GetDataLast();
453  register T result = *dataP;
454 
455  for(; dataP >= GetData(); dataP--)
456  if (*dataP > result)
457  result = *dataP;
458 
459  return result;
460 }
461 
462 template<class T>
464 Matrix<T> out(this->num_rows(),this->num_cols());
465 for(int i=0; i < this->num_rows(); i++)
466  for(int j=0; j < this->num_cols(); j++)
467  if(((*this)[i][j]) >= m[i][j]){
468  out[i][j] = ((*this)[i][j]);
469  }else{
470  out[i][j] = m[i][j];
471  }
472 
473 return out;
474 }
475 
476 template<class T>
477 void Matrix<T>::GetMaxMin(T& max, T& min) const
478 {
479  max = min = *GetDataLast();
480  for(register const T* dataP = GetDataLast(); dataP >= GetData(); dataP--) {
481  if (*dataP<min) min = *dataP;
482  else if (*dataP>max) max = *dataP;
483  }
484 }
485 
486 template<class T>
487 void Matrix<T>::GetAbsMaxMin(T& max, T& min) const
488 {
489  BIASERR("does not exist for this storaget type");
490  BIASABORT;
491 }
492 
493 template<>
494 void Matrix<double>::GetAbsMaxMin(double& max, double& min) const
495 {
496  max = min = fabs( (*GetDataLast()) );
497  for(register const double* dataP = GetDataLast(); dataP >= GetData(); dataP--) {
498 
499  if (fabs(*dataP)<min) min = fabs(*dataP);
500  else if (fabs(*dataP)>max) max = fabs(*dataP);
501  }
502 }
503 
504 template<class T>
506 {
507  // initialize result
508  T result = 0;
509  for(register const T* dataP = GetDataLast(); dataP >= GetData(); dataP--)
510  result = result + T(*dataP);
511  //result += T(*dataP);
512 
513  result = result/T(GetNumElements());
514  return result;
515 }
516 
517 template<class T>
518 bool Matrix<T>::Load(const std::string & filename){
519  std::ifstream fs( filename.c_str() );
520  if (!fs) {
521  return false; // error, could not open file.
522  } else {
523  // read in
524  fs>>(*this);
525  fs.close();
526  };
527  return true;
528 }
529 
530 
531 template<class T>
532 bool Matrix<T>::Save(const std::string & filename) const {
533  std::ofstream fs( filename.c_str() );
534  if (!fs) {
535  return false; // error, could not open file.
536  } else {
537  // write out to disk
538  fs<<(*this);
539  fs.close();
540  };
541  return true;
542 }
543 
544 
545 template<class T>
546 int Matrix<T>::
547 WriteMatlab(std::ostream& ostr, const std::string& name) const {
548  if (!ostr) {
549  BIASERR("Invalid ostream");
550  return -1;
551  } else {
552  ostr << name << " = [ ..." << endl;
553  for (int i=0; i<this->num_rows(); i++) {
554  for (int j=0; j<=this->num_cols(); j++) {
555  ostr << (*this)[i][j] << " ";
556  }
557  ostr << "; ..." << endl;
558  }
559  ostr << "];" << endl;
560  }
561  return 0;
562 }
563 
564 template<class T>
565 bool Matrix<T>::BinRead(const char * filename) const
566 {
567  ifstream filein;
568  //filein.open(filename, ios::in);
569  filein.open(filename, ios::in|ios::binary);
570  if ( !filein.is_open() )
571  {
572  cerr << "Error opening file '" << filename << "'" << endl;
573  return false;
574  }
575 
576  // read and verify dimension
577  int m,n;
578  filein.read( (char*) &m, sizeof(int) );
579  filein.read( (char*) &n, sizeof(int) );
580 
581  if ( m!=this->m_ || n!=this->n_ )
582  {
583  BIASERR("Matrix has wrong dimension! This one is "
584  << this->m_ << "x" << this->n_ << " but file is "
585  << m << "x" << n << "." << endl);
586  return false;
587  }
588 
589  // read values
590  for(int i=0; i<this->m_; i++)
591  for(int j=0; j<this->n_; j++)
592  filein.read( (char*) &((*this)[i][j]), sizeof(T) );
593 
594  filein.close();
595  return true;
596 }
597 
598 
599 template<class T>
600 bool Matrix<T>::BinWrite(const char * filename) const
601 {
602  ofstream fileout;
603  //fileout.open(filename, ios::out);
604  fileout.open(filename, ios::out|ios::binary);
605  if ( !fileout.is_open() )
606  {
607  cerr << "Error opening file '" << filename << "'" << endl;
608  return false;
609  }
610 
611  // store the dimension
612  fileout.write( (char*) &this->m_, sizeof(int) );
613  fileout.write( (char*) &this->n_, sizeof(int) );
614 
615  // store values
616  for(int i=0; i<this->m_; i++)
617  for(int j=0; j<this->n_; j++)
618  fileout.write( (char*) &((*this)[i][j]), sizeof(T) );
619 
620  fileout.close();
621  return true;
622 }
623 
624 
625 template<>
626 bool Matrix<double>::IsZero( double eps /*=0.0*/) const
627 {
628  bool result=true;
629  for (int i=0; i<this->num_rows(); i++)
630  for (int j=0; j<this->num_cols(); j++)
631  if ( fabs((*this)[i][j]) > eps )
632  result=false;
633  return result;
634 }
635 
636 
637 template<class T>
638 bool Matrix<T>::IsZero( double eps /*=0.0*/) const
639 {
640  if ( eps != 0 )
641  {
642  BIASERR("Epsilon environment is not implemented for this type!");
643  }
644  bool result=true;
645  for (int i=0; i<this->num_rows(); i++)
646  for (int j=0; j<this->num_cols(); j++)
647  if ( (*this)[i][j] != 0 )
648  result=false;
649  return result;
650 }
651 
652 
653 template<>
654 bool Matrix<double>::IsIdentity( double eps /*=0.0*/ ) const
655 {
656  bool result=true;
657  for (int i=0; i<this->num_rows(); i++)
658  for (int j=0; j<this->num_cols(); j++)
659  {
660  if ( i==j && fabs((*this)[i][j]-1.0) > eps )
661  result=false;
662  else if ( i!=j && fabs((*this)[i][j]) > eps )
663  result=false;
664  }
665  return result;
666 }
667 
668 template<class T>
669 bool Matrix<T>::IsIdentity( double eps /*=0.0*/ ) const
670 {
671  if ( eps != 0 )
672  {
673  BIASERR("Epsilon environment is not implemented for this type!");
674  }
675  bool result=true;
676  for (int i=0; i<this->num_rows(); i++)
677  for (int j=0; j<this->num_cols(); j++)
678  {
679  if ( i==j && (*this)[i][j]!=1 )
680  result=false;
681  else if ( i!=j && (*this)[i][j] != 0 )
682  result=false;
683  }
684  return result;
685 }
686 
687 /** vec-operator returns the elements of the matrix columnwise as vector */
688 template<class T>
689 void Matrix<T>::Vec(Vector<T> &dest) const {
690  unsigned int rows = this->num_rows();
691  unsigned int cols = this->num_cols();
692  dest.newsize(rows*cols);
693  for (unsigned int i=0; i<cols; i++) {
694  for (unsigned int j=0; j<rows; j++) {
695  dest[i*rows+j] = (*this)[j][i];
696  }
697  }
698 }
699 
700 /** Kronecker-product with matrix B, result in dest */
701 template<class T>
702 void Matrix<T>::Kronecker(Matrix<T> const B, Matrix<T> &dest) const {
703  unsigned int A_rows = this->num_rows();
704  unsigned int A_cols = this->num_cols();
705  unsigned int B_rows = B.num_rows();
706  unsigned int B_cols = B.num_cols();
707 
708  dest.newsize (A_rows*B_rows, A_cols*B_cols);
709  for (unsigned int i=0; i<A_rows; i++) {
710  for (unsigned int j=0; j<A_cols; j++) {
711  for (unsigned int r=0; r<B_rows; r++) {
712  for (unsigned int s=0; s<B_cols; s++) {
713  dest[i*B_rows+r][j*B_cols+s] = (*this)[i][j] * B[r][s];
714  }
715  }
716  }
717  }
718 }
719 
720 
721 
722 
723 
724 template<class T>
725 void Matrix<T>::SwapRows(const int i, const int r)
726 {
727  T tmp;
728  const int numc = this->num_cols();
729  for (int c=0; c<numc; c++) {
730  tmp = (*this)[i][c];
731  (*this)[i][c] = (*this)[r][c];
732  (*this)[r][c] = tmp;
733  }
734 }
735 
736 //#define MDOUT(arg) if (verbose) cout << arg;
737 #define MDOUT(arg) {}
738 
739 template<class T>
741 {
742  //const bool verbose = false;
743  const int numr = this->num_rows(), numc = this->num_cols();
744  const int max = min(numr, numc);
745  ///<< offset to right from diagonal, the working column is given by r+offs
746  int offs = 0;
747  for (int r=0; r<max; r++){ ///<< r is the working row
748  MDOUT("working row: "<<r<<endl);
749  // search for the next column wich has non zero elements in or
750  // below working row
751  for ( ;r+offs<numc && (*this)[r][r+offs]==0.; offs++){
752  // search for the next row with non-zero element in current column
753  MDOUT(*this<<"\nsearching for the next row with non-zero element "
754  <<"in current column "<<r+offs<<endl);
755  int rr;
756  for (rr=r+1; rr<numr && (*this)[rr][r+offs]==0.; rr++){}
757  if (rr!=numr) {
758  MDOUT("found next non-zero element in column "<<r+offs<<" and row "<<rr
759  <<", swapping rows"<<endl);
760  SwapRows(r, rr);
761  break;
762  }
763  MDOUT("only zeros below ["<<r<<"]["<<r+offs<<"], increasing offset\n");
764  }
765  if (r+offs==numc) {
766  // only zeros below and right of [rr][r+offs]
767  MDOUT("no further non-zero elements below and right\n");
768  break;
769  }
770  MDOUT("working column: "<<r+offs<<endl);
771 
772  /// this is guaranteed by the above
773  BIASASSERT((*this)[r][r+offs] != 0.0);
774 
775  // divide working row by value of working position to get a 1 on the
776  // diagonal
777  T tempval=(*this)[r][r+offs];
778  MDOUT((*this)<<"\nscaling working row by "<<tempval<<endl);
779  for (int col=0; col<numc; col++) {
780  (*this)[r][col]=(*this)[r][col]/tempval;
781  }
782 
783  // eliminate values below working position by subtracting a multiple of
784  // the current row
785  MDOUT("eliminitaing entries in working column ("<<r+offs
786  <<") below working row ("<<r<<")\n");
787  for (long row=r+1; row<numr; ++row) {
788  T wval=(*this)[row][r+offs];
789  for (int col=0; col<numc; col++) {
790  (*this)[row][col]-=wval*(*this)[r][col];
791  }
792  }
793  MDOUT("finished manipulation of row "<<r<<"\n"<<*this<<endl<<"---------\n");
794  }
795 
796  // zero the elements above the leading element in each row
797  MDOUT("zero the elements above the leading element in each row\n");
798  for (int r=numr-1; r>=0; --r) {
799  // search for leading element
800  int c;
801  for (c=r; c<numc && (*this)[r][c]==0.; c++){}
802  // eliminate value above working position by subtracting a multiple of
803  // the current row
804  for (int row=r-1; row>=0; --row) {
805  T wval=(*this)[row][c];
806  for (int col=0; col<numc; ++col) {
807  (*this)[row][col]-=wval*(*this)[r][col];
808  }
809  }
810  }
811  MDOUT("finished computation of reduced row echelon form: "<<*this<<endl);
812 }
813 #undef MDOUT
814 
815 template<class T>
816 void Matrix<T>::Set(const int row, const int col, const Matrix<T> &data)
817 {
818  if ( row+data.num_rows() > this->num_rows() ||
819  col+data.num_cols() > this->num_cols() ){
820  // BIASERR("cannot carry data, own size to small");
821  BEXCEPTION("cannot carry data, own size to small");
822  }
823  const int numr = data.num_rows(), numc = data.num_cols();
824  int r, c, tr, tc;
825  for (r=0, tr=row; r<numr; r++, tr++){
826  for (c=0, tc=col; c<numc; c++, tc++){
827  (*this)[tr][tc] = data[r][c];
828  }
829  }
830 }
831 
832 
833 template<class T>
834 void Matrix<T>::Set(const int row, const int col, const Vector<T> &data)
835 {
836  if ( row+data.size() > this->num_rows() ||
837  col >= this->num_cols() ){
838  // BIASERR("cannot carry data, own size to small");
839  BEXCEPTION("cannot carry data, own size to small");
840  }
841  const int num = data.size();
842  int r, tr;
843  for (r=0, tr=row; r<num; r++, tr++){
844  (*this)[tr][col] = data[r];
845  }
846 }
847 
848 
849 template<class T>
850 void Matrix<T>::SetTranspose(const int row, const int col,
851  const Vector<T> &data)
852 {
853  if ( row >= this->num_rows() ||
854  col+data.size() > this->num_cols() ){
855  // BIASERR("cannot carry data, own size to small");
856  BEXCEPTION("cannot carry data, own size to small");
857  }
858  const int num = data.size();
859  int c, tc;
860  for (c=0, tc=col; c<num; c++, tc++){
861  (*this)[row][tc] = data[c];
862  }
863 }
864 
865 } // namespace BIAS
866 
867 
868 ///
869 /// explicit instantiation
870 ///
871 #define INST(type) \
872 template class BIASMathBase_EXPORT BIAS::Matrix<type>;\
873 template class BIASMathBase_EXPORT TNT::Matrix<type>;\
874 
875 
876 INST(unsigned char)
877 INST(char)
878 INST(float)
879 INST(short)
880 INST(unsigned short)
881 INST(long int)
882 INST(int)
883 INST(unsigned int)
884 INST(double)
885 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
886 INST(BIAS::Polynom)
887 #endif
Matrix< T > & operator=(const Matrix< T > &A)
Definition: cmat.h:285
void ScaleCol(int NoCol, T scale)
Scales column NoCol with scale.
Definition: Matrix.cpp:224
class for Polynoms of arbitary order
Definition: Polynom.hh:46
void NormalizeCols()
Normalizes each coloumn to L_2 norm one.
Definition: Matrix.cpp:189
Subscript num_cols() const
Definition: cmat.h:320
class for column vectors with arbitrary size
T GetMin() const
Returns the minimum value of the matrix elements.
Definition: Matrix.cpp:409
T Normalize()
Normalizes the matrix by the entry with the biggest absolute value by dividing all elements with this...
Definition: Matrix.cpp:437
void NormalizeColsToOne(const int norm_row_index)
divides each column of the matrix through the element norm_row_index.
Definition: Matrix.cpp:89
void Fill(const T &scalar)
Takes the elements of a Vector and put them as diagonal elements into a matrix.
Definition: Matrix.cpp:82
void GetAbsMaxMin(T &max, T &min) const
return biggest and smallest absolute values
Definition: Matrix.cpp:487
Matrix< T > & newsize(Subscript M, Subscript N)
Definition: cmat.h:269
void GetSubMatrix(const size_t startRow, const size_t startCol, const size_t numRows, const size_t numCols, Matrix< T > &submatrix) const
return a submatrix from this.
Definition: Matrix.cpp:285
Vector< T > GetCol(const int &col) const
return a copy of column &quot;col&quot;, zero based counting
Definition: Matrix.cpp:252
void SetRow(const int row, const Vector< T > &data)
set a row of matrix from vector
Definition: Matrix.cpp:265
void AbsIP()
absolute values of all elements of the matrix (in place)
Definition: Matrix.cpp:199
void SetCol(const int row, const Vector< T > &data)
set a col of matrix from vector
Definition: Matrix.cpp:275
Vector< T > & newsize(Subscript N)
Definition: vec.h:220
virtual ~Matrix()
Definition: Matrix.cpp:61
void NormalizeRowsToOne(const int norm_col_index)
divides each row of the matrix through the element norm_col_index.
Definition: Matrix.cpp:135
Vector< T > GetRow(const int &row) const
return a copy of row &quot;row&quot; of this matrix, zero based counting
Definition: Matrix.cpp:233
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
class Vector3 contains a Vector of fixed dim.
Definition: Matrix.hh:53
matrix class with arbitrary size, indexing is row major.
void GetMaxMin(T &max, T &min) const
return biggest and smallest entry
Definition: Matrix.cpp:477
Subscript num_rows() const
Definition: cmat.h:319
void SetSubMatrix(const size_t startRowInThis, const size_t startColInThis, const Matrix< T > &submatrix, const size_t startRowInSub, const size_t startColInSub, const size_t numRows, const size_t numCols)
sets a submatrix in this.
Definition: Matrix.cpp:331
T GetMax() const
Returns the maximum value of the matrix elements.
Definition: Matrix.cpp:449
void NormalizeRows()
Normalizes each row to L2 norm one.
Definition: Matrix.cpp:178
void ScaleRow(int NoRow, T scale)
Scales row NoRow with scale.
Definition: Matrix.cpp:215
Subscript size() const
Definition: vec.h:262