00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __OPENKN_MATH_RANK_HPP__
00027 #define __OPENKN_MATH_RANK_HPP__
00028
00029
00030
00031
00032
00033 #include <algorithm>
00034
00035
00036
00037
00038 #include "MathException.hpp"
00039 #include "Matrix.hpp"
00040
00041
00042 namespace kn{
00043
00049 template <class T>
00050 unsigned int rank(const Matrix<T> & A_){
00051
00052 const double rankZero = 1.0e-10;
00053
00054
00055 Matrix<T> A(A_);
00056
00057
00058 unsigned int nbIteration = 0;
00059 while(nbIteration < A.rows()){
00060
00061
00062 T maxValue;
00063 unsigned int maxValueRow,maxValueCol;
00064 rankFindPivot(A,nbIteration,maxValueRow,maxValueCol,maxValue);
00065
00066
00067 if(fabs(maxValue) < rankZero)
00068 return nbIteration;
00069
00070
00071 if(maxValueRow != nbIteration){
00072
00073 std::swap_ranges(&(A[maxValueRow][nbIteration]),A[maxValueRow]+A.columns(),&(A[nbIteration][nbIteration]));
00074 }
00075
00076
00077 if(maxValueCol != nbIteration){
00078
00079 A.swapColumns(maxValueCol,nbIteration);
00080 }
00081
00082
00083 rankRowsElimination(A,nbIteration);
00084
00085
00086 ++nbIteration;
00087 }
00088
00089
00090 return A.rows();
00091 }
00092
00093
00103 template <class T>
00104 void rankFindPivot(const Matrix<T> & A, const unsigned int nbIteration,
00105 unsigned int & maxValueRow, unsigned int & maxValueCol, T & maxValue){
00106
00107 maxValueRow = maxValueCol = nbIteration;
00108 maxValue = A[nbIteration][nbIteration];
00109
00110 for(unsigned int i = nbIteration ; i < A.rows(); ++i)
00111 for(unsigned int j = nbIteration ; j < A.columns(); ++j) {
00112 T tmp = T(fabs((A[i][j])));
00113 if((tmp > maxValue)){
00114 maxValueRow = i;
00115 maxValueCol = j;
00116 maxValue = tmp;
00117 }
00118 }
00119 }
00121
00122
00129 template <class T>
00130 void rankRowsElimination(Matrix<T> & A, const unsigned int nbIteration){
00131
00132 for(unsigned int i = nbIteration+1; i < A.rows(); ++i){
00133 T tmp = T(A[i][nbIteration] / A[nbIteration][nbIteration]);
00134
00135
00136 A[i][nbIteration] = T(0);
00137 for(unsigned int j = nbIteration+1; j < A.columns(); ++j){
00138 A[i][j] -= tmp * A[nbIteration][j];
00139 }
00140 }
00141 }
00143
00144
00145
00152 int rank(const Matrix<int> & A_){
00153 throw MathException("invalid input matrix type, convert your matrix in float or double" ,"rank");
00154 }
00156
00157
00158
00159
00160
00161 }
00162
00163
00164
00165
00166 #endif