00001 #ifndef BUNDLE_LINEARSYS_HPP
00002 #define BUNDLE_LINEARSYS_HPP
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <string>
00007 #include <vector>
00008
00009 #include "jmath/matofmat.hpp"
00010 #include "jmath/precond.hpp"
00011 #include "jmath/pcg.hpp"
00012 #include "jmath/ublasExtra.hpp"
00013
00014 #include "bundle/bundleData.hpp"
00015 #include "bundle/bundleVariables.hpp"
00016
00017 namespace jafar {
00018
00019 namespace bundle {
00020
00027 class bundleLinearSys {
00028
00029 public :
00030
00032 jblas::vec gradient;
00033
00035 jblas::vec deltap;
00036
00037 private :
00038
00039
00040
00041
00042 unsigned int nbCam;
00043
00044 unsigned int nbObj3D;
00045
00046 unsigned int nbObs2D;
00047
00048 jmath::matofmat<double,2,6> B1;
00049
00050 jmath::matofmat<double,2,3> B2;
00051
00052 std::vector<jblas::mat66> U;
00053
00054 std::vector<jblas::mat33> V;
00055
00056 std::vector<jblas::mat33> invV;
00057
00058 jblas::mat Y;
00059
00060 std::vector<jblas::mat_range*> rangeY;
00061
00062 jblas::vec T;
00063
00064 std::vector<jblas::vec_range*> rangeT;
00065
00066 jblas::mat S;
00067
00068 std::vector<jblas::mat_range*> rangeS;
00069
00070 jblas::mat D;
00071
00072 std::vector<jblas::mat_range*> rangeD;
00073
00074 std::vector<jblas::vec_range*> gradCpdv;
00075
00076 std::vector<jblas::vec_range*> grad3d;
00077
00078 jblas::vec_range dpcpdv;
00079
00080 jblas::vec_range dp3d;
00081
00082 std::vector<jblas::vec_range*> dp1cpdv;
00083
00084 std::vector<jblas::vec_range*> dp1obj3d;
00085
00086
00087 public :
00088
00089
00090
00091
00092
00093
00097 bundleLinearSys (const observationsContainer obsCon_) :
00098 gradient(6*obsCon_.pbDim.nbCam + 3*obsCon_.pbDim.nbObj3d),
00099 deltap(6*obsCon_.pbDim.nbCam + 3*obsCon_.pbDim.nbObj3d),
00100 nbCam(obsCon_.pbDim.nbCam),
00101 nbObj3D(obsCon_.pbDim.nbObj3d),
00102 nbObs2D(obsCon_.pbDim.nbObs2d),
00103 B1(obsCon_.sparseSB1),
00104 B2(obsCon_.sparseSB2),
00105 U(nbCam),
00106 V(nbObj3D),
00107 invV(nbObj3D),
00108 Y(nbCam*6,3*nbObj3D),
00109 rangeY(nbCam*nbObj3D),
00110 T(6*nbCam),
00111 rangeT(nbCam),
00112 S(6*nbCam,6*nbCam),
00113 rangeS(nbCam*nbCam),
00114 D(6*nbCam,3*nbObj3D),
00115 rangeD(nbCam*nbObj3D),
00116 gradCpdv(nbCam),
00117 grad3d(nbObj3D),
00118 dpcpdv(deltap,ublas::range(0,6*nbCam)),
00119 dp3d(deltap,ublas::range(6*nbCam,6*nbCam+3*nbObj3D)),
00120 dp1cpdv(nbCam),
00121 dp1obj3d(nbObj3D)
00122 {
00123 unsigned int cptcam, cptcam2, cptObj3d, indice;
00124
00125
00126
00127 for (cptcam=0;cptcam<nbCam;cptcam++)
00128 {
00129 ublas::range rglocal(cptcam*6,(cptcam+1)*6);
00130 rangeT[cptcam] = new jblas::vec_range(T,rglocal);
00131 gradCpdv[cptcam] = new jblas::vec_range(gradient,rglocal);
00132 dp1cpdv[cptcam] = new jblas::vec_range(deltap,rglocal);
00133 }
00134
00135
00136 for (cptObj3d=0;cptObj3d<nbObj3D;cptObj3d++)
00137 {
00138 ublas::range rglocal(6*nbCam+cptObj3d*3,6*nbCam+(cptObj3d+1)*3);
00139 grad3d[cptObj3d] = new jblas::vec_range(gradient,rglocal);
00140 dp1obj3d[cptObj3d] = new jblas::vec_range(deltap,rglocal);
00141 }
00142
00143
00144 for (indice=0,cptcam=0;cptcam<nbCam;cptcam++)
00145 {
00146 ublas::range rglocal(cptcam*6,(cptcam+1)*6);
00147 for (cptcam2=0;cptcam2<nbCam;cptcam2++,indice++)
00148 {
00149 ublas::range rglocal2(cptcam2*6,(cptcam2+1)*6);
00150 rangeS[indice] = new jblas::mat_range(S,rglocal,rglocal2);
00151 }
00152 }
00153
00154
00155 for ( indice=0, cptcam=0; cptcam<nbCam ; ++cptcam)
00156 {
00157 ublas::range rglocal(cptcam*6,(cptcam+1)*6);
00158 for (cptObj3d=0; cptObj3d<nbObj3D ; ++cptObj3d, ++indice)
00159 {
00160 ublas::range rglocal2(cptObj3d*3,(cptObj3d+1)*3);
00161 rangeY[indice] = new jblas::mat_range(Y,rglocal,rglocal2);
00162 rangeD[indice] = new jblas::mat_range(D,rglocal,rglocal2);
00163 }
00164 }
00165
00166 };
00167
00168
00169
00170
00171
00172 ~bundleLinearSys ()
00173 {
00174 unsigned int cpt;
00175
00176 for (cpt=0;cpt<nbCam;cpt++)
00177 {
00178 delete rangeT[cpt];
00179 delete gradCpdv[cpt];
00180 delete dp1cpdv[cpt];
00181 }
00182
00183 for (cpt=0;cpt<nbObj3D;cpt++)
00184 {
00185 delete grad3d[cpt];
00186 delete dp1obj3d[cpt];
00187 }
00188
00189
00190 for (cpt=0;cpt<nbCam*nbCam;cpt++)
00191 delete rangeS[cpt];
00192 }
00193
00194
00195
00196
00197
00198
00199 void afficheB1(unsigned int indObs, unsigned int indVue)
00200 {
00201 std::cout << "Elem de B1 en (" << indObs << ", "<< indVue << ") : " << B1(indObs,indVue) << std::endl;
00202 }
00203
00204 void afficheB2(unsigned int indObs, unsigned int indObj)
00205 {
00206 std::cout << "Elem de B2 en (" << indObs << ", "<< indObj << ") : " << B2(indObs,indObj) << std::endl;
00207 }
00208
00213 template <typename typeCam>
00214 void processData (bundle::observationsContainer &bobs, bundle::bundleVariables<typeCam> &bvar)
00215 {
00216 JFR_PRECOND(nbObs2D==bobs.obs2D.size(),"bundle::linearSys : Error number of 2D observation don't match");
00217
00218 unsigned int cpt, indView, indObj3d;
00219 unsigned int nbObsCPDV = bobs.obsCPDV.size(), nbObs3D = bobs.obs3D.size();
00220 unsigned int cptcam, indice, cptObj3d;
00221 unsigned int nbvariables = 6*nbCam+3*nbObj3D;
00222
00223 jblas::mat jacCPDV(2,6);
00224 jblas::mat jacOBJ3D(2,3);
00225
00226 jblas::mat mat66tmp(6,6);
00227 jblas::mat mat33tmp(3,3);
00228 jblas::mat mat22tmp(2,2);
00229
00230 jblas::mat mat63tmp(6,3);
00231 jblas::mat mat26tmp(2,6);
00232 jblas::mat mat23tmp(2,3);
00233
00234 jblas::vec vec2tmp(2), vec2tmp2(2);
00235 jblas::vec vec3tmp(3);
00236 jblas::vec vec6tmp(6);
00237
00238
00239
00240
00241
00242 for (cpt=0;cpt<nbObs2D;cpt++)
00243 {
00244 indView = (*(bobs.obs2D[cpt])).idView;
00245 indObj3d = (*(bobs.obs2D[cpt])).idFeature;
00246
00247 bvar.projectionJac (indObj3d,indView,jacCPDV,jacOBJ3D);
00248 B1(cpt,indView) = jacCPDV;
00249 B2(cpt,indObj3d) = jacOBJ3D;
00250 }
00251
00252
00253
00254
00255 for (unsigned int i=0;i<6;i++)
00256 for (unsigned int j=0; j<3;j++)
00257 mat63tmp(i,j)=0.0;
00258 for (cptcam=0;cptcam<nbCam;cptcam++)
00259 for (cptObj3d=0;cptObj3d<nbObj3D;cptObj3d++)
00260 (*(rangeY[cptcam*nbObj3D+cptObj3d])).assign(mat63tmp);
00261
00262
00263 for (unsigned int i=0;i<6;i++)
00264 for (unsigned int j=0;j<6;j++)
00265 mat66tmp(i,j) = 0.0;
00266 for(indice=0;indice<nbCam;indice++)
00267 U[indice].assign(mat66tmp);
00268
00269
00270 for (unsigned int i=0;i<3;i++)
00271 for (unsigned int j=0;j<3;j++)
00272 mat33tmp(i,j) = 0.0;
00273 for (indice=0;indice<nbObj3D;indice++)
00274 V[indice].assign(mat33tmp);
00275
00276
00277 for (indice=0;indice<nbvariables;indice++)
00278 {
00279 gradient(indice) = 0.0;
00280 deltap(indice) = 0.0;
00281 }
00282
00283
00284
00285
00286
00287 if (nbObsCPDV)
00288 for (cpt=0;cpt<nbObsCPDV;cpt++)
00289 {
00290 indView = (*(bobs.obsCPDV[cpt])).idView;
00291
00292 (*(bobs.obsCPDV[cpt])).getCovMatrix(mat66tmp);
00293 U[indView].assign(mat66tmp);
00294 (*(bobs.obsCPDV[cpt])).getResidual(vec6tmp);
00295 *(gradCpdv[indView]) = prod(mat66tmp,vec6tmp);
00296 }
00297
00298
00299 if (nbObs3D)
00300 for (cpt=0;cpt<nbObs3D;cpt++)
00301 {
00302 indObj3d = (*(bobs.obs3D[cpt])).idFeature;
00303
00304 (*(bobs.obs3D[cpt])).getCovMatrix(mat33tmp);
00305 V[indObj3d].assign(mat33tmp);
00306 (*(bobs.obs3D[cpt])).getResidual(vec3tmp);
00307 *(grad3d[indObj3d]) = prod(mat33tmp,vec3tmp);
00308
00309 }
00310
00311
00312 for (cpt=0;cpt<nbObs2D;cpt++)
00313 {
00314 indView = (*(bobs.obs2D[cpt])).idView;
00315 indObj3d = (*(bobs.obs2D[cpt])).idFeature;
00316
00317 (*(bobs.obs2D[cpt])).getCovMatrix(mat22tmp);
00318 (*(bobs.obs2D[cpt])).getResidual(vec2tmp);
00319
00320
00321
00322 mat26tmp = prod(mat22tmp,B1(cpt,indView));
00323 U[indView] += prod(trans(B1(cpt,indView)),mat26tmp);
00324
00325 mat23tmp = prod(mat22tmp,B2(cpt,indObj3d));
00326 V[indObj3d] += prod(trans(B2(cpt,indObj3d)),mat23tmp);
00327 *(rangeY[indView*nbObj3D+indObj3d]) += prod(trans(B1(cpt,indView)),mat23tmp);
00328
00329
00330 vec2tmp2 = prod(mat22tmp,vec2tmp);
00331 *(grad3d[indObj3d]) += prod(trans(B2(cpt,indObj3d)),vec2tmp2);
00332 *(gradCpdv[indView]) += prod(trans(B1(cpt,indView)),vec2tmp2);
00333
00334 }
00335
00336 };
00337
00344 double maxDiagA ()
00345 {
00346 double maxValue = -1.369e10;
00347 unsigned int matUiSize = U[0].size1();
00348 unsigned int matViSize = V[0].size1();
00349
00350
00351 for ( unsigned int cpt=0; cpt < nbCam ; ++cpt)
00352 for ( unsigned int cpt2=0 ; cpt2 < matUiSize; ++cpt2 )
00353 maxValue = (maxValue>U[cpt](cpt2,cpt2)) ? maxValue : U[cpt](cpt2,cpt2);
00354
00355
00356 for ( unsigned int cpt=0; cpt < nbObj3D ; ++cpt)
00357 for ( unsigned int cpt2=0 ; cpt2 < matViSize; ++cpt2 )
00358 maxValue = (maxValue>V[cpt](cpt2,cpt2)) ? maxValue : V[cpt](cpt2,cpt2);
00359
00360 return maxValue;
00361 }
00362
00366 void solveByLU (double mu=0.0)
00367 {
00368
00369
00370
00371
00372 bundle_forward_substitution(mu);
00373
00374
00375
00376
00377
00378
00379 ublas::permutation_matrix<std::size_t> pmatrix(S.size1());
00380 lu_factorize(S,pmatrix);
00381 lu_substitute(S, pmatrix, T);
00382
00383
00384
00385
00386 dpcpdv = T;
00387
00388
00389
00390
00391
00392 bundle_backward_substitution();
00393
00394 };
00395
00396
00400 void solveByGC (double mu=0.0)
00401 {
00402
00403
00404
00405
00406 bundle_forward_substitution(mu);
00407
00408
00409 CholeskyPreconditioner<jblas::mat> precond(S);
00410 jblas::vec x(dpcpdv);
00411 pcg_solve(S, x, T,
00412 precond,
00413 500,
00414 1e-10,
00415 1e-20);
00416
00417
00418 dpcpdv = x;
00419
00420
00421
00422
00423
00424 bundle_backward_substitution();
00425 }
00426
00427
00428 private :
00429
00430 void bundle_forward_substitution (double const mu)
00431 {
00432 unsigned int cptcam, cptobj;
00433 unsigned int cptS1;
00434
00435 jblas::mat33 mattemp, augmentationV;
00436 jblas::mat66 augmentationU;
00437
00438 jblas::identity_mat id3(3);
00439 jblas::identity_mat id6(6);
00440
00441 augmentationV = mu*id3;
00442 augmentationU = mu*id6;
00443
00444
00445 for (cptcam=0;cptcam<6*nbCam;cptcam++)
00446 {
00447 T[cptcam] = 0.0;
00448 for (cptobj=0;cptobj<6*nbCam;cptobj++)
00449 S(cptcam,cptobj) = 0.0;
00450 }
00451
00452
00453 for (cptobj=0;cptobj<nbObj3D;cptobj++)
00454 {
00455 mattemp = V[cptobj]+augmentationV;
00456 jmath::ublasExtra::details::inv3(mattemp,invV[cptobj]);
00457 }
00458
00459
00460 for ( cptcam=0 ; cptcam<nbCam ; cptcam++ )
00461 *(rangeT[cptcam]) = *(gradCpdv[cptcam]);
00462
00463 for ( cptcam = 0 ; cptcam<nbCam ; cptcam++)
00464 for ( cptobj = 0 ; cptobj<nbObj3D ; cptobj++)
00465 {
00466 *(rangeD[cptcam*nbObj3D+cptobj]) = prod(*(rangeY[cptcam*nbObj3D+cptobj]),invV[cptobj]);
00467 *(rangeT[cptcam]) -= prod(*(rangeD[cptcam*nbObj3D+cptobj]),*(grad3d[cptobj]));
00468 }
00469
00470
00471 jblas::mat matTY(Y.size2(),Y.size1());
00472
00473 for (cptS1=0;cptS1<nbCam;cptS1++)
00474 *(rangeS[cptS1*(nbCam+1)]) = U[cptS1] + augmentationU;
00475
00476
00477
00478
00479 matTY = trans(Y);
00480 S -= prod(D,matTY);
00481
00482 };
00483
00484
00489 void bundle_backward_substitution ()
00490 {
00491 unsigned int cptobj, cptcam;
00492 jblas::vec vtemp(3);
00493
00494 for ( cptobj=0 ; cptobj<nbObj3D ; ++cptobj )
00495 {
00496 vtemp = *(grad3d[cptobj]);
00497 for ( cptcam=0 ; cptcam<nbCam ; ++cptcam )
00498 vtemp -= prod(trans(*(rangeY[cptcam*nbObj3D+cptobj])),*(dp1cpdv[cptcam]));
00499 *(dp1obj3d[cptobj]) = prod(invV[cptobj],vtemp);
00500
00501 }
00502 };
00503
00504
00505 };
00506
00507 }
00508
00509 }
00510
00511 #endif