1 #ifndef GCP_UTIL_MATRIX_H
2 #define GCP_UTIL_MATRIX_H
14 #include "gcp/util/common/Exception.h"
15 #include "gcp/util/common/LogStream.h"
16 #include "gcp/util/common/Vector.h"
30 std::ostream& operator<<(std::ostream& os,
34 std::ostringstream& operator<<(std::ostringstream& os,
73 Matrix(
unsigned nRow,
unsigned nCol);
153 type
det(
unsigned i,
unsigned j);
163 type
cofactor(
unsigned iRow,
unsigned iCol);
179 friend std::ostream& gcp::util::operator << <>
185 friend std::ostringstream& gcp::util::operator << <>
243 for(
unsigned irow=0; irow < nRow_; irow++) {
244 data_[irow].resize(nCol_);
258 for(
unsigned irow=0; irow < nRow; irow++)
259 data_[irow].resize(nCol);
279 if(iRow > data_.size()-1) {
280 errStr.initMessage(
true);
281 errStr <<
"Matrix has no row: " << iRow;
303 if(mat.data_.size() == 0 || data_.size() == 0) {
304 errStr.appendMessage(
true,
"Zero-size dimension encountered");
311 for(
unsigned iRow=0; iRow < mat.data_.size(); iRow++)
312 if(mat.data_[iRow].size() != mat.nCol_) {
313 errStr.appendMessage(
true,
"Matrix has variable dimensions");
317 for(
unsigned iRow=0; iRow < data_.size(); iRow++)
318 if(data_[iRow].size() != nCol_) {
319 errStr.appendMessage(
true,
"Matrix has variable dimensions");
325 if(nRow_ != mat.nCol_ || nCol_ != mat.nRow_)
326 errStr.appendMessage(
true,
"Matrices have incompatible dimensions");
336 for(
unsigned iRow=0; iRow < nRow_; iRow++)
337 for(
unsigned iCol=0; iCol < mat.nCol_; iCol++) {
339 for(
unsigned j=0; j < nCol_; j++) {
341 result[iRow][iCol] = data_[iRow][j] * mat.data_[j][iCol];
344 result[iRow][iCol] += data_[iRow][j] * mat.data_[j][iCol];
360 if(nCol_==0 || vec.
size()==0) {
361 errStr.appendMessage(
true,
"zero dimension encountered");
366 if(nCol_ != vec.
size()) {
367 errStr.appendMessage(
true,
"vector has incompatible dimensions");
380 for(
unsigned iRow=0; iRow < nRow_; iRow++)
381 for(
unsigned j=0; j < nCol_; j++) {
383 result[iRow] = data_[iRow][j] * vec[j];
386 result[iRow] += data_[iRow][j] * vec[j];
401 for(
unsigned iRow=0; iRow < nRow_; iRow++)
402 for(
unsigned iCol=0; iCol < nCol_; iCol++)
403 result[iRow][iCol] *= fac;
414 for(
unsigned iRow=0; iRow < nRow_; iRow++)
415 for(
unsigned iCol=0; iCol < nCol_; iCol++)
416 result[iRow][iCol] /= fac;
427 for(
unsigned iRow=0; iRow < nRow_; iRow++)
428 for(
unsigned iCol=0; iCol < nCol_; iCol++)
429 result[iRow][iCol] += fac;
440 for(
unsigned iRow=0; iRow < nRow_; iRow++)
441 for(
unsigned iCol=0; iCol < nCol_; iCol++)
442 result[iRow][iCol] -= fac;
460 if(mat.nRow_==0 || vec.
size()==0) {
461 errStr.appendMessage(
true,
"zero dimension encountered");
466 if(mat.nRow_ != vec.
size()) {
467 errStr.appendMessage(
true,
"vector has incompatible dimensions");
476 result.resize(mat.nCol_);
480 for(
unsigned iCol=0; iCol < mat.nCol_; iCol++)
481 for(
unsigned j=0; j < mat.nRow_; j++) {
483 result[iCol] = mat.data_[j][iCol] * vec[j];
486 result[iCol] += mat.data_[j][iCol] * vec[j];
497 Matrix<type> operator*(
unsigned fac, Matrix<type>& mat)
503 Matrix<type> operator*(
int fac, Matrix<type>& mat)
509 Matrix<type> operator*(
float fac, Matrix<type>& mat)
515 Matrix<type> operator*(
double fac, Matrix<type>& mat)
524 std::ostream& operator<<(std::ostream& os,
527 for(
unsigned iRow=0; iRow < mat.nRow_; iRow++) {
529 for(
unsigned iCol=0; iCol < mat.nCol_; iCol++) {
532 os << std::setw(10) << std::setprecision(4) << mat.data_[iRow][iCol];
534 os <<
"|" << std::endl;
544 std::ostringstream& operator<<(std::ostringstream& os,
547 for(
unsigned iRow=0; iRow < mat.nRow_; iRow++) {
549 for(
unsigned iCol=0; iCol < mat.nCol_; iCol++) {
552 os << mat.data_[iRow][iCol];
554 os <<
"|" << std::endl;
568 for(
unsigned i=0; i < nRow_; i++)
569 for(
unsigned j=0; j < nCol_; j++)
570 result.data_[j][i] = data_[i][j];
590 for(
unsigned i=0; i < nRow_; i++)
591 for(
unsigned j=0; j < nCol_; j++) {
592 prefac = (i+j)%2 == 0 ? 1 : -1;
593 result.data_[i][j] = prefac * determinant(i, j);
612 type deter = determinant();
614 if(::std::isfinite(1.0/((
double)deter)))
617 ThrowError(
"Matrix is not invertible.");
634 ThrowError(
"Not an N x N matrix");
639 for(
unsigned i=1; i < nRow_; i++)
640 result += data_[i][i];
652 ThrowError(
"Not and N x N matrix");
656 ThrowError(
"Cannot determine cofactors for dimensions < 2");
659 int prefac = (i+j)%2 == 0 ? 1 : -1;
661 return prefac * determinant(i, j);
673 ThrowError(
"Not and N x N matrix");
681 return data_[0][0] * data_[1][1] - data_[1][0] * data_[0][1];
685 for(
unsigned iCol=0; iCol < nCol_; iCol++) {
687 sum = data_[0][iCol] * cofactor(0, iCol);
690 sum += data_[0][iCol] * cofactor(0, iCol);
703 return determinant();
713 ThrowError(
"Not and N x N matrix");
717 ThrowError(
"Cannot compute determinant for dimensions < 2");
731 return determinant(i, j);
740 if(nCol_ == 1 || nRow_ == 1) {
741 ThrowError(
"Matrix dimensions cannot be reduced");
750 for(
unsigned iRow=0, iRowRed=0; iRow < nRow_; iRow++) {
754 for(
unsigned iCol=0, iColRed=0; iCol < nCol_; iCol++) {
757 result.data_[iRowRed][iColRed] = data_[iRow][iCol];
774 #endif // End #ifndef GCP_UTIL_MATRIX_H
bool isError()
Definition: LogStream.cc:55
void report()
Definition: LogStream.cc:194
Matrix< type > reduce(unsigned iRow, unsigned iCol)
Definition: Matrix.h:738
type determinant()
Definition: Matrix.h:668
void operator=(const Matrix< type > &mat)
Definition: Matrix.h:234
Matrix< type > adjoint()
Definition: Matrix.h:585
Vector< type > & operator[](unsigned iRow)
Definition: Matrix.h:275
virtual ~Matrix()
Definition: Matrix.h:269
void resize(unsigned n)
Definition: Vector.h:145
unsigned size()
Definition: Vector.h:64
Matrix< type > operator+(T)
Definition: Matrix.h:423
Matrix< type > transpose()
Definition: Matrix.h:564
Definition: LogStream.h:21
Matrix< type > inverse()
Definition: Matrix.h:609
type trace()
Definition: Matrix.h:631
Matrix()
Definition: Matrix.h:209
Matrix< type > operator-(T)
Definition: Matrix.h:436
type cofactor(unsigned iRow, unsigned iCol)
Definition: Matrix.h:649
Matrix< type > operator/(T)
Definition: Matrix.h:410
Matrix< type > operator*(Matrix< type > &mat)
Definition: Matrix.h:297
type det()
Definition: Matrix.h:701