25 #include <bias_config.h>
26 #include <Base/Common/W32Compat.hh>
28 #ifndef BIAS_SKIP_DLL_CONSISTENCY_CHECK
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!
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!
39 #endif // BIAS_SKIP_DLL_CONSISTENCY_CHECK
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>
66 : TNT::
Matrix<T>(rows, cols, s)
73 for (
int r=0; r<3; r++){
74 for (
int c=0; c<3; c++){
75 (*this)[r][c] = mat[r][c];
91 if (row_to_use >= this->num_rows()) {
93 BIASERR(
"dim of matrix is (" << this->num_rows() <<
" x " << this->num_cols() <<
95 BIASERR(
"cannot normalize cols by elements in row " << row_to_use <<
102 for (
int col = 0; col < this->num_cols(); col++) {
104 divisor = (*this)[row_to_use][col];
105 if (fabs(divisor) > DOUBLE_EPSILON) {
108 for (
int row = 0; row < this->num_cols(); row++) {
111 (*this)[row][col] = ((*this)[row][col]) / (T) divisor;
115 BIASERR(
"could not divide by " << divisor <<
116 " because it is too close to zero. DOUBLE_EPSILON= "
118 BIASERR(
"skipping normalization of this column.");
123 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
127 BIASERR(
"Not implemented for BIAS::Polynom");
137 if (col_to_use >= this->num_cols()) {
139 BIASERR(
"dim of matrix is (" << this->num_rows() <<
"," << this->num_cols() <<
141 BIASERR(
"cannot normalize rows by elements in col " << col_to_use
146 for (
int row = 0; row < this->num_rows(); row++) {
148 divisor = (*this)[row][col_to_use];
149 if (fabs(divisor) > DOUBLE_EPSILON) {
152 for (
int col = 0; col < this->num_rows(); col++) {
155 (*this)[row][col] = ((*this)[row][col]) / (T) divisor;
159 BIASERR(
"could not divide by " << divisor <<
160 " because it is too close to zero. DOUBLE_EPSILON= "
162 BIASERR(
"skipping normalization of this column.");
167 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
171 BIASERR(
"Not implemented for BIAS::Polynom");
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);
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);
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])));
205 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
209 BIASERR(
"Not implemented for BIAS::Polynom");
217 for (
int j = 0; j < this->num_cols(); j++)
219 ((*
this)[NoRow][j]) = ((*
this)[NoRow][j]) * scale;
226 for (
int i = 0; i < this->num_rows(); i++)
228 (*
this)[i][NoCol] = (*this)[i][NoCol] * scale;
235 BIASASSERT(row >= 0 && row < this->num_rows());
238 const unsigned int numcols = this->num_cols();
242 for (
unsigned int col = 0; col < numcols; col++) {
243 vec[col] = (*this)[row][col];
254 BIASASSERT(col >= 0 && col < this->num_cols());
255 const unsigned int numrows = this->num_rows();
258 for (
unsigned int row = 0; row < numrows; row++) {
259 vec[row] = (*this)[row][col];
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];
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];
286 const size_t numRows,
const size_t numCols,
289 size_t m = size_t(this->m_);
290 size_t n = size_t(this->n_);
292 BIASASSERT((startRow+numRows <= m)&&(startCol+numCols <= n));
293 BIASASSERT((numRows != 0)&&(numCols != 0));
295 if ((startRow+numRows != m)||(startCol+numCols != n))
296 submatrix.newsize(numRows,numCols);
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);
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]);
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]);
333 const size_t startRowInSub,
const size_t startColInSub,
334 const size_t numRows,
const size_t numCols)
336 size_t n = size_t(this->n_);
337 size_t nS = size_t(submatrix.n_);
339 BIASASSERT((startRowInThis+numRows <=
size_t(this->m_))&&(startColInThis+numCols <= n));
340 BIASASSERT((startRowInSub+numRows <= (
size_t)submatrix.m_)&&(startColInSub+numCols <= nS));
342 if ((numRows == 0)||(numCols == 0))
return;
344 for (
size_t i=0; i < numRows; i++) {
345 memcpy(this->v_+(i+startRowInThis)*n+startColInThis,
346 submatrix.GetData() + (i+startRowInSub)*nS + startColInSub,
356 BIASASSERT((startRowInThis+3 <=
size_t(this->m_))
357 &&(startColInThis+3 <=
size_t(this->n_)));
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 ]
372 BIASASSERT((startRowInThis+3 <=
size_t(this->m_))
373 &&(startColInThis <
size_t(this->n_)));
375 for (
size_t m=0; m < 3; m++) {
376 this->v_[(m+startRowInThis)*this->n_ + startColInThis]
386 for (
int i = 0; i < this->num_cols() && i < this->num_rows(); i++) {
412 register const T* dataP = GetDataLast();
415 for(; dataP >= GetData(); dataP--)
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]);
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];
452 register const T* dataP = GetDataLast();
453 register T result = *dataP;
455 for(; dataP >= GetData(); dataP--)
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]);
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;
489 BIASERR(
"does not exist for this storaget type");
496 max = min = fabs( (*GetDataLast()) );
497 for(
register const double* dataP = GetDataLast(); dataP >= GetData(); dataP--) {
499 if (fabs(*dataP)<min) min = fabs(*dataP);
500 else if (fabs(*dataP)>max) max = fabs(*dataP);
509 for(
register const T* dataP = GetDataLast(); dataP >= GetData(); dataP--)
510 result = result + T(*dataP);
513 result = result/T(GetNumElements());
519 std::ifstream fs( filename.c_str() );
533 std::ofstream fs( filename.c_str() );
549 BIASERR(
"Invalid ostream");
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] <<
" ";
557 ostr <<
"; ..." << endl;
559 ostr <<
"];" << endl;
569 filein.open(filename, ios::in|ios::binary);
570 if ( !filein.is_open() )
572 cerr <<
"Error opening file '" << filename <<
"'" << endl;
578 filein.read( (
char*) &m,
sizeof(
int) );
579 filein.read( (
char*) &n,
sizeof(
int) );
581 if ( m!=this->m_ || n!=this->n_ )
583 BIASERR(
"Matrix has wrong dimension! This one is "
584 << this->m_ <<
"x" << this->n_ <<
" but file is "
585 << m <<
"x" << n <<
"." << endl);
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) );
604 fileout.open(filename, ios::out|ios::binary);
605 if ( !fileout.is_open() )
607 cerr <<
"Error opening file '" << filename <<
"'" << endl;
612 fileout.write( (
char*) &this->m_,
sizeof(
int) );
613 fileout.write( (
char*) &this->n_,
sizeof(
int) );
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) );
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 )
642 BIASERR(
"Epsilon environment is not implemented for this type!");
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 )
657 for (
int i=0; i<this->num_rows(); i++)
658 for (
int j=0; j<this->num_cols(); j++)
660 if ( i==j && fabs((*
this)[i][j]-1.0) > eps )
662 else if ( i!=j && fabs((*
this)[i][j]) > eps )
673 BIASERR(
"Epsilon environment is not implemented for this type!");
676 for (
int i=0; i<this->num_rows(); i++)
677 for (
int j=0; j<this->num_cols(); j++)
679 if ( i==j && (*
this)[i][j]!=1 )
681 else if ( i!=j && (*
this)[i][j] != 0 )
690 unsigned int rows = this->num_rows();
691 unsigned int cols = this->num_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];
703 unsigned int A_rows = this->num_rows();
704 unsigned int A_cols = this->num_cols();
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];
728 const int numc = this->num_cols();
729 for (
int c=0; c<numc; c++) {
731 (*this)[i][c] = (*this)[r][c];
737 #define MDOUT(arg) {}
743 const int numr = this->num_rows(), numc = this->num_cols();
744 const int max = min(numr, numc);
747 for (
int r=0; r<max; r++){
748 MDOUT(
"working row: "<<r<<endl);
751 for ( ;r+offs<numc && (*this)[r][r+offs]==0.; offs++){
753 MDOUT(*
this<<
"\nsearching for the next row with non-zero element "
754 <<
"in current column "<<r+offs<<endl);
756 for (rr=r+1; rr<numr && (*this)[rr][r+offs]==0.; rr++){}
758 MDOUT(
"found next non-zero element in column "<<r+offs<<
" and row "<<rr
759 <<
", swapping rows"<<endl);
763 MDOUT(
"only zeros below ["<<r<<
"]["<<r+offs<<
"], increasing offset\n");
767 MDOUT(
"no further non-zero elements below and right\n");
770 MDOUT(
"working column: "<<r+offs<<endl);
773 BIASASSERT((*
this)[r][r+offs] != 0.0);
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;
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];
793 MDOUT(
"finished manipulation of row "<<r<<
"\n"<<*
this<<endl<<
"---------\n");
797 MDOUT(
"zero the elements above the leading element in each row\n");
798 for (
int r=numr-1; r>=0; --r) {
801 for (c=r; c<numc && (*this)[r][c]==0.; c++){}
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];
811 MDOUT(
"finished computation of reduced row echelon form: "<<*
this<<endl);
818 if ( row+data.
num_rows() > this->num_rows() ||
819 col+data.
num_cols() > this->num_cols() ){
821 BEXCEPTION(
"cannot carry data, own size to small");
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];
836 if ( row+data.
size() > this->num_rows() ||
837 col >= this->num_cols() ){
839 BEXCEPTION(
"cannot carry data, own size to small");
841 const int num = data.
size();
843 for (r=0, tr=row; r<num; r++, tr++){
844 (*this)[tr][col] = data[r];
853 if ( row >= this->num_rows() ||
854 col+data.
size() > this->num_cols() ){
856 BEXCEPTION(
"cannot carry data, own size to small");
858 const int num = data.
size();
860 for (c=0, tc=col; c<num; c++, tc++){
861 (*this)[row][tc] = data[c];
872 template class BIASMathBase_EXPORT BIAS::Matrix<type>;\
873 template class BIASMathBase_EXPORT TNT::Matrix<type>;\
885 #ifdef BUILD_ALLOW_NON_INTEGRAL_MATRIX_ELEMENTS
Matrix< T > & operator=(const Matrix< T > &A)
void ScaleCol(int NoCol, T scale)
Scales column NoCol with scale.
class for Polynoms of arbitary order
void NormalizeCols()
Normalizes each coloumn to L_2 norm one.
Subscript num_cols() const
class for column vectors with arbitrary size
T GetMin() const
Returns the minimum value of the matrix elements.
T Normalize()
Normalizes the matrix by the entry with the biggest absolute value by dividing all elements with this...
void NormalizeColsToOne(const int norm_row_index)
divides each column of the matrix through the element norm_row_index.
void Fill(const T &scalar)
Takes the elements of a Vector and put them as diagonal elements into a matrix.
void GetAbsMaxMin(T &max, T &min) const
return biggest and smallest absolute values
Matrix< T > & newsize(Subscript M, Subscript N)
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.
Vector< T > GetCol(const int &col) const
return a copy of column "col", zero based counting
void SetRow(const int row, const Vector< T > &data)
set a row of matrix from vector
void AbsIP()
absolute values of all elements of the matrix (in place)
void SetCol(const int row, const Vector< T > &data)
set a col of matrix from vector
Vector< T > & newsize(Subscript N)
void NormalizeRowsToOne(const int norm_col_index)
divides each row of the matrix through the element norm_col_index.
Vector< T > GetRow(const int &row) const
return a copy of row "row" of this matrix, zero based counting
is a 'fixed size' quadratic matrix of dim.
class Vector3 contains a Vector of fixed dim.
matrix class with arbitrary size, indexing is row major.
void GetMaxMin(T &max, T &min) const
return biggest and smallest entry
Subscript num_rows() const
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.
T GetMax() const
Returns the maximum value of the matrix elements.
void NormalizeRows()
Normalizes each row to L2 norm one.
void ScaleRow(int NoRow, T scale)
Scales row NoRow with scale.