1 #ifndef SZA_UTIL_MATRIX_H
2 #define SZA_UTIL_MATRIX_H
16 #include "carma/szautil/Vector.h"
30 std::ostream& operator<<(std::ostream& os,
34 std::ostringstream& operator<<(std::ostringstream& os,
38 Vector<type> operator*(Vector<type>& vec,
44 Matrix<type> operator*(
unsigned fac, Matrix<type>& mat);
47 Matrix<type> operator*(
int fac, Matrix<type>& mat);
50 Matrix<type> operator*(
float fac, Matrix<type>& mat);
53 Matrix<type> operator*(
double fac, Matrix<type>& mat);
68 Matrix(
const Matrix<type>& mat);
73 Matrix(
unsigned nRow,
unsigned nCol);
83 Vector<type>& operator[](
unsigned iRow);
88 Matrix<type> operator*(Matrix<type>& mat);
93 void operator=(
const Matrix<type>& mat);
99 Matrix<type> operator*(T);
105 Matrix<type> operator/(T);
111 Matrix<type> operator+(T);
117 Matrix<type> operator-(T);
122 Vector<type> operator*( Vector<type>& vec);
127 Matrix<type> reduce(
unsigned iRow,
unsigned iCol);
132 Matrix<type> transpose();
133 Matrix<type> trans();
138 Matrix<type> adjoint();
144 Matrix<type> inverse();
152 type determinant(
unsigned i,
unsigned j);
153 type det(
unsigned i,
unsigned j);
163 type cofactor(
unsigned iRow,
unsigned iCol);
173 friend Vector<type>
operator * <>
174 ( Vector<type>& vec, Matrix<type>& mat);
179 friend std::ostream& operator << <>
180 (std::ostream& os, Matrix<type>& mat);
185 friend std::ostringstream& operator << <>
186 (std::ostringstream& os, Matrix<type>& mat);
192 Vector<Vector<type> > data_;
209 Matrix<type>::Matrix()
219 Matrix<type>::Matrix(
const Matrix<type>& mat)
234 void Matrix<type>::operator=(
const Matrix<type>& mat)
243 for(
unsigned irow=0; irow < nRow_; irow++) {
244 data_[irow].resize(nCol_);
254 Matrix<type>::Matrix(
unsigned nRow,
unsigned nCol)
258 for(
unsigned irow=0; irow < nRow; irow++)
259 data_[irow].resize(nCol);
269 Matrix<type>::~Matrix() {}
275 Vector<type>& Matrix<type>::operator[](
unsigned iRow)
277 sza::util::LogStream errStr;
279 if(iRow > data_.size()-1) {
280 errStr.initMessage(
true);
281 errStr <<
"Matrix has no row: " << iRow;
297 Matrix<type>::operator*(Matrix<type>& mat)
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");
328 if(errStr.isError()) {
333 Matrix<type> result(nRow_, mat.nCol_);
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];
356 Matrix<type>::operator*( Vector<type>& vec)
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");
376 result.resize(nRow_);
380 for(
unsigned iRow=0; iRow < nRow_; iRow++)
381 for(
unsigned j=0; j < nCol_; j++) {
383 result[iRow] = vec[j] * data_[iRow][j];
386 result[iRow] += vec[j] * data_[iRow][j];
397 Matrix<type> Matrix<type>::operator*(T fac)
399 Matrix<type> result = *
this;
401 for(
unsigned iRow=0; iRow < nRow_; iRow++)
402 for(
unsigned iCol=0; iCol < nCol_; iCol++)
403 result[iRow][iCol] *= fac;
410 Matrix<type> Matrix<type>::operator/(T fac)
412 Matrix<type> result = *
this;
414 for(
unsigned iRow=0; iRow < nRow_; iRow++)
415 for(
unsigned iCol=0; iCol < nCol_; iCol++)
416 result[iRow][iCol] /= fac;
423 Matrix<type> Matrix<type>::operator+(T fac)
425 Matrix<type> result = *
this;
427 for(
unsigned iRow=0; iRow < nRow_; iRow++)
428 for(
unsigned iCol=0; iCol < nCol_; iCol++)
429 result[iRow][iCol] += fac;
436 Matrix<type> Matrix<type>::operator-(T fac)
438 Matrix<type> result = *
this;
440 for(
unsigned iRow=0; iRow < nRow_; iRow++)
441 for(
unsigned iCol=0; iCol < nCol_; iCol++)
442 result[iRow][iCol] -= fac;
455 Vector<type> operator*( Vector<type>& vec,
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;
564 Matrix<type> Matrix<type>::transpose()
566 Matrix<type> result(nCol_, nRow_);
568 for(
unsigned i=0; i < nRow_; i++)
569 for(
unsigned j=0; j < nCol_; j++)
570 result.data_[j][i] = data_[i][j];
576 Matrix<type> Matrix<type>::trans()
585 Matrix<type> Matrix<type>::adjoint()
587 Matrix<type> result(nCol_, nRow_);
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);
596 return result.transpose();
600 Matrix<type> Matrix<type>::adj()
609 Matrix<type> Matrix<type>::inverse()
611 Matrix<type> result = adjoint();
612 type deter = determinant();
614 if(::std::isfinite(1.0/((
double)deter)))
617 ThrowError(
"Matrix is not invertible.");
622 Matrix<type> Matrix<type>::inv()
631 type Matrix<type>::trace()
634 ThrowError(
"Not an N x N matrix");
637 Matrix<type> result = data_[0][0];
639 for(
unsigned i=1; i < nRow_; i++)
640 result += data_[i][i];
649 type Matrix<type>::cofactor(
unsigned i,
unsigned j)
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);
668 type Matrix<type>::determinant()
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);
701 type Matrix<type>::det()
703 return determinant();
710 type Matrix<type>::determinant(
unsigned i,
unsigned j)
713 ThrowError(
"Not and N x N matrix");
717 ThrowError(
"Cannot compute determinant for dimensions < 2");
720 Matrix<type> reduced = reduce(i, j);
722 return reduced.determinant();
729 type Matrix<type>::det(
unsigned i,
unsigned j)
731 return determinant(i, j);
738 Matrix<type> Matrix<type>::reduce(
unsigned i,
unsigned j)
740 if(nCol_ == 1 || nRow_ == 1) {
741 ThrowError(
"Matrix dimensions cannot be reduced");
746 Matrix<type> result(nRow_-1, nCol_-1);
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];
773 #endif // End #ifndef SZA_UTIL_MATRIX_H
Started: Sun Dec 14 07:19:50 UTC 2003.
Tagged: Fri Nov 14 12:39:33 UTC 2003.