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
00027
00028
00029
00030
00031
00032 #ifndef GAUSSIAN_ELIMINATION_H
00033 #define GAUSSIAN_ELIMINATION_H
00034
00035 #include <utility>
00036 #include <cmath>
00037 #include <TooN/TooN.h>
00038
00039 namespace TooN {
00044 template<int N, typename Precision>
00045 inline Vector<N, Precision> gaussian_elimination (Matrix<N,N,Precision> A, Vector<N, Precision> b) {
00046 using std::swap;
00047 using std::abs;
00048
00049 int size=b.size();
00050
00051 for (int i=0; i<size; ++i) {
00052 int argmax = i;
00053 Precision maxval = abs(A[i][i]);
00054
00055 for (int ii=i+1; ii<size; ++ii) {
00056 double v = abs(A[ii][i]);
00057 if (v > maxval) {
00058 maxval = v;
00059 argmax = ii;
00060 }
00061 }
00062 Precision pivot = A[argmax][i];
00063
00064 Precision inv_pivot = static_cast<Precision>(1)/pivot;
00065 if (argmax != i) {
00066 for (int j=i; j<size; ++j)
00067 swap(A[i][j], A[argmax][j]);
00068 swap(b[i], b[argmax]);
00069 }
00070
00071 for (int j=i+1; j<size; ++j)
00072 A[i][j] *= inv_pivot;
00073 b[i] *= inv_pivot;
00074
00075 for (int u=i+1; u<size; ++u) {
00076 double factor = A[u][i];
00077
00078 for (int j=i+1; j<size; ++j)
00079 A[u][j] -= factor * A[i][j];
00080 b[u] -= factor * b[i];
00081 }
00082 }
00083
00084 Vector<N,Precision> x(size);
00085 for (int i=size-1; i>=0; --i) {
00086 x[i] = b[i];
00087 for (int j=i+1; j<size; ++j)
00088 x[i] -= A[i][j] * x[j];
00089 }
00090 return x;
00091 }
00092
00093 namespace Internal
00094 {
00095 template<int i, int j, int k> struct Size3
00096 {
00097 static const int s=(i!= -1)?i:(j!=-1?j:k);
00098 };
00099
00100 };
00101
00106 template<int R1, int C1, int R2, int C2, typename Precision>
00107 inline Matrix<Internal::Size3<R1, C1, R2>::s, C2, Precision> gaussian_elimination (Matrix<R1,C1,Precision> A, Matrix<R2, C2, Precision> b) {
00108 using std::swap;
00109 using std::abs;
00110 SizeMismatch<R1, C1>::test(A.num_rows(), A.num_cols());
00111 SizeMismatch<R1, R2>::test(A.num_rows(), b.num_rows());
00112
00113 int size=A.num_rows();
00114
00115 for (int i=0; i<size; ++i) {
00116 int argmax = i;
00117 Precision maxval = abs(A[i][i]);
00118
00119 for (int ii=i+1; ii<size; ++ii) {
00120 double v = abs(A[ii][i]);
00121 if (v > maxval) {
00122 maxval = v;
00123 argmax = ii;
00124 }
00125 }
00126 Precision pivot = A[argmax][i];
00127
00128 Precision inv_pivot = static_cast<Precision>(1)/pivot;
00129 if (argmax != i) {
00130 for (int j=i; j<size; ++j)
00131 swap(A[i][j], A[argmax][j]);
00132
00133 for(int j=0; j < b.num_cols(); j++)
00134 swap(b[i][j], b[argmax][j]);
00135 }
00136
00137 for (int j=i+1; j<size; ++j)
00138 A[i][j] *= inv_pivot;
00139 b[i] *= inv_pivot;
00140
00141 for (int u=i+1; u<size; ++u) {
00142 double factor = A[u][i];
00143
00144 for (int j=i+1; j<size; ++j)
00145 A[u][j] -= factor * A[i][j];
00146 b[u] -= factor * b[i];
00147 }
00148 }
00149
00150 Matrix<Internal::Size3<R1, C1, R2>::s,C2,Precision> x(b.num_rows(), b.num_cols());
00151 for (int i=size-1; i>=0; --i) {
00152 for(int k=0; k <b.num_cols(); k++)
00153 {
00154 x[i][k] = b[i][k];
00155 for (int j=i+1; j<size; ++j)
00156 x[i][k] -= A[i][j] * x[j][k];
00157 }
00158 }
00159 return x;
00160 }
00161 }
00162 #endif