Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
linearsys.hpp
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       // Not commented. All next fields correspond to variables used 
00040       // to compute coefficients o the system linear and to resolve it
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       // Constructor
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   /* Allocation for rangeT, gradCPDV and dp1CPDV */
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   /* Allocation for grad3d and dp1obj3d */
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   /* Allocation for rangeS */
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   /* Allocation for rangeD and rangeY */
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       // Destructor
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       // Computation methods
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   // First Step :: compute non zero elements of B1 and B2
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   // Second Step :: zero-initialization of vectors and matrices
00253 
00254   /* Initialisation de Y */
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   /* Initialisation de U */
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   /* Initialisation de V */ 
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   /* Initialisation des vecteurs */
00277   for (indice=0;indice<nbvariables;indice++)
00278     {
00279       gradient(indice) = 0.0;
00280       deltap(indice) = 0.0;
00281     }
00282 
00283 
00284 
00285   // Third Step :: compute JtJ and gradient
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       /* Elements of the matrix A (see Lourakis's TR) */
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       /* Elements of Gradient */      
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   // Search in U
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   // Search in V
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   // First step :: Forward substitution
00370   //
00371   // Fill S and T
00372   bundle_forward_substitution(mu);
00373 
00374   // Secont Step :: Solve the linear system Sx=T
00375   //
00376   // Remarks :
00377   //  1 - No recopy of S-matrix because we don't need contained data
00378   //  2 - No recopy of T-matrix for the same reason
00379   ublas::permutation_matrix<std::size_t> pmatrix(S.size1());  
00380   lu_factorize(S,pmatrix);  
00381   lu_substitute(S, pmatrix, T);
00382   
00383   
00384   // At this point T contained dpCPDV.
00385   // We must copy T in dpCPDV       
00386   dpcpdv = T;
00387     
00388   
00389   // Third Step :: Backward substitution
00390   //
00391   // Compute dp3d;
00392   bundle_backward_substitution();         
00393     
00394       };
00395       
00396 
00400       void solveByGC (double mu=0.0)
00401       {
00402   
00403   // First step :: Forward substitution
00404   //
00405   // Fill S and T
00406   bundle_forward_substitution(mu);
00407 
00408   // Secont Step :: Solve the linear system Sx=T
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   // At this point x contained new dpCPDV
00418   dpcpdv = x;
00419   
00420   
00421   // Third Step :: Backward substitution
00422   //
00423   // Compute dp3d;
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   // Initialisation de T et de S
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   /* Inversion of augmented V-vector */
00453   for (cptobj=0;cptobj<nbObj3D;cptobj++)
00454     { 
00455       mattemp = V[cptobj]+augmentationV;
00456       jmath::ublasExtra::details::inv3(mattemp,invV[cptobj]);     
00457     }     
00458 
00459   /* Generate T */
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   /* Generate S */       
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 //  D.exportFullMatrix(matD);
00477 //  Y.exportFullMatrix(matY);
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     }; // end class bundleLinearSys       
00506   
00507   } // end namespace bundle
00508   
00509 } // end namespace jafar
00510 
00511 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:17 for Jafar by doxygen 1.7.6.1
LAAS-CNRS