/*Header-MicMac-eLiSe-25/06/2007 MicMac : Multi Image Correspondances par Methodes Automatiques de Correlation eLiSe : ELements of an Image Software Environnement www.micmac.ign.fr Copyright : Institut Geographique National Author : Marc Pierrot Deseilligny Contributors : Gregoire Maillet, Didier Boldo. [1] M. Pierrot-Deseilligny, N. Paparoditis. "A multiresolution and optimization-based image matching approach: An application to surface reconstruction from SPOT5-HRS stereo imagery." In IAPRS vol XXXVI-1/W41 in ISPRS Workshop On Topographic Mapping From Space (With Special Emphasis on Small Satellites), Ankara, Turquie, 02-2006. [2] M. Pierrot-Deseilligny, "MicMac, un lociel de mise en correspondance d'images, adapte au contexte geograhique" to appears in Bulletin d'information de l'Institut Geographique National, 2007. Francais : MicMac est un logiciel de mise en correspondance d'image adapte au contexte de recherche en information geographique. Il s'appuie sur la bibliotheque de manipulation d'image eLiSe. Il est distibue sous la licences Cecill-B. Voir en bas de fichier et http://www.cecill.info. English : MicMac is an open source software specialized in image matching for research in geographic information. MicMac is built on the eLiSe image library. MicMac is governed by the "Cecill-B licence". See below and http://www.cecill.info. Header-MicMac-eLiSe-25/06/2007*/ #include "general/all.h" #include "private/all.h" cSparseMatrForGradConj::cSparseMatrForGradConj(cVectMatMul & aVMM,cVectPreCond & aVPC) : mEpsB (1e-6), mEpsSolInit (-1), mVMM (aVMM), mVPC (aVPC), mImBLin (1), mImXSol (1), mImPk (1), mImAPk (1), mImRk (1), mImZk (1), mImM (1) { } void cSparseMatrForGradConj::SetEpsB(REAL anEpsB) { mEpsB = anEpsB; } void cSparseMatrForGradConj::SetEpsRel(REAL anEpsRel) { mEpsSolInit = anEpsRel; } /* void cSparseMatrForGradConj::NR_SparseSolve(const double *b,int n,double * x,double * rsq) { b--; x--; int j,iter,irst=0; double aden,anum,bsq,dgg,eps2,gam,gg,rp; Im1D_REAL8 Ig(n+1),Ih(n+1),Ixi(n+1),Ixj(n+1); double * g = Ig.data(); double * h = Ih.data(); double * xi = Ixi.data(); double * xj = Ixj.data(); eps2=n*mEpsB*mEpsB; for (;;) { ++irst; asub(x,xi,n); rp=bsq=0.0; for (j=1;j<=n;j++) { bsq += b[j]*b[j]; xi[j] -= b[j]; rp += xi[j]*xi[j]; } atsub(xi,g,n); for (j=1;j<=n;j++) h[j] = g[j] = -g[j]; REAL Ec0 = -1; for (iter=1;iter<=20*n;iter++) { asub(h,xi,n); anum=aden=0.0; for (j=1;j<=n;j++) { anum += g[j]*h[j]; aden += xi[j]*xi[j]; } if (aden==0) { ELISE_ASSERT(anum==0,"Very singular matrix in SPARSE"); } else anum /= aden; for (j=1;j<=n;j++) { xi[j]=x[j]; x[j] += anum*h[j]; } asub(x,xj,n); *rsq=0.0; for (j=1;j<=n;j++) { xj[j] -= b[j]; *rsq += xj[j]*xj[j]; } REAL Ec = *rsq / n ; if (Ec0<0) Ec0 = Ec; if (false && ((iter%10)==5)) cout << mEpsSolInit << " " << iter << " ECARTS " << Ec << " " << Ec/Ec0 << "\n"; // cout << "ITER GCONJ " << iter << " " << *rsq << " " << bsq << "\n"; if (*rsq == rp || *rsq <= bsq*eps2) return; if (*rsq == rp || (Ec < Ec0 * mEpsSolInit)) return; if (*rsq > rp) { for (j=1;j<=n;j++) x[j]=xi[j]; if (irst >= 3) return; break; } rp = *rsq; atsub(xj,xi,n); gg=dgg=0.0; for (j=1;j<=n;j++) { gg += g[j]*g[j]; dgg += (xi[j]+g[j])*xi[j]; } if (gg == 0.0) return; gam=dgg/gg; for (j=1;j<=n;j++) { g[j] = -xi[j]; h[j]=g[j]+gam*h[j]; } } // ELISE_ASSERT(false,"Too many interations in routine SPARSE"); } } */ //============================================================== class cVecByIm1 { public : typedef Im1D_REAL8 tVec; static double Scal(const tVec & aV1,const tVec & aV2); static void AddAlphaV(tVec & aV1,const double aAlpha,const tVec & aV2); // aV1 += aAlpha * aV2 static void MulAlphaAndAdd(tVec & aV1,const double aAlpha,const tVec & aV2); // aV1 = aV1*aAlpha + aV2 static void SetDiff(tVec & aV1,const tVec & aV2,const tVec & aV3); static void Affect(tVec & aV1,const tVec & aV2); }; double cVecByIm1::Scal(const tVec & aV1,const tVec & aV2) { int aNb = aV1.tx(); const double * aD1 = aV1.data(); const double * aD2 = aV2.data(); double aRes = 0.0; for (int aK=0 ; aKGetElemQuad(aK,aK); } else { mPreCond = false; mZk = mRk; mM = 0; } */ } // #define Sgn -1 // Voir http://en.wikipedia.org/wiki/Conjugate_gradient_method void cSparseMatrForGradConj::MpdGC_InitOneEtape() { // FAIT // Rk = b - A XSol // Pk = Rk // SMFGC_Asub(mXsol,mAPk,mN); mVMM.VMMDo(mImXSol,mImAPk); Type::SetDiff(mImRk,mImBLin,mImAPk); mVPC.VPCDo(mImRk,mImZk); /* if (mPreCond) { for (int anI=0 ;anI aEpsResidu) { std::cout << "RESIDU = " << aResisu << "\n"; ELISE_ASSERT(false,"cSparseMatrForGradConj::VerifResidu"); } } bool cSparseMatrForGradConj::MpdGC_SolveComplePrecis ( Im1D_REAL8 aImB, Im1D_REAL8 aImX, // const double * b, // double *x, int n, int aNbIter, cGenSysSurResol * aSP ) { MpdGC_AllocAndInitGlob(aImB,aImX,n,aSP); for (int aK=0 ; aK