00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef RTC_LINEARSYSTEM_H
00020 #define RTC_LINEARSYSTEM_H
00021
00022
00023 #include "rtc/rtcMath.h"
00024 #include "rtc/rtcSMat.h"
00025 #include "rtc/rtcVec.h"
00026
00027 #define LSC_PO 0
00028
00029
00030 namespace rtc {
00031
00035 template <class T, int M>
00036 class LinearSystem {
00037 public:
00038
00039 LinearSystem(SMat<T,M>& a_, bool overwrite_ = true);
00040 ~LinearSystem();
00041
00042
00043 int forceRefresh(int decomp = 0);
00044 int cholesky(const Vec<T,M>& b, Vec<T,M>& sol);
00045 int lu(const Vec<T,M>& b, Vec<T,M>& sol);
00046 int gaussianElim(const Vec<T,M>& b, Vec<T,M>& sol);
00047 protected:
00048
00049 SMat<T,M>& a;
00050 SMat<T,M>* d;
00051 Vec<int,M> indx;
00052 int haveDecomp;
00053 bool overwrite;
00054 };
00055
00056
00057 typedef LinearSystem<float,2> LinearSystem2f;
00058 typedef LinearSystem<double,2> LinearSystem2d;
00059 typedef LinearSystem<float,3> LinearSystem3f;
00060 typedef LinearSystem<double,3> LinearSystem3d;
00061 typedef LinearSystem<float,4> LinearSystem4f;
00062 typedef LinearSystem<double,4> LinearSystem4d;
00063 typedef LinearSystem<float,5> LinearSystem5f;
00064 typedef LinearSystem<double,5> LinearSystem5d;
00065 typedef LinearSystem<float,6> LinearSystem6f;
00066 typedef LinearSystem<double,6> LinearSystem6d;
00067
00068
00069
00078 template <class T, int M>
00079 inline LinearSystem<T,M>::LinearSystem(SMat<T,M>& a_, bool overwrite_) :
00080 a(a_), overwrite(overwrite_) {
00081 haveDecomp = 0;
00082 if (!overwrite) d = new SMat<T,M>(a);
00083 else d = &a;
00084 if (LSC_PO>1) std::cout << "Built LinearSystem class instance with ";
00085 if (LSC_PO>1) {
00086 if (overwrite) std::cout << "overwrite enabled.\n";
00087 else std::cout << "overwrite disabled.\n";
00088 }
00089 }
00090
00093 template <class T, int M>
00094 inline LinearSystem<T,M>::~LinearSystem() {
00095 if (!overwrite) {
00096 delete d;
00097 }
00098 if (LSC_PO>1) std::cout << "Deleted LinearSystem.\n";
00099 }
00100
00101
00102
00113 template <class T, int M>
00114 inline int LinearSystem<T,M>::forceRefresh(int decomp) {
00115 if (decomp == 0 && !haveDecomp) {
00116 std::cerr << "No decomposition specified and none active.\n";
00117 return 1;
00118 }
00119 if (decomp == 0 && haveDecomp) {
00120 decomp = haveDecomp;
00121 haveDecomp = 0;
00122 }
00123 switch (decomp) {
00124 case 1:
00125 if (d->luDecomp(indx)) return 1; else haveDecomp = 1; break;
00126 case 2:
00127 if (d->choleskyDecomp()) return 1; else haveDecomp = 2; break;
00128 default:
00129 std::cerr << "Decomposition number " << decomp << " is not a valid choice.\n"
00130 << "Please choose from 1: LU, 2: Cholesky\n";
00131 return 1;
00132 }
00133 }
00134
00139 template <class T, int M>
00140 inline int LinearSystem<T,M>::lu(const Vec<T,M>& b, Vec<T,M>& sol) {
00141 if (haveDecomp != 1) {
00142 if (haveDecomp != 0) {
00143 if (!overwrite) { d->set(a); } else {
00144 std::cerr << "Can't perform LU Decomposition because A already "
00145 << "contains ";
00146 switch (haveDecomp) {
00147 case 2: std::cerr << "a Cholesky Decomposition.\n"; break;
00148 case 3: std::cerr << "a Gauss-Jordan Decomposition.\n"; break;
00149 default: std::cerr << "an Unknown decomposition.\n" << haveDecomp; break;
00150 }
00151 return 1;
00152 }
00153 }
00154 if (LSC_PO>1) std::cout << "Performing LU Decomposition...";
00155 if (d->luDecomp(indx)) return 1;
00156 else haveDecomp = 1;
00157 if (LSC_PO>1) std::cout << "Done.\n";
00158 }
00159 if (LSC_PO>1) std::cout << "Performing LU Solve...";
00160 sol.set(b);
00161 d->luSolve(indx,sol);
00162 if (LSC_PO>1) std::cout << "Done.\n";
00163 return 0;
00164 }
00165
00170 template <class T, int M>
00171 inline int LinearSystem<T,M>::cholesky(const Vec<T,M>& b, Vec<T,M>& sol) {
00172 if (haveDecomp != 2) {
00173 if (haveDecomp != 0) {
00174 if (!overwrite) { d->set(a); } else {
00175 std::cerr << "Can't perform Cholesky Decomposition because A already " << "contains ";
00176 switch (haveDecomp) {
00177 case 1: std::cerr << "an LU Decomposition.\n"; break;
00178 case 3: std::cerr << "a Gauss-Jordan Decomposition.\n"; break;
00179 default: std::cerr << "an Unknown decomposition.\n" << haveDecomp; break;
00180 }
00181 return 1;
00182 }
00183 }
00184 if (LSC_PO>1) std::cout << "Performing Cholesky Decomposition...";
00185 if (d->choleskyDecomp()) return 1;
00186 else haveDecomp = 2;
00187 if (LSC_PO>1) std::cout << "Done.\n";
00188 }
00189 if (LSC_PO>1) std::cout << "Performing Cholesky Solve...";
00190 sol.set(b);
00191 d->choleskySolve(sol);
00192 if (LSC_PO>1) std::cout << "Done.\n";
00193 return 0;
00194 }
00195
00201 template<class T, int M>
00202 inline int LinearSystem<T,M>::gaussianElim(const Vec<T,M>& b, Vec<T,M>& sol)
00203 {
00204 if (haveDecomp != 0) {
00205 if (!overwrite) {
00206 d->set(a);
00207 } else {
00208 std::cerr << "Can't perform Gauss-Jordan Decomposition because A already "<< "contains ";
00209 switch (haveDecomp) {
00210 case 1:
00211 std::cerr << "an LU Decomposition.\n";
00212 break;
00213 case 2:
00214 std::cerr << "a Cholesky Decomposition.\n";
00215 break;
00216 case 3:
00217 std::cerr << "a different Gauss-Jordan Decomposition\n";
00218 break;
00219 default:
00220 std::cerr << "an Unknown decomposition.\n"<< haveDecomp;
00221 break;
00222 }
00223 return 1;
00224 }
00225 }
00226 haveDecomp = 3;
00227 if (LSC_PO>1)
00228 std::cout << "Performing Gauss-Jordan Decomposition/Solve...";
00229
00230 T tmp, pvt;
00231 T *t;
00232 T* aa[M];
00233 T bb[M];
00234 int i, j, k;
00235
00236
00237 for (i=0; i<M; i++) {
00238 aa[i] = &((*d)(i, 0));
00239 bb[i] = b.x[i];
00240 }
00241 for (i=0; i<M; i++) {
00242 pvt = aa[i][i];
00243 if (!pvt) {
00244 for (j=i+1; j<M; j++) {
00245 if ((pvt = a(j, i)) != 0.0)
00246 break;
00247 }
00248 if (!pvt)
00249 return 1;
00250 t=aa[j];
00251 aa[j]=aa[i];
00252 aa[i]=t;
00253 tmp=bb[j];
00254 bb[j]=bb[i];
00255 bb[i]=tmp;
00256 }
00257 for (k=i+1; k<M; k++) {
00258 tmp = aa[k][i]/pvt;
00259 for (j=i+1; j<M; j++) {
00260 aa[k][j] -= tmp*aa[i][j];
00261 }
00262 bb[k] -= tmp*bb[i];
00263 }
00264 }
00265
00266 for (i=M-1; i>=0; i--) {
00267 sol.x[i]=bb[i];
00268 for (j=M-1; j>i; j--) {
00269 sol.x[i] -= aa[i][j]*sol.x[j];
00270 }
00271 sol.x[i] /= aa[i][i];
00272 }
00273 if (LSC_PO>1)
00274 std::cout << "Done.\n";
00275 return 0;
00276 }
00277
00278
00279 }
00280
00281 #endif // RTC_LINEARSYSTEM_H defined
00282
00283