Skip to content

Commit

Permalink
Merge branch 'mpd'
Browse files Browse the repository at this point in the history
  • Loading branch information
deseilligny committed Jan 10, 2024
2 parents c299a3b + dccb58c commit e7ce945
Show file tree
Hide file tree
Showing 28 changed files with 2,537 additions and 412 deletions.
407 changes: 406 additions & 1 deletion MMVII/Doc/Programmer/NonLinearOptim.tex

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions MMVII/include/MMVII_Bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ void Bench_ToHomMult(cParamExeBench & aParam); // Test conversion set pair Hom =

void Bench_SpatialIndex(cParamExeBench & aParam); /// test spatial index

void BenchLinearConstr(cParamExeBench & aParam); /// elementary test on linear constr




/* Called by BenchGlobImage */
Expand Down
14 changes: 8 additions & 6 deletions MMVII/include/MMVII_Images.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,16 @@ template <class Type,const int Dim> class cDataTypedIm : public cDataGenUnTypedI
cDataTypedIm (const cPtxd<int,Dim> & aP0,const cPtxd<int,Dim> & aP1,
Type * DataLin=nullptr,eModeInitImage=eModeInitImage::eMIA_NoInit); ///< Only cstr
virtual ~cDataTypedIm(); ///< Big obj, do it virtual
// All distance-norm are normalized/averaged , so that const image has a norm equal to the constante
double L1Dist(const cDataTypedIm<Type,Dim> & aV) const; ///< Distance som abs
double L2Dist(const cDataTypedIm<Type,Dim> & aV) const; ///< Dist som square
double SqL2Dist(const cDataTypedIm<Type,Dim> & aV) const; ///< Square L2Dist
// If Avg=true, All distance-norm are normalized/averaged , so that const image has a norm equal to the constante
// This is default for image, but not for matrix/vector
double L1Dist(const cDataTypedIm<Type,Dim> & aV,bool Avg=true) const; ///< Distance som abs
double L2Dist(const cDataTypedIm<Type,Dim> & aV,bool Avg=true) const; ///< Dist som square
double SqL2Dist(const cDataTypedIm<Type,Dim> & aV,bool Avg=true) const; ///< Square L2Dist
double LInfDist(const cDataTypedIm<Type,Dim> & aV) const; ///< Dist max
double L1Norm() const; ///< Norm som abs
double L2Norm() const; ///< Norm square
double L1Norm(bool Avg=true) const; ///< Norm som abs
double L2Norm(bool Avg=true) const; ///< Norm square
double LInfNorm() const; ///< Nomr max
double SqL2Norm(bool Avg=true) const; ///< Norm square

Type MinVal() const;
Type MaxVal() const;
Expand Down
85 changes: 71 additions & 14 deletions MMVII/include/MMVII_Matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ template <class Type> struct cCplIV
template <class Type> class cSparseVect : public cMemCheck
{
public :

typedef cSparseVect<Type> tSV;
typedef cCplIV<Type> tCplIV;
typedef std::vector<tCplIV> tCont;
typedef typename tCont::const_iterator const_iterator;
Expand All @@ -50,14 +52,16 @@ template <class Type> class cSparseVect : public cMemCheck
const tCont & IV() const { return *(mIV.get());}
tCont & IV() { return *(mIV.get());}

void AddIV(const int & anInd,const Type & aV)
{
IV().push_back(tCplIV(anInd,aV));
}
void AddIV(const tCplIV & aCpl) { IV().push_back(aCpl); }
void AddIV(const int & anInd,const Type & aV) ; /// "Raw" add, dont check if ind exist
void AddIV(const tCplIV & aCpl) ; /// "Raw" add, dont check if ind exist
void CumulIV(const tCplIV & aCpl) ; /// Create only if not exist, else add in place

/// Random sparse vector
static cSparseVect<Type> RanGenerate(int aNbVar,double aProba);
static cSparseVect<Type> RanGenerate(int aNbVar,double aProba,tREAL8 aMinVal= 1e-2,int aMinSize=1);

// generate NbVect of dimension NbVar with average density a Proba, assuring that in all vector we have
// dist(Uk, < aCosMax
// static std::list<cSparseVect<Type> > GenerateKVect(int aNbVar,int aNbVect,double aProba,tREAL8 aDMin);

/// SzInit fill with arbitray value, only to reserve space
// cSparseVect(int aSzReserve=-1,int aSzInit=-1) ;
Expand All @@ -66,6 +70,16 @@ template <class Type> class cSparseVect : public cMemCheck
/// Check the vector can be used in a matrix,vect [0,Nb[, used in the assertions
bool IsInside(int aNb) const;
void Reset();

const tCplIV * Find(int anInd) const; /// return the pair of a given index
tCplIV * Find(int anInd) ; /// return the pair of a given index

// Maximum index, aDef is used if empty, if aDef<=-2 & empty erreur
int MaxIndex(int aDef=-1) const;

void EraseIndex(int anInd);
/// Create a real duplicata, as copy-constructor return the same shared ptr
tSV Dup() const;
private :
/*
inline void MakeSort(){if (!mIsSorted) Sort();}
Expand All @@ -84,11 +98,13 @@ template <class Type> class cDenseVect
typedef cIm1D<Type> tIM;
typedef cDataIm1D<Type> tDIM;
typedef cSparseVect<Type> tSpV;
typedef cDenseVect<Type> tDV;

cDenseVect(int aSz, eModeInitImage=eModeInitImage::eMIA_NoInit);
cDenseVect(tIM anIm);
cDenseVect(const std::vector<Type> & aVect);
cDenseVect(int Sz,const tSpV &);
// Adapt size , set
cDenseVect(const tSpV &,int aSz=-1);
static cDenseVect<Type> Cste(int aSz,const Type & aVal);
cDenseVect<Type> Dup() const;
static cDenseVect<Type> RanGenerate(int aNbVar);
Expand All @@ -102,13 +118,16 @@ template <class Type> class cDenseVect
Type & operator() (int aK) {return DIm().GetV(aK);}
const int & Sz() const {return DIm().Sz();}

double L1Dist(const cDenseVect<Type> & aV) const;
double L2Dist(const cDenseVect<Type> & aV) const;
// For vector/matrix it's more standard than norm are a sum and not an average
double L1Dist(const cDenseVect<Type> & aV,bool Avg=false) const;
double L2Dist(const cDenseVect<Type> & aV,bool Avg=false) const;

double L1Norm() const; ///< Norm som abs
double L2Norm() const; ///< Norm square
double L1Norm(bool Avg=false) const; ///< Norm som abs
double L2Norm(bool Avg=false) const; ///< Norm square
double SqL2Norm(bool Avg=false) const; ///< Norm square
double LInfNorm() const; ///< Nomr max

tDV VecUnit() const; // return V/|V|

Type * RawData();
const Type * RawData() const;
Expand All @@ -126,15 +145,44 @@ template <class Type> class cDenseVect
Type AvgElem() const; ///< Avereage of all elements
void SetAvg(const Type & anAvg); ///< multiply by a cste to fix the average



// operator -=
double DotProduct(const cDenseVect &) const;
double DotProduct(const cDenseVect &) const; //== scalar product
void TplCheck(const tSpV & aV) const
{
MMVII_INTERNAL_ASSERT_medium(aV.IsInside(Sz()) ,"Sparse Vector out dense vect");
}
void WeightedAddIn(Type aWeight,const tSpV & aColLine);

/* ========= Othognalization & projection stuff =========== */

// ---------- Projection, Dist to space ------------------
/// return orthognal projection on subspace defined by aVVect, use least square (slow ? At least good enough for bench )
tDV ProjOnSubspace(const std::vector<tDV> & aVVect) const;
/// return distance to subspace (i.e distance to proj)
Type DistToSubspace(const std::vector<tDV> &) const;

/// Theoretically max min distance, but before I find an exact algorithm, just the max on all vect , compute 2 way
static Type ApproxDistBetweenSubspace(const std::vector<tDV> &,const std::vector<tDV> &);


// -------------- Gram schmitd method for orthogonalization -------------------
/** Elementary step of Gram-Schmit orthogonalization method ; return a vector orthogonal
to all VV and that belong to the space "this+aVV", assumme aVV are already orthogonal */
tDV GramSchmidtCompletion(const std::vector<tDV> & aVV) const;
/// full method of gram schmidt to orthogonalize
static std::vector<tDV> GramSchmidtOrthogonalization(const std::vector<tDV> & aVV) ;

// ---------------- Base complementation in orthogonal subspace, slow but dont require initial base orthog --------
/// Return a unitary vector not colinear to VV, by iteration then randomization, untill the Dist to subspace > DMin
static tDV VecComplem(const std::vector<tDV> & aVV,Type DMin=0.1) ;
/// Complement the base with vector orthogonal to the base, and orthog between them (if WithInit contain initial vect + added)
static std::vector<tDV> BaseComplem(const std::vector<tDV> & aVV,bool WithInit=false,Type DMin=0.1) ;

private :

static Type ASymApproxDistBetweenSubspace(const std::vector<tDV> &,const std::vector<tDV> &);
tIM mIm;
};
/* To come, sparse vector, will be vect<int> + vect<double> */
Expand Down Expand Up @@ -184,6 +232,7 @@ template <class Type> class cMatrix : public cRect2
virtual void ReadLineInPlace(int aY,tDV &) const;
virtual tDV ReadLine(int aY) const;
virtual void WriteLine(int aY,const tDV &) ;
std::vector<tDV> MakeLines() const; // generate all the lines



Expand Down Expand Up @@ -351,15 +400,22 @@ template <class Type> class cDenseMatrix : public cUnOptDenseMatrix<Type>
cDenseMatrix Dup() const;
static cDenseMatrix Identity(int aSz); ///< return identity matrix
static cDenseMatrix Diag(const tDV &);
static cDenseMatrix FromLines(const std::vector<tDV> &); // Create from set of "line vector"
cDenseMatrix ClosestOrthog() const; ///< return closest

tDM SubMatrix(const cPt2di & aSz) const;
tDM SubMatrix(const cPt2di & aP0,const cPt2di & aP1) const;

/** Generate a random square matrix having "good" conditionning property , i.e with eigen value constraint,
usefull for bench as when the random matrix is close to singular, it may instability that fail
the numerical test.
*/
static tDM RandomSquareRegMatrix(const cPt2di&aSz,bool IsSym,double aAmplAcc,double aCondMinAccept);
static tRSVD RandomSquareRegSVD(const cPt2di&aSz,bool IsSym,double aAmplAcc,double aCondMinAccept);


static tDM RandomOrthogMatrix(const int aSz);

/* Generate a matrix rank deficient, where aSzK is the size of the kernel */
static tRSVD RandomSquareRankDefSVD(const cPt2di & aSz,int aSzK);
static tDM RandomSquareRankDefMatrix(const cPt2di & aSz,int aSzK);
Expand Down Expand Up @@ -448,6 +504,7 @@ template <class Type> class cDenseMatrix : public cUnOptDenseMatrix<Type>
void ChangSign(); ///< Multiply by -1
void SetDirectBySign(); ///< Multiply by -1 if indirect

tDV Random1LineCombination() const; // retunr a vector that is a random combination of lines
// ===== Overridng of cMatrix classe ====
void MulColInPlace(tDV &,const tDV &) const override;
Type MulColElem(int aY,const tDV &)const override;
Expand All @@ -463,8 +520,8 @@ template <class Type> class cDenseMatrix : public cUnOptDenseMatrix<Type>
void Weighted_Add_tAA(Type aWeight,const tSpV & aColLine,bool OnlySup=true) override;

// === method implemente with DIm
Type L2Dist(const cDenseMatrix<Type> & aV) const;
Type SqL2Dist(const cDenseMatrix<Type> & aV) const;
Type L2Dist(const cDenseMatrix<Type> & aV,bool Avg=false) const;
Type SqL2Dist(const cDenseMatrix<Type> & aV,bool Avg=false) const;
// void operator -= (const cDenseMatrix<Type> &) ; => see "include/MMVII_Tpl_Images.h"

private :
Expand Down
3 changes: 3 additions & 0 deletions MMVII/include/MMVII_PhgrDist.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ NS_SymbolicDerivative::cCalculator<double> * EqDist3DParam(bool WithDerive,int a
/// let pk=(xk,yk,zk), R=(r00..r22) Residual : R(p2-p2) - {dx,dy,dz}
NS_SymbolicDerivative::cCalculator<double> * EqTopoSubFrame(bool WithDerive,int aSzBuf);

/// Sum of square of unknown, to test non linear constraints
NS_SymbolicDerivative::cCalculator<double> * EqSumSquare(int aNb,bool WithDerive,int aSzBuf,bool ReUse);



// ............. Equation implying 2D distance conservation .............
Expand Down
58 changes: 53 additions & 5 deletions MMVII/include/MMVII_SysSurR.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ template <class Type> class cResidualWeighter;
// template <class Type> class cObjOfMultipleObjUk;
template <class Type> class cObjWithUnkowns;
template <class Type> class cSetInterUK_MultipeObj;
template <class Type> class cSetLinearConstraint; // defined in "src/Matrix"


/** Class for weighting residuals : compute the vector of weight from a
vector of residual; default return {1.0,1.0,...}
Expand Down Expand Up @@ -54,6 +56,18 @@ template <class Type> class cResidualWeighterExplicit: public cResidualWeighter<
tStdVect mWeights;
};


template <class Type> class cREAL8_RWAdapt : public cResidualWeighter<Type>
{
public :
typedef std::vector<Type> tStdVect;
cREAL8_RWAdapt(const cResidualWeighter<tREAL8> * aRW) ;
tStdVect WeightOfResidual(const tStdVect & aVIn) const override;
private :
const cResidualWeighter<tREAL8>* mRW;
};


/// Index to use in vector of index indicating a variable to substituate
static constexpr int RSL_INDEX_SUBST_TMP = -1;

Expand Down Expand Up @@ -124,12 +138,30 @@ class cREAL8_RSNL
void UnfrozeAll() ; ///< indicate it var must be frozen /unfrozen
bool VarIsFrozen(int aK) const; ///< indicate it var must be frozen /unfrozen
void AssertNotInEquation() const; ///< verify that we are notin equation step (to allow froze modification)
// To update with Shared
int CountFreeVariables() const; ///< number of free variables

// ------------------ Handling shared unknowns --------------------
void SetShared(const std::vector<int> & aVUk);
void SetUnShared(const std::vector<int> & aVUk);
void SetAllUnShared();

// ===
protected :
static constexpr int TheLabelFrozen =-1;
static constexpr int TheLabelNoEquiv =-2;

void SetPhaseEq();
/// Mut be defined in inherited class because maniupulate mLinearConstr which depend of type
virtual void InitConstraint() = 0;

int mNbVar;
bool mInPhaseAddEq; ///< check that dont modify val fixed after adding equations
std::vector<bool> mVarIsFrozen; ///< indicate for each var is it is frozen
bool mInPhaseAddEq; ///< check that dont modify val fixed after adding equations
std::vector<bool> mVarIsFrozen; ///< indicate for each var is it is frozen
int mNbIter; ///< Number of iteration made
// int mNbUnkown;
int mCurMaxEquiv; ///< Used to label the
std::vector<int> mEquivNum; ///< Equivalence numerotation, used for shared unknowns
};


Expand Down Expand Up @@ -163,6 +195,7 @@ template <class Type> class cResolSysNonLinear : public cREAL8_RSNL
/// destructor
~cResolSysNonLinear();


/// Accessor
const tDVect & CurGlobSol() const;
cREAL8_RSNL::tDVect R_CurGlobSol() const override; ///< tREAL8 Equivalent
Expand All @@ -178,7 +211,7 @@ template <class Type> class cResolSysNonLinear : public cREAL8_RSNL
void SetCurSol(int aNumV,const Type&) ;
void R_SetCurSol(int aNumV,const tREAL8&) override; ///< tREAL8 Equivalent

tLinearSysSR * SysLinear() ;
tLinearSysSR * SysLinear() ; ///< Accessor

/// Solve solution, update the current solution, Reset the least square system
const tDVect & SolveUpdateReset(const Type & aLVM =0.0) ;
Expand All @@ -201,6 +234,8 @@ template <class Type> class cResolSysNonLinear : public cREAL8_RSNL
void AddEqFixNewVal(const tObjWUk & anObj,const cPtxd<Type,3> &,const cPtxd<Type,3> &,const Type& aWeight);


void AddNonLinearConstr(tCalc * aCalcVal,const tVectInd & aVInd,const tStdVect& aVObs,bool OnlyIfFirst=true);

/// Basic Add 1 equation , no bufferistion, no schur complement
void CalcAndAddObs(tCalc *,const tVectInd &,const tStdVect& aVObs,const tResidualW & = tResidualW());
void R_CalcAndAddObs(tCalc *,const tVectInd &,const tR_Up::tStdVect& aVObs,const tR_Up::tResidualW & ) override;
Expand Down Expand Up @@ -242,6 +277,8 @@ template <class Type> class cResolSysNonLinear : public cREAL8_RSNL

int GetNbObs() const; ///< get number of observations (last iteration if after reset, or current number if after AddObs)

void AddConstr(const tSVect & aVect,const Type & aCste,bool OnlyIfFirstIter=true);
void SupressAllConstr();
private :
cResolSysNonLinear(const tRSNL & ) = delete;

Expand All @@ -251,16 +288,23 @@ template <class Type> class cResolSysNonLinear : public cREAL8_RSNL
/// Add observations as computed by CalcVal
void AddObs(const std::vector<tIO_RSNL>&);

void InitConstraint() override;
/** Bases function of calculating derivatives, dont modify the system as is
to avoid in case of schur complement */
void CalcVal(tCalc *,std::vector<tIO_RSNL>&,const tStdVect & aVTmp,bool WithDer,const tResidualW & );
to avoid in case of schur complement , if it is used for linearizeing constraint "ForConstr" the process is slightly diff*/
void CalcVal(tCalc *,std::vector<tIO_RSNL>&,const tStdVect & aVTmp,bool WithDer,const tResidualW &,bool ForConstr );

tDVect mCurGlobSol; ///< Curent solution
tLinearSysSR* mSysLinear; ///< Sys to solve equations, equation are concerning the differences with current solution

std::vector<Type> mValueFrozenVar; ///< indicate for each var the possible value where it is frozen
int lastNbObs; ///< number of observations of last solving
int currNbObs; ///< number of observations currently added

/// handle the linear constraint : fix var, shared var, gauge ...
cSetLinearConstraint<Type>* mLinearConstr;

std::vector<Type> mVCstrCstePart; /// Cste part of linear constraint that dont have specific struct (i.e vs Froze/Share)
std::vector<tSVect> mVCstrLinearPart; /// Linerar Part of
};


Expand Down Expand Up @@ -292,6 +336,7 @@ template <class Type> class cInputOutputRSNL
std::vector<tStdVect> mDers; ///< derivate of fctr
size_t mNbTmpUk;

// use a s converter from tREAL8, "Fake" is used to separate from copy construtcor when Type == tREAL8
cInputOutputRSNL(bool Fake,const cInputOutputRSNL<tREAL8> &);
private :
// cInputOutputRSNL(const cInputOutputRSNL<Type> &) = delete;
Expand Down Expand Up @@ -801,6 +846,9 @@ template <class Type> class cObjWithUnkowns // : public cObjOfMultipleObjUk<Typ
int mIndUk1;
};

template <class T1,class T2> void ConvertVWD(cInputOutputRSNL<T1> & aIO1 , const cInputOutputRSNL<T2> & aIO2);


};

#endif // _MMVII_SysSurR_H_
2 changes: 1 addition & 1 deletion MMVII/include/MMVII_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ class cSetIntDyn
void Clear();
void AddIndFixe(size_t aK) ///< Add an element, assume sizeof vector of
{
if (!mOccupied[aK])
if (!mOccupied.at(aK))
{
mOccupied[aK] = true;
mVIndOcc.push_back(aK);
Expand Down
1 change: 1 addition & 0 deletions MMVII/src/Bench/BenchGlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ int cAppli_MMVII_Bench::ExecuteBench(cParamExeBench & aParam)
Bench_MatEss(aParam);
Bench_SpatialIndex(aParam);
Bench_ToHomMult(aParam);
BenchLinearConstr(aParam);
}

// Now call the bench of all application that define their own bench
Expand Down
Loading

0 comments on commit e7ce945

Please sign in to comment.