From fd798b3a898972f7d76cb4d5dd5d19d48bb73343 Mon Sep 17 00:00:00 2001 From: deseilligny Date: Fri, 30 Apr 2021 07:42:42 +0200 Subject: [PATCH 01/25] Dans Map/SymbDer avant modif symbder --- MMVII/include/MMVII_Geom2D.h | 25 + MMVII/include/MMVII_Mappings.h | 281 ++++++++++- MMVII/include/MMVII_all.h | 7 + MMVII/include/SymbDer/SymbDer_Common.h | 3 + MMVII/src/Mappings/Mapping2D.cpp | 49 -- MMVII/src/Mappings/MappingElems.cpp | 68 +++ MMVII/src/Mappings/MappingGen.cpp | 445 +++++++++--------- MMVII/src/Mappings/MappingInverse.cpp | 511 +++++++++++++++++++++ MMVII/src/SymbDerGen/Formulas_CamStenope.h | 2 +- MMVII/src/SymbDerGen/GenerateCodes.cpp | 10 +- MMVII/src/Utils/uti_times.cpp | 80 ++++ 11 files changed, 1185 insertions(+), 296 deletions(-) delete mode 100644 MMVII/src/Mappings/Mapping2D.cpp create mode 100644 MMVII/src/Mappings/MappingElems.cpp create mode 100644 MMVII/src/Mappings/MappingInverse.cpp diff --git a/MMVII/include/MMVII_Geom2D.h b/MMVII/include/MMVII_Geom2D.h index e62ed331f9..53c181e48e 100644 --- a/MMVII/include/MMVII_Geom2D.h +++ b/MMVII/include/MMVII_Geom2D.h @@ -49,6 +49,31 @@ template inline cPtxd PSymXY (const cPtxd & aP) } +template class cSim2D +{ + public : + typedef Type TheType; + static constexpr int TheDim=2; + + typedef cPtxd tPt; + + cSim2D(const tPt & aTr,const tPt & aSc) : + mTr (aTr), + mSc (aSc) + { + } + static const int NbDOF() {return 4;} + + inline tPt Value(const tPt & aP) const {return mTr + aP * mSc;} + inline tPt Inverse(const tPt & aP) const {return (aP-mTr)/mSc ;} + + cSim2D MapInverse() const {return cSim2D(-mTr/mSc,tPt(1.0,0.0)/mSc);} + + private : + tPt mTr; + tPt mSc; +}; + }; diff --git a/MMVII/include/MMVII_Mappings.h b/MMVII/include/MMVII_Mappings.h index 2e450ba833..68366d9ee5 100644 --- a/MMVII/include/MMVII_Mappings.h +++ b/MMVII/include/MMVII_Mappings.h @@ -1,6 +1,31 @@ #ifndef _MMVII_MAPPINGS_H_ #define _MMVII_MAPPINGS_H_ +/* For in & out computation of vector of points, do we use static buffer or + do each object has its own buffer. First option is more economic, but can lead to + sides effect if buffering is not well understood . So for now I maintain the possibility + to have the two option +*/ + +#define MAP_STATIC_BUF true + + + /* These macro are for now the only way I found for detecting infinite recursion + in case user did define neither buffered nor unbuffered methods for Values, Jacobian, Inverse ... + + Not very proud of that, but can help to detect the error + */ + + +#define MACRO_CHECK_RECURS_BEGIN\ + static int aCPT_CHECK_RECURS=0;\ + MMVII_INTERNAL_ASSERT_strong((aCPT_CHECK_RECURS==0),"Forbiden Recursive Call");\ + aCPT_CHECK_RECURS++; + +#define MACRO_CHECK_RECURS_END\ + aCPT_CHECK_RECURS--; + + namespace MMVII { template class cDataBoundedSet ; @@ -12,6 +37,62 @@ template class cDataMapping; Most probably this will evolve a lot, with several reengenering phases. + Mapping are object for representing mathematicall smooth function from R^K to R^N. + + [1] WHAT + The typicall mapping used in photogrammetry are : + * distorsion (fraser, brown, polynomial) R^2 => R^2 + * projection (stenope,fisheye, pushbroom) R^3 => R^2 + * polynomial model R^K => R ^N + * parametric maping for estimating global transformation between repair, image ... + # External orientation, helmert transform ... R^3 => R^3 + # parametric 2D maping for estimating global image tranform (rotation,affine,homography, polynomial) + * generic epipolar ressempling R^2 => R^1 + + [2] WHY + The typicall thing we want to do with mappings are : + * compute their value M(P) + * when N=K: + # for a given P, compute the invert value Q such that M(Q) = P + # for certain mapping belong to a given group, compute its exact invert mapping + (i.e affinty, homogra ...) + # compute M' an approximate inverse of M such that M'(M(P)) ~ P, typically M' can be polynomial + and approximation can be made by least square + * compute the value of the differential in given point + * estimate a mapping M from a set of example (Pi,Qi) such that M(Pi)~Qi , taking, or not, + into account the presence of outlayers + * use a mapping to re-sample an image + + [3] HOW + The implementation in MMVII plane to have the following objective : + * be general in WHAT and WHY + * be relatively simple to use, i.e. for defining a new mapping the user has + the minimum to do : define the direct mapping + * be efficient in term of memory and time by offering the user to define more + than the minimum (own jacobian, own inverse ...) + + Typically, the idea is that main services, like estimation, inversion, resampling ... + are implemanted using virtual base classes, and user can benefit of these services with his + new mapping functions, as soon as they redefine a minimum of methods. + + I hope this implimentation complies with the above requirement, hower it comes to certain + complexity on my side (implementation of the general class). + + For the trade-off between efficiency and simplicity on user side, the general philosphy is to offer the + user the possibility to choice. For example : + + * if simplicity is priviligiated, user can just define a methode operating on a single + value and he will have acces to derivative (with finite difference) and to the inverse + (if he provide an additionnal rough inverse) with an iterative methods + + * is efficiency is priviligiated, user can define a method computing value and jacobian + operating and vectors for taking benefit of his parallel implementation. + + +*/ + +/** Shared pointer on the real class, later it will be the main class accessible by non derived + In the devlopment step cDataMapping is still accessible. */ template class cMapping @@ -27,6 +108,10 @@ template class cMapping tDataMap* mRawPtr; }; +/** Class for defining a bounded subset of R^n. TO DEVLOP ... +*/ + + template class cDataBoundedSet : public cMemCheck { public : @@ -39,7 +124,57 @@ template class cDataBoundedSet : public cMemCheck cTplBox mBox; }; -/// Class that represent a continous mapping R^k -> R^n + + +/** Mother base classe for defining a mapping R^k => R^n with k=DimIn and n=DimOut + + The virtual methods "Values" and "Value" compute the image of poinst by the mapping. + The derived classe MUST override at least "Values" or "Value" + + * Value works on single points, if not overrided, Values is called with one element vector + * Values works on vector, if not override, Value is called for each element of the vector + + If nor Value neither Values are defined, we have a potential infinite recursion (which is + cathed by Macros MACRO_CHECK_RECURS_BEGIN / MACRO_CHECK_RECURS_END to avoid an unclear + core-dump). Conversely it is possible (but probably not very usefull) to override both method + for very fine optimzation. + + There is two methods values : + V2 : virtual const vec& Values(vec&,cons vec&) + V1 : const vec& Values(cons vec&) + The medod V2 is the "fundental" one which must be overrided. V1 is just a facility that use + the internal buffer. + + ----------------------------------------------------------- + + There is exactly the same contruction with Jacobian(s) which are methods for computing the + jacobian(s) AND the value(s) of point(s). + + * Jacobian => return a pair (Point,Matrix) + * Jacobians => return a pair (pointer on vector of Point,pointer on vector of Matrix) + + However there is a TRICKY thing to take care of : + + * between different calls to Values or Jacobians, if user use V1 of J1 methods , + the results are returns as a reference to an internal buffer + * so afetr each calls , the result overwrite the previous one + * for values, if the vector must be memorized, it is sufficient to do something + tVecPt V=Values(..) + and it will create a copy that will not be overide + * for Jacobian this would not work, the copy would be made, but as the matrix + are stored as pointer (shared) to the real data, it will be always the same matrices + that will be used. + + Maybe later, offer an additionale safe copy version.... + + ----------------------------------------------------------- + This design is motivated by the following reasons : + + * use buffered mode (on vector) and compute simultaneously values & jacobian to + take benfit of the opportunity of code generation in MMVII + + * offers non buffered mode when simplicity is privilegiated on efficiency +*/ @@ -54,20 +189,20 @@ template class cDataMapping : publ typedef cDenseMatrix tJac; ///< jacobian (DimIn DimOut); DimOut=1 =>line vector/linear form typedef std::vector tVecJac; typedef std::pair tResJac; - typedef std::pair tResVecJac; + typedef std::pair tCsteResVecJac; + typedef std::pair tResVecJac; // ========== Computation of values ============== - virtual const tVecOut & Direct(const tVecIn & ) const; - virtual tPtOut Direct(const tPtIn &) const; + virtual const tVecOut & Values(tVecOut &,const tVecIn & ) const; //V2 + const tVecOut & Values(const tVecIn & ) const; // V1 + virtual tPtOut Value(const tPtIn &) const; - virtual tResVecJac Jacobian(const tVecIn &) const; + virtual tCsteResVecJac Jacobian(tResVecJac,const tVecIn &) const; //J2 + tCsteResVecJac Jacobian(const tVecIn &) const; //J1 virtual tResJac Jacobian(const tPtIn &) const; - // virtual void ComputeValAndJac() const; - /// Compute image in direct sens - // virtual const std::pair & ComputeValAndGrad(const tPtIn &) const; /// compute diffenrentiable method , default = erreur protected : @@ -75,54 +210,130 @@ template class cDataMapping : publ cDataMapping(); /** EpsJac is used to compute the jacobian by finite difference, */ cDataMapping(const tPtIn & aEps); + /** call "cDataMapping(tPt)" with cste point */ + cDataMapping(const Type & aEps); tPtIn mEpsJac; bool mJacByFiniteDif; // std::vector mGrads; // std::vector mResGrads; +#if (MAP_STATIC_BUF) + static tVecOut& BufOut() {static tVecOut aRes; return aRes;} + static tVecOut& JBufOut() {static tVecOut aRes; return aRes;} + static tVecIn& BufIn() {static tVecIn aRes; return aRes;} + static tVecIn& JBufIn() {static tVecIn aRes; return aRes;} + + static tVecOut& BufOutCleared() { BufOut().clear() ; return BufOut();} + static tVecOut& JBufOutCleared() {JBufOut().clear() ; return JBufOut();} + static tVecIn& BufInCleared() { BufIn().clear() ; return BufIn(); } + static tVecIn& JBufInCleared() {JBufIn().clear() ; return JBufIn(); } + + static tVecIn & BufIn1Val() {static tVecIn aRes{tPtIn()}; return aRes;} + static tVecJac & BufJac(tU_INT4 aSz) ; +#else // !MAP_STATIC_BUF + private : mutable tVecOut mBufOut; mutable tVecOut mJBufOut; mutable tVecIn mBufIn; + mutable tVecIn mJBufIn; mutable tVecIn mBufIn1Val; mutable tVecJac mJacReserve; mutable tVecJac mJacResult; + protected : inline tVecOut& BufOut() const {return mBufOut;} inline tVecOut& BufOutCleared() const {mBufOut.clear();return mBufOut;} inline tVecOut& JBufOut() const {return mJBufOut;} inline tVecOut& JBufOutCleared() const {mJBufOut.clear();return mJBufOut;} inline tVecIn& BufIn() const {return mBufIn;} inline tVecIn& BufInCleared() const {mBufIn.clear(); return mBufIn;} + inline tVecIn& JBufIn() const {return mJBufIn;} + inline tVecIn& JBufInCleared() const {mJBufIn.clear(); return mJBufIn;} inline tVecIn & BufIn1Val() const {return mBufIn1Val;} - tVecJac & BufJac(tU_INT4 aSz) const ; /// Sz<0 => means clear buf + tVecJac & BufJac(tU_INT4 aSz) const ; +#endif // MAP_STATIC_BUF }; -template class cInvertDIMByIter; +/** This is the mother class of maping that can compute the inverse of a point. + + The method comptuing the inverse are "Inverse(s)", and we have the same behaviour as with Value(s). +*/ template class cDataInvertibleMapping : public cDataMapping { public : - friend class cInvertDIMByIter ; - typedef cDataMapping tDataMap; - typedef cMapping tMap; typedef typename tDataMap::tPtIn tPt; typedef typename tDataMap::tVecIn tVecPt; + + + // ========== Constructors ============== + cDataInvertibleMapping(const tPt &); + cDataInvertibleMapping(); + + // ========== Computation of inverses ============== + virtual const tVecPt & Inverses(tVecPt &,const tVecPt & ) const; + const tVecPt & Inverses(const tVecPt & ) const; + virtual tPt Inverse(const tPt &) const; + + private : +#if (MAP_STATIC_BUF) + static tVecPt& BufInvOut() {static tVecPt aRes; return aRes;} + static tVecPt& BufInvOutCleared() { BufInvOut().clear() ; return BufInvOut();} +#else // !MAP_STATIC_BUF + mutable tVecPt mBufInvOut; + inline tVecPt& BufInvOut() const {return mBufInvOut;} + inline tVecPt& BufInvOutCleared() const {mBufInvOut.clear();return mBufOut;} +#endif +}; + + + + +/* class doing the real iterative computation */ + +template class cInvertDIMByIter; +/** This class offer a concrete computation of the inverse by a iterative method, relying + on jacobian computation. A first "guess" of the inverse must be given. If the mapping is + very smooth globally close to a linear mapping the guess is of no importance for the convergence. + On the other hand, giving a relatively accurate guess will accelerate the result and, more + importantly, will be safer for the convergence. +*/ + +template class cDataIterInvertMapping : public cDataInvertibleMapping +{ + public : + typedef cInvertDIMByIter tHelperInvertIter; + friend tHelperInvertIter; + + typedef cDataInvertibleMapping tDataInvMap; + typedef typename tDataInvMap::tPt tPt; + typedef typename tDataInvMap::tVecPt tVecPt; + + typedef cMapping tMap; + typedef cDataMapping tDataMap; typedef typename tDataMap::tResVecJac tResVecJac; - void SetRoughInv(tMap,const Type& aDistTol,int aNbIterMax); - const tDataMap * RoughInv() const ; - virtual const tVecPt & ComputeInverse(const tVecPt &) const; + + const tVecPt & Inverses(tVecPt &,const tVecPt &) const override; + // Accessors + const tDataMap * RoughInv() const ; + const Type & DTolInv() const; protected : - cDataInvertibleMapping(); + cDataIterInvertMapping(const tPt &,tMap,const Type& aDistTol,int aNbIterMax); + cDataIterInvertMapping(tMap,const Type& aDistTol,int aNbIterMax); + + private : + tHelperInvertIter * StrInvertIter() const; + mutable std::shared_ptr mStrInvertIter; tMap mRoughInv; Type mDTolInv; int mNbIterMaxInv; }; -/* -*/ + +/** Represntation of identity as a mapping */ template class cMappingIdentity : public cDataMapping { @@ -130,15 +341,35 @@ template class cMappingIdentity : public cDataMappin typedef cDataMapping tDataMap; typedef typename tDataMap::tPtIn tPt; typedef typename tDataMap::tVecIn tVecPt; - tPt Direct(const tPt &) const override; - const tVecPt & Direct(const tVecPt & ) const override; + tPt Value(const tPt &) const override; + const tVecPt & Values(tVecPt &,const tVecPt & ) const override; +}; + +template class cInvertMappingFromElem : public + cDataInvertibleMapping +{ + public : + static constexpr int Dim=cMapElem::TheDim; + typedef typename cMapElem::TheType TheType; + static_assert(cMapElem::TheDim==cIMapElem::TheDim); + + typedef cDataInvertibleMapping tDataIMap; + typedef typename tDataIMap::tPt tPt; + typedef typename tDataIMap::tVecPt tVecPt; + + const tVecPt & Values(tVecPt & aRes,const tVecPt & aVIn ) const override; + tPt Value(const tPt &) const override; + const tVecPt & Inverses(tVecPt & aRes,const tVecPt & aVIn ) const override; + tPt Inverse(const tPt &) const override; + + cInvertMappingFromElem(const cMapElem & aMap,const cIMapElem & aIMap); + cInvertMappingFromElem(const cMapElem & aMap); // requires that aMap can compute its inverse + private : + cMapElem mMap; // Map + cIMapElem mIMap; // Map inverse }; -/* -*/ -/** We coul expect that DimIn=DimOut, but in fact in can be used -to represent a mapping from a part of the plane to a part of the sphere */ /* diff --git a/MMVII/include/MMVII_all.h b/MMVII/include/MMVII_all.h index bbbf0c905c..1608cfd4c4 100644 --- a/MMVII/include/MMVII_all.h +++ b/MMVII/include/MMVII_all.h @@ -78,4 +78,11 @@ #include "SymbDer/SymbDer_Common.h" #include "../kapture/kapture.h" +namespace MMVII +{ +// used for bench now To put elsewhere later, +NS_SymbolicDerivative::cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf); +}; + + #endif // _MMVII_ALL_H_ diff --git a/MMVII/include/SymbDer/SymbDer_Common.h b/MMVII/include/SymbDer/SymbDer_Common.h index 8380917228..142549f7a5 100644 --- a/MMVII/include/SymbDer/SymbDer_Common.h +++ b/MMVII/include/SymbDer/SymbDer_Common.h @@ -71,6 +71,7 @@ class cCalculator bool BufIsFull() const {return mNbInBuf == mSzBuf;} ///< Can we push more value ? size_t SzBuf() const {return mSzBuf;} ///< Total Number of value we can push size_t FreeSzBuf() const {return mSzBuf - mNbInBuf;} ///< Number of value we can still add + size_t NbInBuf() const {return mNbInBuf;} ///< Number of value already in buf /// Add a new set of vals (unknown + Obs) inside de evaluation "queue" @@ -94,10 +95,12 @@ class cCalculator return mBufRes.at(aNumPush)->at(mSzInterval*aKElem +1 + aKVarDer); } + const bool WithDer() const { return mWithDer; } // With derive ? Usable for checking const size_t NbUk() const { return mNbUK; } // Nb of unknowns const size_t NbObs() const { return mNbObs; } // Nb of Observations const size_t NbElem() const { return mNbElem; } // Nb of primary values returned by formula (w/o counting derivatives) const std::vector & Result() const { return mBufRes; } + protected: cCalculator(const std::string& aName, int aSzBuf, size_t aNbUk, size_t aNbObs, bool aWithDer=false, int aSzInterval=1) : diff --git a/MMVII/src/Mappings/Mapping2D.cpp b/MMVII/src/Mappings/Mapping2D.cpp deleted file mode 100644 index 9f532ef8b8..0000000000 --- a/MMVII/src/Mappings/Mapping2D.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "include/MMVII_all.h" - -namespace MMVII -{ - -/* ============================================= */ -/* cDataMapping */ -/* ============================================= */ - - -template class cSimil2D : public cDataMapping -{ - public : - typedef cDataMapping tSuper; - typedef cPtxd tPt; - typedef std::vector tVPt; - - cSimil2D(const tPt &aTr,const tPt &aSc); - inline tPt Direct(const tPt & aPt) const override { return mTr + mSc * aPt;} - const tVPt & Direct(const std::vector & aPt) const override ; - private : - tPt mTr; - tPt mSc; -}; - -template - cSimil2D::cSimil2D(const tPt &aTr,const tPt &aSc) : - - mTr (aTr), - mSc (aSc) -{ -} - - -template - const std::vector> & cSimil2D::Direct(const tVPt & aVPt) const -{ - typename tSuper::tVecOut& aBuf = tSuper::BufOut(); - for (const auto & aPt : aVPt) - aBuf.push_back(cSimil2D::Direct(aPt)); - return aBuf; -} - - -template class cSimil2D; - - - -}; diff --git a/MMVII/src/Mappings/MappingElems.cpp b/MMVII/src/Mappings/MappingElems.cpp new file mode 100644 index 0000000000..239f33087d --- /dev/null +++ b/MMVII/src/Mappings/MappingElems.cpp @@ -0,0 +1,68 @@ +#include "include/MMVII_all.h" + +namespace MMVII +{ + +/* ============================================= */ +/* cDataMapping */ +/* ============================================= */ + +template + cInvertMappingFromElem::cInvertMappingFromElem + (const cMapElem & aMap,const cIMapElem & aIMap) : + mMap (aMap), + mIMap (aIMap) +{ +} + +template + cInvertMappingFromElem::cInvertMappingFromElem (const cMapElem & aMap) : + cInvertMappingFromElem(aMap,aMap.MapInverse()) +{ +} + + +template + const typename cInvertMappingFromElem::tVecPt & + cInvertMappingFromElem::Values(tVecPt & aRes,const tVecPt & aVIn ) const +{ + for (const auto & aPtIn : aVIn) + aRes.push_back(mMap.Value(aPtIn)); + return aRes; +} + +template + typename cInvertMappingFromElem::tPt + cInvertMappingFromElem::Value(const tPt & aPt) const +{ + return mMap.Value(aPt); +} + +template + const typename cInvertMappingFromElem::tVecPt & + cInvertMappingFromElem::Inverses(tVecPt & aRes,const tVecPt & aVIn ) const +{ + for (const auto & aPtIn : aVIn) + aRes.push_back(mIMap.Value(aPtIn)); + return aRes; +} + +template + typename cInvertMappingFromElem::tPt + cInvertMappingFromElem::Inverse(const tPt & aPt) const +{ + return mIMap.Value(aPt); +} + + + + + + + +template class cInvertMappingFromElem,cSim2D>; + + + + +}; diff --git a/MMVII/src/Mappings/MappingGen.cpp b/MMVII/src/Mappings/MappingGen.cpp index 243c7fdc61..abb95bbf0b 100644 --- a/MMVII/src/Mappings/MappingGen.cpp +++ b/MMVII/src/Mappings/MappingGen.cpp @@ -3,6 +3,7 @@ namespace MMVII { + /* ============================================= */ /* cDataMapping */ /* ============================================= */ @@ -12,17 +13,26 @@ namespace MMVII template cDataMapping::cDataMapping(const tPtIn & aEpsJac) : mEpsJac (aEpsJac), - mJacByFiniteDif (mEpsJac.x()>0), - mBufIn1Val ({tPtIn()}) + mJacByFiniteDif (mEpsJac.x()>0) +#if (! MAP_STATIC_BUF) + , mBufIn1Val ({tPtIn()}) +#endif { // BufIn1Val().clear(); // BufIn1Val().push_back(tPtIn()); // We need to at least be abble to put one point for finite diff } +template + cDataMapping::cDataMapping(const Type & aVal) : + cDataMapping(tPtIn::PCste(aVal)) +{ +} + + template cDataMapping::cDataMapping() : - cDataMapping(tPtIn::PCste(0.0)) + cDataMapping(Type(0.0)) { } @@ -34,21 +44,32 @@ template /// Buffered mode by default calls unbeferred mode template const typename cDataMapping::tVecOut & - cDataMapping::Direct(const tVecIn & aVIn) const + cDataMapping::Values(tVecOut & aBufOut,const tVecIn & aVIn) const +{ +/**/MACRO_CHECK_RECURS_BEGIN; + for (const auto & aP : aVIn) + aBufOut.push_back(Value(aP)); +/**/MACRO_CHECK_RECURS_END; + return aBufOut; +} + +template + const typename cDataMapping::tVecOut & + cDataMapping::Values(const tVecIn & aVIn) const { - tVecOut & aBufOut = BufOutCleared(); - for (const auto & aP : aVIn) - aBufOut.push_back(Direct(aP)); - return aBufOut; + return Values(BufOutCleared(),aVIn); } + + + /// Unbeferred mode by default calls buferred mode template typename cDataMapping::tPtOut - cDataMapping::Direct(const tPtIn & aPt) const + cDataMapping::Value(const tPtIn & aPt) const { BufIn1Val()[0] = aPt; - const tVecOut & aRes = Direct(BufIn1Val()); + const tVecOut & aRes = Values(BufIn1Val()); return aRes[0]; } @@ -56,8 +77,16 @@ template template typename cDataMapping::tVecJac & - cDataMapping::BufJac(tU_INT4 aSz) const + cDataMapping::BufJac(tU_INT4 aSz) +#if (!MAP_STATIC_BUF) + const +#endif { +#if (MAP_STATIC_BUF) + cMemManager::SetActiveMemoryCount(false); // static vector of shared matrix will never be unallocated + static tVecJac mJacReserve; + static tVecJac mJacResult; +#endif while (mJacReserve.size() // If too big while (mJacResult.size()>aSz) mJacResult.pop_back(); +#if (MAP_STATIC_BUF) + cMemManager::SetActiveMemoryCount(true); +#endif return mJacResult; } @@ -73,13 +105,17 @@ template /// Buffered mode by default calls finit difference OR unbeferred mode template - typename cDataMapping::tResVecJac - cDataMapping::Jacobian(const tVecIn & aVIn) const + typename cDataMapping::tCsteResVecJac + cDataMapping::Jacobian(tResVecJac aRes,const tVecIn & aVIn) const { +/**/MACRO_CHECK_RECURS_BEGIN; + tU_INT4 aNbIn = aVIn.size(); - tVecOut & aJBufOut = JBufOutCleared(); - tVecJac & aBufJac = BufJac(aNbIn); + tVecOut & aJBufOut = *(aRes.first); + tVecJac & aBufJac = *(aRes.second); +/* tResVecJac aRes(&aJBufOut,&aBufJac); +*/ // tResVecJac aRes(nullptr,nullptr); if (mJacByFiniteDif) { @@ -88,7 +124,7 @@ template for (tU_INT4 aKpt0=0 ; aKpt0 aPK[aD] -= mEpsJac[aD]; } } - const tVecOut & aResOut = Direct(aBufIn); + const tVecOut & aResOut = Values(aBufIn); int aInd = 0; for (tU_INT4 aKpt=aKpt0 ; aKpt aBufJac[aKpt] = aJac; } } - return aRes; +/**/MACRO_CHECK_RECURS_END; + return tCsteResVecJac(aRes.first,aRes.second); +} + +template + typename cDataMapping::tCsteResVecJac + cDataMapping::Jacobian(const tVecIn & aVIn) const +{ +/**/MACRO_CHECK_RECURS_BEGIN; + tU_INT4 aNbIn = aVIn.size(); + tVecOut & aJBufOut = JBufOutCleared(); + tVecJac & aBufJac = BufJac(aNbIn); + tResVecJac aRes(&aJBufOut,&aBufJac); +/**/MACRO_CHECK_RECURS_END; + return Jacobian(aRes,aVIn); } template @@ -134,7 +184,7 @@ template cDataMapping::Jacobian(const tPtIn & aPtIn) const { BufIn1Val()[0] = aPtIn; - tResVecJac aResVec = Jacobian(BufIn1Val()); + tCsteResVecJac aResVec = Jacobian(BufIn1Val()); return tResJac(aResVec.first->at(0),aResVec.second->at(0)); } @@ -149,181 +199,6 @@ template { } -/* ============================================= */ -/* cInvertByIter */ -/* - cStrPtInvDIM */ -/* ============================================= */ - -template struct cStrPtInvDIM -{ - public : - tU_INT4 mNum; - Type mCurEr; - cPtxd mCurInv; - cPtxd mCurVal; - cPtxd mNewInv; - cPtxd mNewVal; - cPtxd mPTarget; -}; - -template class cInvertDIMByIter -{ - public : - typedef cDataInvertibleMapping tDIM; - typedef cStrPtInvDIM tSPIDIM; - typedef typename tDIM::tPt tPt; - typedef typename tDIM::tVecPt tVecPt; - typedef typename tDIM::tResVecJac tResVecJac; - - - cInvertDIMByIter(const tDIM & aDIM,const tVecPt & aVTarget); - private : - void OneIterInversion(); - - const tDIM & mDIM; - std::vector mVInv; - std::vector mVSubSet; // Subset of index to compute - tSPIDIM & InvOfKSubS(tU_INT4 aInd) {return mVInv.at(mVSubSet.at(aInd));} -}; - -template - void cInvertDIMByIter::OneIterInversion() -{ - // Put in aVCurInv the curent estimation of inverses - tVecPt & aVCurInv = mDIM.BufInCleared(); - for (tU_INT4 aKInd=0 ; aKIndat(aKInd); - tPt aEr = aSInv.mPTarget-aSInv.mCurVal; - aSInv.mCurEr = Norm2(aEr); - if (aSInv.mCurEr< mDIM.mDTolInv) - { - // Nothing to do , mCurInv is a good inverse - } - else - { - // Use Jacobian to compute the correction giving the error - tPt aCor = SolveCol(aVJ.second->at(aKInd),aEr); - aSInv.mNewInv = aSInv.mCurInv+ aCor; // Restimate inverse with correction - aVCurInv.at(aNewInd) = aSInv.mNewInv; // Put new inverse in vect to evaluate - mVSubSet.at(aNewInd) = aSInv.mNum; //this one is in the new subset - aNewInd++; - } - } - // We have filled only partially the new indexes - mVSubSet.resize(aNewInd); - aVCurInv.resize(aNewInd); - - const tVecPt & aVO = mDIM.Direct(aVCurInv); - - for (tU_INT4 aKInd=0 ; aKInd - cInvertDIMByIter::cInvertDIMByIter(const tDIM & aDIM,const tVecPt & aVTarget) : - mDIM (aDIM) - -{ - mVSubSet.clear(); - mVInv.clear(); - const tVecPt & aVInit = mDIM.RoughInv()->Direct(aVTarget); - for (tU_INT4 aKPt=0; aKPt */ -/* ============================================= */ - -template - cDataInvertibleMapping::cDataInvertibleMapping() : - mRoughInv (nullptr) -{ -} - -template - void cDataInvertibleMapping::SetRoughInv(tMap aMap,const Type & aDistTol,int aNbIterMaxInv) -{ - mDTolInv = aDistTol; - mNbIterMaxInv = aNbIterMaxInv; - mRoughInv = aMap; -} - -template - const typename cDataInvertibleMapping::tDataMap * - cDataInvertibleMapping::RoughInv() const -{ - return mRoughInv.DM(); -} - - -#if (0) - - -#endif - -template - const typename cDataInvertibleMapping::tVecPt & - cDataInvertibleMapping::ComputeInverse(const tVecPt & aVTarget) const -{ - const tVecPt & aVInit = mRoughInv.DM()->Direct(aVTarget); -/* - std::vector aVSubSetToC; // Subset of index to compute - std::vector aVInv; - - for (tU_INT4 aKPt=0; aKPt aPtID; - aP.mNum = aKPt; - aP.Target = aVTarget[aKPt]; - aP.mCurInv = aVInit[aKPt] - aP.mLastD = 1e10 * mDTolInv; - aVSubSetToC.push_back(aKPt); - aVInv.push_back(aP); - } -*/ - -/* - bool Cont = true; - while (Cont) - { - tVecPt aVCurs; - aBufIn.clear(); - for (tU_INT4 aKSel=0 ; aKSel */ @@ -332,17 +207,18 @@ template template const typename cMappingIdentity::tVecPt & - cMappingIdentity::Direct(const tVecPt & aVIn) const + cMappingIdentity::Values(tVecPt & aVRes,const tVecPt & aVIn) const { - tVecPt & aBufOut = this->BufOut(); - aBufOut = aVIn; - return aBufOut; + // tVecPt & aBufOut = this->BufOut(); + // aBufOut = aVIn; + aVRes = aVIn; + return aVRes; } template typename cMappingIdentity::tPt - cMappingIdentity::Direct(const tPt & aPt) const + cMappingIdentity::Value(const tPt & aPt) const { return aPt; } @@ -351,24 +227,29 @@ template /* ============================================= */ /* ============================================= */ -/* -template class cDataInvertibleMapping; -template class cMappingIdentity; -template class cMappingIdentity; -*/ -template class cDataMapping; -template class cDataMapping; -template class cDataMapping; -template class cDataMapping; +#define INSTANCE_TWO_DIM_MAPPING(DIM1,DIM2)\ +template class cDataMapping;\ +template class cMapping; #define INSTANCE_ONE_DIM_MAPPING(DIM)\ template class cMappingIdentity;\ -template class cDataInvertibleMapping;\ -template class cInvertDIMByIter;\ +INSTANCE_TWO_DIM_MAPPING(DIM,2);\ +INSTANCE_TWO_DIM_MAPPING(DIM,3); + INSTANCE_ONE_DIM_MAPPING(2) INSTANCE_ONE_DIM_MAPPING(3) + +/* ============================================= */ +/* ============================================= */ +/* ==== === */ +/* ==== CHECK/BENCH === */ +/* ==== === */ +/* ============================================= */ +/* ============================================= */ + + class cTestMapp { public : @@ -395,7 +276,7 @@ class cTestMapp class cTestMap1 : public cDataMapping { public : - cPt3dLR Direct(const cPt2dLR & aP) const override {return cTestMapp::Image(aP);} + cPt3dLR Value(const cPt2dLR & aP) const override {return cTestMapp::Image(aP);} cTestMap1() : cDataMapping(cPt2dLR(1e-3,1e-3)) { @@ -405,9 +286,13 @@ class cTestMap1 : public cDataMapping class cTestMap2 : public cDataMapping { public : - const std::vector & Direct(const std::vector & aVIn) const override + const std::vector & Values + ( + std::vector & aBufOut, + const std::vector & aVIn + ) const override { - std::vector & aBufOut = BufOutCleared(); + // std::vector & aBufOut = *aRes; for (const auto & aP : aVIn) aBufOut.push_back(cTestMapp::Image(aP)); return aBufOut; @@ -438,7 +323,7 @@ template void OneBenchMapping(cParamExeBench & aParam) TypeMap aMap; cDataMapping * aPM = &aMap; // compute vector of input - const auto & aVO2 = aPM->Direct(aVIn); + const auto & aVO2 = aPM->Values(aVIn); MMVII_INTERNAL_ASSERT_bench(aVOut.size()==aSzV,"Sz in BenchMapping"); MMVII_INTERNAL_ASSERT_bench(aVO2.size() ==aSzV,"Sz in BenchMapping"); @@ -446,25 +331,151 @@ template void OneBenchMapping(cParamExeBench & aParam) for (tU_INT4 aKP=0 ; aKPDirect(aVIn[aKP]) )<1e-5,"Buf/UnBuf in mapping"); + MMVII_INTERNAL_ASSERT_bench(Norm2(aVOut[aKP] - aPM->Value(aVIn[aKP]) )<1e-5,"Buf/UnBuf in mapping"); } // check jacobian auto [aVO3,aVG3] = aPM->Jacobian(aVIn); for (tU_INT4 aKP=0 ; aKPat(aKP)<< aVDif[aKP].DIm().L2Dist((*aVG3)[aKP].DIm())<< "\n"; MMVII_INTERNAL_ASSERT_bench(Norm2(aVOut[aKP]-(*aVO3)[aKP])<1e-5,"Val in Grad in mapping"); MMVII_INTERNAL_ASSERT_bench(aVDif[aKP].L2Dist(aVG3->at(aKP))<1e-3,"Jacobian in mapping"); - // std::cout << aVDif[aKP].L2Dist(aVG3->at(aKP)) << "\n"; } } } +#if (0) + +class cTestMapInv : public cDataIterInvertMapping +{ + public : +/* Initialisation a bit tricky, because class is its own rough invers and we must + must avoid infinite recursion, TO CHANGE LATER with a two step init ... +*/ + cTestMapInv(double aFx,double aFy,double aFz,double aFreqCos,double aMulCos,bool ForRoughInv=false) : + cDataIterInvertMapping + ( + cPt3dr::PCste(1e-3/std::max(1e-5,mFreqCos)), + cMapping(ForRoughInv?nullptr:new cTestMapInv(1.0/aFy,1.0/aFx,1.0/aFz,1.0,0.0,true)), + 1e-4, + 20 + ), + mFx (aFx), + mFy (aFy), + mFz (aFz), + mFreqCos (aFreqCos), + mMulCos (aMulCos) + { + } + + cPt3dr Value(const cPt3dr & aP) const override + { + return cPt3dr + ( + mFx * aP.y() + cos((aP.x()+aP.y())*mFreqCos)*mMulCos, + mFy * aP.x() + sin((aP.y()-aP.z())*mFreqCos)*mMulCos, + mFz * aP.z() + sin((1.0+aP.x()-aP.y()+aP.z())*mFreqCos)*mMulCos + ); + } + double mFx; + double mFy; + double mFz; + double mFreqCos; + double mMulCos; +}; + + +void BenchInvertMapping(cParamExeBench & aParam) +{ + // Check in pure linear case, the inverse is exact + { + cTestMapInv aM1(0.3,4.1,2.2,1000.0,0.0); + const cDataMapping & aM2 = *(aM1.RoughInv()); + for (int aK=0; aK<1000 ; aK++) + { + cPt3dr aP1 = cPt3dr::PRandC()*100.0; + cPt3dr aP12 = aM1.Value(aM2.Value(aP1)); + cPt3dr aP21 = aM2.Value(aM1.Value(aP1)); + MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP12)<1e-5,"cTestMapInv rough inverse"); + MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP21)<1e-5,"cTestMapInv rough inverse"); + } + } + + for (int aKMap=0 ; aKMap<100 ; aKMap++) + { + double aFX = RandUnif_C_NotNull(1e-1) * 3.0; + double aFY = RandUnif_C_NotNull(1e-1) * 3.0; + double aFZ = RandUnif_C_NotNull(1e-1) * 3.0; + double aFreq = RandUnif_C_NotNull((1e-1) * 3.0); + double aFMin =std::min(std::abs(aFX),std::min(std::abs(aFY),std::abs(aFZ))); + double aMulCos = (aFMin / aFreq) * 0.2 * RandUnif_0_1(); + + cTestMapInv aM1(aFX,aFY,aFZ,aFreq,aMulCos); +/* + cMapping aMInv(new cTestMapInv(aM1.RoughInverse())); + double aEpsInv = 1e-4; + aM1.SetRoughInv(aMInv,aEpsInv,20); +*/ + cDataInvertibleMapping * aPM1 = & aM1; + + + tREAL8 aEpsInv = aM1.DTolInv(); + for (int aKP=0 ; aKP<100 ; aKP++) + { + cPt3dr aPt = cPt3dr::PRandC()*100.0; + cPt3dr aPtD = aM1.Value(aPt); + cPt3dr aPtDI = aM1.Inverse(aPtD); + + cPt3dr aPtI = aM1.Inverse(aPt); + cPt3dr aPtID = aM1.Value(aPtI); + + MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtDI)<10*aEpsInv,"elem inverse"); + MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtID)<10*aEpsInv,"elem inverse"); + } + + for (int aKV=0 ; aKV<10 ; aKV++) + { + int aNb = RandUnif_N(100); + std::vector aVIn; + for (int aKP=0 ; aKP aVOut = aPM1->Values(aVIn); + std::vector aVInv = aPM1->Inverses(aVOut); + for (int aKP=0 ; aKP +{ + public : +}; + +void BenchInvertMapping(cParamExeBench & aParam); +void BenchSymDerMap(cParamExeBench & aParam); + void BenchMapping(cParamExeBench & aParam) { if (! aParam.NewBench("GenMapping")) return; + + if (aParam.GenerateBug("MapRecursion")) + { + cBugRecMap aMap; + aMap.Value(cPt2dr(2,2)); + } + + BenchInvertMapping(aParam); + BenchSymDerMap(aParam); + OneBenchMapping(aParam); OneBenchMapping(aParam); aParam.EndBench(); diff --git a/MMVII/src/Mappings/MappingInverse.cpp b/MMVII/src/Mappings/MappingInverse.cpp new file mode 100644 index 0000000000..d3501e7749 --- /dev/null +++ b/MMVII/src/Mappings/MappingInverse.cpp @@ -0,0 +1,511 @@ +#include "include/MMVII_all.h" + +namespace MMVII +{ + +/* ============================================= */ +/* cDataInvertibleMapping */ +/* ============================================= */ + +// const tVecPt & Inverses(tVecPt &,const tVecPt & ) const; + +template + cDataInvertibleMapping::cDataInvertibleMapping(const tPt& aEps) : + cDataMapping (aEps) +{ +} + +template + cDataInvertibleMapping::cDataInvertibleMapping() : + cDataMapping (tPt::PCste(0.0)) +{ +} + +template + const typename cDataInvertibleMapping::tVecPt & + cDataInvertibleMapping::Inverses(tVecPt & aBufOut,const tVecPt & aVIn) const +{ +/**/MACRO_CHECK_RECURS_BEGIN; + for (const auto & aP : aVIn) + aBufOut.push_back(Inverse(aP)); +/**/MACRO_CHECK_RECURS_END; + return aBufOut; +} + +template + const typename cDataInvertibleMapping::tVecPt & + cDataInvertibleMapping::Inverses(const tVecPt & aVImages) const +{ + return Inverses(BufInvOutCleared(),aVImages); +} + + +template + typename cDataInvertibleMapping::tPt + cDataInvertibleMapping::Inverse(const tPt & aPImage) const +{ + this->BufIn1Val()[0] = aPImage; + const tVecPt & aRes = Inverses(this->BufIn1Val()); + return aRes[0]; +} + +/* ============================================= */ +/* cInvertByIter */ +/* - cStrPtInvDIM */ +/* ============================================= */ + +template struct cStrPtInvDIM +{ + public : + typedef cPtxd tPt; + Type Score(const tPt & aP) {return Norm2(mPTarget-aP);} + void UpdateNew(const Type & anErr,const tPt & aInv,const tPt & aVal) + { + if (anErr mBestInv; + cPtxd mBestVal; + + // For dicotomy approach, inverse & val at extremities + cPtxd mInvDic0; + cPtxd mValDic0; + cPtxd mInvDic1; + cPtxd mValDic1; + + cPtxd mPTarget; +}; + +template class cInvertDIMByIter +{ + public : + typedef cDataIterInvertMapping tDIM; + typedef cStrPtInvDIM tSPIDIM; + typedef typename tDIM::tPt tPt; + typedef typename tDIM::tVecPt tVecPt; + // typedef typename tDIM::tResVecJac tResVecJac; + typedef typename tDIM::tCsteResVecJac tCsteResVecJac; + + + cInvertDIMByIter(const tDIM & aDIM); + void Init(const tVecPt & aVTarget); + void OneIterInversion(); + const tU_INT4 Remaining() const {return mVSubSet.size();} + + void PushResult(tVecPt &) const; + + private : + void OneIterDicot(); + bool Converged(const tSPIDIM & aSInv) const {return aSInv.mBestErr mVInv; + std::vector mVSubSet; // Subset of index still to compute + std::vector mVSubDicot; // Subset of point that dont improve (enough) with jacobian + tSPIDIM & InvOfKSubS(tU_INT4 aInd) {return mVInv.at(mVSubSet.at(aInd));} +}; + +template + void cInvertDIMByIter::OneIterDicot() +{ + // Push in aVSampleInv the indermediar values (interpol inverse) between mInvDic0 and mInvDic1 + tVecPt & aVSampleInv = mDIM.BufInCleared(); + int aNbInterm = 3; + for (tU_INT4 aKInd = 0 ; aKInd aVInv; + std::vector aVVal; + + aVInv.push_back(aSInv.mInvDic0); // Correponds to pds 0 + aVVal.push_back(aSInv.mValDic0); + for (int aKPds=1 ; aKPds<= aNbInterm ; aKPds++) + { + aVVal.push_back(aVSampleInv.at(aIndEchInv)); + aVInv.push_back(aVSampleVal.at(aIndEchInv)); + aIndEchInv++; + } + aVInv.push_back(aSInv.mInvDic1); // Correpond to pds 1 + aVVal.push_back(aSInv.mValDic1); + + + cWhitchMin aWM(-1,1e30); + for (tU_INT4 aKEch=0 ; aKEch + void cInvertDIMByIter::OneIterInversion() +{ + // Put in aVCurInv the curent estimation of inverses + tVecPt & aVCurInv = mDIM.BufInCleared(); + for (tU_INT4 aKInd=0 ; aKIndat(aKInd); + aSInv.mBestErr = aSInv.Score(aSInv.mBestVal); + aSInv.mThreshNextEr = aSInv.mBestErr / 2.0; + if (Converged(aSInv)) + { + // Nothing to do , mBestInv is a good inverse + } + else + { + tPt aEr = aSInv.mPTarget-aSInv.mBestVal; + // Use Jacobian to compute the correction giving the error + tPt aCor = SolveCol(aVJ.second->at(aKInd),aEr); + + // aCor = SolveLine(aEr,aVJ.second->at(aKInd)); it was to check that it does not work + + tPt aNewInv = aSInv.mBestInv+ aCor; // Restimate inverse with correction + aVCurInv.at(aNewInd) = aNewInv; // Put new inverse in vect to evaluate + mVSubSet.at(aNewInd) = aSInv.mNum; //this one is in the new subset + aNewInd++; + } + } + // We have filled only partially the new indexes + mVSubSet.resize(aNewInd); + aVCurInv.resize(aNewInd); + + const tVecPt & aVO = mDIM.Values(aVCurInv); + + aNewInd=0; + mVSubDicot.clear(); + for (tU_INT4 aKInd=0 ; aKInd + void cInvertDIMByIter::PushResult(tVecPt & aVecPt) const +{ + for (const auto & aSInv : mVInv) + aVecPt.push_back(aSInv.mBestInv); +} + +template + cInvertDIMByIter::cInvertDIMByIter(const tDIM & aDIM): + mDIM (aDIM) +{ +} + + +template + void cInvertDIMByIter::Init(const tVecPt & aVTarget) +{ + mVSubSet.clear(); + mVInv.clear(); + const tVecPt & aVInit = mDIM.RoughInv()->Values(aVTarget); + for (tU_INT4 aKPt=0; aKPt */ +/* ============================================= */ + +template + cDataIterInvertMapping::cDataIterInvertMapping + (const tPt& aEps,tMap aRoughInv,const Type& aDistTol,int aNbIterMaxInv) : + cDataInvertibleMapping (aEps), + mStrInvertIter (nullptr), + mRoughInv (aRoughInv), + mDTolInv (aDistTol), + mNbIterMaxInv (aNbIterMaxInv) +{ +} + +template + cDataIterInvertMapping::cDataIterInvertMapping(tMap aRoughInv,const Type& aDistTol,int aNbIterMaxInv) : + cDataIterInvertMapping(tPt::PCste(0.0),aRoughInv,aDistTol,aNbIterMaxInv) +{ +} + +template + typename cDataIterInvertMapping::tHelperInvertIter * + cDataIterInvertMapping::StrInvertIter() const +{ + if (mStrInvertIter.get()==nullptr) + { + // mStrInvertIter = std::shared_ptr(new tHelperInvertIter(*this)); + mStrInvertIter.reset(new tHelperInvertIter(*this)); + } + return mStrInvertIter.get(); +} + +template + const typename cDataIterInvertMapping::tDataMap * + // std::unique_ptr::tDataMap> + cDataIterInvertMapping::RoughInv() const +{ + return mRoughInv.DM(); +} + +template + const Type & cDataIterInvertMapping::DTolInv() const +{ + return mDTolInv; +} + + +template + const typename cDataIterInvertMapping::tVecPt & + cDataIterInvertMapping::Inverses(tVecPt& aVRes,const tVecPt & aVTarget) const +{ + + // Default method, use iterative approach + MMVII_INTERNAL_ASSERT_strong(RoughInv() != nullptr,"No rough inverse"); + + tHelperInvertIter * aSInvIter = StrInvertIter(); + aSInvIter->Init(aVTarget); + + for (int aKIter=0 ; (aKIterRemaining()!=0); aKIter++) + { + aSInvIter->OneIterInversion(); + } + + // tVecPt & aVRes = this->BufOutCleared(); + aVRes.clear(); + aSInvIter->PushResult(aVRes); + + return aVRes; +} + + + +#define INSTANCE_INVERT_MAPPING(DIM)\ +template class cDataInvertibleMapping;\ +template class cDataIterInvertMapping;\ +template class cInvertDIMByIter; + +INSTANCE_INVERT_MAPPING(2) +INSTANCE_INVERT_MAPPING(3) + + +/* ============================================= */ +/* ============================================= */ +/* ==== === */ +/* ==== CHECK/BENCH === */ +/* ==== === */ +/* ============================================= */ +/* ============================================= */ + + +class cTestMapInv : public cDataIterInvertMapping +{ + public : +/* Initialisation a bit tricky, because class is its own rough invers and we must + must avoid infinite recursion, TO CHANGE LATER with a two step init ... +*/ + cTestMapInv(double aFx,double aFy,double aFz,double aFreqCos,double aMulCos,bool ForRoughInv=false) : + cDataIterInvertMapping + ( + cPt3dr::PCste(1e-3/std::max(1e-5,mFreqCos)), + cMapping(ForRoughInv?nullptr:new cTestMapInv(1.0/aFy,1.0/aFx,1.0/aFz,1.0,0.0,true)), + 1e-4, + 20 + ), + mFx (aFx), + mFy (aFy), + mFz (aFz), + mFreqCos (aFreqCos), + mMulCos (aMulCos) + { + } + + cPt3dr Value(const cPt3dr & aP) const override + { + return cPt3dr + ( + mFx * aP.y() + cos((aP.x()+aP.y())*mFreqCos)*mMulCos, + mFy * aP.x() + sin((aP.y()-aP.z())*mFreqCos)*mMulCos, + mFz * aP.z() + sin((1.0+aP.x()-aP.y()+aP.z())*mFreqCos)*mMulCos + ); + } + double mFx; + double mFy; + double mFz; + double mFreqCos; + double mMulCos; +}; + + +void BenchInvertMapping(cParamExeBench & aParam) +{ + // Check in pure linear case, the inverse is exact + { + cTestMapInv aM1(0.3,4.1,2.2,1000.0,0.0); + const cDataMapping & aM2 = *(aM1.RoughInv()); + for (int aK=0; aK<1000 ; aK++) + { + cPt3dr aP1 = cPt3dr::PRandC()*100.0; + cPt3dr aP12 = aM1.Value(aM2.Value(aP1)); + cPt3dr aP21 = aM2.Value(aM1.Value(aP1)); + MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP12)<1e-5,"cTestMapInv rough inverse"); + MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP21)<1e-5,"cTestMapInv rough inverse"); + } + } + + for (int aKMap=0 ; aKMap<100 ; aKMap++) + { + double aFX = RandUnif_C_NotNull(1e-1) * 3.0; + double aFY = RandUnif_C_NotNull(1e-1) * 3.0; + double aFZ = RandUnif_C_NotNull(1e-1) * 3.0; + double aFreq = RandUnif_C_NotNull((1e-1) * 3.0); + double aFMin =std::min(std::abs(aFX),std::min(std::abs(aFY),std::abs(aFZ))); + double aMulCos = (aFMin / aFreq) * 0.2 * RandUnif_0_1(); + + cTestMapInv aM1(aFX,aFY,aFZ,aFreq,aMulCos); +/* + cMapping aMInv(new cTestMapInv(aM1.RoughInverse())); + double aEpsInv = 1e-4; + aM1.SetRoughInv(aMInv,aEpsInv,20); +*/ + cDataInvertibleMapping * aPM1 = & aM1; + + + tREAL8 aEpsInv = aM1.DTolInv(); + for (int aKP=0 ; aKP<100 ; aKP++) + { + cPt3dr aPt = cPt3dr::PRandC()*100.0; + cPt3dr aPtD = aM1.Value(aPt); + cPt3dr aPtDI = aM1.Inverse(aPtD); + + cPt3dr aPtI = aM1.Inverse(aPt); + cPt3dr aPtID = aM1.Value(aPtI); + + MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtDI)<10*aEpsInv,"elem inverse"); + MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtID)<10*aEpsInv,"elem inverse"); + } + + for (int aKV=0 ; aKV<10 ; aKV++) + { + int aNb = RandUnif_N(100); + std::vector aVIn; + for (int aKP=0 ; aKP aVOut = aPM1->Values(aVIn); + std::vector aVInv = aPM1->Inverses(aVOut); + for (int aKP=0 ; aKP * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf) -{ - return cName2Calc::CalcFromName(NameEqDist(aDeg,WithDerive),aSzBuf); -} /* template class cFormulaMapping : public cMapping @@ -223,8 +219,14 @@ tMMVII_UnikPApli Alloc_GenCode(const std::vector & aVArgs,const cS } } // NS_GenerateCode + +using namespace NS_GenerateCode; namespace MMVII { +cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf) +{ + return cName2Calc::CalcFromName(NameEqDist(aDeg,WithDerive),aSzBuf); +} cSpecMMVII_Appli TheSpecGenSymbDer diff --git a/MMVII/src/Utils/uti_times.cpp b/MMVII/src/Utils/uti_times.cpp index 4d77570744..4585594ec1 100644 --- a/MMVII/src/Utils/uti_times.cpp +++ b/MMVII/src/Utils/uti_times.cpp @@ -117,10 +117,90 @@ void Bench_Duration_Daisy(double aT,const std::string & aStr) } } + +class cBenchTimeCopyVect +{ + public : + cBenchTimeCopyVect(int aNbVect,int aSzVect) : + mNbV (aNbVect), + mSzV (aSzVect), + mVV ( aNbVect,std::vector(aSzVect,0.0)), + mV ( aSzVect,1.0) + { + } + void CPByEl() + { + for (size_t aKV=0 ; aKV< mNbV ; aKV++) + { + for (size_t aKEl=0 ; aKEl> mVV; + std::vector mV; +}; + +void OneBenchTimeVect(int aNbVect,int aSzVect) +{ + int aNbOp = 1e8; + int aNbTimes = aNbOp /(aNbVect*aSzVect); + + cBenchTimeCopyVect aBench(aNbVect,aSzVect); + + double aT0 = cMMVII_Appli::CurrentAppli().SecFromT0(); + for (int aK=0 ;aK Date: Mon, 3 May 2021 11:34:21 +0200 Subject: [PATCH 02/25] Mapping / DerSymb en cour --- MMVII/include/MMVII_Mappings.h | 24 ++ MMVII/include/MMVII_PhgrDist.h | 52 +++++ MMVII/include/MMVII_Ptxd.h | 3 + MMVII/include/MMVII_all.h | 8 +- MMVII/include/SymbDer/SymbDer_Common.h | 129 +++++++++-- MMVII/include/SymbDer/SymbolicDerivatives.h | 62 ++--- MMVII/src/Bench/BenchGlob.cpp | 27 +-- ...CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp | 211 +++++++++--------- .../CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.h | 35 +-- .../CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp | 91 ++++---- .../CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.h | 35 +-- MMVII/src/ImagesBase/PtsBox.cpp | 11 + .../src/ImagesInfoExtract/ExtracExtremum.cpp | 1 - MMVII/src/Mappings/MappingGen.cpp | 108 --------- MMVII/src/Mappings/MappingInverse.cpp | 57 ++++- MMVII/src/SymbDerGen/Formulas_CamStenope.h | 91 ++++---- MMVII/src/SymbDerGen/GenerateCodes.cpp | 90 +++++--- MMVII/src/UtiMaths/uti_fonc_analytique.cpp | 2 - MMVII/src/UtiMaths/uti_nums.cpp | 3 - MMVII/src/UtiMaths/uti_rand.cpp | 1 - 20 files changed, 568 insertions(+), 473 deletions(-) create mode 100644 MMVII/include/MMVII_PhgrDist.h diff --git a/MMVII/include/MMVII_Mappings.h b/MMVII/include/MMVII_Mappings.h index 68366d9ee5..60d7a814b1 100644 --- a/MMVII/include/MMVII_Mappings.h +++ b/MMVII/include/MMVII_Mappings.h @@ -333,6 +333,30 @@ template class cDataIterInvertMapping : public cData int mNbIterMaxInv; }; +/** When we have an existing mapping, we want to invert it by iteration, we cannot inherit +if we cannot modify, so we make it member . The methods just call method of mMap... +*/ + +template class cDataIIMFromMap : public cDataIterInvertMapping +{ + public : + typedef cDataIterInvertMapping tDataIIMap; + typedef cMapping tMap; + + using typename tDataIIMap::tPt; + using typename tDataIIMap::tVecPt; + using typename tDataIIMap::tCsteResVecJac; + using typename tDataIIMap::tResVecJac; + + cDataIIMFromMap(tMap aMap,const tPt &,tMap aRoughInv,const Type& aDistTol,int aNbIterMax); + cDataIIMFromMap(tMap aMap,tMap aRoughInv,const Type& aDistTol,int aNbIterMax); + + const tVecPt & Values(tVecPt &,const tVecPt & ) const override; //V2 + tCsteResVecJac Jacobian(tResVecJac,const tVecPt &) const override; //J2 + private : + tMap mMap; +}; + /** Represntation of identity as a mapping */ template class cMappingIdentity : public cDataMapping diff --git a/MMVII/include/MMVII_PhgrDist.h b/MMVII/include/MMVII_PhgrDist.h new file mode 100644 index 0000000000..a321b8e4aa --- /dev/null +++ b/MMVII/include/MMVII_PhgrDist.h @@ -0,0 +1,52 @@ +#ifndef _MMVII_PHGR_DIST_H_ +#define _MMVII_PHGR_DIST_H_ + + +namespace MMVII +{ +/** Indicate the nature of each coefficient of the distorsion +*/ +enum class eTypeFuncDist + { + eRad, ///< Coefficient for radial distorsion + eDecX, ///< Coefficient for decentric distorsion x mean derived by Cx (it has X and Y components) + eDecY, ///< Coefficient for decentric distorsion y mean derived by Cy (it has X and Y components) + eMonX, ///< Coefficient for a monom in X, of the polynomial distorsion + eMonY, ///< Coefficient for a monom in Y, of the polynomial distorsion + eNbVals ///< Tag for number of value + }; + +/** This class store a complete description of each parameters of the distorsion, + it is used for computing the formula, the vector of name and (later) automatize + conversion, print understandable values .... + + It's rather bad design with the same classe coding different things, and some fields + used of not according to the others, but as it internal/final classes, quick and dirty + exceptionnaly allowed ... +*/ +class cDescOneFuncDist +{ + public : + cDescOneFuncDist(eTypeFuncDist aType,const cPt2di aDeg); + /// Majorarion of norms of jacobian , used in simulation + double MajNormJacOfRho(double aRho) const; + + eTypeFuncDist mType; ///< Type of dist (Rad, DecX ....) + std::string mName; ///< Name : used as id for code gen & prety print + cPt2di mDegMon; ///< Degree for a polynomial + int mNum; ///< Order for radial and decentric + int mDegTot; ///< Total degree of the polynome +}; + + + + +// used for bench now To put elsewhere later, +NS_SymbolicDerivative::cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf); + +const std::vector & DescDist(const cPt3di & aDeg); + + +}; + +#endif // _MMVII_PHGR_DIST_H_ diff --git a/MMVII/include/MMVII_Ptxd.h b/MMVII/include/MMVII_Ptxd.h index b2854e9770..6b3540ee3d 100644 --- a/MMVII/include/MMVII_Ptxd.h +++ b/MMVII/include/MMVII_Ptxd.h @@ -66,6 +66,9 @@ template class cPtxd static cPtxd PRandC(); /// Initialisation random VUnit static cPtxd PRandUnit(); + /// Pt random in sphere + static cPtxd PRandInSphere(); + /// Initialisation random VUnit not too close to P1 static cPtxd PRandUnitDiff(const cPtxd&,const Type &aDist = 1e-2); diff --git a/MMVII/include/MMVII_all.h b/MMVII/include/MMVII_all.h index 1608cfd4c4..12c47c182f 100644 --- a/MMVII/include/MMVII_all.h +++ b/MMVII/include/MMVII_all.h @@ -11,6 +11,7 @@ #include "memory.h" #include #include +#include #include #include #include @@ -77,12 +78,7 @@ #include "SymbDer/SymbDer_Common.h" #include "../kapture/kapture.h" - -namespace MMVII -{ -// used for bench now To put elsewhere later, -NS_SymbolicDerivative::cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf); -}; +#include "MMVII_PhgrDist.h" #endif // _MMVII_ALL_H_ diff --git a/MMVII/include/SymbDer/SymbDer_Common.h b/MMVII/include/SymbDer/SymbDer_Common.h index 142549f7a5..20304dad18 100644 --- a/MMVII/include/SymbDer/SymbDer_Common.h +++ b/MMVII/include/SymbDer/SymbDer_Common.h @@ -53,6 +53,34 @@ static inline void AssertAlmostEqual(const double & aV1,const double & aV2,const InternalError("Test equality failed",""); } +class cConvStrRange +{ + public : + cConvStrRange(const std::vector & aVName) : + mRange2Name (aVName) + { + for (size_t aRange=0 ; aRangesecond; + } + const std::string & NameOfRange(int aRange) const + { + return mRange2Name.at(aRange); + } + const std::vector & Names() const {return mRange2Name;} + private : + std::vector mRange2Name; + std::map mName2Range; +}; template class cCalculator @@ -101,19 +129,37 @@ class cCalculator const size_t NbElem() const { return mNbElem; } // Nb of primary values returned by formula (w/o counting derivatives) const std::vector & Result() const { return mBufRes; } + int RangeOfUk(const std::string & aName,bool SVP=false) const + {return mConvNamesUk.RangeOfName(aName,SVP);} + const std::vector & NamesUk() const {return mConvNamesUk.Names();} + + + int RangeOfObs(const std::string & aName,bool SVP=false) const + {return mConvNamesObs.RangeOfName(aName,SVP);} + const std::vector & NamesObs() const {return mConvNamesObs.Names();} protected: - cCalculator(const std::string& aName, int aSzBuf, size_t aNbUk, size_t aNbObs, bool aWithDer=false, int aSzInterval=1) : - mName (aName), - mSzBuf (aSzBuf), - mNbUK (aNbUk), - mNbObs (aNbObs), - mNbElem (0), - mNbInBuf (0), - mWithDer (aWithDer), - mSzInterval (aSzInterval), - mBufLineRes (mSzBuf), - mBufRes () + cCalculator + ( + const std::string& aName, + int aSzBuf, + const std::vector & aVNUk, // Variable, fix Dim In + const std::vector & aVNObs, + bool aWithDer=false, + int aSzInterval=1 + ) : + mName (aName), + mSzBuf (aSzBuf), + mNbUK (aVNUk.size()), + mConvNamesUk (aVNUk), + mNbObs (aVNObs.size()), + mConvNamesObs (aVNObs), + mNbElem (0), + mNbInBuf (0), + mWithDer (aWithDer), + mSzInterval (aSzInterval), + mBufLineRes (mSzBuf), + mBufRes () { mBufRes.reserve(mSzBuf); } @@ -125,17 +171,20 @@ class cCalculator // Do actual caluculus. Just store resulst in mBurLineRes. This class manages mBufRes virtual void DoEval() = 0; - std::string mName; size_t mSzBuf; ///< Capacity of bufferirsation - size_t mNbUK; ///< Dim=number of unkown + size_t mNbUK; ///< DimIn=number of unkown + cConvStrRange mConvNamesUk; ///< Names of unknonw, used as a helper size_t mNbObs; ///< Number of obserbation variable - size_t mNbElem; ///< Number of elements returned by the formula (w/o derivative) + cConvStrRange mConvNamesObs; ///< Names of observation, used as a helper + size_t mNbElem; ///< DimOut=Number of elements returned by the formula (w/o derivative) size_t mNbInBuf; ///< Number of Unknown/Obs vect currenlty loaded in buf bool mWithDer; ///< Done With Derivate int mSzInterval; ///< Size between two val, depends if computation done with deriv - std::vector mBufLineRes; ///< Reserve memory for each line - std::vector mBufRes; ///< Reserve memory for result itself + std::vector mBufLineRes; ///< Reserve memory for each line, make the allocation at init + std::vector mBufRes; ///< Reserve memory for result itself, point on mBufLineRes to limit allocation + + }; template @@ -171,10 +220,56 @@ const std::vector *> & cCalculator::EvalAndClear() return mBufRes; } +/** Specilisation for calculator opering generated code (v.s dynamic just after formula) +*/ +template class cCompiledCalculator : public cCalculator +{ + public : + + cCompiledCalculator + ( + const std::string& aName, + size_t aSzBuf, + size_t aNbElem, // Dim out + size_t aSzLine, // should be aNbElem * aSzInterval + const std::vector & aVNUk, // Variable, fix Dim In + const std::vector & aVNObs, + bool aWithDer, + size_t aSzInterval + ) : + cCalculator (aName,aSzBuf,aVNUk,aVNObs,aWithDer,aSzInterval) , + mVUk (aSzBuf), + mVObs (aSzBuf) + { + this->mNbElem = aNbElem; + for (auto& line : this->mBufLineRes) + line.resize(aSzLine); + for (auto& aUk : this->mVUk) + aUk.resize(this->NbUk()); + for (auto& aObs : this->mVObs) + aObs.resize(this->NbObs()); + + } + protected : + virtual void SetNewUks(const std::vector & aVUks) override + { + for (size_t i=0; iNbUk(); i++) + this->mVUk[this->mNbInBuf][i] = aVUks[i]; + } + virtual void SetNewObs(const std::vector & aVObs) override + { + for (size_t i=0; iNbObs(); i++) + this->mVObs[this->mNbInBuf][i] = aVObs[i]; + } + std::vector> mVUk; + std::vector> mVObs; +}; + + template class cName2Calc { public : - typedef cCalculator tCalc; + typedef cCompiledCalculator tCalc; typedef tCalc * (* tAllocator) (int aSzBuf); /// That's what we want : alloc an object from its name diff --git a/MMVII/include/SymbDer/SymbolicDerivatives.h b/MMVII/include/SymbDer/SymbolicDerivatives.h index 92a0714ca8..94a37d78bf 100644 --- a/MMVII/include/SymbDer/SymbolicDerivatives.h +++ b/MMVII/include/SymbDer/SymbolicDerivatives.h @@ -7,7 +7,7 @@ using namespace std; #endif -#define WITH_MMVII false +#define WITH_MMVII true #define WITH_EIGEN false @@ -206,6 +206,8 @@ template class cFormula ; /** Class for managing the "context", i.e. coordinating all the formula and their derivative corresponding to a single use . + + A coordinator is also a calculator, as it make computation on formulas */ template class cCoordinatorF; @@ -867,7 +869,7 @@ cCoordinatorF::cCoordinatorF const std::vector & aVNameUK, const std::vector & aVNameObs ) : - cCalculator(aName,aSzBuf,aVNameUK.size(),aVNameObs.size()), + cCalculator(aName,aSzBuf,aVNameUK,aVNameObs), mNbCste (0), mCste0 (CsteOfVal(0.0)), mCste1 (CsteOfVal(1.0)), @@ -1084,6 +1086,19 @@ void cCoordinatorF::ShowStackFunc() const std::cout << "\n"; } +// return +inline std::string VStr2CPP(const std::vector & aVS) +{ + std::string aRes = "{"; + for (size_t aK=0 ; aK std::string cCoordinatorF::GenCodeCommon(const std::string& aPrefix, std::string aTypeName, bool isShortExpr) const { @@ -1105,7 +1120,7 @@ std::string cCoordinatorF::GenCodeCommon(const std::string& aPrefix, s if (! isShortExpr) aClassName = aClassName + "LongExpr"; - std::string aParentClass = "cCalculator<" + aTypeName + ">"; + std::string aParentClass = "cCompiledCalculator<" + aTypeName + ">"; std::string aFileName = aPrefix + aClassName; std::ofstream aOs(mDirGenCode + aFileName + ".h"); @@ -1126,37 +1141,24 @@ std::string cCoordinatorF::GenCodeCommon(const std::string& aPrefix, s "{\n" "public:\n" " typedef " << aParentClass << " Super;\n" - " " << aClassName << "(size_t aSzBuf) : \n" - " Super(\"" << aName << "\", aSzBuf," - << this->mNbUK << "," - << this->mNbObs << "," - << this->mWithDer << "," - << this->mSzInterval << "),\n" - " mVUk(aSzBuf),mVObs(aSzBuf)\n" + " " << aClassName << "(size_t aSzBuf) : \n"; + aOs + << " Super(\n" + << " \"" << aName << "\",\n" + << " " << " aSzBuf,//SzBuf\n" + << " " << this->mNbElem << ",//NbElement\n" + << " " << mVCurF.size() << ",//SzOfLine\n" + << " " << VStr2CPP(this->NamesUk()) << ",// Name Unknowns\n" + << " " << VStr2CPP(this->NamesObs()) << ",// Name Observations\n" + << " " << this->mWithDer << ",//With derivative ?\n" + << " " << this->mSzInterval << "//Size of interv\n" + << " )\n"; + aOs<< " {\n" - " this->mNbElem = " << this->mNbElem << ";\n" - " for (auto& line : this->mBufLineRes)\n" - " line.resize(" << mVCurF.size() << ");\n" - " for (auto& aUk : this->mVUk)\n" - " aUk.resize(this->NbUk());\n" - " for (auto& aObs : this->mVObs)\n" - " aObs.resize(this->NbObs());\n" " }\n" " static std::string FormulaName() { return \"" << aName << "\";}\n" "protected:\n" - " virtual void SetNewUks(const " << aVectorName << " & aVUks) override\n" - " {\n" - " for (size_t i=0; iNbUk(); i++)\n" - " this->mVUk[this->mNbInBuf][i] = aVUks[i];\n" - " }\n" - " virtual void SetNewObs(const " << aVectorName << " & aVObs) override\n" - " {\n" - " for (size_t i=0; iNbObs(); i++)\n" - " this->mVObs[this->mNbInBuf][i] = aVObs[i];\n" - " }\n" " virtual void DoEval() override;\n" - " std::vector<" << aVectorName << "> mVUk;\n" - " std::vector<" << aVectorName << "> mVObs;\n" "};\n" "\n"; @@ -1208,7 +1210,7 @@ std::string cCoordinatorF::GenCodeCommon(const std::string& aPrefix, s if (mUseAllocByName) { - aOs << "cCalculator<" << aTypeName << "> * Alloc_" << aName << "(int aSzBuf)\n" + aOs << "cCompiledCalculator<" << aTypeName << "> * Alloc_" << aName << "(int aSzBuf)\n" << "{\n" << " return new c" << aName << "(aSzBuf);\n" << "}\n\n" diff --git a/MMVII/src/Bench/BenchGlob.cpp b/MMVII/src/Bench/BenchGlob.cpp index 0343cdd924..1ddece4b6a 100644 --- a/MMVII/src/Bench/BenchGlob.cpp +++ b/MMVII/src/Bench/BenchGlob.cpp @@ -156,21 +156,6 @@ void Bench_0000_SysDepString(cParamExeBench & aParam) #endif void TestDir(const std::string & aDir); -/* -{ - std::cout << "DDDD=[" << aDir << "]\n"; - const char * aC = aDir.c_str(); - int aL = strlen(aC); - - if ((aL>0) && (aC[aL-1] == path::preferred_separator)) aL--; - aL--; - - if (aL>0) - { - std::cout << "C=" << aC[aL] << "\n"; - } -} -*/ void Bench_0000_String(cParamExeBench & aParam) { @@ -879,7 +864,11 @@ void TestVectBool() StdOut() << "END TBYTE \n"; getchar(); } -bool F(const std::string & aMes) {std::cout <<"FFFFF=" << aMes << "\n"; return true;} +bool PrintAndTrue(const std::string & aMes) +{ + StdOut() <<"FFFFF=" << aMes << "\n"; + return true; +} #define UN 1 #define DEUX 2 @@ -925,11 +914,11 @@ int cAppli_MPDTest::Exe() printf("VVVVV=%05.2f\n",aV); } - if ((UN>DEUX) && F("aaaa")) + if ((UN>DEUX) && PrintAndTrue("aaaa")) { - F("bbbb"); + PrintAndTrue("bbbb"); } - F("ccccc"); + PrintAndTrue("ccccc"); cRotation3D::RandomRot(); diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp index 05291e6791..3665c5a3cd 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp @@ -11,120 +11,109 @@ void cEqDist_Dist_Rad3_Dec1_XY1VDer::DoEval() // Declare local vars in loop to make them per thread double &xPi = this->mVUk[aK][0]; double &yPi = this->mVUk[aK][1]; - double &PPx = this->mVObs[aK][0]; - double &PPy = this->mVObs[aK][1]; - double &PPz = this->mVObs[aK][2]; - double &K1 = this->mVObs[aK][3]; - double &K2 = this->mVObs[aK][4]; - double &K3 = this->mVObs[aK][5]; - double &p1 = this->mVObs[aK][6]; - double &p2 = this->mVObs[aK][7]; - double &b2 = this->mVObs[aK][8]; - double &b1 = this->mVObs[aK][9]; - double F15 = (xPi * xPi); - double F38 = (b1 * xPi); - double F86 = (2 * xPi); - double F37 = (b2 * yPi); - double F74 = (yPi + yPi); - double F51 = (xPi + xPi); - double F17 = (xPi * yPi); - double F65 = (2 * yPi); - double F16 = (yPi * yPi); - double F67 = (F51 * 2); - double F105 = (F86 * p1); - double F55 = (F51 * K1); - double F102 = (F74 * 2); - double F95 = (F65 * p1); - double F78 = (F74 * K1); - double F66 = (F65 * p2); - double F88 = (F74 * p1); - double F87 = (F86 * p2); - double F33 = (F16 * 2); - double F94 = (F51 * p2); - double F29 = (F17 * 2); - double F39 = (F37 + F38); - double F18 = (F15 + F16); - double F26 = (F15 * 2); - double F21 = (F18 * K1); - double F34 = (F18 + F33); - double F31 = (F29 * p2); - double F30 = (F29 * p1); - double F89 = (F88 + F87); - double F19 = (F18 * F18); - double F75 = (F18 * F74); - double F103 = (F74 + F102); - double F68 = (F51 + F67); - double F27 = (F26 + F18); - double F96 = (F94 + F95); - double F52 = (F18 * F51); - double F81 = (F19 * F74); - double F35 = (F34 * p2); - double F28 = (F27 * p1); - double F53 = (F52 + F52); - double F20 = (F18 * F19); - double F76 = (F75 + F75); - double F104 = (F103 * p2); - double F58 = (F19 * F51); - double F69 = (F68 * p1); - double F22 = (F19 * K2); - double F70 = (F66 + F69); - double F57 = (F18 * F53); - double F32 = (F28 + F31); - double F24 = (F20 * K3); - double F54 = (F53 * K2); - double F77 = (F76 * K2); - double F80 = (F18 * F76); - double F106 = (F104 + F105); - double F23 = (F21 + F22); - double F36 = (F30 + F35); - double F59 = (F57 + F58); - double F25 = (F24 + F23); - double F82 = (F80 + F81); - double F79 = (F78 + F77); - double F56 = (F55 + F54); - double F44 = (F25 * yPi); - double F40 = (F25 * xPi); - double F60 = (F59 * K3); - double F83 = (F82 * K3); - double F45 = (F44 + yPi); - double F84 = (F79 + F83); - double F41 = (F40 + xPi); - double F61 = (F56 + F60); - double F46 = (F36 + F45); - double F62 = (F61 * xPi); - double F42 = (F32 + F41); - double F99 = (F84 * yPi); - double F93 = (F61 * yPi); - double F85 = (F84 * xPi); - double F97 = (F93 + F96); - double F49 = (F46 * PPz); - double F100 = (F25 + F99); - double F90 = (F85 + F89); - double F63 = (F25 + F62); - double F43 = (F42 + F39); - double F101 = (F100 + 1); - double F47 = (F43 * PPz); - double F98 = (F97 * PPz); - double F50 = (F49 + PPy); - double F91 = (F90 + b2); - double F64 = (F63 + 1); - double F92 = (F91 * PPz); - double F71 = (F64 + F70); - double F48 = (F47 + PPx); - double F107 = (F101 + F106); - double F72 = (F71 + b1); - double F108 = (F107 * PPz); - double F73 = (F72 * PPz); - this->mBufLineRes[aK][0] = F48; - this->mBufLineRes[aK][1] = F73; - this->mBufLineRes[aK][2] = F92; - this->mBufLineRes[aK][3] = F50; - this->mBufLineRes[aK][4] = F98; - this->mBufLineRes[aK][5] = F108; + double &K1 = this->mVObs[aK][0]; + double &K2 = this->mVObs[aK][1]; + double &K3 = this->mVObs[aK][2]; + double &p1 = this->mVObs[aK][3]; + double &p2 = this->mVObs[aK][4]; + double &b2 = this->mVObs[aK][5]; + double &b1 = this->mVObs[aK][6]; + double F66 = (yPi + yPi); + double F35 = (b1 * xPi); + double F34 = (b2 * yPi); + double F44 = (xPi + xPi); + double F58 = (2 * yPi); + double F78 = (2 * xPi); + double F14 = (xPi * yPi); + double F13 = (yPi * yPi); + double F12 = (xPi * xPi); + double F95 = (F78 * p1); + double F70 = (F66 * K1); + double F60 = (F44 * 2); + double F80 = (F66 * p1); + double F59 = (F58 * p2); + double F79 = (F78 * p2); + double F30 = (F13 * 2); + double F48 = (F44 * K1); + double F85 = (F44 * p2); + double F36 = (F34 + F35); + double F86 = (F58 * p1); + double F92 = (F66 * 2); + double F23 = (F12 * 2); + double F15 = (F12 + F13); + double F26 = (F14 * 2); + double F28 = (F26 * p2); + double F61 = (F44 + F60); + double F18 = (F15 * K1); + double F16 = (F15 * F15); + double F67 = (F15 * F66); + double F24 = (F23 + F15); + double F81 = (F80 + F79); + double F93 = (F66 + F92); + double F27 = (F26 * p1); + double F45 = (F15 * F44); + double F31 = (F15 + F30); + double F87 = (F85 + F86); + double F17 = (F15 * F16); + double F73 = (F16 * F66); + double F25 = (F24 * p1); + double F68 = (F67 + F67); + double F32 = (F31 * p2); + double F94 = (F93 * p2); + double F51 = (F16 * F44); + double F62 = (F61 * p1); + double F19 = (F16 * K2); + double F46 = (F45 + F45); + double F69 = (F68 * K2); + double F29 = (F25 + F28); + double F33 = (F27 + F32); + double F50 = (F15 * F46); + double F72 = (F15 * F68); + double F47 = (F46 * K2); + double F20 = (F18 + F19); + double F21 = (F17 * K3); + double F96 = (F95 + F94); + double F63 = (F59 + F62); + double F74 = (F72 + F73); + double F49 = (F48 + F47); + double F52 = (F50 + F51); + double F71 = (F70 + F69); + double F22 = (F21 + F20); + double F53 = (F52 * K3); + double F75 = (F74 * K3); + double F41 = (F22 * yPi); + double F37 = (F22 * xPi); + double F42 = (F41 + yPi); + double F38 = (F37 + xPi); + double F76 = (F71 + F75); + double F54 = (F49 + F53); + double F84 = (F54 * yPi); + double F89 = (F76 * yPi); + double F43 = (F33 + F42); + double F77 = (F76 * xPi); + double F55 = (F54 * xPi); + double F39 = (F29 + F38); + double F90 = (F22 + F89); + double F40 = (F39 + F36); + double F88 = (F84 + F87); + double F82 = (F77 + F81); + double F56 = (F22 + F55); + double F57 = (F56 + 1); + double F91 = (F90 + 1); + double F83 = (F82 + b2); + double F64 = (F57 + F63); + double F97 = (F91 + F96); + double F65 = (F64 + b1); + this->mBufLineRes[aK][0] = F40; + this->mBufLineRes[aK][1] = F65; + this->mBufLineRes[aK][2] = F83; + this->mBufLineRes[aK][3] = F43; + this->mBufLineRes[aK][4] = F88; + this->mBufLineRes[aK][5] = F97; } } -cCalculator * Alloc_EqDist_Dist_Rad3_Dec1_XY1VDer(int aSzBuf) +cCompiledCalculator * Alloc_EqDist_Dist_Rad3_Dec1_XY1VDer(int aSzBuf) { return new cEqDist_Dist_Rad3_Dec1_XY1VDer(aSzBuf); } diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.h b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.h index 77e9852fee..e71eeb6377 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.h +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.h @@ -5,37 +5,26 @@ namespace NS_SymbolicDerivative { -class cEqDist_Dist_Rad3_Dec1_XY1VDer : public cCalculator +class cEqDist_Dist_Rad3_Dec1_XY1VDer : public cCompiledCalculator { public: - typedef cCalculator Super; + typedef cCompiledCalculator Super; cEqDist_Dist_Rad3_Dec1_XY1VDer(size_t aSzBuf) : - Super("EqDist_Dist_Rad3_Dec1_XY1VDer", aSzBuf,2,10,1,3), - mVUk(aSzBuf),mVObs(aSzBuf) + Super( + "EqDist_Dist_Rad3_Dec1_XY1VDer", + aSzBuf,//SzBuf + 2,//NbElement + 6,//SzOfLine + {"xPi","yPi"},// Name Unknowns + {"K1","K2","K3","p1","p2","b2","b1"},// Name Observations + 1,//With derivative ? + 3//Size of interv + ) { - this->mNbElem = 2; - for (auto& line : this->mBufLineRes) - line.resize(6); - for (auto& aUk : this->mVUk) - aUk.resize(this->NbUk()); - for (auto& aObs : this->mVObs) - aObs.resize(this->NbObs()); } static std::string FormulaName() { return "EqDist_Dist_Rad3_Dec1_XY1VDer";} protected: - virtual void SetNewUks(const std::vector & aVUks) override - { - for (size_t i=0; iNbUk(); i++) - this->mVUk[this->mNbInBuf][i] = aVUks[i]; - } - virtual void SetNewObs(const std::vector & aVObs) override - { - for (size_t i=0; iNbObs(); i++) - this->mVObs[this->mNbInBuf][i] = aVObs[i]; - } virtual void DoEval() override; - std::vector> mVUk; - std::vector> mVObs; }; } // namespace NS_SymbolicDerivative diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp index bc228e8822..e57254ec7a 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp @@ -11,58 +11,51 @@ void cEqDist_Dist_Rad3_Dec1_XY1Val::DoEval() // Declare local vars in loop to make them per thread double &xPi = this->mVUk[aK][0]; double &yPi = this->mVUk[aK][1]; - double &PPx = this->mVObs[aK][0]; - double &PPy = this->mVObs[aK][1]; - double &PPz = this->mVObs[aK][2]; - double &K1 = this->mVObs[aK][3]; - double &K2 = this->mVObs[aK][4]; - double &K3 = this->mVObs[aK][5]; - double &p1 = this->mVObs[aK][6]; - double &p2 = this->mVObs[aK][7]; - double &b2 = this->mVObs[aK][8]; - double &b1 = this->mVObs[aK][9]; - double F15 = (xPi * xPi); - double F38 = (b1 * xPi); - double F37 = (b2 * yPi); - double F16 = (yPi * yPi); - double F17 = (xPi * yPi); - double F33 = (F16 * 2); - double F26 = (F15 * 2); - double F39 = (F37 + F38); - double F18 = (F15 + F16); - double F29 = (F17 * 2); - double F19 = (F18 * F18); - double F30 = (F29 * p1); - double F34 = (F18 + F33); - double F27 = (F26 + F18); - double F31 = (F29 * p2); - double F21 = (F18 * K1); - double F35 = (F34 * p2); - double F28 = (F27 * p1); - double F22 = (F19 * K2); - double F20 = (F18 * F19); - double F36 = (F30 + F35); - double F23 = (F21 + F22); - double F32 = (F28 + F31); - double F24 = (F20 * K3); - double F25 = (F24 + F23); - double F44 = (F25 * yPi); - double F40 = (F25 * xPi); - double F41 = (F40 + xPi); - double F45 = (F44 + yPi); - double F42 = (F32 + F41); - double F46 = (F36 + F45); - double F43 = (F42 + F39); - double F49 = (F46 * PPz); - double F47 = (F43 * PPz); - double F50 = (F49 + PPy); - double F48 = (F47 + PPx); - this->mBufLineRes[aK][0] = F48; - this->mBufLineRes[aK][1] = F50; + double &K1 = this->mVObs[aK][0]; + double &K2 = this->mVObs[aK][1]; + double &K3 = this->mVObs[aK][2]; + double &p1 = this->mVObs[aK][3]; + double &p2 = this->mVObs[aK][4]; + double &b2 = this->mVObs[aK][5]; + double &b1 = this->mVObs[aK][6]; + double F12 = (xPi * xPi); + double F35 = (b1 * xPi); + double F34 = (b2 * yPi); + double F13 = (yPi * yPi); + double F14 = (xPi * yPi); + double F30 = (F13 * 2); + double F15 = (F12 + F13); + double F23 = (F12 * 2); + double F36 = (F34 + F35); + double F26 = (F14 * 2); + double F27 = (F26 * p1); + double F18 = (F15 * K1); + double F31 = (F15 + F30); + double F28 = (F26 * p2); + double F24 = (F23 + F15); + double F16 = (F15 * F15); + double F25 = (F24 * p1); + double F19 = (F16 * K2); + double F17 = (F15 * F16); + double F32 = (F31 * p2); + double F29 = (F25 + F28); + double F33 = (F27 + F32); + double F20 = (F18 + F19); + double F21 = (F17 * K3); + double F22 = (F21 + F20); + double F41 = (F22 * yPi); + double F37 = (F22 * xPi); + double F42 = (F41 + yPi); + double F38 = (F37 + xPi); + double F43 = (F33 + F42); + double F39 = (F29 + F38); + double F40 = (F39 + F36); + this->mBufLineRes[aK][0] = F40; + this->mBufLineRes[aK][1] = F43; } } -cCalculator * Alloc_EqDist_Dist_Rad3_Dec1_XY1Val(int aSzBuf) +cCompiledCalculator * Alloc_EqDist_Dist_Rad3_Dec1_XY1Val(int aSzBuf) { return new cEqDist_Dist_Rad3_Dec1_XY1Val(aSzBuf); } diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.h b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.h index eae7779637..bbf84b1976 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.h +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.h @@ -5,37 +5,26 @@ namespace NS_SymbolicDerivative { -class cEqDist_Dist_Rad3_Dec1_XY1Val : public cCalculator +class cEqDist_Dist_Rad3_Dec1_XY1Val : public cCompiledCalculator { public: - typedef cCalculator Super; + typedef cCompiledCalculator Super; cEqDist_Dist_Rad3_Dec1_XY1Val(size_t aSzBuf) : - Super("EqDist_Dist_Rad3_Dec1_XY1Val", aSzBuf,2,10,0,1), - mVUk(aSzBuf),mVObs(aSzBuf) + Super( + "EqDist_Dist_Rad3_Dec1_XY1Val", + aSzBuf,//SzBuf + 2,//NbElement + 2,//SzOfLine + {"xPi","yPi"},// Name Unknowns + {"K1","K2","K3","p1","p2","b2","b1"},// Name Observations + 0,//With derivative ? + 1//Size of interv + ) { - this->mNbElem = 2; - for (auto& line : this->mBufLineRes) - line.resize(2); - for (auto& aUk : this->mVUk) - aUk.resize(this->NbUk()); - for (auto& aObs : this->mVObs) - aObs.resize(this->NbObs()); } static std::string FormulaName() { return "EqDist_Dist_Rad3_Dec1_XY1Val";} protected: - virtual void SetNewUks(const std::vector & aVUks) override - { - for (size_t i=0; iNbUk(); i++) - this->mVUk[this->mNbInBuf][i] = aVUks[i]; - } - virtual void SetNewObs(const std::vector & aVObs) override - { - for (size_t i=0; iNbObs(); i++) - this->mVObs[this->mNbInBuf][i] = aVObs[i]; - } virtual void DoEval() override; - std::vector> mVUk; - std::vector> mVObs; }; } // namespace NS_SymbolicDerivative diff --git a/MMVII/src/ImagesBase/PtsBox.cpp b/MMVII/src/ImagesBase/PtsBox.cpp index 87dd789c21..d16a5d8e6e 100644 --- a/MMVII/src/ImagesBase/PtsBox.cpp +++ b/MMVII/src/ImagesBase/PtsBox.cpp @@ -142,6 +142,16 @@ template cPtxd cPtxd::PRandUnit( return VUnit(aRes); } +template cPtxd cPtxd::PRandInSphere() +{ + cPtxd aRes = PRandC(); + while (Norm2(aRes)>1.0) + aRes = PRandC(); + return aRes; +} + + + template cPtxd cPtxd::PRandUnitDiff(const cPtxd& aP0,const Type & aDist) { @@ -654,6 +664,7 @@ template cPtxd cPtxd::PCste(const TYPE&);\ template cPtxd cPtxd::PRand();\ template cPtxd cPtxd::PRandC();\ template cPtxd cPtxd::PRandUnit();\ +template cPtxd cPtxd::PRandInSphere();\ template cPtxd cPtxd::PRandUnitDiff(const cPtxd& ,const TYPE&);\ template double NormK(const cPtxd & aPt,double anExp);\ template double Norm2(const cPtxd & aPt);\ diff --git a/MMVII/src/ImagesInfoExtract/ExtracExtremum.cpp b/MMVII/src/ImagesInfoExtract/ExtracExtremum.cpp index b3734740a5..1d48960425 100644 --- a/MMVII/src/ImagesInfoExtract/ExtracExtremum.cpp +++ b/MMVII/src/ImagesInfoExtract/ExtracExtremum.cpp @@ -476,7 +476,6 @@ cIm2D ImageBenchExtrem(const cPt2di aSz,int aNbVal,int aSzMaj) // regularize it with majority-filter SelfLabMaj(aRes,cRect2::BoxWindow(aSzMaj)); - // std::cout << "IIIII " << aDRes.GetV(cPt2di(0,0)) << " " << aDRes.GetV(cPt2di(4,2)) << "\n"; return aRes; } diff --git a/MMVII/src/Mappings/MappingGen.cpp b/MMVII/src/Mappings/MappingGen.cpp index abb95bbf0b..079ac79548 100644 --- a/MMVII/src/Mappings/MappingGen.cpp +++ b/MMVII/src/Mappings/MappingGen.cpp @@ -344,115 +344,7 @@ template void OneBenchMapping(cParamExeBench & aParam) } } -#if (0) -class cTestMapInv : public cDataIterInvertMapping -{ - public : -/* Initialisation a bit tricky, because class is its own rough invers and we must - must avoid infinite recursion, TO CHANGE LATER with a two step init ... -*/ - cTestMapInv(double aFx,double aFy,double aFz,double aFreqCos,double aMulCos,bool ForRoughInv=false) : - cDataIterInvertMapping - ( - cPt3dr::PCste(1e-3/std::max(1e-5,mFreqCos)), - cMapping(ForRoughInv?nullptr:new cTestMapInv(1.0/aFy,1.0/aFx,1.0/aFz,1.0,0.0,true)), - 1e-4, - 20 - ), - mFx (aFx), - mFy (aFy), - mFz (aFz), - mFreqCos (aFreqCos), - mMulCos (aMulCos) - { - } - - cPt3dr Value(const cPt3dr & aP) const override - { - return cPt3dr - ( - mFx * aP.y() + cos((aP.x()+aP.y())*mFreqCos)*mMulCos, - mFy * aP.x() + sin((aP.y()-aP.z())*mFreqCos)*mMulCos, - mFz * aP.z() + sin((1.0+aP.x()-aP.y()+aP.z())*mFreqCos)*mMulCos - ); - } - double mFx; - double mFy; - double mFz; - double mFreqCos; - double mMulCos; -}; - - -void BenchInvertMapping(cParamExeBench & aParam) -{ - // Check in pure linear case, the inverse is exact - { - cTestMapInv aM1(0.3,4.1,2.2,1000.0,0.0); - const cDataMapping & aM2 = *(aM1.RoughInv()); - for (int aK=0; aK<1000 ; aK++) - { - cPt3dr aP1 = cPt3dr::PRandC()*100.0; - cPt3dr aP12 = aM1.Value(aM2.Value(aP1)); - cPt3dr aP21 = aM2.Value(aM1.Value(aP1)); - MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP12)<1e-5,"cTestMapInv rough inverse"); - MMVII_INTERNAL_ASSERT_bench(Norm2(aP1-aP21)<1e-5,"cTestMapInv rough inverse"); - } - } - - for (int aKMap=0 ; aKMap<100 ; aKMap++) - { - double aFX = RandUnif_C_NotNull(1e-1) * 3.0; - double aFY = RandUnif_C_NotNull(1e-1) * 3.0; - double aFZ = RandUnif_C_NotNull(1e-1) * 3.0; - double aFreq = RandUnif_C_NotNull((1e-1) * 3.0); - double aFMin =std::min(std::abs(aFX),std::min(std::abs(aFY),std::abs(aFZ))); - double aMulCos = (aFMin / aFreq) * 0.2 * RandUnif_0_1(); - - cTestMapInv aM1(aFX,aFY,aFZ,aFreq,aMulCos); -/* - cMapping aMInv(new cTestMapInv(aM1.RoughInverse())); - double aEpsInv = 1e-4; - aM1.SetRoughInv(aMInv,aEpsInv,20); -*/ - cDataInvertibleMapping * aPM1 = & aM1; - - - tREAL8 aEpsInv = aM1.DTolInv(); - for (int aKP=0 ; aKP<100 ; aKP++) - { - cPt3dr aPt = cPt3dr::PRandC()*100.0; - cPt3dr aPtD = aM1.Value(aPt); - cPt3dr aPtDI = aM1.Inverse(aPtD); - - cPt3dr aPtI = aM1.Inverse(aPt); - cPt3dr aPtID = aM1.Value(aPtI); - - MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtDI)<10*aEpsInv,"elem inverse"); - MMVII_INTERNAL_ASSERT_bench(Norm2(aPt -aPtID)<10*aEpsInv,"elem inverse"); - } - - for (int aKV=0 ; aKV<10 ; aKV++) - { - int aNb = RandUnif_N(100); - std::vector aVIn; - for (int aKP=0 ; aKP aVOut = aPM1->Values(aVIn); - std::vector aVInv = aPM1->Inverses(aVOut); - for (int aKP=0 ; aKP { diff --git a/MMVII/src/Mappings/MappingInverse.cpp b/MMVII/src/Mappings/MappingInverse.cpp index d3501e7749..795e5150dd 100644 --- a/MMVII/src/Mappings/MappingInverse.cpp +++ b/MMVII/src/Mappings/MappingInverse.cpp @@ -3,6 +3,8 @@ namespace MMVII { +// extern bool BUGINVMAP; + /* ============================================= */ /* cDataInvertibleMapping */ /* ============================================= */ @@ -87,7 +89,7 @@ template struct cStrPtInvDIM cPtxd mPTarget; }; -template class cInvertDIMByIter +template class cInvertDIMByIter : public cMemCheck { public : typedef cDataIterInvertMapping tDIM; @@ -301,6 +303,7 @@ template aStr.mNum = aKPt; aStr.mPTarget = aVTarget[aKPt]; aStr.mBestInv = aVInit[aKPt]; + // aStr.mBestErr = 1e mVSubSet.push_back(aKPt); mVInv.push_back(aStr); } @@ -379,9 +382,60 @@ template return aVRes; } +/* ============================================= */ +/* cDataIterInvertMapping */ +/* ============================================= */ +/* +template class cDataIIMFroMap : public cDataIterInvertMapping +{ + public : + cDataIIMFroMap(tMap aMap,const tPt &,tMap aRoughInv,const Type& aDistTol,int aNbIterMax); + cDataIIMFroMap(tMap aMap,tMap aRoughInv,const Type& aDistTol,int aNbIterMax); + + tCsteResVecJac Jacobian(tResVecJac,const tVecIn &) const override; //J2 + private : + tMap mMap; +}; +*/ + +template + cDataIIMFromMap::cDataIIMFromMap + (tMap aMap,const tPt & aEps,tMap aRoughInv,const Type& aDistTol,int aNbIterMax) : + tDataIIMap (aEps,aRoughInv,aDistTol,aNbIterMax), + mMap(aMap) +{ +} + +template + cDataIIMFromMap::cDataIIMFromMap + (tMap aMap,tMap aRoughInv,const Type& aDistTol,int aNbIterMax) : + tDataIIMap (aRoughInv,aDistTol,aNbIterMax), + mMap (aMap) +{ +} + + + + + +template + const typename cDataIIMFromMap::tVecPt & + cDataIIMFromMap::Values(tVecPt & aVecOut,const tVecPt & aVecIn) const +{ + return mMap.DM()->Values(aVecOut,aVecIn); +} + +template + typename cDataIIMFromMap::tCsteResVecJac + cDataIIMFromMap::Jacobian(tResVecJac aResJac,const tVecPt & aVecIn) const +{ + return mMap.DM()->Jacobian(aResJac,aVecIn); +} + #define INSTANCE_INVERT_MAPPING(DIM)\ +template class cDataIIMFromMap;\ template class cDataInvertibleMapping;\ template class cDataIterInvertMapping;\ template class cInvertDIMByIter; @@ -500,7 +554,6 @@ void BenchInvertMapping(cParamExeBench & aParam) { double aD = Norm2(aVIn[aKP] - aVInv[aKP]); MMVII_INTERNAL_ASSERT_bench(aD<10*aEpsInv,"elem inverse"); -// std::cout << "NNN: " << Norm2(aVIn[aKP] - aVInv[aKP]) << "\n"; } } } diff --git a/MMVII/src/SymbDerGen/Formulas_CamStenope.h b/MMVII/src/SymbDerGen/Formulas_CamStenope.h index 92e321cbbe..e7e8959994 100644 --- a/MMVII/src/SymbDerGen/Formulas_CamStenope.h +++ b/MMVII/src/SymbDerGen/Formulas_CamStenope.h @@ -203,39 +203,6 @@ namespace MMVII */ -/** Indicate the nature of each coefficient of the distorsion -*/ -enum class eTypeFuncDist - { - eRad, ///< Coefficient for radial distorsion - eDecX, ///< Coefficient for decentric distorsion x mean derived by Cx (it has X and Y components) - eDecY, ///< Coefficient for decentric distorsion y mean derived by Cy (it has X and Y components) - eMonX, ///< Coefficient for a monom in X, of the polynomial distorsion - eMonY, ///< Coefficient for a monom in Y, of the polynomial distorsion - eNbVals ///< Tag for number of value - }; - -/** This class store a complete description of each parameters of the distorsion, - it is used for computing the formula, the vector of name and (later) automatize - conversion, print understandable values .... - - It's rather bad design with the same classe coding different things, and some fields - used of not according to the others, but as it internal/final classes, quick and dirty - exceptionnaly allowed ... -*/ - -class cDescOneFuncDist -{ - public : - cDescOneFuncDist(eTypeFuncDist aType,const cPt2di aDeg); - - eTypeFuncDist mType; ///< Type of dist (Rad, DecX ....) - std::string mName; ///< Name : used as id for code gen & prety print - cPt2di mDegMon; ///< Degree for a polynomial - int mNum; ///< Order for radial and decentric - int mDegTot; ///< Total degree of the polynome -}; - cDescOneFuncDist::cDescOneFuncDist(eTypeFuncDist aType,const cPt2di aDegXY) : mType (aType), mDegMon (-1,-1), @@ -295,9 +262,9 @@ class cMMVIIUnivDist } /// Used to indicate reason why monom sould be removes. To maintain for debug ? - void ShowElim(const std::string aMesWhy, bool isX, int aDegX, int aDegY ) + void ShowElim(const std::string aMesWhy, bool isX, int aDegX, int aDegY ) const { - // std::cout << aMesWhy << " " << (isX?"x":"y") << " " << aDegX << " " << aDegY << "\n"; + // StdOut() << aMesWhy << " " << (isX?"x":"y") << " " << aDegX << " " << aDegY << "\n"; } @@ -316,7 +283,7 @@ class cMMVIIUnivDist bool isX, // Is it x component of distorsion int aDegX, // Degree in x int aDegY // Degree in y - ) + ) const { // degre 0 : avoid, it's already modelized by PP if ((aDegX ==0) && (aDegY==0)) @@ -369,7 +336,7 @@ class cMMVIIUnivDist // supress X^n Y^n, not X^0Y^0 (already PP) and if ( (aDegX==aDegY) && (aDegX>=1) && (aDegX<=DegDec())) { - // std::cout << "DEC " << (isX?"x":"y") << " " << aDegX << " " << aDegY << "\n"; + // StdOut() << "DEC " << (isX?"x":"y") << " " << aDegX << " " << aDegY << "\n"; ShowElim("DEC",isX,aDegX,aDegY); return false; } @@ -385,7 +352,7 @@ class cMMVIIUnivDist * generating description or accessing parameters by names */ - const std::vector & VDescParams() + const std::vector & VDescParams() const { // static_assert(DegRad>=DegDec(),"Too much decentrik"); static std::vector VDesc; @@ -426,7 +393,7 @@ class cMMVIIUnivDist } /** Names of all param, used to automatize symbolic derivation */ - const std::vector & VNamesParams() + const std::vector & VNamesParams() const { static std::vector VNames; if (VNames.empty()) @@ -446,7 +413,7 @@ class cMMVIIUnivDist const tScal & xIn,const tScal & yIn, const std::vector & aVParam, unsigned int aK0P - ) + ) const { tScal aC0 = CreateCste(0.0,xIn); tScal aC1 = CreateCste(1.0,xIn); @@ -822,25 +789,44 @@ template template class cEqDist { public : - cEqDist(const TypeDist & aDist) : - mDist (aDist), - mVNamesObs (Append({"PPx","PPy","PPz"},mDist.VNamesParams())) + cEqDist(const TypeDist & aDist) : mDist (aDist) { } + static std::vector VNamesUnknowns() {return {"xPi","yPi"}; } + const std::vector & VNamesObs() const {return mDist.VNamesParams();} + + std::string FormulaName() const { return "EqDist_" + mDist.NameModel();} + + template + std::vector formula + ( + const std::vector & aVUk, + const std::vector & aVObs + ) const { + return mDist.PProjToImNorm(aVUk.at(0),aVUk.at(1),aVObs,0); } + private : + TypeDist mDist; +}; + + + - static const std::vector& VNamesUnknowns() +template class cEqIntr +{ + public : + cEqIntr(const TypeDist & aDist) : + mDist (aDist), + mVNamesObs (Append({"PPx","PPy","PPz"},mDist.VNamesParams())) { - static std::vector TheV {"xPi","yPi"}; - return TheV; } - - const std::vector & VNamesObs() + static const std::vector VNamesUnknowns() { return {"xPi","yPi"}; } + const std::vector & VNamesObs() const { return mVNamesObs; } - std::string FormulaName() const { return "EqDist_" + mDist.NameModel();} + std::string FormulaName() const { return "EqIntr_" + mDist.NameModel();} /* Capital letter for 3D variable/formulas and small for 2D */ template @@ -848,13 +834,14 @@ template class cEqDist ( const std::vector & aVUk, const std::vector & aVObs - ) + ) const { // Now compute the distorsion - auto aVDist = mDist.PProjToImNorm(aVUk.at(0),aVUk.at(1),aVObs,3); + auto XY = mDist.PProjToImNorm(aVUk.at(0),aVUk.at(1),aVObs,3); - return TransformPPxyz(aVDist,aVObs,0); + return { aVObs[0] + aVObs[2] * XY[0], + aVObs[1] + aVObs[2] * XY[1] }; } private : TypeDist mDist; diff --git a/MMVII/src/SymbDerGen/GenerateCodes.cpp b/MMVII/src/SymbDerGen/GenerateCodes.cpp index 3255b8e1d1..8f0f501b38 100644 --- a/MMVII/src/SymbDerGen/GenerateCodes.cpp +++ b/MMVII/src/SymbDerGen/GenerateCodes.cpp @@ -43,7 +43,7 @@ template class cFormulaMapping : public cMapp /* BENCH PART */ /* **************************** */ -template void OneBenchProjToDirBundle() +template void OneBenchProjToDirBundle(cParamExeBench & aParam) { // Just to force compile with these tricky classes if (NeverHappens()) @@ -70,22 +70,25 @@ template void OneBenchProjToDirBundle() aK++; } } - std::cout << "NAME=" << TyProj::NameProj() << "\n"; + if (aParam.Show()) + { + StdOut() << "NAME=" << TyProj::NameProj() << "\n"; + } } -void BenchProjToDirBundle() +void BenchProjToDirBundle(cParamExeBench & aParam) { - if (true) + if (aParam.Show()) { - std::cout << "T0:" << cName2Calc::CalcFromName("toto",10,true) << "\n"; - std::cout << "T1:" << cName2Calc::CalcFromName("EqDistDist_Rad3_Dec1_XY1",10,true) << "\n"; + StdOut()<<"cName2Calc T0:"<::CalcFromName("toto",10,true)<<"\n"; + StdOut()<<"cName2Calc T1:"<::CalcFromName("EqDistDist_Rad3_Dec1_XY1",10,true)<<"\n"; } - OneBenchProjToDirBundle (); - OneBenchProjToDirBundle (); - OneBenchProjToDirBundle (); - OneBenchProjToDirBundle (); - OneBenchProjToDirBundle (); + OneBenchProjToDirBundle (aParam); + OneBenchProjToDirBundle (aParam); + OneBenchProjToDirBundle (aParam); + OneBenchProjToDirBundle (aParam); + OneBenchProjToDirBundle (aParam); } @@ -112,7 +115,7 @@ class cAppli : public cMMVII_Appli int ExecuteBench(cParamExeBench &) override ; // private : - template void GenCodesDist(const tDist & aDist,bool WithDerive,bool PP); + template void GenCodesFormula(const tDist & aDist,bool WithDerive); // =========== Data ======== // Mandatory args @@ -157,29 +160,28 @@ cCollecSpecArg2007 & cAppli::ArgOpt(cCollecSpecArg2007 & anArgOpt) -template void cAppli::GenCodesDist(const tDist & aDist,bool WithDerive,bool PP) +template void cAppli::GenCodesFormula(const tFormula & aFormula,bool WithDerive) { - - int SzBuf=0; - cEqDist anEq(aDist); - + int aSzBuf=1; // std::string aNF = anEq.FormulaName() + std::string(WithDerive ?"VDer":"Val"); - std::string aNF = NameFormula(anEq,WithDerive); + std::string aNF = NameFormula(aFormula,WithDerive); NS_SymbolicDerivative::cCoordinatorF - aCEq(aNF,SzBuf,anEq.VNamesUnknowns(),anEq.VNamesObs()); + aCEq(aNF,aSzBuf,aFormula.VNamesUnknowns(),aFormula.VNamesObs()); // Gives the liste of names // Set header in a place to compilation path of MMVII aCEq.SetHeaderIncludeSymbDer("include/SymbDer/SymbDer_Common.h"); - aCEq.SetUseAllocByName(true); + aCEq.SetUseAllocByName(true); // generate allocators aCEq.SetDirGenCode(mDirGenCode); - auto aXY= anEq.formula(aCEq.VUk(),aCEq.VObs()); + auto aXY= aFormula.formula(aCEq.VUk(),aCEq.VObs()); // Give ths list of atomic formula if (WithDerive) aCEq.SetCurFormulasWithDerivative(aXY); else aCEq.SetCurFormulas(aXY); aCEq.GenerateCode("CodeGen_"); +/* +*/ }; @@ -188,10 +190,15 @@ template void cAppli::GenCodesDist(const tDist & aDist,bool Wit int cAppli::Exe() { mDirGenCode = TopDirMMVII() + "src/GeneratedCodes/"; - cMMVIIUnivDist aDist(3,1,1); - - GenCodesDist(aDist,false,false); - GenCodesDist(aDist,true,false); + cMMVIIUnivDist aDist(3,1,1); + cEqDist anEqDist(aDist); + cEqIntr anEqIntr(aDist); + + GenCodesFormula(anEqDist,false); + GenCodesFormula(anEqDist,true); + GenCodesFormula(anEqIntr,false); + GenCodesFormula(anEqIntr,true); + // GenCodesFormula(aDist,true,false); return EXIT_SUCCESS; } @@ -202,7 +209,7 @@ cAppliBenchAnswer cAppli::BenchAnswer() const int cAppli::ExecuteBench(cParamExeBench & aParam) { - BenchProjToDirBundle(); + BenchProjToDirBundle(aParam); return EXIT_SUCCESS; } @@ -223,11 +230,42 @@ tMMVII_UnikPApli Alloc_GenCode(const std::vector & aVArgs,const cS using namespace NS_GenerateCode; namespace MMVII { + +double cDescOneFuncDist::MajNormJacOfRho(double aRho) const +{ + switch(mType) + { + case eTypeFuncDist::eRad : + return mDegTot * pow(aRho,mDegTot-1); + case eTypeFuncDist::eDecX : + case eTypeFuncDist::eDecY : + return mDegTot*(mDegTot+1) * pow(aRho,mDegTot-1); + + case eTypeFuncDist::eMonX : + case eTypeFuncDist::eMonY : + return Norm2(mDegMon) * pow(aRho,mDegTot-1); + default : + ; + } + + MMVII_INTERNAL_ERROR("Bad num in cDescOneFuncDist::MajNormJacOfRho"); + return 0.0; +} + + cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf) { return cName2Calc::CalcFromName(NameEqDist(aDeg,WithDerive),aSzBuf); } +const std::vector & DescDist(const cPt3di & aDeg) +{ + cMMVIIUnivDist aDist(aDeg.x(),aDeg.y(),aDeg.z()); + + return aDist.VDescParams(); + +} + cSpecMMVII_Appli TheSpecGenSymbDer ( diff --git a/MMVII/src/UtiMaths/uti_fonc_analytique.cpp b/MMVII/src/UtiMaths/uti_fonc_analytique.cpp index 1bc08c3366..ac0a7b97f5 100644 --- a/MMVII/src/UtiMaths/uti_fonc_analytique.cpp +++ b/MMVII/src/UtiMaths/uti_fonc_analytique.cpp @@ -36,9 +36,7 @@ template Type AtanXsY_sX(const Type & X,const Type & Y,const Typ { if (std::abs(X) > aEps * std::abs(Y)) return std::atan2(X,Y) / X; - // atan(X,Y) = X/Y -1/3 (X/Y) ^3 + 1/5 (X/Y) ^5 - 1/7 .... -// std::cout << "HHHHHHHHhhhhhhh\n"; Type XsY2 = Square(X/Y); Type XsY4 = XsY2 * XsY2; diff --git a/MMVII/src/UtiMaths/uti_nums.cpp b/MMVII/src/UtiMaths/uti_nums.cpp index 6eb88cd97b..e00b0a4133 100644 --- a/MMVII/src/UtiMaths/uti_nums.cpp +++ b/MMVII/src/UtiMaths/uti_nums.cpp @@ -237,7 +237,6 @@ template void BenchFuncAnalytique(int aNb,double aEps,double EpsDer Type aTeta2Sx = AtanXsY_sX(aX,aY,aEps); Type aTeta1Sx = Teta / aX; - // std::cout << RelativeDifference(aTeta2Sx,aTeta1Sx) << " " << (aTeta2Sx-aTeta1Sx)*1e10 << "\n"; MMVII_INTERNAL_ASSERT_bench(std::abs(aTeta2Sx-aTeta1Sx) void BenchFuncAnalytique(int aNb,double aEps,double EpsDer Type aDerDifY = (AtanXsY_sX(aX,aY+aDDif,aEps)-AtanXsY_sX(aX,aY-aDDif,aEps)) / (2*aDDif); Type aDerY = DerYAtanXsY_sX(aX,aY); - // std::cout << "DDyyy " << RelativeDifference(aDerDifY,aDerY) << "\n"; MMVII_INTERNAL_ASSERT_bench(RelativeDifference(aDerDifY,aDerY) Date: Thu, 6 May 2021 10:53:57 +0200 Subject: [PATCH 03/25] MMVII: Alternate Makefile Use ccache if present, manage dependencies automagically Compatible with Mk-MMVII.makefile --- MMVII/.gitignore | 5 +++ MMVII/apipy/setup.py | 2 +- MMVII/bin/Makefile | 80 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 MMVII/bin/Makefile diff --git a/MMVII/.gitignore b/MMVII/.gitignore index f730706847..9a1e343264 100644 --- a/MMVII/.gitignore +++ b/MMVII/.gitignore @@ -7,3 +7,8 @@ include/CodeGen_*.h *.toc MMVII/MMVII-TestDir/Input/Files/RelTest.xml MMVII/MMVII-TestDir/Input/Files/RelTest_0-5.xml +.*.d +!bin/ +bin/* +!bin/Makefile +!bin/Mk-MMVII.makefile diff --git a/MMVII/apipy/setup.py b/MMVII/apipy/setup.py index f0b9cfa306..e15bf07211 100644 --- a/MMVII/apipy/setup.py +++ b/MMVII/apipy/setup.py @@ -32,7 +32,7 @@ library_dirs = [], include_dirs = ['/usr/local/include', '.', '../include/', '../ExternalInclude/'], language = 'c++', - extra_objects = ['../bin/P2007.a', '../../lib/libelise.a', '../../lib/libANN.a'], + extra_objects = ['../bin/libP2007.a', '../../lib/libelise.a', '../../lib/libANN.a'], extra_compile_args = ['-std=c++17', '-fopenmp'] ) diff --git a/MMVII/bin/Makefile b/MMVII/bin/Makefile new file mode 100644 index 0000000000..c777bf2b85 --- /dev/null +++ b/MMVII/bin/Makefile @@ -0,0 +1,80 @@ +# =========== Directories +MMV1_DIR=../.. +MMV1_LIBDIR=${MMV1_DIR}/lib +MMV2_DIR=${MMV1_DIR}/MMVII +MMV2_BINDIR=${MMV2_DIR}/bin +MMV2_SRCDIR=${MMV2_DIR}/src +MMV2_EXE=${MMV2_BINDIR}/MMVII +MMV2_INSTALL_PATH=${dir ${abspath ${MMV2_EXE}}} + +# =========== Includes & Libraries +MMV1_INCLUDES=-I ${MMV1_DIR}/include -I${MMV1_DIR} +MMV2_INCLUDES=-I ${MMV2_DIR} -I ${MMV2_DIR}/ExternalInclude + +MMV2_LIBNAME=P2007 +MMV2_LIB=${MMV2_BINDIR}/lib${MMV2_LIBNAME}.a +MMV1_LIBS=${MMV1_LIBDIR}/libelise.a ${MMV1_LIBDIR}/libANN.a +QT_LIBS=-lXext -lGLU -lGL -lQt5Core -lQt5Gui -lQt5Xml -lQt5OpenGL -lQt5Concurrent -lQt5Widgets +## MacOS : may be -lstdc++fs should be replaced by -lc++experimental +EXT_LIBS=-lpthread -lX11 ${QT_LIBS} -lstdc++fs + + +# =========== Compiler & Flags +CXX=g++ +LD=g++ +CXXFLAGS= -std=c++17 -Wall -Werror -O4 -fPIC -march=native ${MMV2_INCLUDES} ${MMV1_INCLUDES} +LDFLAGS= + + +# =========== Use ccache if found +CCACHE:=${shell which ccache} +ifneq (,${CCACHE}) + CXX:=${CCACHE} ${CXX} +endif + + +# ============ Targets +all: ${MMV2_EXE} + +clean: + rm -f ${OBJS} ${DEPS} ${MMV2_EXE} ${MMV2_LIB} + + +# =========== Build Lib +LIB_SRCS=${wildcard ${MMV2_SRCDIR}/*/*.cpp} ${wildcard ${MMV2_DIR}/kapture/*.cpp} +LIB_OBJS:=${LIB_SRCS:.cpp=.o} +LIB_OBJS:=${filter-out ${MMV2_SRCDIR}/BinaireInstall/%,${LIB_OBJS}} +LIB_OBJS:=${filter-out ${MMV2_SRCDIR}/ResultInstall/%,${LIB_OBJS}} +LIB_OBJS:=${filter-out ${MMV2_SRCDIR}/TestCodeGen/%,${LIB_OBJS}} + +%.o: %.cpp Makefile + ${CXX} -c ${CXXFLAGS} $< -o $@ + +${MMV2_LIB}: ${LIB_OBJS} + rm -f $@ + ar crs $@ $^ + +# ========== Build Main +MAIN_OBJ=${MMV2_SRCDIR}/main.o +MMV2_RESULT_INSTALL=${MMV2_SRCDIR}/ResultInstall/ResultInstall.cpp + +${MMV2_RESULT_INSTALL}: + mkdir -p ${dir ${MMV2_RESULT_INSTALL}} + echo '#include \nnamespace MMVII {\nconst std::string DirBin2007="${MMV2_INSTALL_PATH}";\n};\n' > ${MMV2_RESULT_INSTALL} + +${MAIN_OBJ}: ${MMV2_RESULT_INSTALL} + +${MMV2_EXE}: ${MAIN_OBJ} ${MMV2_LIB} ${MMV1_LIBS} + ${CXX} ${LDFLAGS} $^ ${EXT_LIBS} -o $@ + +# =========== Auto dependancies +OBJS=${LIB_OBJS} ${MAIN_OBJ} +DEPS=${join ${addsuffix ., ${dir ${OBJS}}}, ${notdir ${OBJS:.o=.d}}} + +.%.d: %.cpp + @set -e; rm -f $@; \ + ${CXX} -MM -MP -MT '${patsubst %.cpp,%.o,$<} $@' -MF $@ ${CXXFLAGS} $< 2>/dev/null + +ifneq (${MAKECMDGOALS},clean) +-include ${DEPS} +endif From 3a0454663ed69df56320f605d41e4a6266bda18d Mon Sep 17 00:00:00 2001 From: deseilligny Date: Thu, 6 May 2021 17:33:38 +0200 Subject: [PATCH 04/25] Fichier manquant --- MMVII/include/MMVII_Mappings.h | 16 +- MMVII/include/MMVII_Ptxd.h | 14 +- MMVII/include/SymbDer/SymbDer_Common.h | 33 ++- MMVII/include/SymbDer/SymbolicDerivatives.h | 24 +- MMVII/include/TreeDist.h | 26 +- MMVII/src/ImagesBase/PtsBox.cpp | 25 ++ MMVII/src/Mappings/MappingGen.cpp | 75 ++++++ MMVII/src/Mappings/MappingSymDer.cpp | 265 +++++++++++++++++++ MMVII/src/SymbDerGen/Formulas_CamStenope.cpp | 104 ++++++++ MMVII/src/SymbDerGen/Formulas_CamStenope.h | 36 --- MMVII/src/SymbDerGen/GenerateCodes.cpp | 37 --- 11 files changed, 550 insertions(+), 105 deletions(-) create mode 100644 MMVII/src/Mappings/MappingSymDer.cpp create mode 100644 MMVII/src/SymbDerGen/Formulas_CamStenope.cpp diff --git a/MMVII/include/MMVII_Mappings.h b/MMVII/include/MMVII_Mappings.h index 60d7a814b1..a494b2849c 100644 --- a/MMVII/include/MMVII_Mappings.h +++ b/MMVII/include/MMVII_Mappings.h @@ -115,10 +115,20 @@ template class cMapping template class cDataBoundedSet : public cMemCheck { public : - typedef cPtxd tPt; - - /// Does it belong to the set; default true + typedef cPtxd tPt; + typedef std::vector tVecPt; + typedef cTplBox tBox; + + cDataBoundedSet(const tBox &); + /// Does it belong to the set; default =belong to box + virtual bool InsideWithBox(const tPt &) const; + /// Does it belong to the set; default =true virtual bool Inside(const tPt &) const; + + const tBox & Box() const; + + void GridPointInsideAtStep(tVecPt&,Type aStepMoy) const; + void GridPointInsideOfNbPoints(tVecPt&,int aStepMoy) const; private : cTplBox mBox; diff --git a/MMVII/include/MMVII_Ptxd.h b/MMVII/include/MMVII_Ptxd.h index 6b3540ee3d..e0631453a5 100644 --- a/MMVII/include/MMVII_Ptxd.h +++ b/MMVII/include/MMVII_Ptxd.h @@ -226,6 +226,7 @@ template inline T NormInf(const cPtxd & aP) {return std::max(std: /// Currently, the L2 norm is used for comparaison, no need to extract square root template inline T SqN2(const cPtxd & aP) {return Square(aP.x());} template inline T SqN2(const cPtxd & aP) {return Square(aP.x())+Square(aP.y());} +template inline T SqN2(const cPtxd & aP) {return Square(aP.x())+Square(aP.y())+Square(aP.z());} /// Sort vector by norm, typically dont need to compute square root template bool CmpN2(const cPtxd &aP1,const cPtxd & aP2) { @@ -349,6 +350,8 @@ typedef cPtxd cPt3df ; // Most frequent conversion inline cPt2di ToI(const cPt2dr & aP) {return cPt2di(round_ni(aP.x()),round_ni(aP.y()));} inline cPt2dr ToR(const cPt2di & aP) {return cPt2dr(aP.x(),aP.y());} +inline cPt3di ToI(const cPt3dr & aP) {return cPt3di(round_ni(aP.x()),round_ni(aP.y()),round_ni(aP.z()));} +inline cPt3dr ToR(const cPt3di & aP) {return cPt3dr(aP.x(),aP.y(),aP.z());} template bool CmpCoord(const cPtxd & aP1,const cPtxd & aP2) { @@ -437,11 +440,13 @@ extern cPt2di TAB4Corner[4] ; ///< {{1,1},{-1,1},{-1,-1},{1,-1}}; template class cTplBox { public : + typedef Type tNum ; typedef typename tNumTrait::tBig tBigNum ; typedef cTplBox tBox; typedef cPtxd tPt; typedef cPtxd tBigPt; + typedef tPt tCorner[1< class cTplBox static cPtxd RandomNormalised() ; ///< Random point in "hyper cube" [0,1] ^ Dim tPt GeneratePointInside() const; ///< Random point in integer rect tBox GenerateRectInside(double aPowSize=1.0) const; ///< Hig Power generate "small" rect, never empty - - + void Corners(tCorner & aRes) const; + Type Dist2Corners(const tPt&) const; protected : tPt mP0; ///< "smallest" @@ -509,6 +514,11 @@ template class cTplBox private : }; +/** Function computing corner of box, this one is specific to dim=1 because it respect +trigonometric order, a notion not generalisable */ + +template void CornersTrigo(typename cTplBox::tCorner & aRes,const cTplBox&); + typedef cTplBox cBox2di; typedef cTplBox cBox2dr; cBox2dr ToR(const cBox2di &); ///< Basic conversion diff --git a/MMVII/include/SymbDer/SymbDer_Common.h b/MMVII/include/SymbDer/SymbDer_Common.h index 20304dad18..673746f6a9 100644 --- a/MMVII/include/SymbDer/SymbDer_Common.h +++ b/MMVII/include/SymbDer/SymbDer_Common.h @@ -1,6 +1,28 @@ #ifndef _SymbDer_Common_H_ #define _SymbDer_Common_H_ + +#define SYMBDER_WITH_MMVII true + +namespace NS_SymbolicDerivative +{ +template class cCalculator; +template class cCompiledCalculator; +}; + + +#if (SYMBDER_WITH_MMVII) +#include "include/MMVII_all.h" +#include "include/MMVII_Derivatives.h" +#define SYMBDER_cMemCheck MMVII::cMemCheck +#else //========================================================== WITH_MMVI +class SYMBDER_cMemCheck +{ +}; +#endif + + + #include #include #include @@ -10,6 +32,7 @@ #include #include + namespace NS_SymbolicDerivative { /* These functions are required if we want to have same operation on numbers double and formulas @@ -53,10 +76,10 @@ static inline void AssertAlmostEqual(const double & aV1,const double & aV2,const InternalError("Test equality failed",""); } -class cConvStrRange +class cConvStrRank { public : - cConvStrRange(const std::vector & aVName) : + cConvStrRank (const std::vector & aVName) : mRange2Name (aVName) { for (size_t aRange=0 ; aRange -class cCalculator +class cCalculator : public SYMBDER_cMemCheck { public: typedef T TypeElem; @@ -174,9 +197,9 @@ class cCalculator std::string mName; size_t mSzBuf; ///< Capacity of bufferirsation size_t mNbUK; ///< DimIn=number of unkown - cConvStrRange mConvNamesUk; ///< Names of unknonw, used as a helper + cConvStrRank mConvNamesUk; ///< Names of unknonw, used as a helper size_t mNbObs; ///< Number of obserbation variable - cConvStrRange mConvNamesObs; ///< Names of observation, used as a helper + cConvStrRank mConvNamesObs; ///< Names of observation, used as a helper size_t mNbElem; ///< DimOut=Number of elements returned by the formula (w/o derivative) size_t mNbInBuf; ///< Number of Unknown/Obs vect currenlty loaded in buf bool mWithDer; ///< Done With Derivate diff --git a/MMVII/include/SymbDer/SymbolicDerivatives.h b/MMVII/include/SymbDer/SymbolicDerivatives.h index 94a37d78bf..ae063f8a23 100644 --- a/MMVII/include/SymbDer/SymbolicDerivatives.h +++ b/MMVII/include/SymbDer/SymbolicDerivatives.h @@ -7,11 +7,11 @@ using namespace std; #endif -#define WITH_MMVII true -#define WITH_EIGEN false +// #define SYMBDER_WITH_MMVII true +#define SYMBDER_WITH_EIGEN false -#if WITH_EIGEN +#if SYMBDER_WITH_EIGEN #include "ExternalInclude/Eigen/Dense" // TODO => replace with standard eigen file #define EIGEN_ALLIGNMENT_IN_MMVII EIGEN_MAKE_ALIGNED_OPERATOR_NEW #else @@ -87,14 +87,22 @@ using namespace std; #include "SymbDer_Common.h" -#if (WITH_MMVII) +/* +#if (SYMBDER_WITH_MMVII) #include "include/MMVII_all.h" #include "include/MMVII_Derivatives.h" -using namespace MMVII; +#define SYMBDER_cMemCheck MMVII::cMemCheck #else //========================================================== WITH_MMVI -class cMemCheck +class SYMBDER_cMemCheck { }; +#endif +*/ + + + +#if (SYMBDER_WITH_MMVII) +#else #include #include #include @@ -293,7 +301,7 @@ template Type powI(const Type & aV,const int & aExp) // -------- Declaration of Coordinator class ---------------- -template class cCoordinatorF : public cCalculator,public cMemCheck +template class cCoordinatorF : public cCalculator // , public SYMBDER_cMemCheck { public : @@ -494,7 +502,7 @@ template class cPowF ; ///< Class for division of 2 functio // cFormula / cImplemF // ---------------------------------------------------------------- -template class cImplemF : public cMemCheck +template class cImplemF : public SYMBDER_cMemCheck { public : // See eigen documentation, this macro is mandatory for alignment reason diff --git a/MMVII/include/TreeDist.h b/MMVII/include/TreeDist.h index 0284ce7e83..4c5a2b5b37 100644 --- a/MMVII/include/TreeDist.h +++ b/MMVII/include/TreeDist.h @@ -22,14 +22,14 @@ // Set false for external use, set true inside MMMVII to benefit from functionality // with additionnal correctness checking -#define WITH_MMVII false +#define TREEDIST_WITH_MMVII true -#if (WITH_MMVII) +#if (TREEDIST_WITH_MMVII) #include "include/MMVII_all.h" -using namespace MMVII; +#define TREEDIST_cMemCheck MMVII::cMemCheck #else //========================================================== WITH_MMVI -class cMemCheck +class TREEDIST_cMemCheck { }; #include @@ -114,7 +114,7 @@ mEndNeigh 0 1 2 3 4 */ -class cAdjGraph : public cMemCheck +class cAdjGraph : public TREEDIST_cMemCheck { public : /// We dont want unvolontar copy @@ -150,7 +150,7 @@ class cAdjGraph : public cMemCheck /** A cFastTreeDist will make several recursive split and store the computation of the corresponing level in cOneLevFTD */ -class cOneLevFTD : public cMemCheck +class cOneLevFTD : public TREEDIST_cMemCheck { public : friend class cFastTreeDist; @@ -652,12 +652,10 @@ int cFastTreeDist::Dist(int aI1,int aI2) const /* | cOneBenchFastTreeDist | */ /* ---------------------------------- */ -#if (! WITH_MMVII) // Some basic rand function defined in MMVII, used to generated random tree -inline int RandUnif_N(int aNb) { return rand() % aNb; } -#define NB_RAND_UNIF 1000000 -inline float RandUnif_0_1() { return RandUnif_N(NB_RAND_UNIF) / float(NB_RAND_UNIF); } -#endif +inline int TREEDIST_RandUnif_N(int aNb) { return rand() % aNb; } +#define TREEDIST_NB_RAND_UNIF 1000000 +inline float TREEDIST_RandUnif_0_1() { return TREEDIST_RandUnif_N(TREEDIST_NB_RAND_UNIF) / float(TREEDIST_NB_RAND_UNIF); } /** Class to check correctness of implemantion. Basically, the serice offered in @@ -710,7 +708,7 @@ void cOneBenchFastTreeDist::MakeOneTest(bool Show,bool CheckDist) std::vector> aVCC(mNbCC); // set of connected components for (int aK=0 ; aK aVR; for (int aK=0 ; aK cPtxd cTplBox::FromNorm // return Proj(aRes); } +template void cTplBox::Corners(tCorner & aRes) const +{ + for (size_t aKpt=0; aKpt<(1< cPtxd cTplBox::ToNormaliseCoord(const cPtxd & aP) const { @@ -592,6 +602,19 @@ cBox2dr operator * (const cBox2dr & aBox,double aScale) return cBox2dr(aBox.P0()*aScale,aBox.P1()*aScale); } +// x0,y1 x1,y1 +// x0,y0 x1,y0 + +template + void CornersTrigo(typename cTplBox::tCorner & aRes,const cTplBox& aBox) +{ + aRes[0] = cPtxd(aBox.P1().x(),aBox.P1().y()); + aRes[1] = cPtxd(aBox.P0().x(),aBox.P1().y()); + aRes[2] = cPtxd(aBox.P0().x(),aBox.P0().y()); + aRes[3] = cPtxd(aBox.P1().x(),aBox.P0().y()); +} + + /* ========================== */ @@ -657,6 +680,8 @@ template cPtxd Pt_round_ni(const cPtxd::tCorner & aRes,const cTplBox&); +template void CornersTrigo(typename cTplBox::tCorner & aRes,const cTplBox&); #define MACRO_INSTATIATE_PTXD(TYPE,DIM)\ template std::ostream & operator << (std::ostream & OS,const cPtxd &aP);\ diff --git a/MMVII/src/Mappings/MappingGen.cpp b/MMVII/src/Mappings/MappingGen.cpp index 079ac79548..9f5648d23f 100644 --- a/MMVII/src/Mappings/MappingGen.cpp +++ b/MMVII/src/Mappings/MappingGen.cpp @@ -3,6 +3,80 @@ namespace MMVII { +/* ============================================= */ +/* cDataBoundedSet */ +/* ============================================= */ + +template + cDataBoundedSet::cDataBoundedSet(const tBox & aBox) : + mBox(aBox) +{ +} + +template + bool cDataBoundedSet::InsideWithBox(const tPt & aPt) const +{ + return mBox.Inside(aPt); +} + +template + bool cDataBoundedSet::Inside(const tPt & aPt) const +{ + return true; +} + +template + const typename cDataBoundedSet::tBox & cDataBoundedSet::Box() const +{ + return mBox; +} + +template + void cDataBoundedSet::GridPointInsideAtStep(tVecPt& aRes,Type aStepMoy) const +{ + cPtxd aNb = Pt_round_up(mBox.Sz()/aStepMoy); + cPixBox aPixB (aNb+cPtxd::PCste(1)); + tPt aStep = DivCByC(mBox.Sz(),ToR(aNb)); + + for (const auto & aPix : aPixB) + { + tPt aPt = mBox.P0() + MulCByC(ToR(aPix),aStep); + if (Inside(aPt)) + aRes.push_back(aPt); + } +} + +template + void cDataBoundedSet::GridPointInsideOfNbPoints(tVecPt& aRes,int aNbPts) const +{ + Type aVolMoy = mBox.NbElem() / double(aNbPts); + Type aStepMoy = pow(aVolMoy,1/double(Dim)); + + GridPointInsideAtStep(aRes,aStepMoy); +} + +/* +template + cCalcMapLinearRoughIn(verse::cCalcMapLinearRoughInverse(const tSet & aSet,int aNbPts) : + mSet (aSet), + mBoxIm (aSet.Box()) +{ + Type aVolMoy = mBoxIm.NbElem() / double(aNbPts); + Type aStepMoy = pow(aVolMoy,1/double(Dim)); + tPtI aNb = Pt_round_up(mBoxIm.Sz()/aStepMoy); + cPixBox aPixB (aNb+tPtI::PCste(1)); + // tPt aStep = mBoxIm.Sz().DivCByC(aNb); + tPt aStep = DivCByC(mBoxIm.Sz(),ToR(aNb)); + + for (const auto & aPix : aPixB) + { + tPt aPtOut0 = mBoxIm.P0() + MulCByC(ToR(aPix),aStep); +FakeUseIt(aPtOut0); + } + +} +*/ + /* ============================================= */ /* cDataMapping */ @@ -232,6 +306,7 @@ template class cDataMapping;\ template class cMapping; #define INSTANCE_ONE_DIM_MAPPING(DIM)\ +template class cDataBoundedSet;\ template class cMappingIdentity;\ INSTANCE_TWO_DIM_MAPPING(DIM,2);\ INSTANCE_TWO_DIM_MAPPING(DIM,3); diff --git a/MMVII/src/Mappings/MappingSymDer.cpp b/MMVII/src/Mappings/MappingSymDer.cpp new file mode 100644 index 0000000000..8679522cf4 --- /dev/null +++ b/MMVII/src/Mappings/MappingSymDer.cpp @@ -0,0 +1,265 @@ +#include "include/MMVII_all.h" + +using namespace NS_SymbolicDerivative ; + + +namespace MMVII +{ + +/* ============================================= */ +/* cDataMapping */ +/* ============================================= */ + +template + class cDataMapCalcSymbDer : public cDataMapping +{ + public : + typedef cCalculator tCalc; + typedef cDataMapping tDataMap; + + using typename tDataMap::tVecIn; + using typename tDataMap::tVecOut; + using typename tDataMap::tCsteResVecJac; + using typename tDataMap::tResVecJac; + using typename tDataMap::tVecJac; + using typename tDataMap::tPtIn; + using typename tDataMap::tPtOut; +/* + typedef typename tDataMap::tVecIn tVecIn; + typedef typename tDataMap::tPtIn tPtIn; + typedef typename tDataMap::tPtOut tPtOut; + typedef typename tDataMap::tVecOut tVecOut; + typedef typename tDataMap::tCsteResVecJac tCsteResVecJac; + typedef typename tDataMap::tResVecJac tResVecJac; +*/ + + const tVecOut & Values(tVecOut &,const tVecIn & ) const override; //V2 + tCsteResVecJac Jacobian(tResVecJac,const tVecIn &) const override; //J2 + + cDataMapCalcSymbDer(tCalc * aCalcVal,tCalc * aCalcDer,const std::vector & aVObs); + void SetObs(const std::vector &); + + private : + void CheckDim(tCalc *,bool Derive); + tCalc * mCalcVal; + tCalc * mCalcDer; + std::vector mVObs; +}; + +template + void cDataMapCalcSymbDer::CheckDim(tCalc * aCalc,bool Derive) +{ + MMVII_INTERNAL_ASSERT_strong(DimIn==aCalc->NbUk(),"Input dim in calculator"); + MMVII_INTERNAL_ASSERT_strong(DimOut==aCalc->NbElem(),"Output dim in calculator"); + MMVII_INTERNAL_ASSERT_strong(aCalc->WithDer()==Derive,"Derive dim in calculator"); +} + +template + void cDataMapCalcSymbDer::SetObs(const std::vector & aVObs) +{ + mVObs = aVObs; +} + +template + cDataMapCalcSymbDer::cDataMapCalcSymbDer + ( + tCalc * aCalcVal, + tCalc * aCalcDer, + const std::vector & aVObs + ) : + mCalcVal (aCalcVal), + mCalcDer (aCalcDer), + mVObs (aVObs) +{ + CheckDim(mCalcVal,false); + CheckDim(mCalcDer,true); + // mCalcVal.NbUk() +} + + +template + const typename cDataMapCalcSymbDer::tVecOut & + cDataMapCalcSymbDer::Values(tVecOut & aRes,const tVecIn & aVecIn) const +{ + aRes.clear(); + std::vector aVUk(DimIn); + + MMVII_INTERNAL_ASSERT_strong(mCalcVal->NbInBuf()==0,"Buff not empty"); + tU_INT4 aSzBuf = mCalcVal->SzBuf(); + for (tU_INT4 aK0=0 ;aK0PushNewEvals(aVUk,mVObs); + } + mCalcVal->EvalAndClear(); + for (tU_INT4 aK=aK0 ; aKValComp(aK-aK0,aD); + } + aRes.push_back(aPRes); + } + } + return aRes; +} + +template + typename cDataMapCalcSymbDer::tCsteResVecJac + cDataMapCalcSymbDer::Jacobian(tResVecJac aRes,const tVecIn & aVecIn) const +{ + tVecOut * aVecOut=aRes.first; + tVecJac * aVecJac=aRes.second; + + std::vector aVUk(DimIn); + + MMVII_INTERNAL_ASSERT_strong(mCalcDer->NbInBuf()==0,"Buff not empty"); + tU_INT4 aSzBuf = mCalcDer->SzBuf(); + for (tU_INT4 aK0=0 ;aK0PushNewEvals(aVUk,mVObs); + } + + mCalcDer->EvalAndClear(); + for (tU_INT4 aK=aK0 ; aKValComp(aK-aK0,aDOut); + for (int aDIn=0 ; aDInDerComp(aK-aK0,aDOut,aDIn); + } + SetLine(aDOut,(*aVecJac)[aK],aLineJac); + // SetCol((*aVecJac)[aK],aDOut,aLineJac); + } + aVecOut->push_back(aPRes); + } + } + return tCsteResVecJac(aVecOut,aVecJac); +} + +template class cDataMapCalcSymbDer ; + // cDataIIMFromMap; + + +/* +template class cDataDistCloseId : cDataIterInvertMapping +{ + public : + cDataDistCloseId( + private : +}; +*/ + +bool BUGINVMAP =false; + +void TestJacob(cDataMapCalcSymbDer * aMCS,const cPt2dr & aP) +{ +double aEps= 1e-5; +// cPt2dr aP0 = aMCS->cDataMapping::Value(aP) ; +cPt2dr aPPx = aMCS->cDataMapping::Value(aP +cPt2dr(aEps,0.0)) ; +cPt2dr aPmx = aMCS->cDataMapping::Value(aP +cPt2dr(-aEps,0.0)) ; +cPt2dr aPPy = aMCS->cDataMapping::Value(aP +cPt2dr(0.0,aEps)) ; +cPt2dr aPmy = aMCS->cDataMapping::Value(aP +cPt2dr(0.0,-aEps)) ; + +double aRho = Norm2(aP); +StdOut() << " GX: " << (aPPx-aPmx)/(2*aEps) + << " GY: " << (aPPy-aPmy)/(2*aEps) + << " 7R6 " << 7 * pow(aRho,6) + << "\n"; +} + + +void BenchSymDerMap(cParamExeBench & aParam) +{ + cPt3di aDeg(3,1,1); + const std::vector & aVecD = DescDist(aDeg); + + for (int aKTest=0 ; aKTest<100 ; aKTest++) + { + cCalculator * anEqVal = EqDist(aDeg,false,1+RandUnif_N(50)); + cCalculator * anEqDer = EqDist(aDeg, true,1+RandUnif_N(50)); + int aNbPar = anEqVal->NbObs(); + std::vector aVParam(aNbPar,0.0); + + // Basic Test, with all param=0, distortion=identity + { + cDataMapCalcSymbDer aMCS(anEqVal,anEqDer,aVParam); + cPt2dr aP = cPt2dr::PRandC(); + cPt2dr aQ = aMCS.Value(aP); + MMVII_INTERNAL_ASSERT_bench(Norm2(aP-aQ)<1e-5,"Value in MCS"); + } + + // compute a distortion with random value + double aSomJac=0; + for (int aKPar=0 ; aKParNamesObs().at(aKPar) << " : " << aVParam[aKPar] << "\n"; + } + + // cDataMapCalcSymbDer aMCS(anEqVal,anEqDer,aVParam); + auto aMCS = new cDataMapCalcSymbDer(anEqVal,anEqDer,aVParam); + cMapping aMapCS(aMCS); + + auto aDId = new cMappingIdentity ; + cMapping aMapId(aDId); + + cDataIIMFromMap aIMap(aMapCS,aMapId,1e-6,5); + + int aNbPts = 1+RandUnif_N(100); + std::vector aVIn; + for (int aKPts=0 ; aKPts::Values(aVIn); + + + const std::vector & aVOut = aIMap.cDataInvertibleMapping::Inverses(aVIn); + double aMaxD=0.0; + double aMaxDisto=0.0; + for (int aKPts=0 ; aKPtscDataMapping::Value(aVOut[aKPts]) ; + aMaxD = std::max(aMaxD,Norm2(aDif)); + aMaxDisto = std::max(aMaxDisto,Norm2(aVIn[aKPts]-aVOut[aKPts])); + + // StdOut() << "Kp: " << aKPts << " PTS "<< aVIn[aKPts]<< " Dif " << aDif << "\n"; + // TestJacob(aMCS,aVOut[aKPts]); + + } + // StdOut() << "MOYD " << aMaxD << " " << aMaxDisto << "\n"; + MMVII_INTERNAL_ASSERT_bench(aMaxD<1e-5,"Distorsion inverse"); + // getchar(); + + // StdOut() << aP << aQ << aP - aQ << " NBPAR " << aNbPar << "\n"; + + delete anEqVal; + delete anEqDer; + } + +} + +}; diff --git a/MMVII/src/SymbDerGen/Formulas_CamStenope.cpp b/MMVII/src/SymbDerGen/Formulas_CamStenope.cpp new file mode 100644 index 0000000000..91580a3f59 --- /dev/null +++ b/MMVII/src/SymbDerGen/Formulas_CamStenope.cpp @@ -0,0 +1,104 @@ +#include "include/MMVII_all.h" +#include "include/SymbDer/SymbolicDerivatives.h" +#include "include/SymbDer/SymbDer_MACRO.h" + +using namespace NS_SymbolicDerivative; + + +namespace MMVII +{ + +cDescOneFuncDist::cDescOneFuncDist(eTypeFuncDist aType,const cPt2di aDegXY) : + mType (aType), + mDegMon (-1,-1), + mNum (-1) +{ + int aNum = aDegXY.x(); + if (mType==eTypeFuncDist::eRad) + { + mName = "K" + ToStr(aNum); // K1 K2 K3 ... + mDegTot = 1 + 2 * (aNum); // X (X^2+Y^2) ^N + mNum = aNum; + } + else if ((mType==eTypeFuncDist::eDecX) || (mType==eTypeFuncDist::eDecY)) + { + int aDec = (mType==eTypeFuncDist::eDecX)?-1:0; + // p1,p2 as usual, and by generalization p3 p4 p5 ... + mName = "p" + ToStr(2*aNum+aDec); + mDegTot = 2 * (aNum); // Derivates of X (X^2+Y^2) ^N + mNum = aNum; + } + else + { + mDegMon = aDegXY; + mDegTot = mDegMon.x() + mDegMon.y(); + if ((mType==eTypeFuncDist::eMonX) && (mDegTot==1)) + { + mName = ( mDegMon.x() == 1) ? "b1" : "b2"; // Usual convention + } + else + { + mName = std::string((mType==eTypeFuncDist::eMonX) ? "x" : "y") + + "_" + ToStr(mDegMon.x()) + + "_" + ToStr(mDegMon.y()) ; + } + } +} + +double cDescOneFuncDist::MajNormJacOfRho(double aRho) const +{ + switch(mType) + { + case eTypeFuncDist::eRad : + return mDegTot * powI(aRho,mDegTot-1); // Rho ^degT + case eTypeFuncDist::eDecX : + case eTypeFuncDist::eDecY : + return mDegTot*(mDegTot+1) * powI(aRho,mDegTot-1); // d/drho (Rho ^(degT+1)) + + case eTypeFuncDist::eMonX : + case eTypeFuncDist::eMonY : + return Norm2(mDegMon) * powI(aRho,mDegTot-1); // + default : + ; + } + + MMVII_INTERNAL_ERROR("Bad num in cDescOneFuncDist::MajNormJacOfRho"); + return 0.0; +} + +double MajNormJacOfRho + ( + const double & aRho, + const std::vector & aVDesc, + const std::vector & aVCoef + ) +{ + MMVII_INTERNAL_ASSERT_medium(aVDesc.size()==aVCoef.size(),"Sz in MajNormJacOfRho"); + double aRes =0.0; + + for (size_t aK=0 ; aK & aCenter, + const cTplBox & aBox, + const std::vector & aVDesc, + const std::vector & aVCoef + ) +{ + double aRes =0.0; + typename cTplBox::tCorner aTabC; +} +*/ + + + + +};// namespace MMVII + diff --git a/MMVII/src/SymbDerGen/Formulas_CamStenope.h b/MMVII/src/SymbDerGen/Formulas_CamStenope.h index e7e8959994..51fa1a7a61 100644 --- a/MMVII/src/SymbDerGen/Formulas_CamStenope.h +++ b/MMVII/src/SymbDerGen/Formulas_CamStenope.h @@ -203,42 +203,6 @@ namespace MMVII */ -cDescOneFuncDist::cDescOneFuncDist(eTypeFuncDist aType,const cPt2di aDegXY) : - mType (aType), - mDegMon (-1,-1), - mNum (-1) -{ - int aNum = aDegXY.x(); - if (mType==eTypeFuncDist::eRad) - { - mName = "K" + ToStr(aNum); // K1 K2 K3 ... - mDegTot = 1 + 2 * (aNum); // X (X^2+Y^2) ^N - mNum = aNum; - } - else if ((mType==eTypeFuncDist::eDecX) || (mType==eTypeFuncDist::eDecY)) - { - int aDec = (mType==eTypeFuncDist::eDecX)?-1:0; - // p1,p2 as usual, and by generalization p3 p4 p5 ... - mName = "p" + ToStr(2*aNum+aDec); - mDegTot = 2 * (aNum); // Derivates of X (X^2+Y^2) ^N - mNum = aNum; - } - else - { - mDegMon = aDegXY; - mDegTot = mDegMon.x() + mDegMon.y(); - if ((mType==eTypeFuncDist::eMonX) && (mDegTot==1)) - { - mName = ( mDegMon.x() == 1) ? "b1" : "b2"; // Usual convention - } - else - { - mName = std::string((mType==eTypeFuncDist::eMonX) ? "x" : "y") - + "_" + ToStr(mDegMon.x()) - + "_" + ToStr(mDegMon.y()) ; - } - } -} /** This class aims to be the universol model of distorsion in MicMac, it is templ */ diff --git a/MMVII/src/SymbDerGen/GenerateCodes.cpp b/MMVII/src/SymbDerGen/GenerateCodes.cpp index 8f0f501b38..d877d74244 100644 --- a/MMVII/src/SymbDerGen/GenerateCodes.cpp +++ b/MMVII/src/SymbDerGen/GenerateCodes.cpp @@ -23,21 +23,6 @@ std::string NameEqDist(const cPt3di & aDeg,bool WithDerive) } -/* -template class cFormulaMapping : public cMapping -{ - public : - /// Compute image in direct sens - tPtOut Direct(const tPtIn &) const override; - - /// Has it a diffenrentiable method : default false - bool HasValAndGrad() const override; - /// compute diffenrentiable method , default = erreur - std::pair ComputeValAndGrad(const tPtIn &) const override; - -}; -*/ - /* **************************** */ /* BENCH PART */ @@ -231,28 +216,6 @@ using namespace NS_GenerateCode; namespace MMVII { -double cDescOneFuncDist::MajNormJacOfRho(double aRho) const -{ - switch(mType) - { - case eTypeFuncDist::eRad : - return mDegTot * pow(aRho,mDegTot-1); - case eTypeFuncDist::eDecX : - case eTypeFuncDist::eDecY : - return mDegTot*(mDegTot+1) * pow(aRho,mDegTot-1); - - case eTypeFuncDist::eMonX : - case eTypeFuncDist::eMonY : - return Norm2(mDegMon) * pow(aRho,mDegTot-1); - default : - ; - } - - MMVII_INTERNAL_ERROR("Bad num in cDescOneFuncDist::MajNormJacOfRho"); - return 0.0; -} - - cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf) { return cName2Calc::CalcFromName(NameEqDist(aDeg,WithDerive),aSzBuf); From 67cc3b0f785a96023b702765c0c71a18b3b22ae7 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Mon, 26 Apr 2021 16:18:11 +0200 Subject: [PATCH 05/25] fix EditSet --- MMVII/Doc/Doc2007.tex | 19 +++++++++++++++++++ MMVII/Doc/Generalities/Intro.tex | 17 ++++++++++------- MMVII/src/Appli/cMMVII_CalcSet.cpp | 12 ++++++++++-- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/MMVII/Doc/Doc2007.tex b/MMVII/Doc/Doc2007.tex index 3a486396ac..57a3567849 100755 --- a/MMVII/Doc/Doc2007.tex +++ b/MMVII/Doc/Doc2007.tex @@ -44,6 +44,25 @@ \setcounter{secnumdepth}{4} +%allow to break on / in texttt +\usepackage{xparse} +\ExplSyntaxOn +\NewDocumentCommand{\replace}{mmm} + { + \marian_replace:nnn {#1} {#2} {#3} + } +\tl_new:N \l_marian_input_text_tl +\cs_new_protected:Npn \marian_replace:nnn #1 #2 #3 + { + \tl_set:Nn \l_marian_input_text_tl { #1 } + \tl_replace_all:Nnn \l_marian_input_text_tl { #2 } { #3 } + \tl_use:N \l_marian_input_text_tl + } +\ExplSyntaxOff +\let\OldTexttt\texttt +\renewcommand{\texttt}[1]{\OldTexttt{\replace{#1}{/}{/\allowbreak}}} +\let\Oldtt\tt +\renewcommand{\tt}[1]{\Oldtt{\replace{#1}{/}{/\allowbreak}}} %--------------------------------------------- \newcommand{\CPP}{\mbox{\tt C\hspace{-0.05cm}\raisebox{0.2ex}{\small ++} }} diff --git a/MMVII/Doc/Generalities/Intro.tex b/MMVII/Doc/Generalities/Intro.tex index 7d8e1537e9..f689eb2aa5 100755 --- a/MMVII/Doc/Generalities/Intro.tex +++ b/MMVII/Doc/Generalities/Intro.tex @@ -121,12 +121,15 @@ \subsection{Getting help} == Mandatory unnamed args : == * string [FDP] :: Full Name of Xml in/out - * string :: Operator in (+= *= -= = =0) - * string [MPI0] :: Pattern or Xml for modifying + * OpAff :: Operator + * string [MPF0] :: Pattern or Xml for modifying == Optional named args : == - * [Name=Show] int :: Show detail of set before/after , (def) 0->none, (1) modif, (2) all + * [Name=Show] int :: Show detail of set before/after, 0->none, (1) modif, (2) all ,[Default=0] * [Name=Out] string :: Destination, def=Input, no save for NONE + * [Name=FFI0] string [FFI0] :: File Filter Interval, Main Set + + \end{verbatim} We get three part : @@ -137,7 +140,7 @@ \subsection{Getting help} the entry point of the command is implemented (may be of interest to programmers); \item second part contains the description of mandatory args, we see that here we - have three mandatory args; for each args is indicated the type (here all strings), + have three mandatory args; for each args is indicated the type (string for the first), and after {\tt ::}, the semantic of the parameter; sometime it is inserted inside square bracket (like {\tt [FDP]}) some "predefined semantics" that will be described later (~\ref{Param:Pred:Sem}); @@ -218,7 +221,7 @@ \subsection{basic usage} As always when a regular expression is used to specify set of file, it is understood as a filter on existing file. So if one had used {\tt "F([0-3]|[a-z]).txt"}, -given the file present in {\tt {\MMVIDIR}MMVII-TestDir/Input/Files}, we woul have +given the file present in \texttt{{\MMVIDIR}MMVII-TestDir/Input/Files}, we would have obtained exactly the same result. \subsubsection{Exercices} @@ -239,7 +242,7 @@ \subsection{Optional paramaters} \subsubsection{{\tt Out} paramater} Optional parameter are given after the mandary one in a list of -string {\tt Name=Value}. For example until now we have use +string {\tt Name=Value}. For example until now we have used the file {\tt File.xml} both as input and output, but sometime we don't want to modify the input file, we can the use the optionnal {\tt Out} parameter. For example if we enter : @@ -249,7 +252,7 @@ \subsubsection{{\tt Out} paramater} MMVII EditSet File.xml += "F[7-9].txt" Out=File2.xml \end{verbatim} -After first line {\tt File.xml} contains t$4$ names. +After first line {\tt File.xml} contains $4$ names. After second line, the {\tt File.xml} is unchanged while {\tt File2.xml} contains $7$ names. diff --git a/MMVII/src/Appli/cMMVII_CalcSet.cpp b/MMVII/src/Appli/cMMVII_CalcSet.cpp index 30fc5f0c75..883bef3dd6 100644 --- a/MMVII/src/Appli/cMMVII_CalcSet.cpp +++ b/MMVII/src/Appli/cMMVII_CalcSet.cpp @@ -30,6 +30,7 @@ namespace MMVII - substract a new set (-=) - intersect a new set (*=) - overwrite with a new set (=) + - empty (=0) Most command take as input a set of file, single case can be pattern, but more complex require Xml file that can be edited. @@ -44,6 +45,8 @@ class cAppli_EditSet : public cMMVII_Appli cCollecSpecArg2007 & ArgOpt(cCollecSpecArg2007 & anArgOpt) override; ///< return spec of optional args cAppliBenchAnswer BenchAnswer() const override ; ///< Has it a bench, default : no int ExecuteBench(cParamExeBench &) override ; + protected : + bool AcceptEmptySet(int aK) const override; private : std::string mNameXmlIn; ///< Save Input file, generally in-out std::string mNameXmlOut; ///< Output file, when != Input @@ -57,6 +60,10 @@ cAppliBenchAnswer cAppli_EditSet::BenchAnswer() const return cAppliBenchAnswer(true,1e-5); } +bool cAppli_EditSet::AcceptEmptySet(int) const +{ + return (mOp==eOpAff::eReset); //accept empty set only if operator is =0 +} static void OneBenchEditSet ( @@ -194,7 +201,7 @@ cCollecSpecArg2007 & cAppli_EditSet::ArgOpt(cCollecSpecArg2007 & anArgOpt) { return anArgOpt - << AOpt2007(mShow,"Show","Show detail of set before/after , (def) 0->none, (1) modif, (2) all",{{eTA2007::HDV}}) + << AOpt2007(mShow,"Show","Show detail of set before/after, 0->none, (1) modif, (2) all",{{eTA2007::HDV}}) << AOpt2007(mNameXmlOut,"Out","Destination, def=Input, no save for " + MMVII_NONE,{}) ; } @@ -282,6 +289,7 @@ cSpecMMVII_Appli TheSpecEditSet - substract a new set (-=) - intersect a new set (*=) - overwrite with a new set (=) + - empty (=0) */ class cAppli_EditRel : public cMMVII_Appli { @@ -354,7 +362,7 @@ cCollecSpecArg2007 & cAppli_EditRel::ArgOpt(cCollecSpecArg2007 & anArgOpt) ; /* - // << AOpt2007(mShow,"Show","Show detail of set before/after , (def) 0->none, (1) modif, (2) all",{}) + // << AOpt2007(mShow,"Show","Show detail of set before/after, 0->none, (1) modif, (2) all",{}) << AOpt2007(mNameXmlOut,"Out","Destination, def=Input, no save for " + MMVII_NONE,{}); */ } From 2a5ff82e419168246466a00535b8f6b903e0de63 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Fri, 7 May 2021 14:43:34 +0200 Subject: [PATCH 06/25] update doxyfile --- MMVII/.gitignore | 5 + MMVII/Doxyfile | 240 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 175 insertions(+), 70 deletions(-) diff --git a/MMVII/.gitignore b/MMVII/.gitignore index 9a1e343264..10b286bc20 100644 --- a/MMVII/.gitignore +++ b/MMVII/.gitignore @@ -5,6 +5,8 @@ include/CodeGen_*.h *.log *.out *.toc +*.ilg +*.ind MMVII/MMVII-TestDir/Input/Files/RelTest.xml MMVII/MMVII-TestDir/Input/Files/RelTest_0-5.xml .*.d @@ -12,3 +14,6 @@ MMVII/MMVII-TestDir/Input/Files/RelTest_0-5.xml bin/* !bin/Makefile !bin/Mk-MMVII.makefile +html/ +latex/ +doxygen/ diff --git a/MMVII/Doxyfile b/MMVII/Doxyfile index e0a06a2fbe..3da356e8df 100644 --- a/MMVII/Doxyfile +++ b/MMVII/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.14 +# Doxyfile 1.8.17 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -17,10 +17,10 @@ # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "MMVII" +PROJECT_NAME = MMVII # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = +OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. @@ -189,6 +197,16 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -236,7 +254,12 @@ TAB_SIZE = 4 # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) ALIASES = @@ -274,17 +297,26 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # @@ -295,7 +327,7 @@ EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -307,7 +339,7 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 @@ -443,6 +475,12 @@ EXTRACT_ALL = NO EXTRACT_PRIVATE = YES +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -497,8 +535,8 @@ HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -521,7 +559,7 @@ INTERNAL_DOCS = NO # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. +# (including Cygwin) ands Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES @@ -753,7 +791,8 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. # The default value is: NO. WARN_NO_PARAMDOC = NO @@ -790,7 +829,12 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = src/ include/ src/Appli/ src/Bench/ src/Serial/ src/Utils/ +INPUT = src/ \ + include/ \ + src/Appli/ \ + src/Bench/ \ + src/Serial/ \ + src/Utils/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -812,8 +856,10 @@ INPUT_ENCODING = UTF-8 # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), +# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen +# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -873,7 +919,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -#EXCLUDE = include/MMVII_all.h +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -1011,7 +1057,7 @@ INLINE_SOURCES = YES STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -1048,7 +1094,7 @@ SOURCE_TOOLTIPS = YES # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1070,6 +1116,35 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files +# were built. This is equivalent to specifying the "-p" option to a clang tool, +# such as clang-check. These options will then be passed to the parser. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1226,9 +1301,9 @@ HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that -# are dynamically created via Javascript. If disabled, the navigation index will +# are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have Javascript, +# page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1258,13 +1333,13 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1303,7 +1378,7 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output @@ -1379,7 +1454,7 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). +# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1387,7 +1462,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). +# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1395,21 +1471,23 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). +# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = @@ -1513,8 +1591,14 @@ FORMULA_FONTSIZE = 10 FORMULA_TRANSPARENT = YES +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1542,7 +1626,7 @@ MATHJAX_FORMAT = HTML-CSS # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest @@ -1584,7 +1668,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1668,21 +1752,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1817,6 +1915,14 @@ LATEX_BIB_STYLE = plain LATEX_TIMESTAMP = NO +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1856,9 +1962,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1867,8 +1973,8 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = @@ -1954,6 +2060,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -2155,12 +2268,6 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -2172,16 +2279,7 @@ PERL_PATH = /usr/bin/perl # powerful graphs. # The default value is: YES. -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = +CLASS_DIAGRAMS = NO # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The @@ -2201,9 +2299,9 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: NO. +# The default value is: YES. -HAVE_DOT = NO +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed # to run in parallel. When set to 0 doxygen will base this on the number of @@ -2357,7 +2455,9 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, +# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and # png:gdiplus:gdiplus. # The default value is: png. From 948282c6b78241516824fc550e6845248739bf79 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Fri, 7 May 2021 14:45:46 +0200 Subject: [PATCH 07/25] mmv2 apipy: fix exceptions --- MMVII/apipy/Makefile_apipy_linux | 2 +- MMVII/apipy/api/api_mmv2.cpp | 1 + MMVII/apipy/ex/ex1.py | 69 +++++++++++++++++++------------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/MMVII/apipy/Makefile_apipy_linux b/MMVII/apipy/Makefile_apipy_linux index 26fc3508fd..39d95a727d 100644 --- a/MMVII/apipy/Makefile_apipy_linux +++ b/MMVII/apipy/Makefile_apipy_linux @@ -14,7 +14,7 @@ apipy: clean python3 setup.py bdist_wheel USEQT=$(USEQT) pip3 install --user dist/*.whl #python3 setup.py install --user USEQT=$(USEQT) - if python3 -c "import mmv2" ; then echo "APIPY OK" ; else echo "APIPY error! Use c++filt to demangle symbol." ; fi + @if python3 -c "import mmv2" ; then echo "APIPY OK" ; else echo "APIPY error! Use c++filt to demangle missing symbols." ; fi all: apipy doc diff --git a/MMVII/apipy/api/api_mmv2.cpp b/MMVII/apipy/api/api_mmv2.cpp index a4a76216b2..2bd929548f 100644 --- a/MMVII/apipy/api/api_mmv2.cpp +++ b/MMVII/apipy/api/api_mmv2.cpp @@ -16,6 +16,7 @@ static void ErrHanlderPy(const std::string & aType,const std::string & aMes,con MMVII::ErrOut() << "Mes=[" << aMes << "]\n"; if (aFile) MMVII::ErrOut() << "at line " << aLine << " of file " << aFile << "\n"; + throw std::runtime_error(aType + " " + aMes); } void mmv2_init() diff --git a/MMVII/apipy/ex/ex1.py b/MMVII/apipy/ex/ex1.py index 896d7626f4..8f2d1187c5 100644 --- a/MMVII/apipy/ex/ex1.py +++ b/MMVII/apipy/ex/ex1.py @@ -1,30 +1,45 @@ import mmv2 -startState = mmv2.cMemManager_CurState() -if (1): - im=mmv2.cIm2Du1.FromFile("ex/image.tif") #req template cIm2Du1 - #im.DIm().ToFile("ex/out.tif") #req template cDataIm2Du1 + +def checkMem(): + import sys + print("Nb objects created: ", mmv2.cMemManager_CurState().NbObjCreated()) + startState = mmv2.cMemManager_CurState() + def tmp(): + im=mmv2.cIm2Du1.FromFile("ex/image.tif") + tmp() print("Nb objects created: ", mmv2.cMemManager_CurState().NbObjCreated()) + mmv2.cMemManager_CheckRestoration(startState) + + b=mmv2.cIm2Du1.FromFile("ex/image.tif") + print("Nb objects created: ", mmv2.cMemManager_CurState().NbObjCreated()) + #del b + try: + mmv2.cMemManager_CheckRestoration(startState) + print("cMemManager_CheckRestoration OK") + except: + print("cMemManager_CheckRestoration failed") + print("Error: ",sys.exc_info()[0]) + +def createImage(): + aSz = mmv2.Pt2di(100,20) + aFileIm = mmv2.cDataFileIm2D_Create("ex/toto.tif",mmv2.eTyNums_eTN_U_INT1,aSz,1); + aIDup = mmv2.cIm2Du1(aSz) + aIDup.Write(aFileIm,mmv2.Pt2di(0,0)) + +def quickDezoom(): + im=mmv2.cIm2Du1.FromFile("ex/image.tif") #here image type must be exact + im2 = im.GaussDeZoom(3) + im2.DIm().ToFile("ex/out.tif") + +def imageScale(): + mScale = 2 + mDilate = 1.0 + aFileIn = mmv2.cDataFileIm2D_Create("ex/image.tif",True) + aImIn = mmv2.cIm2Dr4(aFileIn.Sz()) + aImIn.Read(aFileIn,mmv2.Pt2di(0,0)) + + aImOut = aImIn.GaussDeZoom(mScale,3,mDilate) + aFileOut = mmv2.cDataFileIm2D_Create("ex/out.tif",aFileIn.Type(),aImOut.DIm().Sz(),1) + aImOut.Write(aFileOut,mmv2.Pt2di(0,0)) + -mmv2.cMemManager_CheckRestoration(startState) -#del b -#mmv2.cMemManager_CheckRestoration(startState) - -aSz = mmv2.Pt2di(100,20) -aFileIm = mmv2.cDataFileIm2D_Create("ex/toto.tif",mmv2.eTyNums_eTN_U_INT1,aSz,1); -aIDup = mmv2.cIm2Du1(aSz) -aIDup.Write(aFileIm,mmv2.Pt2di(0,0)) - -im=mmv2.cIm2Du1.FromFile("ex/image.tif") #here image type must be exact -im2 = im.GaussDeZoom(3) -im2.DIm().ToFile("ex/out.tif") - -#ImageScale python remake -mScale = 2 -mDilate = 1.0 -aFileIn = mmv2.cDataFileIm2D_Create("ex/image.tif",True) -aImIn = mmv2.cIm2Dr4(aFileIn.Sz()) -aImIn.Read(aFileIn,mmv2.Pt2di(0,0)) - -aImOut = aImIn.GaussDeZoom(mScale,3,mDilate) -aFileOut = mmv2.cDataFileIm2D_Create("ex/out.tif",aFileIn.Type(),aImOut.DIm().Sz(),1) -aImOut.Write(aFileOut,mmv2.Pt2di(0,0)) From cd938d6d8f2df631dd0974d5d2fd7c0e7307db59 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Fri, 7 May 2021 14:46:36 +0200 Subject: [PATCH 08/25] mmv2 apipy: image data access --- MMVII/apipy/ex/ex1.py | 10 +++++ MMVII/apipy/mmv2.i | 101 ++++++++++++++++++++++++++++-------------- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/MMVII/apipy/ex/ex1.py b/MMVII/apipy/ex/ex1.py index 8f2d1187c5..45639a461d 100644 --- a/MMVII/apipy/ex/ex1.py +++ b/MMVII/apipy/ex/ex1.py @@ -42,4 +42,14 @@ def imageScale(): aFileOut = mmv2.cDataFileIm2D_Create("ex/out.tif",aFileIn.Type(),aImOut.DIm().Sz(),1) aImOut.Write(aFileOut,mmv2.Pt2di(0,0)) +def imgNumpyRawData(): + im=mmv2.cIm2Du1.FromFile("ex/image.tif") + d=im.DIm() + v=d.rawData() + from PIL import Image + import numpy as np + array = np.array(v, dtype=np.uint8) + array = array.reshape((d.SzY(), d.SzX())) + img = Image.fromarray(array) + img.show() diff --git a/MMVII/apipy/mmv2.i b/MMVII/apipy/mmv2.i index e73b109c7b..f81e80858b 100644 --- a/MMVII/apipy/mmv2.i +++ b/MMVII/apipy/mmv2.i @@ -19,7 +19,7 @@ %include %include %include -%include stl.i +%include @@ -79,34 +79,42 @@ %include "MMVII_Images.h" %include "MMVII_memory.h" -//templates have to be named to be exported -namespace MMVII { - %template(cIm2Du1) cIm2D; - %template(cIm2Dr4) cIm2D; - %template(cDataIm2Du1) cDataIm2D; - %template(cDataIm2Dr4) cDataIm2D; - //%template(cBox2di) cTplBox; - - //%template(Pt1dr) cPtxd ; - //%template(Pt1di) cPtxd ; - //%template(Pt1df) cPtxd ; - %template(Pt2dr) cPtxd ; - %template(Pt2di) cPtxd ; - //%template(Pt2df) cPtxd ; - %template(Pt3dr) cPtxd ; - //%template(Pt3di) cPtxd ; - //%template(Pt3df) cPtxd ; -} - -//used to make them usable as python lists -namespace std { - %template(IntVector) vector; - %template(DoubleVector) vector; - %template(FloatVector) vector; - %template(StringVector) vector; - -} +//HERE typedefs are mandatory. include MMVII_nums.h is not working... +typedef float tREAL4; +typedef double tREAL8; +typedef long double tREAL16; +typedef signed char tINT1; +typedef signed short tINT2; +typedef signed int tINT4; +typedef long int tINT8; +typedef unsigned char tU_INT1; +typedef unsigned short tU_INT2; +typedef unsigned int tU_INT4; +typedef int tStdInt; ///< "natural" int +typedef double tStdDouble; ///< "natural" int +//templates have to be named to be exported +%template(cIm2Du1) MMVII::cIm2D; +%template(cIm2Dr4) MMVII::cIm2D; +%template(cDataIm2Du1) MMVII::cDataIm2D; +%template(cDataIm2Dr4) MMVII::cDataIm2D; +//%template(cBox2di) MMVII::cTplBox; + +//%template(Pt1dr) MMVII::cPtxd ; +//%template(Pt1di) MMVII::cPtxd ; +//%template(Pt1df) MMVII::cPtxd ; +%template(Pt2dr) MMVII::cPtxd ; +%template(Pt2di) MMVII::cPtxd ; +//%template(Pt2df) MMVII::cPtxd ; +%template(Pt3dr) MMVII::cPtxd ; +//%template(Pt3di) MMVII::cPtxd ; +//%template(Pt3df) MMVII::cPtxd ; + +%template(tU_INT1Vector) std::vector; +%template(IntVector) std::vector; +%template(DoubleVector) std::vector; +%template(FloatVector) std::vector; +%template(StringVector) std::vector; //---------------------------------------------------------------------- //run on import @@ -121,24 +129,49 @@ mmv2_init(); %extend MMVII::cPtxd { char *__repr__() { static char tmp[1024]; - sprintf(tmp, "[%d, %d]", $self->x(), $self->y()); + sprintf(tmp, "Pt [%d, %d]", $self->x(), $self->y()); return tmp; } -}; +} %extend MMVII::cPtxd { char *__repr__() { static char tmp[1024]; - sprintf(tmp, "[%f, %f]", $self->x(), $self->y()); + sprintf(tmp, "Pt [%f, %f]", $self->x(), $self->y()); return tmp; } -}; +} %extend MMVII::cPtxd { char *__repr__() { static char tmp[1024]; - sprintf(tmp, "[%f, %f, %f]", $self->x(), $self->y(), $self->z()); + sprintf(tmp, "Pt [%f, %f, %f]", $self->x(), $self->y(), $self->z()); + return tmp; + } +} + +%extend MMVII::cIm2D { + char *__repr__() { + static char tmp[1024]; + sprintf(tmp, "Im2D [%d, %d]", $self->DIm().SzX(), $self->DIm().SzY()); return tmp; } -}; +} +%extend MMVII::cDataIm2D { + char *__repr__() { + static char tmp[1024]; + sprintf(tmp, "DataIm2D [%d, %d]", $self->SzX(), $self->SzY()); + return tmp; + } +} + +//must redefine virtual functions to access base class methods, when base class is abstract and template? +%extend MMVII::cDataIm2D { + std::vector rawData() { + int size = $self->SzX()*$self->SzY(); + tU_INT1* data = $self->cDataTypedIm::RawDataLin(); + std::vector out(data ,data + size); + return out; + } +} From 14446d65997a9970ed14f729a83b5193bb0a55c7 Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Fri, 7 May 2021 18:23:32 +0200 Subject: [PATCH 09/25] MMVII: Makefile add -fopenmp --- MMVII/bin/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MMVII/bin/Makefile b/MMVII/bin/Makefile index c777bf2b85..813f98e75c 100644 --- a/MMVII/bin/Makefile +++ b/MMVII/bin/Makefile @@ -22,8 +22,8 @@ EXT_LIBS=-lpthread -lX11 ${QT_LIBS} -lstdc++fs # =========== Compiler & Flags CXX=g++ LD=g++ -CXXFLAGS= -std=c++17 -Wall -Werror -O4 -fPIC -march=native ${MMV2_INCLUDES} ${MMV1_INCLUDES} -LDFLAGS= +CXXFLAGS=-fopenmp -std=c++17 -Wall -Werror -O4 -fPIC ${MMV2_INCLUDES} ${MMV1_INCLUDES} +LDFLAGS=-fopenmp # =========== Use ccache if found From 0b294b1e283c94f4dfee4db3e8e6a4f0b60745ce Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Fri, 7 May 2021 18:04:49 +0200 Subject: [PATCH 10/25] MMVII: Mk-MMVII.makefile: use libP2007.a instead of P2007.a --- MMVII/bin/Mk-MMVII.makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MMVII/bin/Mk-MMVII.makefile b/MMVII/bin/Mk-MMVII.makefile index 256a8b9300..4e7917884e 100644 --- a/MMVII/bin/Mk-MMVII.makefile +++ b/MMVII/bin/Mk-MMVII.makefile @@ -168,8 +168,8 @@ LibsFlags= ${MMV2ElisePath} -lX11 ${BOOST_LIBS} ${QTAnnLibs} -lstdc++fs # ${MMV2DirBin}${MMV2Exe} : ${OBJ} ${MAIN} ${MMV2ResultInstal} ${MMV2ElisePath} ${CXX} ${MAIN} ${CFlags} ${OBJ} ${LibsFlags} -o ${MMV2DirBin}${MMV2Exe} - rm -f P2007.a - ar rvs P2007.a ${OBJ} + rm -f libP2007.a + ar rvs libP2007.a ${OBJ} # # ========== INSTALLATION ================= # From 9e1512896dddb564162e5ba86e34c75c13fd1a09 Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Fri, 7 May 2021 18:09:01 +0200 Subject: [PATCH 11/25] MMVII: Remove unused Test4MkFile/ --- MMVII/src/Test4Mkfile/Info.txt | 2 -- MMVII/src/Test4Mkfile/TestCompile.cpp | 28 --------------------------- MMVII/src/Test4Mkfile/TestMkf1.cpp | 2 -- 3 files changed, 32 deletions(-) delete mode 100644 MMVII/src/Test4Mkfile/Info.txt delete mode 100644 MMVII/src/Test4Mkfile/TestCompile.cpp delete mode 100644 MMVII/src/Test4Mkfile/TestMkf1.cpp diff --git a/MMVII/src/Test4Mkfile/Info.txt b/MMVII/src/Test4Mkfile/Info.txt deleted file mode 100644 index a8429695a9..0000000000 --- a/MMVII/src/Test4Mkfile/Info.txt +++ /dev/null @@ -1,2 +0,0 @@ -Ce dossier sert a tester le makefile - diff --git a/MMVII/src/Test4Mkfile/TestCompile.cpp b/MMVII/src/Test4Mkfile/TestCompile.cpp deleted file mode 100644 index 296919d525..0000000000 --- a/MMVII/src/Test4Mkfile/TestCompile.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "include/MMVII_all.h" - - -/* -class cTestUnikPtr; -extern cTestUnikPtr * AllocUnikPtr(); - -void DeleteUnikPtr(cTestUnikPtr *); -typedef void (*tDeleteUnikPtr)(cTestUnikPtr *); - -void TestCompile() -{ - // std::unique_ptr aP (AllocUnikPtr(),DeleteUnikPtr); - std::unique_ptr aP (AllocUnikPtr(),DeleteUnikPtr); -} -*/ - -/* -class cTestUnikPtr -{ - public : - virtual ~cTestUnikPtr() ; -} virtual void F() = 0; -*/ - - - - diff --git a/MMVII/src/Test4Mkfile/TestMkf1.cpp b/MMVII/src/Test4Mkfile/TestMkf1.cpp deleted file mode 100644 index 00f8dfb52d..0000000000 --- a/MMVII/src/Test4Mkfile/TestMkf1.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "include/MMVII_all.h" - From dde685e79c7c6e4d9723f1653d0c42e6958a7db0 Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Fri, 7 May 2021 18:12:20 +0200 Subject: [PATCH 12/25] MMVII: simplify initialization of binary install path in main.cpp --- MMVII/bin/Makefile | 9 +-------- MMVII/bin/Mk-MMVII.makefile | 23 +++++------------------ MMVII/src/main.cpp | 5 ++++- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/MMVII/bin/Makefile b/MMVII/bin/Makefile index 813f98e75c..30d988ade6 100644 --- a/MMVII/bin/Makefile +++ b/MMVII/bin/Makefile @@ -22,7 +22,7 @@ EXT_LIBS=-lpthread -lX11 ${QT_LIBS} -lstdc++fs # =========== Compiler & Flags CXX=g++ LD=g++ -CXXFLAGS=-fopenmp -std=c++17 -Wall -Werror -O4 -fPIC ${MMV2_INCLUDES} ${MMV1_INCLUDES} +CXXFLAGS=-fopenmp -std=c++17 -Wall -Werror -O4 -fPIC -march=native ${MMV2_INCLUDES} ${MMV1_INCLUDES} -D'MMVII_INSTALL_PATH="${MMV2_INSTALL_PATH}"' LDFLAGS=-fopenmp @@ -56,13 +56,6 @@ ${MMV2_LIB}: ${LIB_OBJS} # ========== Build Main MAIN_OBJ=${MMV2_SRCDIR}/main.o -MMV2_RESULT_INSTALL=${MMV2_SRCDIR}/ResultInstall/ResultInstall.cpp - -${MMV2_RESULT_INSTALL}: - mkdir -p ${dir ${MMV2_RESULT_INSTALL}} - echo '#include \nnamespace MMVII {\nconst std::string DirBin2007="${MMV2_INSTALL_PATH}";\n};\n' > ${MMV2_RESULT_INSTALL} - -${MAIN_OBJ}: ${MMV2_RESULT_INSTALL} ${MMV2_EXE}: ${MAIN_OBJ} ${MMV2_LIB} ${MMV1_LIBS} ${CXX} ${LDFLAGS} $^ ${EXT_LIBS} -o $@ diff --git a/MMVII/bin/Mk-MMVII.makefile b/MMVII/bin/Mk-MMVII.makefile index 4e7917884e..67d30ab89e 100644 --- a/MMVII/bin/Mk-MMVII.makefile +++ b/MMVII/bin/Mk-MMVII.makefile @@ -9,20 +9,13 @@ MMV2Objects=${MMV2Dir}object/ MMV2DirIncl=${MMV2Dir}include/ MMV2ElisePath=${MMDir}/lib/libelise.a MMV2Exe=MMVII +MMV2_INSTALL_PATH=${abspath ${MMV2DirBin}} MMSymbDerHeader=$(wildcard ${MMV2DirIncl}/SymbDer/*.h) MMKaptureHeader=$(wildcard ${MMV2Dir}/kapture/*.h) all : ${MMV2DirBin}${MMV2Exe} -# -# -# ===== INSTALLATION ======================================== -# => for setting MMVII directory -# -MMV2ResultInstal=${MMV2DirSrc}ResultInstall/ResultInstall.cpp -MMV2SrcInstal=${MMV2DirSrc}BinaireInstall/InstalMM.cpp -MMV2BinInstal=../Instal2007 # #=========== Sous directory des sources # @@ -160,25 +153,19 @@ HEADER=$(wildcard ${MMV2DirIncl}*.h) #== CFLAGS etc... # CXX=g++ -CFlags= "-fopenmp" "-std=c++17" "-Wall" "-Werror" "-O4" "-march=native" "-fPIC" -I${MMV2Dir} -I${MMV2Dir}/ExternalInclude -I${MMDir}/include/ -I${MMDir} +CFlags= "-fopenmp" "-std=c++17" "-Wall" "-Werror" "-O4" "-march=native" "-fPIC" -I${MMV2Dir} -I${MMV2Dir}/ExternalInclude -I${MMDir}/include/ -I${MMDir} -D'MMVII_INSTALL_PATH="${MMV2_INSTALL_PATH}"' + + BOOST_LIBS= QTAnnLibs= -lXext /usr/lib/x86_64-linux-gnu/libQt5Core.so /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Xml.so /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so -lGLU -lGL -ldl -lpthread /usr/lib/x86_64-linux-gnu/libQt5Xml.so /usr/lib/x86_64-linux-gnu/libQt5Concurrent.so /usr/lib/x86_64-linux-gnu/libQt5OpenGL.so /usr/lib/x86_64-linux-gnu/libQt5Widgets.so /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Core.so ../../lib/libANN.a ## MacOS : may be -lstdc++fs should be replaced by -lc++experimental LibsFlags= ${MMV2ElisePath} -lX11 ${BOOST_LIBS} ${QTAnnLibs} -lstdc++fs # -${MMV2DirBin}${MMV2Exe} : ${OBJ} ${MAIN} ${MMV2ResultInstal} ${MMV2ElisePath} +${MMV2DirBin}${MMV2Exe} : ${OBJ} ${MAIN} ${MMV2ElisePath} ${CXX} ${MAIN} ${CFlags} ${OBJ} ${LibsFlags} -o ${MMV2DirBin}${MMV2Exe} rm -f libP2007.a ar rvs libP2007.a ${OBJ} # -# ========== INSTALLATION ================= -# -${MMV2ResultInstal} : ${MMV2SrcInstal} - ${CXX} -std=c++17 ${MMV2SrcInstal} -o ${MMV2BinInstal} - mkdir -p `dirname ${MMV2ResultInstal}` - ${MMV2BinInstal} - rm ${MMV2BinInstal} -# # ================ Objects ================== # ${MMV2DirMatchTieP}%.o : ${MMV2DirMatchTieP}%.cpp ${HEADER} diff --git a/MMVII/src/main.cpp b/MMVII/src/main.cpp index 19639a286c..8c839248f3 100644 --- a/MMVII/src/main.cpp +++ b/MMVII/src/main.cpp @@ -1,6 +1,9 @@ #include "../include/MMVII_all.h" -#include "ResultInstall/ResultInstall.cpp" +namespace MMVII { + const std::string DirBin2007=MMVII_INSTALL_PATH; +}; + using namespace MMVII; From 7dc1758add1a46b4bfffcc4b849d265f36ec9ebc Mon Sep 17 00:00:00 2001 From: ewelina rupnik Date: Mon, 10 May 2021 09:50:34 +0200 Subject: [PATCH 13/25] Update readme add Windows WSL setup --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3bae6e77c8..afd1ca876c 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,10 @@ or build your own image from scratch using the existing Dockerfile: [![Docker Status](https://dockeri.co/image/rupnike/micmac)](https://hub.docker.com/r/rupnike/micmac/) +## Install MicMac in WinOS subsystem + +You can also use MicMac on Windows 10 through the Windows Subsystem for Linux (WSL). WSL allows you to run a Linux distribution (e.g. Ubuntu) directly on Windows, unmodified, without the overhead of a traditional virtual machine or dualboot setup. For further information please refer to the instructions in this [WSL tutorial](https://micmac.ensg.eu/index.php/Install_MicMac_in_Windows_Subsystem_for_Linux). + # Installation test The website [logiciels.ign.fr](http://logiciels.ign.fr/?Telechargement,20) also provides a test dataset called `Boudha_dataset.zip`. From 51c593ac2169078bf65fe871e85ffd2fd9317fe3 Mon Sep 17 00:00:00 2001 From: deseilligny Date: Mon, 10 May 2021 15:41:12 +0200 Subject: [PATCH 14/25] Avant de m'y remettre ... --- MMVII/include/MMVII_Geom2D.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/MMVII/include/MMVII_Geom2D.h b/MMVII/include/MMVII_Geom2D.h index 53c181e48e..33a1a14f28 100644 --- a/MMVII/include/MMVII_Geom2D.h +++ b/MMVII/include/MMVII_Geom2D.h @@ -48,6 +48,32 @@ template inline cPtxd PSymXY (const cPtxd & aP) return cPtxd(aP.y(),aP.x()); } +/** This class represent 2D Homotetie , it can aussi be used for an non + distorted camera with : + * mTr -> principal point + * mSc -> focale +*/ + +template class cHomot2D +{ + public : + static constexpr int TheDim=2; + typedef Type TheType; + typedef cPtxd tPt; + + static const int NbDOF() {return 3;} + cHomot2D(const tPt & aTr,const Type & aSc) : + mTr (aTr), + mSc (aSc) + { + } + inline tPt Value(const tPt & aP) const {return mTr + aP * mSc;} + inline tPt Inverse(const tPt & aP) const {return (aP-mTr)/mSc ;} + cHomot2D MapInverse() const {return cHomot2D(-mTr/mSc,1.0/mSc);} + private : + tPt mTr; + Type mSc; +}; template class cSim2D { From c499566700ed3d526fcc1ca1045cdc3e34b13233 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Mon, 10 May 2021 15:33:00 +0200 Subject: [PATCH 15/25] MMVII apipy: typemaps --- MMVII/apipy/.gitignore | 1 + MMVII/apipy/Makefile_apipy_linux | 7 ++- MMVII/apipy/gen_typemaps.py | 82 ++++++++++++++++++++++++++++++++ MMVII/apipy/mmv2.i | 6 ++- MMVII/apipy/setup.py | 2 +- 5 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 MMVII/apipy/gen_typemaps.py diff --git a/MMVII/apipy/.gitignore b/MMVII/apipy/.gitignore index a879d58958..e35a63aefb 100644 --- a/MMVII/apipy/.gitignore +++ b/MMVII/apipy/.gitignore @@ -6,3 +6,4 @@ __pycache__/ .eggs/ dist/ mmv2.egg-info/ +typemaps.i diff --git a/MMVII/apipy/Makefile_apipy_linux b/MMVII/apipy/Makefile_apipy_linux index 39d95a727d..dc3a8638a9 100644 --- a/MMVII/apipy/Makefile_apipy_linux +++ b/MMVII/apipy/Makefile_apipy_linux @@ -9,7 +9,7 @@ WRAP_O_FILES = $(I_SRCS:.i=_wrap.o) .PHONY: clean doc apipy -apipy: clean +apipy: clean typemaps.i python3 setup.py build python3 setup.py bdist_wheel USEQT=$(USEQT) pip3 install --user dist/*.whl @@ -18,11 +18,14 @@ apipy: clean all: apipy doc +typemaps.i: + python3 gen_typemaps.py > typemaps.i + doc: cd $(DOCDIR) && doxygen clean: - rm -f $(PY_FILES) $(WRAP_CXX_FILES) $(WRAP_O_FILES) + rm -f $(PY_FILES) $(WRAP_CXX_FILES) $(WRAP_O_FILES) typemaps.i rm -Rf $(DOCDIR)/html build/ dist/ mmv2.egg-info/ __pycache__/ python3 setup.py clean pip3 uninstall -y $(MODULE_NAME) diff --git a/MMVII/apipy/gen_typemaps.py b/MMVII/apipy/gen_typemaps.py new file mode 100644 index 0000000000..4455b24cb4 --- /dev/null +++ b/MMVII/apipy/gen_typemaps.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +dimNames = ['x', 'y', 'z'] +debug = False + +def write_typemap_point(cName, swigType, nDim, isConstRef) : + + refStr='' + constStr='' + if isConstRef: + refStr=' & ' + constStr=' const ' + print('//--------------------------------------------------------') + print('//Typemap '+constStr+' '+cName+' '+refStr) + print() + print('//typecheck to allow overloaded functions or default values') + print('//see http://www.swig.org/Doc1.3/Typemaps.html#Typemaps_nn27') + print('%typemap(typecheck,precedence=SWIG_TYPECHECK_BOOL) '+constStr+' '+cName+' '+refStr+' {') + print(' //test if '+cName); + print(' int res = SWIG_CheckState(SWIG_ConvertPtr($input, 0, '+swigType+', SWIG_POINTER_NO_NULL | 0));') + print(' if (!res) //test if sequence') + print(' res = (PySequence_Check($input)) && (PyObject_Length($input) == '+str(nDim)+');') + print(' $1 = res;') + print('}') + print() + print('//convert py seq of 2 scalars into '+cName) + print('%typemap(in) '+constStr+' '+cName+' '+refStr+' ('+cName+' pt){') + if debug: + print(' printf("In typemap '+constStr+' '+cName+' '+refStr+'\\n");') + print(' if (!PySequence_Check($input)) { //not a seq: must be a '+cName) + print(' PyObject *args = $input;') + print(' void *argp1 ;') + print(' int res1 = 0 ;') + print(' res1 = SWIG_ConvertPtr(args, &argp1, '+swigType+', 0 | 0);') + print(' if (!SWIG_IsOK(res1)) {') + print(' SWIG_exception_fail(SWIG_ArgError(res1), " impossible to convert argument into '+cName+'"); ') + print(' }') + print(' if (!argp1) {') + print(' SWIG_exception_fail(SWIG_ValueError, "invalid null reference type '+cName+'");') + print(' } else {') + if isConstRef: + print(' $1 = reinterpret_cast< '+cName+' * >(argp1);') + else: + print(' Pt2d * temp = reinterpret_cast< Pt2d * >(argp1);') + print(' pt = *temp;') + print(' if (SWIG_IsNewObj(res1)) delete temp;') + print(' $1 = pt;') + print(' }') + print(' }else{ //convert sequence into '+cName+'') + print(' if (PyObject_Length($input) != '+str(nDim)+') {') + print(' PyErr_SetString(PyExc_ValueError,"Expecting a sequence with '+str(nDim)+' elements");') + print(' return NULL;') + print(' }') + print(' double temp['+str(nDim)+'];') + print(' int i;') + print(' for (i =0; i < '+str(nDim)+'; i++) {') + print(' PyObject *o = PySequence_GetItem($input,i);') + print(' if (PyFloat_Check(o)) {') + print(' temp[i] = PyFloat_AsDouble(o);') + print(' }else if (PyLong_Check(o)) {') + print(' temp[i] = PyLong_AsDouble(o);') + print(' }else{') + print(' Py_XDECREF(o);') + print(' PyErr_SetString(PyExc_ValueError,"Expecting a sequence of scalars");') + print(' return NULL;') + print(' }') + print(' temp[i] = PyFloat_AsDouble(o);') + print(' Py_DECREF(o);') + print(' }') + for i in range(nDim): + print(' pt.'+dimNames[i]+'() = temp['+str(i)+'];') + print(' $1 = '+refStr+'pt;') + print(' }') + print('};') + print() + +write_typemap_point('MMVII::cPt2di', 'SWIGTYPE_p_MMVII__cPtxdT_int_2_t', 2, False) +write_typemap_point('MMVII::cPt2di', 'SWIGTYPE_p_MMVII__cPtxdT_int_2_t', 2, True) +write_typemap_point('MMVII::cPt2dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_2_t', 2, False) +write_typemap_point('MMVII::cPt2dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_2_t', 2, True) +write_typemap_point('MMVII::cPt3dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_3_t', 3, False) +write_typemap_point('MMVII::cPt3dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_3_t', 3, True) diff --git a/MMVII/apipy/mmv2.i b/MMVII/apipy/mmv2.i index f81e80858b..7ec93e1b18 100644 --- a/MMVII/apipy/mmv2.i +++ b/MMVII/apipy/mmv2.i @@ -45,6 +45,11 @@ } } +//---------------------------------------------------------------------- +//add typemaps +%include typemaps.i + + //---------------------------------------------------------------------- //things to ignore in next includes to be able to compile //must ignore forbidden cPtxd methods according to dim @@ -174,4 +179,3 @@ mmv2_init(); } } - diff --git a/MMVII/apipy/setup.py b/MMVII/apipy/setup.py index e15bf07211..6d2f6d0e4b 100644 --- a/MMVII/apipy/setup.py +++ b/MMVII/apipy/setup.py @@ -30,7 +30,7 @@ swig_opts=['-python', '-py3', '-DFORSWIG', '-Wall', '-c++', '-I.','-I../include/'], libraries = ['X11', 'Xext', 'm', 'dl', 'pthread', 'stdc++fs', 'gomp']+libs, library_dirs = [], - include_dirs = ['/usr/local/include', '.', '../include/', '../ExternalInclude/'], + include_dirs = ['/usr/local/include', '.', '..', '../include/', '../ExternalInclude/'], language = 'c++', extra_objects = ['../bin/libP2007.a', '../../lib/libelise.a', '../../lib/libANN.a'], extra_compile_args = ['-std=c++17', '-fopenmp'] From b98094b2ea9ba4cf2cc9645ed9af09acb813c661 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Mon, 10 May 2021 17:49:33 +0200 Subject: [PATCH 16/25] MMVII apipy: fix some warnings --- MMVII/apipy/mmv2.i | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/MMVII/apipy/mmv2.i b/MMVII/apipy/mmv2.i index 7ec93e1b18..61aa2f9b3e 100644 --- a/MMVII/apipy/mmv2.i +++ b/MMVII/apipy/mmv2.i @@ -24,7 +24,7 @@ //---------------------------------------------------------------------- -//rename overloaded methods to avoid shadowing + //Reserved names in python3 %rename(_True) FBool::True; @@ -74,6 +74,38 @@ %ignore MMVII::cPtxd::ToStdVector; %ignore MMVII::cPtxd::FromVect; %ignore MMVII::cPtxd::FromStdVector; +//ignore const overloading +%ignore MMVII::cPtxd::x() const; +%ignore MMVII::cPtxd::y() const; +%ignore MMVII::cPtxd::PtRawData() const; +%ignore MMVII::cPtxd::x() const; +%ignore MMVII::cPtxd::y() const; +%ignore MMVII::cPtxd::PtRawData() const; +%ignore MMVII::cPtxd::x() const; +%ignore MMVII::cPtxd::y() const; +%ignore MMVII::cPtxd::z() const; +%ignore MMVII::cPtxd::PtRawData() const; + +%ignore MMVII::cIm2D::DIm() const; +%ignore MMVII::cIm2D::DIm() const; +%ignore MMVII::cDataIm2D::ExtractRawData2D() const; +%ignore MMVII::cDataIm2D::GetLine(int) const; +%ignore MMVII::cDataIm2D::ExtractRawData2D() const; +%ignore MMVII::cDataIm2D::GetLine(int) const; +//remove warnings + +//rename overloaded methods to avoid shadowing +//here params must appread exactly as in source (no MMVII::...) +%rename(ToI2) ToI(const cPt2dr &); +%rename(ToI3) ToI(const cPt3dr &); +%rename(E2Str_TySC) MMVII::E2Str(const eTySC &); +%rename(E2Str_OpAff) MMVII::E2Str(const eOpAff &); +%rename(E2Str_TA2007) MMVII::E2Str(const eTA2007 &); +%rename(E2Str_TyUEr) MMVII::E2Str(const eTyUEr &); +%rename(E2Str_TyNums) MMVII::E2Str(const eTyNums &); +%rename(E2Str_TyInvRad) MMVII::E2Str(const eTyInvRad &); +%rename(E2Str_TyPyrTieP) MMVII::E2Str(const eTyPyrTieP &); +%rename(E2Str_ModeEpipMatch) MMVII::E2Str(const eModeEpipMatch &); //---------------------------------------------------------------------- //classes to export @@ -121,6 +153,7 @@ typedef double tStdDouble; ///< "natural" int %template(FloatVector) std::vector; %template(StringVector) std::vector; + //---------------------------------------------------------------------- //run on import %pythoncode %{ @@ -173,7 +206,7 @@ mmv2_init(); %extend MMVII::cDataIm2D { std::vector rawData() { int size = $self->SzX()*$self->SzY(); - tU_INT1* data = $self->cDataTypedIm::RawDataLin(); + tU_INT1* data = $self->RawDataLin(); std::vector out(data ,data + size); return out; } From 13d3d23bd9905de764df331c65cac09ff30ca6f0 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Tue, 11 May 2021 11:27:25 +0200 Subject: [PATCH 17/25] MMVII apipy: add cPt3di --- MMVII/apipy/ex/ex1.py | 6 +++--- MMVII/apipy/gen_typemaps.py | 2 ++ MMVII/apipy/mmv2.i | 28 ++++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/MMVII/apipy/ex/ex1.py b/MMVII/apipy/ex/ex1.py index 45639a461d..a8b050ce63 100644 --- a/MMVII/apipy/ex/ex1.py +++ b/MMVII/apipy/ex/ex1.py @@ -24,7 +24,7 @@ def createImage(): aSz = mmv2.Pt2di(100,20) aFileIm = mmv2.cDataFileIm2D_Create("ex/toto.tif",mmv2.eTyNums_eTN_U_INT1,aSz,1); aIDup = mmv2.cIm2Du1(aSz) - aIDup.Write(aFileIm,mmv2.Pt2di(0,0)) + aIDup.Write(aFileIm,(0,0)) #points params can be given as sequences def quickDezoom(): im=mmv2.cIm2Du1.FromFile("ex/image.tif") #here image type must be exact @@ -36,11 +36,11 @@ def imageScale(): mDilate = 1.0 aFileIn = mmv2.cDataFileIm2D_Create("ex/image.tif",True) aImIn = mmv2.cIm2Dr4(aFileIn.Sz()) - aImIn.Read(aFileIn,mmv2.Pt2di(0,0)) + aImIn.Read(aFileIn,(0,0)) aImOut = aImIn.GaussDeZoom(mScale,3,mDilate) aFileOut = mmv2.cDataFileIm2D_Create("ex/out.tif",aFileIn.Type(),aImOut.DIm().Sz(),1) - aImOut.Write(aFileOut,mmv2.Pt2di(0,0)) + aImOut.Write(aFileOut,(0,0)) def imgNumpyRawData(): im=mmv2.cIm2Du1.FromFile("ex/image.tif") diff --git a/MMVII/apipy/gen_typemaps.py b/MMVII/apipy/gen_typemaps.py index 4455b24cb4..ab7d6e070e 100644 --- a/MMVII/apipy/gen_typemaps.py +++ b/MMVII/apipy/gen_typemaps.py @@ -78,5 +78,7 @@ def write_typemap_point(cName, swigType, nDim, isConstRef) : write_typemap_point('MMVII::cPt2di', 'SWIGTYPE_p_MMVII__cPtxdT_int_2_t', 2, True) write_typemap_point('MMVII::cPt2dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_2_t', 2, False) write_typemap_point('MMVII::cPt2dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_2_t', 2, True) +write_typemap_point('MMVII::cPt3di', 'SWIGTYPE_p_MMVII__cPtxdT_int_3_t', 3, False) +write_typemap_point('MMVII::cPt3di', 'SWIGTYPE_p_MMVII__cPtxdT_int_3_t', 3, True) write_typemap_point('MMVII::cPt3dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_3_t', 3, False) write_typemap_point('MMVII::cPt3dr', 'SWIGTYPE_p_MMVII__cPtxdT_double_3_t', 3, True) diff --git a/MMVII/apipy/mmv2.i b/MMVII/apipy/mmv2.i index 61aa2f9b3e..218ae1b577 100644 --- a/MMVII/apipy/mmv2.i +++ b/MMVII/apipy/mmv2.i @@ -67,13 +67,23 @@ %ignore MMVII::cPtxd::cPtxd(const double & x,const double &y); %ignore MMVII::cPtxd::cPtxd(const double & x,const double &y,const double &z,const double &t); %ignore MMVII::cPtxd::t; +%ignore MMVII::cPtxd::cPtxd(const int & x); +%ignore MMVII::cPtxd::cPtxd(const int & x,const int &y); +%ignore MMVII::cPtxd::cPtxd(const int & x,const int &y,const int &z,const int &t); +%ignore MMVII::cPtxd::t; //not implemented %ignore MMVII::cPtxd::Col; %ignore MMVII::cPtxd::Line; %ignore MMVII::cPtxd::ToVect; %ignore MMVII::cPtxd::ToStdVector; +%ignore MMVII::cPtxd::ToStdVector; +%ignore MMVII::cPtxd::ToStdVector; +%ignore MMVII::cPtxd::ToStdVector; %ignore MMVII::cPtxd::FromVect; %ignore MMVII::cPtxd::FromStdVector; +%ignore MMVII::cPtxd::FromStdVector; +%ignore MMVII::cPtxd::FromStdVector; +%ignore MMVII::cPtxd::FromStdVector; //ignore const overloading %ignore MMVII::cPtxd::x() const; %ignore MMVII::cPtxd::y() const; @@ -85,6 +95,10 @@ %ignore MMVII::cPtxd::y() const; %ignore MMVII::cPtxd::z() const; %ignore MMVII::cPtxd::PtRawData() const; +%ignore MMVII::cPtxd::x() const; +%ignore MMVII::cPtxd::y() const; +%ignore MMVII::cPtxd::z() const; +%ignore MMVII::cPtxd::PtRawData() const; %ignore MMVII::cIm2D::DIm() const; %ignore MMVII::cIm2D::DIm() const; @@ -98,6 +112,8 @@ //here params must appread exactly as in source (no MMVII::...) %rename(ToI2) ToI(const cPt2dr &); %rename(ToI3) ToI(const cPt3dr &); +%rename(ToR2) ToR(const cPt2di &); +%rename(ToR3) ToR(const cPt3di &); %rename(E2Str_TySC) MMVII::E2Str(const eTySC &); %rename(E2Str_OpAff) MMVII::E2Str(const eOpAff &); %rename(E2Str_TA2007) MMVII::E2Str(const eTA2007 &); @@ -144,7 +160,7 @@ typedef double tStdDouble; ///< "natural" int %template(Pt2di) MMVII::cPtxd ; //%template(Pt2df) MMVII::cPtxd ; %template(Pt3dr) MMVII::cPtxd ; -//%template(Pt3di) MMVII::cPtxd ; +%template(Pt3di) MMVII::cPtxd ; //%template(Pt3df) MMVII::cPtxd ; %template(tU_INT1Vector) std::vector; @@ -185,6 +201,13 @@ mmv2_init(); return tmp; } } +%extend MMVII::cPtxd { + char *__repr__() { + static char tmp[1024]; + sprintf(tmp, "Pt [%d, %d, %d]", $self->x(), $self->y(), $self->z()); + return tmp; + } +} %extend MMVII::cIm2D { char *__repr__() { @@ -202,7 +225,8 @@ mmv2_init(); } } -//must redefine virtual functions to access base class methods, when base class is abstract and template? +//must redefine virtual functions to access base class methods, +//when base class is abstract and template? %extend MMVII::cDataIm2D { std::vector rawData() { int size = $self->SzX()*$self->SzY(); From 393ba2bf7c49eb66496e7b8b84142d33b7ccfe8a Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Wed, 12 May 2021 11:00:25 +0200 Subject: [PATCH 18/25] When using MMVII includes in MMV1, special care must be taken --- MMVII/include/TreeDist.h | 3 +++ src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h | 1 + 2 files changed, 4 insertions(+) diff --git a/MMVII/include/TreeDist.h b/MMVII/include/TreeDist.h index 4c5a2b5b37..55fe959127 100644 --- a/MMVII/include/TreeDist.h +++ b/MMVII/include/TreeDist.h @@ -22,7 +22,10 @@ // Set false for external use, set true inside MMMVII to benefit from functionality // with additionnal correctness checking + +#ifndef TREEDIST_WITH_MMVII #define TREEDIST_WITH_MMVII true +#endif #if (TREEDIST_WITH_MMVII) diff --git a/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h index e27e933199..7e782685fa 100644 --- a/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h +++ b/src/uti_phgrm/NewOri/cNewO_SolGlobInit_RandomDFS.h @@ -42,6 +42,7 @@ Header-MicMac-eLiSe-25/06/2007*/ //#include "general/CMake_defines.h" #include "graphes/cNewO_BuildOptions.h" #include +#define TREEDIST_WITH_MMVII false #include "../../../MMVII/include/TreeDist.h" #ifdef GRAPHVIZ_ENABLED From eb7b90a286659b6684e3444516db24a4d449ae0b Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Wed, 12 May 2021 13:09:56 +0200 Subject: [PATCH 19/25] MMVII: Makefile: INSTALL_PATH needs a terminating '/' --- MMVII/bin/Mk-MMVII.makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MMVII/bin/Mk-MMVII.makefile b/MMVII/bin/Mk-MMVII.makefile index 67d30ab89e..0dc1ccc510 100644 --- a/MMVII/bin/Mk-MMVII.makefile +++ b/MMVII/bin/Mk-MMVII.makefile @@ -9,7 +9,7 @@ MMV2Objects=${MMV2Dir}object/ MMV2DirIncl=${MMV2Dir}include/ MMV2ElisePath=${MMDir}/lib/libelise.a MMV2Exe=MMVII -MMV2_INSTALL_PATH=${abspath ${MMV2DirBin}} +MMV2_INSTALL_PATH=${abspath ${MMV2DirBin}}/ MMSymbDerHeader=$(wildcard ${MMV2DirIncl}/SymbDer/*.h) MMKaptureHeader=$(wildcard ${MMV2Dir}/kapture/*.h) From 5e0e97e607abec03f66b4f53c5fb0e6b09d8a8f8 Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Wed, 12 May 2021 10:24:33 +0200 Subject: [PATCH 20/25] MMVII: Makefile: remove now unused file InstalMM.cpp --- MMVII/src/BinaireInstall/InstalMM.cpp | 81 --------------------------- 1 file changed, 81 deletions(-) delete mode 100644 MMVII/src/BinaireInstall/InstalMM.cpp diff --git a/MMVII/src/BinaireInstall/InstalMM.cpp b/MMVII/src/BinaireInstall/InstalMM.cpp deleted file mode 100644 index bc8eeac834..0000000000 --- a/MMVII/src/BinaireInstall/InstalMM.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include -#include -#include - -#include - - - -FILE * FopenNN(const std::string & aName,const char * aMode) -{ - FILE * aFp = fopen(aName.c_str(),aMode); - assert(aFp!=0); - return aFp; -} - -using namespace std::experimental::filesystem; - - -int main(int,char **) -{ - char aSep = path::preferred_separator; - char Buf[1024]; - getcwd(Buf,1000); - FILE * aFp =FopenNN("../src/ResultInstall/ResultInstall.cpp","w"); - fprintf(aFp,"#include \n "); - fprintf(aFp,"namespace MMVII {\n "); - fprintf(aFp," const std::string DirBin2007=\"%s%c\";\n",Buf,aSep); - fprintf(aFp,"};\n"); - fclose(aFp); - - return EXIT_SUCCESS; -} - - - -/* -#include "memory.h" -#include -#include -#include -#include -#include -#include -*/ - - -/* -void StrSystem(const std::string & aCom) -{ - int Ok = system(aCom.c_str()); - assert(Ok==EXIT_SUCCESS); -} - - -std::string GetLineFromFile(const std::string & aName) -{ - std::string aRes; - FILE * aFp = FopenNN(aName); - bool cont=true; - while(cont) - { - int aC = fgetc(aFp); - if(isspace(aC) || isblank(aC) || aC==EOF) - cont = false; - else - aRes += aC; - } - fclose(aFp); - return aRes; -} - -std::string GetPWD() -{ - std::string PDWFile="PWD.txt"; - StrSystem("pwd >"+PDWFile); - std::string PWDLine = GetLineFromFile(PDWFile); - return PWDLine; -} -*/ From 11c8305c6e44a3f5dbb3995a2b633f6e852f103e Mon Sep 17 00:00:00 2001 From: Christophe Meynard Date: Wed, 12 May 2021 09:34:25 +0200 Subject: [PATCH 21/25] MMVII: TestCodeGen : make it work again --- MMVII/include/SymbDer/SymbDer_Common.h | 3 ++- MMVII/src/TestCodeGen/CodeGenerator.cpp | 9 +-------- MMVII/src/TestCodeGen/Makefile | 4 ++-- MMVII/src/TestCodeGen/TestCodeGen.cpp | 6 +++--- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/MMVII/include/SymbDer/SymbDer_Common.h b/MMVII/include/SymbDer/SymbDer_Common.h index 673746f6a9..7092877658 100644 --- a/MMVII/include/SymbDer/SymbDer_Common.h +++ b/MMVII/include/SymbDer/SymbDer_Common.h @@ -1,8 +1,9 @@ #ifndef _SymbDer_Common_H_ #define _SymbDer_Common_H_ - +#ifndef SYMBDER_WITH_MMVII #define SYMBDER_WITH_MMVII true +#endif namespace NS_SymbolicDerivative { diff --git a/MMVII/src/TestCodeGen/CodeGenerator.cpp b/MMVII/src/TestCodeGen/CodeGenerator.cpp index d5be3e71fb..015e4ab9ff 100644 --- a/MMVII/src/TestCodeGen/CodeGenerator.cpp +++ b/MMVII/src/TestCodeGen/CodeGenerator.cpp @@ -17,11 +17,6 @@ void GenerateCode(bool WithDerivative) { std::string aPost = WithDerivative ? "_ValAndDer" : "_Val"; -{ // A voir avec Jo pk ca plante apres si aPost!="" =>JO? - aPost=""; -// aPost="x"; -} - NS_SymbolicDerivative::cCoordinatorF mCFD1(FORMULA::FormulaName()+aPost,0,FORMULA::VNamesUnknowns(),FORMULA::VNamesObs()); @@ -39,7 +34,7 @@ void GenerateCode(bool WithDerivative) int main(int , char **) { - for (int aTime=0 ; aTime<1 ; aTime++) + for (int aTime=0 ; aTime<2 ; aTime++) { bool WithDer = (aTime==0); // GenerateCode>>(WithDer); @@ -50,8 +45,6 @@ int main(int , char **) GenerateCode>>(WithDer); GenerateCode>>(WithDer); GenerateCode>>(WithDer); -/* -*/ } std::ofstream os(std::string("CodeGen_IncludeAll.h")); diff --git a/MMVII/src/TestCodeGen/Makefile b/MMVII/src/TestCodeGen/Makefile index fa024775ba..f26c35c8cc 100644 --- a/MMVII/src/TestCodeGen/Makefile +++ b/MMVII/src/TestCodeGen/Makefile @@ -1,5 +1,5 @@ -INCDIR=../../include/ -CXXFLAGS=-fopenmp -std=c++14 -Wall -Werror -O4 -march=native -I$(INCDIR) +INCDIR=-I ../../ -I../../include +CXXFLAGS=-fopenmp -std=c++17 -Wall -Werror -O4 -march=native $(INCDIR) -D"SYMBDER_WITH_MMVII=false" SYMBDER_INCLUDES=$(wildcard $(INCDIR)/SymbDer/*.h) all: CodeGen_IncludeAll.h TestCodeGen diff --git a/MMVII/src/TestCodeGen/TestCodeGen.cpp b/MMVII/src/TestCodeGen/TestCodeGen.cpp index 3b455d5144..e772aa8b6e 100644 --- a/MMVII/src/TestCodeGen/TestCodeGen.cpp +++ b/MMVII/src/TestCodeGen/TestCodeGen.cpp @@ -10,10 +10,10 @@ namespace SD = NS_SymbolicDerivative; -class TestPrimitives : public cCodeGenTest +class TestPrimitives : public cCodeGenTest { public: - TestPrimitives(size_t nbTest) : cCodeGenTest(nbTest) + TestPrimitives(size_t nbTest) : cCodeGenTest(nbTest) { mVUk[0] = 1; mVUk[1] = 2; @@ -45,7 +45,7 @@ static int doTest(int sizeBuf, int nbThreads, const std::string& name) obs[10] = 0.2; // cCodeGenTest test(1000000); - cCodeGenTest>,SD::cEqColLinearityXYPol_Deg7,SD::cEqColLinearityXYPol_Deg7LongExpr> test(100000,name); + cCodeGenTest>,SD::cEqColLinearityXYPol_Deg7_ValAndDer,SD::cEqColLinearityXYPol_Deg7_ValAndDerLongExpr> test(100000,name); // cCodeGenTest,SD::cEqColLinearityFraser,SD::cEqColLinearityFraserLongExpr> test(1000000); test.mVUk = uk; test.mVObs = obs; From cf3bf83c2caef5e556bce9d9fc56aa6e5d1b9adb Mon Sep 17 00:00:00 2001 From: deseilligny Date: Mon, 17 May 2021 08:32:15 +0200 Subject: [PATCH 22/25] Avant de s'y remettre ... --- MMVII/include/MMVII_PhgrDist.h | 2 +- ...CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp | 174 +++++++++--------- .../CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp | 54 +++--- MMVII/src/SymbDerGen/Formulas_CamStenope.h | 75 +++++--- MMVII/src/SymbDerGen/GenerateCodes.cpp | 15 +- 5 files changed, 176 insertions(+), 144 deletions(-) diff --git a/MMVII/include/MMVII_PhgrDist.h b/MMVII/include/MMVII_PhgrDist.h index a321b8e4aa..25f0eca7b4 100644 --- a/MMVII/include/MMVII_PhgrDist.h +++ b/MMVII/include/MMVII_PhgrDist.h @@ -44,7 +44,7 @@ class cDescOneFuncDist // used for bench now To put elsewhere later, NS_SymbolicDerivative::cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf); -const std::vector & DescDist(const cPt3di & aDeg); +std::vector DescDist(const cPt3di & aDeg); }; diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp index 3665c5a3cd..c281f7ef24 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1VDer.cpp @@ -18,98 +18,98 @@ void cEqDist_Dist_Rad3_Dec1_XY1VDer::DoEval() double &p2 = this->mVObs[aK][4]; double &b2 = this->mVObs[aK][5]; double &b1 = this->mVObs[aK][6]; - double F66 = (yPi + yPi); - double F35 = (b1 * xPi); - double F34 = (b2 * yPi); - double F44 = (xPi + xPi); - double F58 = (2 * yPi); - double F78 = (2 * xPi); - double F14 = (xPi * yPi); - double F13 = (yPi * yPi); + double F50 = (xPi + xPi); + double F40 = (b2 * yPi); + double F41 = (b1 * xPi); double F12 = (xPi * xPi); - double F95 = (F78 * p1); - double F70 = (F66 * K1); - double F60 = (F44 * 2); - double F80 = (F66 * p1); - double F59 = (F58 * p2); - double F79 = (F78 * p2); - double F30 = (F13 * 2); - double F48 = (F44 * K1); - double F85 = (F44 * p2); - double F36 = (F34 + F35); - double F86 = (F58 * p1); - double F92 = (F66 * 2); - double F23 = (F12 * 2); + double F84 = (2 * xPi); + double F64 = (2 * yPi); + double F72 = (yPi + yPi); + double F13 = (yPi * yPi); + double F14 = (xPi * yPi); + double F76 = (F72 * K1); + double F66 = (F50 * 2); + double F34 = (F13 * 2); + double F65 = (F64 * p2); + double F54 = (F50 * K1); + double F42 = (F40 + F41); + double F31 = (F14 * 2); + double F85 = (F84 * p2); + double F91 = (F50 * p2); + double F92 = (F64 * p1); + double F101 = (F84 * p1); + double F98 = (F72 * 2); + double F86 = (F72 * p1); double F15 = (F12 + F13); - double F26 = (F14 * 2); - double F28 = (F26 * p2); - double F61 = (F44 + F60); - double F18 = (F15 * K1); + double F29 = (F12 * 2); + double F99 = (F72 + F98); + double F30 = (F29 + F15); + double F87 = (F86 + F85); + double F33 = (F31 * p1); + double F35 = (F15 + F34); + double F67 = (F50 + F66); + double F51 = (F15 * F50); + double F36 = (F31 * p2); + double F93 = (F91 + F92); + double F73 = (F15 * F72); double F16 = (F15 * F15); - double F67 = (F15 * F66); - double F24 = (F23 + F15); - double F81 = (F80 + F79); - double F93 = (F66 + F92); - double F27 = (F26 * p1); - double F45 = (F15 * F44); - double F31 = (F15 + F30); - double F87 = (F85 + F86); + double F18 = (F15 * K1); + double F68 = (F67 * p1); + double F79 = (F16 * F72); + double F74 = (F73 + F73); + double F57 = (F16 * F50); + double F38 = (F35 * p2); + double F52 = (F51 + F51); + double F32 = (F30 * p1); + double F100 = (F99 * p2); + double F21 = (F16 * K2); double F17 = (F15 * F16); - double F73 = (F16 * F66); - double F25 = (F24 * p1); - double F68 = (F67 + F67); - double F32 = (F31 * p2); - double F94 = (F93 * p2); - double F51 = (F16 * F44); - double F62 = (F61 * p1); - double F19 = (F16 * K2); - double F46 = (F45 + F45); - double F69 = (F68 * K2); - double F29 = (F25 + F28); - double F33 = (F27 + F32); - double F50 = (F15 * F46); - double F72 = (F15 * F68); - double F47 = (F46 * K2); - double F20 = (F18 + F19); - double F21 = (F17 * K3); - double F96 = (F95 + F94); - double F63 = (F59 + F62); - double F74 = (F72 + F73); - double F49 = (F48 + F47); - double F52 = (F50 + F51); - double F71 = (F70 + F69); - double F22 = (F21 + F20); - double F53 = (F52 * K3); - double F75 = (F74 * K3); - double F41 = (F22 * yPi); - double F37 = (F22 * xPi); - double F42 = (F41 + yPi); - double F38 = (F37 + xPi); - double F76 = (F71 + F75); - double F54 = (F49 + F53); - double F84 = (F54 * yPi); - double F89 = (F76 * yPi); - double F43 = (F33 + F42); - double F77 = (F76 * xPi); - double F55 = (F54 * xPi); - double F39 = (F29 + F38); - double F90 = (F22 + F89); - double F40 = (F39 + F36); - double F88 = (F84 + F87); + double F39 = (F33 + F38); + double F78 = (F15 * F74); + double F75 = (F74 * K2); + double F102 = (F101 + F100); + double F37 = (F32 + F36); + double F25 = (F17 * K3); + double F69 = (F65 + F68); + double F22 = (F18 + F21); + double F53 = (F52 * K2); + double F56 = (F15 * F52); + double F77 = (F76 + F75); + double F26 = (F25 + F22); + double F55 = (F54 + F53); + double F58 = (F56 + F57); + double F80 = (F78 + F79); + double F59 = (F58 * K3); + double F81 = (F80 * K3); + double F43 = (F26 * xPi); + double F47 = (F26 * yPi); + double F44 = (F43 + xPi); double F82 = (F77 + F81); - double F56 = (F22 + F55); - double F57 = (F56 + 1); - double F91 = (F90 + 1); - double F83 = (F82 + b2); - double F64 = (F57 + F63); - double F97 = (F91 + F96); - double F65 = (F64 + b1); - this->mBufLineRes[aK][0] = F40; - this->mBufLineRes[aK][1] = F65; - this->mBufLineRes[aK][2] = F83; - this->mBufLineRes[aK][3] = F43; - this->mBufLineRes[aK][4] = F88; - this->mBufLineRes[aK][5] = F97; + double F48 = (F47 + yPi); + double F60 = (F55 + F59); + double F49 = (F39 + F48); + double F45 = (F37 + F44); + double F90 = (F60 * yPi); + double F83 = (F82 * xPi); + double F61 = (F60 * xPi); + double F95 = (F82 * yPi); + double F46 = (F45 + F42); + double F62 = (F26 + F61); + double F94 = (F90 + F93); + double F88 = (F83 + F87); + double F96 = (F26 + F95); + double F97 = (F96 + 1); + double F63 = (F62 + 1); + double F89 = (F88 + b2); + double F70 = (F63 + F69); + double F103 = (F102 + F97); + double F71 = (F70 + b1); + this->mBufLineRes[aK][0] = F46; + this->mBufLineRes[aK][1] = F71; + this->mBufLineRes[aK][2] = F89; + this->mBufLineRes[aK][3] = F49; + this->mBufLineRes[aK][4] = F94; + this->mBufLineRes[aK][5] = F103; } } diff --git a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp index e57254ec7a..fea0ff7d6c 100644 --- a/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp +++ b/MMVII/src/GeneratedCodes/CodeGen_cEqDist_Dist_Rad3_Dec1_XY1Val.cpp @@ -19,39 +19,39 @@ void cEqDist_Dist_Rad3_Dec1_XY1Val::DoEval() double &b2 = this->mVObs[aK][5]; double &b1 = this->mVObs[aK][6]; double F12 = (xPi * xPi); - double F35 = (b1 * xPi); - double F34 = (b2 * yPi); + double F41 = (b1 * xPi); + double F40 = (b2 * yPi); double F13 = (yPi * yPi); double F14 = (xPi * yPi); - double F30 = (F13 * 2); + double F34 = (F13 * 2); double F15 = (F12 + F13); - double F23 = (F12 * 2); - double F36 = (F34 + F35); - double F26 = (F14 * 2); - double F27 = (F26 * p1); + double F29 = (F12 * 2); + double F42 = (F40 + F41); + double F31 = (F14 * 2); + double F33 = (F31 * p1); double F18 = (F15 * K1); - double F31 = (F15 + F30); - double F28 = (F26 * p2); - double F24 = (F23 + F15); + double F35 = (F15 + F34); + double F36 = (F31 * p2); + double F30 = (F29 + F15); double F16 = (F15 * F15); - double F25 = (F24 * p1); - double F19 = (F16 * K2); + double F32 = (F30 * p1); + double F21 = (F16 * K2); double F17 = (F15 * F16); - double F32 = (F31 * p2); - double F29 = (F25 + F28); - double F33 = (F27 + F32); - double F20 = (F18 + F19); - double F21 = (F17 * K3); - double F22 = (F21 + F20); - double F41 = (F22 * yPi); - double F37 = (F22 * xPi); - double F42 = (F41 + yPi); - double F38 = (F37 + xPi); - double F43 = (F33 + F42); - double F39 = (F29 + F38); - double F40 = (F39 + F36); - this->mBufLineRes[aK][0] = F40; - this->mBufLineRes[aK][1] = F43; + double F38 = (F35 * p2); + double F37 = (F32 + F36); + double F39 = (F33 + F38); + double F22 = (F18 + F21); + double F25 = (F17 * K3); + double F26 = (F25 + F22); + double F47 = (F26 * yPi); + double F43 = (F26 * xPi); + double F48 = (F47 + yPi); + double F44 = (F43 + xPi); + double F49 = (F39 + F48); + double F45 = (F37 + F44); + double F46 = (F45 + F42); + this->mBufLineRes[aK][0] = F46; + this->mBufLineRes[aK][1] = F49; } } diff --git a/MMVII/src/SymbDerGen/Formulas_CamStenope.h b/MMVII/src/SymbDerGen/Formulas_CamStenope.h index 51fa1a7a61..f19f62bfd0 100644 --- a/MMVII/src/SymbDerGen/Formulas_CamStenope.h +++ b/MMVII/src/SymbDerGen/Formulas_CamStenope.h @@ -220,9 +220,11 @@ class cMMVIIUnivDist std::string NameModel() const { return std::string("Dist") + + std::string(mForBase?"_Base" : "") + std::string("_Rad") + std::to_string(DegRad()) + std::string("_Dec") + std::to_string(DegDec()) - + std::string("_XY") + std::to_string(DegUniv()); + + std::string("_XY") + std::to_string(DegUniv()) + ; } /// Used to indicate reason why monom sould be removes. To maintain for debug ? @@ -316,12 +318,10 @@ class cMMVIIUnivDist * generating description or accessing parameters by names */ - const std::vector & VDescParams() const + std::vector VDescParams() const { // static_assert(DegRad>=DegDec(),"Too much decentrik"); - static std::vector VDesc; - if (VDesc.empty()) - { + std::vector VDesc; // Generate description of radial parameters, x used for num, y not used => -1 for (int aDR=1 ; aDR<=DegRad() ; aDR++) { @@ -352,15 +352,14 @@ class cMMVIIUnivDist } } } - } - return VDesc; + return VDesc; } /** Names of all param, used to automatize symbolic derivation */ - const std::vector & VNamesParams() const + const std::vector VNamesParams() const { - static std::vector VNames; - if (VNames.empty()) + std::vector VNames; + if (VNames.empty() && (!mForBase)) { for (const auto & aDesc : VDescParams()) { @@ -381,6 +380,8 @@ class cMMVIIUnivDist { tScal aC0 = CreateCste(0.0,xIn); tScal aC1 = CreateCste(1.0,xIn); + std::vector aVBaseX; + std::vector aVBaseY; int aPowR2 = std::max(DegRad(),DegDec()); int aPowMon = std::max(2,DegUniv()); @@ -416,7 +417,9 @@ class cMMVIIUnivDist tScal aPolY = aC0; ///< will contain Y component of polynomial distorsion for (const auto & aDesc : VDescParams()) { - tScal aParam = aVParam.at(aK0P++); + tScal aParam = mForBase ? aC0 : aVParam.at(aK0P++); // If for base, Param empty + tScal aBaseX = aC0; // because must init, init ok for monoms + tScal aBaseY = aC0; // because must init, init ok for monoms if (aDesc.mType <= eTypeFuncDist::eDecY) { int aNum = aDesc.mNum; @@ -425,50 +428,72 @@ class cMMVIIUnivDist if (aDesc.mType==eTypeFuncDist::eRad) { aDR2 = aDR2 + aParam * aR2N ; + aBaseX = xIn*aR2N; + aBaseY = yIn*aR2N; } // [R2^N+2NX^2R2^(N-1),2NXYR2^(N-1)] :N=1=>[R2+2X^2,2XY]=[3X2+Y2,2XY] else if (aDesc.mType==eTypeFuncDist::eDecX) { - aDecX = aDecX + aParam*(aR2N + aX2*(2.0*aNum*aR2Nm1)); - aDecY = aDecY + aParam*(aXY*(2.0*aNum*aR2Nm1)); + aBaseX = aR2N + aX2*(2.0*aNum*aR2Nm1); + aBaseY = aXY*(2.0*aNum*aR2Nm1); + aDecX = aDecX + aParam* aBaseX; + aDecY = aDecY + aParam* aBaseY; } // [2XYNR2^(N-1), R2^N+2NY^2R^(N-1) ] :N=1=>[2XY,R2+2Y^2]=[2XY,X2+3Y2] else if (aDesc.mType==eTypeFuncDist::eDecY) { - aDecX = aDecX + aParam*(aXY*(2.0*aNum*aR2Nm1)); - aDecY = aDecY + aParam*(aR2N + aY2*(2.0*aNum*aR2Nm1)); + aBaseX = aXY*(2.0*aNum*aR2Nm1); + aBaseY = aR2N + aY2*(2.0*aNum*aR2Nm1); + aDecX = aDecX + aParam* aBaseX; + aDecY = aDecY + aParam* aBaseY; } } else { cPt2di aD = aDesc.mDegMon; - tScal aMon = aParam * aVMonX.at(aD.x()) * aVMonY.at(aD.y()); + tScal aMon = aVMonX.at(aD.x()) * aVMonY.at(aD.y()); if (aDesc.mType==eTypeFuncDist::eMonX) - aPolX = aPolX + aMon; + { + aPolX = aPolX + aParam* aMon; + aBaseX = aMon; + } else - aPolY = aPolY + aMon; + { + aPolY = aPolY + aParam* aMon; + aBaseY = aMon; + } + } + if (mForBase) + { + aVBaseX.push_back(aBaseX); + aVBaseY.push_back(aBaseY); } } tScal xDist = xIn + xIn*aDR2 + aDecX + aPolX; tScal yDist = yIn + yIn*aDR2 + aDecY + aPolY; MMVII_INTERNAL_ASSERT_always(aK0P==aVParam.size(),"Inconsistent param number"); - return {xDist,yDist}; + if (mForBase) + return Append(aVBaseX,aVBaseY) ; + + return {xDist,yDist} ; } - cMMVIIUnivDist(const int & aDegRad,const int & aDegDec,const int & aDegUniv) : + cMMVIIUnivDist(const int & aDegRad,const int & aDegDec,const int & aDegUniv,bool ForBase) : mTheDegRad (aDegRad), mTheDegDec (aDegDec), - mTheDegUniv (aDegUniv) + mTheDegUniv (aDegUniv), + mForBase (ForBase) { } private : - int mTheDegRad; - int mTheDegDec; - int mTheDegUniv; + int mTheDegRad; + int mTheDegDec; + int mTheDegUniv; + bool mForBase; // If true, generate the base of function and not the sum }; @@ -755,7 +780,7 @@ template class cEqDist public : cEqDist(const TypeDist & aDist) : mDist (aDist) { } static std::vector VNamesUnknowns() {return {"xPi","yPi"}; } - const std::vector & VNamesObs() const {return mDist.VNamesParams();} + const std::vector VNamesObs() const {return mDist.VNamesParams();} std::string FormulaName() const { return "EqDist_" + mDist.NameModel();} diff --git a/MMVII/src/SymbDerGen/GenerateCodes.cpp b/MMVII/src/SymbDerGen/GenerateCodes.cpp index d877d74244..3d6a61fda9 100644 --- a/MMVII/src/SymbDerGen/GenerateCodes.cpp +++ b/MMVII/src/SymbDerGen/GenerateCodes.cpp @@ -16,7 +16,7 @@ template std::string NameFormula(const TypeFormula & anEq std::string NameEqDist(const cPt3di & aDeg,bool WithDerive) { - cMMVIIUnivDist aDist(aDeg.x(),aDeg.y(),aDeg.z()); + cMMVIIUnivDist aDist(aDeg.x(),aDeg.y(),aDeg.z(),false); cEqDist anEq(aDist); return NameFormula(anEq,WithDerive); @@ -175,15 +175,22 @@ template void cAppli::GenCodesFormula(const tFormula & aForm int cAppli::Exe() { mDirGenCode = TopDirMMVII() + "src/GeneratedCodes/"; - cMMVIIUnivDist aDist(3,1,1); + cMMVIIUnivDist aDist(3,1,1,false); cEqDist anEqDist(aDist); cEqIntr anEqIntr(aDist); + GenCodesFormula(anEqDist,false); GenCodesFormula(anEqDist,true); GenCodesFormula(anEqIntr,false); GenCodesFormula(anEqIntr,true); // GenCodesFormula(aDist,true,false); + + cMMVIIUnivDist aDistBase(3,1,1,true); + cEqDist anEqBase(aDistBase); + GenCodesFormula(anEqBase,false); +/* +*/ return EXIT_SUCCESS; } @@ -221,9 +228,9 @@ cCalculator * EqDist(const cPt3di & aDeg,bool WithDerive,int aSzBuf) return cName2Calc::CalcFromName(NameEqDist(aDeg,WithDerive),aSzBuf); } -const std::vector & DescDist(const cPt3di & aDeg) +std::vector DescDist(const cPt3di & aDeg) { - cMMVIIUnivDist aDist(aDeg.x(),aDeg.y(),aDeg.z()); + cMMVIIUnivDist aDist(aDeg.x(),aDeg.y(),aDeg.z(),false); return aDist.VDescParams(); From 91e706d7fed0feb3f385eb463bf2b1a0817b48c9 Mon Sep 17 00:00:00 2001 From: jmmuller Date: Mon, 17 May 2021 15:59:48 +0200 Subject: [PATCH 23/25] MMVII apipy: fill image from numpy array --- MMVII/apipy/ex/ex1.py | 17 ++++++++++++++++- MMVII/apipy/gen_typemaps.py | 2 +- MMVII/apipy/mmv2.i | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/MMVII/apipy/ex/ex1.py b/MMVII/apipy/ex/ex1.py index a8b050ce63..dc4455d31f 100644 --- a/MMVII/apipy/ex/ex1.py +++ b/MMVII/apipy/ex/ex1.py @@ -45,7 +45,7 @@ def imageScale(): def imgNumpyRawData(): im=mmv2.cIm2Du1.FromFile("ex/image.tif") d=im.DIm() - v=d.rawData() + v=d.getRawData() from PIL import Image import numpy as np array = np.array(v, dtype=np.uint8) @@ -53,3 +53,18 @@ def imgNumpyRawData(): img = Image.fromarray(array) img.show() +def PIL2mmv2Img(): + from PIL import Image + import numpy as np + path="ex/png.png" + pil_image = Image.open(path).convert('L') + pil_image_array=np.array(pil_image) + im=mmv2.cIm2Du1( (5,5) ) + im.DIm().setRawData( pil_image_array ) + d=im.DIm() + v=d.getRawData() + array = np.array(v, dtype=np.uint8) + array = array.reshape((d.SzY(), d.SzX())) + img = Image.fromarray(array) + img.show() + diff --git a/MMVII/apipy/gen_typemaps.py b/MMVII/apipy/gen_typemaps.py index ab7d6e070e..02dbff2b1e 100644 --- a/MMVII/apipy/gen_typemaps.py +++ b/MMVII/apipy/gen_typemaps.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 dimNames = ['x', 'y', 'z'] debug = False diff --git a/MMVII/apipy/mmv2.i b/MMVII/apipy/mmv2.i index 218ae1b577..36d987f92a 100644 --- a/MMVII/apipy/mmv2.i +++ b/MMVII/apipy/mmv2.i @@ -12,6 +12,11 @@ %} //---------------------------------------------------------------------- +%include "numpy.i" +%init %{ +import_array(); +%} + #define ElSTDNS std:: #define ElTmplSpecNull template <> %include @@ -225,14 +230,22 @@ mmv2_init(); } } + //must redefine virtual functions to access base class methods, //when base class is abstract and template? %extend MMVII::cDataIm2D { - std::vector rawData() { + std::vector getRawData() { int size = $self->SzX()*$self->SzY(); tU_INT1* data = $self->RawDataLin(); std::vector out(data ,data + size); return out; } + //here tU_INT1* IN_ARRAY2 is not recognized + void setRawData(unsigned char* IN_ARRAY2, int DIM1, int DIM2) { + $self->Resize( MMVII::cPtxd(0,0), MMVII::cPtxd(DIM2,DIM1) ); + for (long i=0;iRawDataLin()[i] = IN_ARRAY2[i]; + } } + From 8733faa72b6c30be93b321d56a5105cb4d160a9a Mon Sep 17 00:00:00 2001 From: jmmuller Date: Mon, 17 May 2021 17:41:59 +0200 Subject: [PATCH 24/25] MMVII apipy: add numpy.i --- MMVII/apipy/numpy.i | 3180 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3180 insertions(+) create mode 100644 MMVII/apipy/numpy.i diff --git a/MMVII/apipy/numpy.i b/MMVII/apipy/numpy.i new file mode 100644 index 0000000000..60930c0983 --- /dev/null +++ b/MMVII/apipy/numpy.i @@ -0,0 +1,3180 @@ +/* -*- C -*- (not really, but good for syntax highlighting) */ + +/* + * Copyright (c) 2005-2015, NumPy Developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of the NumPy Developers nor the names of any + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef SWIGPYTHON + +%{ +#ifndef SWIG_FILE_WITH_INIT +#define NO_IMPORT_ARRAY +#endif +#include "stdio.h" +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include +%} + +/**********************************************************************/ + +%fragment("NumPy_Backward_Compatibility", "header") +{ +%#if NPY_API_VERSION < 0x00000007 +%#define NPY_ARRAY_DEFAULT NPY_DEFAULT +%#define NPY_ARRAY_FARRAY NPY_FARRAY +%#define NPY_FORTRANORDER NPY_FORTRAN +%#endif +} + +/**********************************************************************/ + +/* The following code originally appeared in + * enthought/kiva/agg/src/numeric.i written by Eric Jones. It was + * translated from C++ to C by John Hunter. Bill Spotz has modified + * it to fix some minor bugs, upgrade from Numeric to numpy (all + * versions), add some comments and functionality, and convert from + * direct code insertion to SWIG fragments. + */ + +%fragment("NumPy_Macros", "header") +{ +/* Macros to extract array attributes. + */ +%#if NPY_API_VERSION < 0x00000007 +%#define is_array(a) ((a) && PyArray_Check((PyArrayObject*)a)) +%#define array_type(a) (int)(PyArray_TYPE((PyArrayObject*)a)) +%#define array_numdims(a) (((PyArrayObject*)a)->nd) +%#define array_dimensions(a) (((PyArrayObject*)a)->dimensions) +%#define array_size(a,i) (((PyArrayObject*)a)->dimensions[i]) +%#define array_strides(a) (((PyArrayObject*)a)->strides) +%#define array_stride(a,i) (((PyArrayObject*)a)->strides[i]) +%#define array_data(a) (((PyArrayObject*)a)->data) +%#define array_descr(a) (((PyArrayObject*)a)->descr) +%#define array_flags(a) (((PyArrayObject*)a)->flags) +%#define array_clearflags(a,f) (((PyArrayObject*)a)->flags) &= ~f +%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f +%#define array_is_fortran(a) (PyArray_ISFORTRAN((PyArrayObject*)a)) +%#else +%#define is_array(a) ((a) && PyArray_Check(a)) +%#define array_type(a) PyArray_TYPE((PyArrayObject*)a) +%#define array_numdims(a) PyArray_NDIM((PyArrayObject*)a) +%#define array_dimensions(a) PyArray_DIMS((PyArrayObject*)a) +%#define array_strides(a) PyArray_STRIDES((PyArrayObject*)a) +%#define array_stride(a,i) PyArray_STRIDE((PyArrayObject*)a,i) +%#define array_size(a,i) PyArray_DIM((PyArrayObject*)a,i) +%#define array_data(a) PyArray_DATA((PyArrayObject*)a) +%#define array_descr(a) PyArray_DESCR((PyArrayObject*)a) +%#define array_flags(a) PyArray_FLAGS((PyArrayObject*)a) +%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f) +%#define array_clearflags(a,f) PyArray_CLEARFLAGS((PyArrayObject*)a,f) +%#define array_is_fortran(a) (PyArray_IS_F_CONTIGUOUS((PyArrayObject*)a)) +%#endif +%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a)) +%#define array_is_native(a) (PyArray_ISNOTSWAPPED((PyArrayObject*)a)) +} + +/**********************************************************************/ + +%fragment("NumPy_Utilities", + "header") +{ + /* Given a PyObject, return a string describing its type. + */ + const char* pytype_string(PyObject* py_obj) + { + if (py_obj == NULL ) return "C NULL value"; + if (py_obj == Py_None ) return "Python None" ; + if (PyCallable_Check(py_obj)) return "callable" ; + if (PyBytes_Check( py_obj)) return "string" ; + if (PyLong_Check( py_obj)) return "int" ; + if (PyFloat_Check( py_obj)) return "float" ; + if (PyDict_Check( py_obj)) return "dict" ; + if (PyList_Check( py_obj)) return "list" ; + if (PyTuple_Check( py_obj)) return "tuple" ; + + return "unknown type"; + } + + /* Given a NumPy typecode, return a string describing the type. + */ + const char* typecode_string(int typecode) + { + static const char* type_names[25] = {"bool", + "byte", + "unsigned byte", + "short", + "unsigned short", + "int", + "unsigned int", + "long", + "unsigned long", + "long long", + "unsigned long long", + "float", + "double", + "long double", + "complex float", + "complex double", + "complex long double", + "object", + "string", + "unicode", + "void", + "ntypes", + "notype", + "char", + "unknown"}; + return typecode < 24 ? type_names[typecode] : type_names[24]; + } + + /* Make sure input has correct numpy type. This now just calls + PyArray_EquivTypenums(). + */ + int type_match(int actual_type, + int desired_type) + { + return PyArray_EquivTypenums(actual_type, desired_type); + } + +%#ifdef SWIGPY_USE_CAPSULE + void free_cap(PyObject * cap) + { + void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME); + if (array != NULL) free(array); + } +%#endif + + +} + +/**********************************************************************/ + +%fragment("NumPy_Object_to_Array", + "header", + fragment="NumPy_Backward_Compatibility", + fragment="NumPy_Macros", + fragment="NumPy_Utilities") +{ + /* Given a PyObject pointer, cast it to a PyArrayObject pointer if + * legal. If not, set the python error string appropriately and + * return NULL. + */ + PyArrayObject* obj_to_array_no_conversion(PyObject* input, + int typecode) + { + PyArrayObject* ary = NULL; + if (is_array(input) && (typecode == NPY_NOTYPE || + PyArray_EquivTypenums(array_type(input), typecode))) + { + ary = (PyArrayObject*) input; + } + else if is_array(input) + { + const char* desired_type = typecode_string(typecode); + const char* actual_type = typecode_string(array_type(input)); + PyErr_Format(PyExc_TypeError, + "Array of type '%s' required. Array of type '%s' given", + desired_type, actual_type); + ary = NULL; + } + else + { + const char* desired_type = typecode_string(typecode); + const char* actual_type = pytype_string(input); + PyErr_Format(PyExc_TypeError, + "Array of type '%s' required. A '%s' was given", + desired_type, + actual_type); + ary = NULL; + } + return ary; + } + + /* Convert the given PyObject to a NumPy array with the given + * typecode. On success, return a valid PyArrayObject* with the + * correct type. On failure, the python error string will be set and + * the routine returns NULL. + */ + PyArrayObject* obj_to_array_allow_conversion(PyObject* input, + int typecode, + int* is_new_object) + { + PyArrayObject* ary = NULL; + PyObject* py_obj; + if (is_array(input) && (typecode == NPY_NOTYPE || + PyArray_EquivTypenums(array_type(input),typecode))) + { + ary = (PyArrayObject*) input; + *is_new_object = 0; + } + else + { + py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT); + /* If NULL, PyArray_FromObject will have set python error value.*/ + ary = (PyArrayObject*) py_obj; + *is_new_object = 1; + } + return ary; + } + + /* Given a PyArrayObject, check to see if it is contiguous. If so, + * return the input pointer and flag it as not a new object. If it is + * not contiguous, create a new PyArrayObject using the original data, + * flag it as a new object and return the pointer. + */ + PyArrayObject* make_contiguous(PyArrayObject* ary, + int* is_new_object, + int min_dims, + int max_dims) + { + PyArrayObject* result; + if (array_is_contiguous(ary)) + { + result = ary; + *is_new_object = 0; + } + else + { + result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary, + array_type(ary), + min_dims, + max_dims); + *is_new_object = 1; + } + return result; + } + + /* Given a PyArrayObject, check to see if it is Fortran-contiguous. + * If so, return the input pointer, but do not flag it as not a new + * object. If it is not Fortran-contiguous, create a new + * PyArrayObject using the original data, flag it as a new object + * and return the pointer. + */ + PyArrayObject* make_fortran(PyArrayObject* ary, + int* is_new_object) + { + PyArrayObject* result; + if (array_is_fortran(ary)) + { + result = ary; + *is_new_object = 0; + } + else + { + Py_INCREF(array_descr(ary)); + result = (PyArrayObject*) PyArray_FromArray(ary, + array_descr(ary), +%#if NPY_API_VERSION < 0x00000007 + NPY_FORTRANORDER); +%#else + NPY_ARRAY_F_CONTIGUOUS); +%#endif + *is_new_object = 1; + } + return result; + } + + /* Convert a given PyObject to a contiguous PyArrayObject of the + * specified type. If the input object is not a contiguous + * PyArrayObject, a new one will be created and the new object flag + * will be set. + */ + PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, + int typecode, + int* is_new_object) + { + int is_new1 = 0; + int is_new2 = 0; + PyArrayObject* ary2; + PyArrayObject* ary1 = obj_to_array_allow_conversion(input, + typecode, + &is_new1); + if (ary1) + { + ary2 = make_contiguous(ary1, &is_new2, 0, 0); + if ( is_new1 && is_new2) + { + Py_DECREF(ary1); + } + ary1 = ary2; + } + *is_new_object = is_new1 || is_new2; + return ary1; + } + + /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the + * specified type. If the input object is not a Fortran-ordered + * PyArrayObject, a new one will be created and the new object flag + * will be set. + */ + PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input, + int typecode, + int* is_new_object) + { + int is_new1 = 0; + int is_new2 = 0; + PyArrayObject* ary2; + PyArrayObject* ary1 = obj_to_array_allow_conversion(input, + typecode, + &is_new1); + if (ary1) + { + ary2 = make_fortran(ary1, &is_new2); + if (is_new1 && is_new2) + { + Py_DECREF(ary1); + } + ary1 = ary2; + } + *is_new_object = is_new1 || is_new2; + return ary1; + } +} /* end fragment */ + +/**********************************************************************/ + +%fragment("NumPy_Array_Requirements", + "header", + fragment="NumPy_Backward_Compatibility", + fragment="NumPy_Macros") +{ + /* Test whether a python object is contiguous. If array is + * contiguous, return 1. Otherwise, set the python error string and + * return 0. + */ + int require_contiguous(PyArrayObject* ary) + { + int contiguous = 1; + if (!array_is_contiguous(ary)) + { + PyErr_SetString(PyExc_TypeError, + "Array must be contiguous. A non-contiguous array was given"); + contiguous = 0; + } + return contiguous; + } + + /* Test whether a python object is (C_ or F_) contiguous. If array is + * contiguous, return 1. Otherwise, set the python error string and + * return 0. + */ + int require_c_or_f_contiguous(PyArrayObject* ary) + { + int contiguous = 1; + if (!(array_is_contiguous(ary) || array_is_fortran(ary))) + { + PyErr_SetString(PyExc_TypeError, + "Array must be contiguous (C_ or F_). A non-contiguous array was given"); + contiguous = 0; + } + return contiguous; + } + + /* Require that a numpy array is not byte-swapped. If the array is + * not byte-swapped, return 1. Otherwise, set the python error string + * and return 0. + */ + int require_native(PyArrayObject* ary) + { + int native = 1; + if (!array_is_native(ary)) + { + PyErr_SetString(PyExc_TypeError, + "Array must have native byteorder. " + "A byte-swapped array was given"); + native = 0; + } + return native; + } + + /* Require the given PyArrayObject to have a specified number of + * dimensions. If the array has the specified number of dimensions, + * return 1. Otherwise, set the python error string and return 0. + */ + int require_dimensions(PyArrayObject* ary, + int exact_dimensions) + { + int success = 1; + if (array_numdims(ary) != exact_dimensions) + { + PyErr_Format(PyExc_TypeError, + "Array must have %d dimensions. Given array has %d dimensions", + exact_dimensions, + array_numdims(ary)); + success = 0; + } + return success; + } + + /* Require the given PyArrayObject to have one of a list of specified + * number of dimensions. If the array has one of the specified number + * of dimensions, return 1. Otherwise, set the python error string + * and return 0. + */ + int require_dimensions_n(PyArrayObject* ary, + int* exact_dimensions, + int n) + { + int success = 0; + int i; + char dims_str[255] = ""; + char s[255]; + for (i = 0; i < n && !success; i++) + { + if (array_numdims(ary) == exact_dimensions[i]) + { + success = 1; + } + } + if (!success) + { + for (i = 0; i < n-1; i++) + { + sprintf(s, "%d, ", exact_dimensions[i]); + strcat(dims_str,s); + } + sprintf(s, " or %d", exact_dimensions[n-1]); + strcat(dims_str,s); + PyErr_Format(PyExc_TypeError, + "Array must have %s dimensions. Given array has %d dimensions", + dims_str, + array_numdims(ary)); + } + return success; + } + + /* Require the given PyArrayObject to have a specified shape. If the + * array has the specified shape, return 1. Otherwise, set the python + * error string and return 0. + */ + int require_size(PyArrayObject* ary, + npy_intp* size, + int n) + { + int i; + int success = 1; + size_t len; + char desired_dims[255] = "["; + char s[255]; + char actual_dims[255] = "["; + for(i=0; i < n;i++) + { + if (size[i] != -1 && size[i] != array_size(ary,i)) + { + success = 0; + } + } + if (!success) + { + for (i = 0; i < n; i++) + { + if (size[i] == -1) + { + sprintf(s, "*,"); + } + else + { + sprintf(s, "%ld,", (long int)size[i]); + } + strcat(desired_dims,s); + } + len = strlen(desired_dims); + desired_dims[len-1] = ']'; + for (i = 0; i < n; i++) + { + sprintf(s, "%ld,", (long int)array_size(ary,i)); + strcat(actual_dims,s); + } + len = strlen(actual_dims); + actual_dims[len-1] = ']'; + PyErr_Format(PyExc_TypeError, + "Array must have shape of %s. Given array has shape of %s", + desired_dims, + actual_dims); + } + return success; + } + + /* Require the given PyArrayObject to to be Fortran ordered. If the + * the PyArrayObject is already Fortran ordered, do nothing. Else, + * set the Fortran ordering flag and recompute the strides. + */ + int require_fortran(PyArrayObject* ary) + { + int success = 1; + int nd = array_numdims(ary); + int i; + npy_intp * strides = array_strides(ary); + if (array_is_fortran(ary)) return success; + int n_non_one = 0; + /* Set the Fortran ordered flag */ + const npy_intp *dims = array_dimensions(ary); + for (i=0; i < nd; ++i) + n_non_one += (dims[i] != 1) ? 1 : 0; + if (n_non_one > 1) + array_clearflags(ary,NPY_ARRAY_CARRAY); + array_enableflags(ary,NPY_ARRAY_FARRAY); + /* Recompute the strides */ + strides[0] = strides[nd-1]; + for (i=1; i < nd; ++i) + strides[i] = strides[i-1] * array_size(ary,i-1); + return success; + } +} + +/* Combine all NumPy fragments into one for convenience */ +%fragment("NumPy_Fragments", + "header", + fragment="NumPy_Backward_Compatibility", + fragment="NumPy_Macros", + fragment="NumPy_Utilities", + fragment="NumPy_Object_to_Array", + fragment="NumPy_Array_Requirements") +{ +} + +/* End John Hunter translation (with modifications by Bill Spotz) + */ + +/* %numpy_typemaps() macro + * + * This macro defines a family of 75 typemaps that allow C arguments + * of the form + * + * 1. (DATA_TYPE IN_ARRAY1[ANY]) + * 2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) + * 3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) + * + * 4. (DATA_TYPE IN_ARRAY2[ANY][ANY]) + * 5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * 6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) + * 7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * 8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) + * + * 9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) + * 10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) + * 13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) + * + * 15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) + * 16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) + * 19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) + * + * 21. (DATA_TYPE INPLACE_ARRAY1[ANY]) + * 22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) + * 23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) + * + * 24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) + * 25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * 26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) + * 27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * 28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) + * + * 29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) + * 30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) + * 33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * 34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) + * + * 35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) + * 36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) + * 39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + * 40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) + * + * 41. (DATA_TYPE ARGOUT_ARRAY1[ANY]) + * 42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) + * 43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) + * + * 44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) + * + * 45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) + * + * 46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) + * + * 47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) + * 48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) + * + * 49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + * 50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) + * 51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + * 52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) + * + * 53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + * 54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) + * 55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + * 56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) + * + * 57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) + * 58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) + * 59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) + * 60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) + * + * 61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) + * 62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) + * + * 63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + * 64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) + * 65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + * 66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) + * + * 67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + * 68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) + * 69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + * 70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) + * + * 71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) + * 72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) + * 73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) + * 74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) + * + * 75. (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) + * + * where "DATA_TYPE" is any type supported by the NumPy module, and + * "DIM_TYPE" is any int-like type suitable for specifying dimensions. + * The difference between "ARRAY" typemaps and "FARRAY" typemaps is + * that the "FARRAY" typemaps expect Fortran ordering of + * multidimensional arrays. In python, the dimensions will not need + * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1" + * typemaps). The IN_ARRAYs can be a numpy array or any sequence that + * can be converted to a numpy array of the specified type. The + * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The + * ARGOUT_ARRAYs will be returned as new numpy arrays of the + * appropriate type. + * + * These typemaps can be applied to existing functions using the + * %apply directive. For example: + * + * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)}; + * double prod(double* series, int length); + * + * %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2) + * {(int rows, int cols, double* matrix )}; + * void floor(int rows, int cols, double* matrix, double f); + * + * %apply (double IN_ARRAY3[ANY][ANY][ANY]) + * {(double tensor[2][2][2] )}; + * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) + * {(double low[2][2][2] )}; + * %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY]) + * {(double upp[2][2][2] )}; + * void luSplit(double tensor[2][2][2], + * double low[2][2][2], + * double upp[2][2][2] ); + * + * or directly with + * + * double prod(double* IN_ARRAY1, int DIM1); + * + * void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f); + * + * void luSplit(double IN_ARRAY3[ANY][ANY][ANY], + * double ARGOUT_ARRAY3[ANY][ANY][ANY], + * double ARGOUT_ARRAY3[ANY][ANY][ANY]); + */ + +%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE) + +/************************/ +/* Input Array Typemaps */ +/************************/ + +/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE IN_ARRAY1[ANY]) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE IN_ARRAY1[ANY]) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[1] = { $1_dim0 }; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 1) || + !require_size(array, size, 1)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(freearg) + (DATA_TYPE IN_ARRAY1[ANY]) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[1] = { -1 }; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 1) || + !require_size(array, size, 1)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); +} +%typemap(freearg) + (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[1] = {-1}; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 1) || + !require_size(array, size, 1)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE IN_ARRAY2[ANY][ANY]) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE IN_ARRAY2[ANY][ANY]) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { $1_dim0, $1_dim1 }; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(freearg) + (DATA_TYPE IN_ARRAY2[ANY][ANY]) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} +%typemap(freearg) + (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_fortran_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} +%typemap(freearg) + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_fortran_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; + array = obj_to_array_contiguous_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(freearg) + (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} +%typemap(freearg) + (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + /* for now, only concerned with lists */ + $1 = PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) +{ + npy_intp size[2] = { -1, -1 }; + PyArrayObject* temp_array; + Py_ssize_t i; + int is_new_object; + + /* length of the list */ + $2 = PyList_Size($input); + + /* the arrays */ + array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); + object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); + is_new_object_array = (int *)calloc($2,sizeof(int)); + + if (array == NULL || object_array == NULL || is_new_object_array == NULL) + { + SWIG_fail; + } + + for (i=0; i<$2; i++) + { + temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); + + /* the new array must be stored so that it can be destroyed in freearg */ + object_array[i] = temp_array; + is_new_object_array[i] = is_new_object; + + if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail; + + /* store the size of the first array in the list, then use that for comparison. */ + if (i == 0) + { + size[0] = array_size(temp_array,0); + size[1] = array_size(temp_array,1); + } + + if (!require_size(temp_array, size, 2)) SWIG_fail; + + array[i] = (DATA_TYPE*) array_data(temp_array); + } + + $1 = (DATA_TYPE**) array; + $3 = (DIM_TYPE) size[0]; + $4 = (DIM_TYPE) size[1]; +} +%typemap(freearg) + (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + Py_ssize_t i; + + if (array$argnum!=NULL) free(array$argnum); + + /*freeing the individual arrays if needed */ + if (object_array$argnum!=NULL) + { + if (is_new_object_array$argnum!=NULL) + { + for (i=0; i<$2; i++) + { + if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) + { Py_DECREF(object_array$argnum[i]); } + } + free(is_new_object_array$argnum); + } + free(object_array$argnum); + } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* IN_ARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} +%typemap(freearg) + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* IN_FARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_fortran_allow_conversion($input, + DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3}; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 4) || + !require_size(array, size, 4)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(freearg) + (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY]) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[4] = { -1, -1, -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 4) || + !require_size(array, size, 4)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); + $5 = (DIM_TYPE) array_size(array,3); +} +%typemap(freearg) + (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + /* for now, only concerned with lists */ + $1 = PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL) +{ + npy_intp size[3] = { -1, -1, -1 }; + PyArrayObject* temp_array; + Py_ssize_t i; + int is_new_object; + + /* length of the list */ + $2 = PyList_Size($input); + + /* the arrays */ + array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); + object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); + is_new_object_array = (int *)calloc($2,sizeof(int)); + + if (array == NULL || object_array == NULL || is_new_object_array == NULL) + { + SWIG_fail; + } + + for (i=0; i<$2; i++) + { + temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object); + + /* the new array must be stored so that it can be destroyed in freearg */ + object_array[i] = temp_array; + is_new_object_array[i] = is_new_object; + + if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail; + + /* store the size of the first array in the list, then use that for comparison. */ + if (i == 0) + { + size[0] = array_size(temp_array,0); + size[1] = array_size(temp_array,1); + size[2] = array_size(temp_array,2); + } + + if (!require_size(temp_array, size, 3)) SWIG_fail; + + array[i] = (DATA_TYPE*) array_data(temp_array); + } + + $1 = (DATA_TYPE**) array; + $3 = (DIM_TYPE) size[0]; + $4 = (DIM_TYPE) size[1]; + $5 = (DIM_TYPE) size[2]; +} +%typemap(freearg) + (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + Py_ssize_t i; + + if (array$argnum!=NULL) free(array$argnum); + + /*freeing the individual arrays if needed */ + if (object_array$argnum!=NULL) + { + if (is_new_object_array$argnum!=NULL) + { + for (i=0; i<$2; i++) + { + if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i]) + { Py_DECREF(object_array$argnum[i]); } + } + free(is_new_object_array$argnum); + } + free(object_array$argnum); + } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, + * DATA_TYPE* IN_ARRAY4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[4] = { -1, -1, -1 , -1}; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 4) || + !require_size(array, size, 4)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DIM_TYPE) array_size(array,3); + $5 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[4] = { -1, -1, -1, -1 }; + array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 4) || + !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); + $5 = (DIM_TYPE) array_size(array,3); +} +%typemap(freearg) + (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, + * DATA_TYPE* IN_FARRAY4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[4] = { -1, -1, -1 , -1 }; + array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 4) || + !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DIM_TYPE) array_size(array,3); + $5 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/***************************/ +/* In-Place Array Typemaps */ +/***************************/ + +/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE INPLACE_ARRAY1[ANY]) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE INPLACE_ARRAY1[ANY]) + (PyArrayObject* array=NULL) +{ + npy_intp size[1] = { $1_dim0 }; + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) || + !require_contiguous(array) || !require_native(array)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) + (PyArrayObject* array=NULL, int i=1) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,1) || !require_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = 1; + for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); +} + +/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1) + (PyArrayObject* array=NULL, int i=0) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,1) || !require_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = 1; + for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i); + $2 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) + (PyArrayObject* array=NULL) +{ + npy_intp size[2] = { $1_dim0, $1_dim1 }; + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) || + !require_contiguous(array) || !require_native(array)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) || + !require_native(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) + || !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) || + !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) + (PyArrayObject* array=NULL) +{ + npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 }; + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) || + !require_contiguous(array) || !require_native(array)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) || + !require_native(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} + +/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) +{ + npy_intp size[2] = { -1, -1 }; + PyArrayObject* temp_array; + Py_ssize_t i; + + /* length of the list */ + $2 = PyList_Size($input); + + /* the arrays */ + array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); + object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); + + if (array == NULL || object_array == NULL) + { + SWIG_fail; + } + + for (i=0; i<$2; i++) + { + temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); + + /* the new array must be stored so that it can be destroyed in freearg */ + object_array[i] = temp_array; + + if ( !temp_array || !require_dimensions(temp_array, 2) || + !require_contiguous(temp_array) || + !require_native(temp_array) || + !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) + ) SWIG_fail; + + /* store the size of the first array in the list, then use that for comparison. */ + if (i == 0) + { + size[0] = array_size(temp_array,0); + size[1] = array_size(temp_array,1); + } + + if (!require_size(temp_array, size, 2)) SWIG_fail; + + array[i] = (DATA_TYPE*) array_data(temp_array); + } + + $1 = (DATA_TYPE**) array; + $3 = (DIM_TYPE) size[0]; + $4 = (DIM_TYPE) size[1]; +} +%typemap(freearg) + (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + if (array$argnum!=NULL) free(array$argnum); + if (object_array$argnum!=NULL) free(object_array$argnum); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* INPLACE_ARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) || + !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* INPLACE_FARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) + || !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY]) + (PyArrayObject* array=NULL) +{ + npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 }; + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) || + !require_contiguous(array) || !require_native(array)) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,4) || !require_contiguous(array) || + !require_native(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); + $5 = (DIM_TYPE) array_size(array,3); +} + +/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + $1 = PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL) +{ + npy_intp size[3] = { -1, -1, -1 }; + PyArrayObject* temp_array; + Py_ssize_t i; + + /* length of the list */ + $2 = PyList_Size($input); + + /* the arrays */ + array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *)); + object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *)); + + if (array == NULL || object_array == NULL) + { + SWIG_fail; + } + + for (i=0; i<$2; i++) + { + temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE); + + /* the new array must be stored so that it can be destroyed in freearg */ + object_array[i] = temp_array; + + if ( !temp_array || !require_dimensions(temp_array, 3) || + !require_contiguous(temp_array) || + !require_native(temp_array) || + !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE) + ) SWIG_fail; + + /* store the size of the first array in the list, then use that for comparison. */ + if (i == 0) + { + size[0] = array_size(temp_array,0); + size[1] = array_size(temp_array,1); + size[2] = array_size(temp_array,2); + } + + if (!require_size(temp_array, size, 3)) SWIG_fail; + + array[i] = (DATA_TYPE*) array_data(temp_array); + } + + $1 = (DATA_TYPE**) array; + $3 = (DIM_TYPE) size[0]; + $4 = (DIM_TYPE) size[1]; + $5 = (DIM_TYPE) size[2]; +} +%typemap(freearg) + (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + if (array$argnum!=NULL) free(array$argnum); + if (object_array$argnum!=NULL) free(object_array$argnum); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, + * DATA_TYPE* INPLACE_ARRAY4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,4) || !require_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DIM_TYPE) array_size(array,3); + $5 = (DATA_TYPE*) array_data(array); +} + +/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3, DIM_TYPE DIM4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,4) || !require_contiguous(array) || + !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); + $5 = (DIM_TYPE) array_size(array,3); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* INPLACE_FARRAY4) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,4) || !require_contiguous(array) + || !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DIM_TYPE) array_size(array,3); + $5 = (DATA_TYPE*) array_data(array); +} + +/*************************/ +/* Argout Array Typemaps */ +/*************************/ + +/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY]) + */ +%typemap(in,numinputs=0, + fragment="NumPy_Backward_Compatibility,NumPy_Macros") + (DATA_TYPE ARGOUT_ARRAY1[ANY]) + (PyObject* array = NULL) +{ + npy_intp dims[1] = { $1_dim0 }; + array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(argout) + (DATA_TYPE ARGOUT_ARRAY1[ANY]) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) + */ +%typemap(in,numinputs=1, + fragment="NumPy_Fragments") + (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) + (PyObject* array = NULL) +{ + npy_intp dims[1]; + if (!PyLong_Check($input)) + { + const char* typestring = pytype_string($input); + PyErr_Format(PyExc_TypeError, + "Int dimension expected. '%s' given.", + typestring); + SWIG_fail; + } + $2 = (DIM_TYPE) PyLong_AsSsize_t($input); + if ($2 == -1 && PyErr_Occurred()) SWIG_fail; + dims[0] = (npy_intp) $2; + array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); +} +%typemap(argout) + (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) + */ +%typemap(in,numinputs=1, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) + (PyObject* array = NULL) +{ + npy_intp dims[1]; + if (!PyLong_Check($input)) + { + const char* typestring = pytype_string($input); + PyErr_Format(PyExc_TypeError, + "Int dimension expected. '%s' given.", + typestring); + SWIG_fail; + } + $1 = (DIM_TYPE) PyLong_AsSsize_t($input); + if ($1 == -1 && PyErr_Occurred()) SWIG_fail; + dims[0] = (npy_intp) $1; + array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $2 = (DATA_TYPE*) array_data(array); +} +%typemap(argout) + (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) + */ +%typemap(in,numinputs=0, + fragment="NumPy_Backward_Compatibility,NumPy_Macros") + (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) + (PyObject* array = NULL) +{ + npy_intp dims[2] = { $1_dim0, $1_dim1 }; + array = PyArray_SimpleNew(2, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(argout) + (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY]) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) + */ +%typemap(in,numinputs=0, + fragment="NumPy_Backward_Compatibility,NumPy_Macros") + (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) + (PyObject* array = NULL) +{ + npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 }; + array = PyArray_SimpleNew(3, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(argout) + (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY]) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) + */ +%typemap(in,numinputs=0, + fragment="NumPy_Backward_Compatibility,NumPy_Macros") + (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) + (PyObject* array = NULL) +{ + npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 }; + array = PyArray_SimpleNew(4, dims, DATA_TYPECODE); + if (!array) SWIG_fail; + $1 = ($1_ltype) array_data(array); +} +%typemap(argout) + (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY]) +{ + $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum); +} + +/*****************************/ +/* Argoutview Array Typemaps */ +/*****************************/ + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) +{ + $1 = &data_temp; + $2 = &dim_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) +{ + npy_intp dims[1] = { *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEW_ARRAY1) + (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim_temp; + $2 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) +{ + npy_intp dims[1] = { *$1 }; + PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) +{ + npy_intp dims[2] = { *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_ARRAY2) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) +{ + npy_intp dims[2] = { *$1, *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) +{ + npy_intp dims[2] = { *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) +{ + npy_intp dims[2] = { *$1, *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[3] = { *$2, *$3, *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, + DATA_TYPE** ARGOUTVIEW_ARRAY3) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) +{ + npy_intp dims[3] = { *$1, *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[3] = { *$2, *$3, *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, + DATA_TYPE** ARGOUTVIEW_FARRAY3) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEW_FARRAY3) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) +{ + npy_intp dims[3] = { *$1, *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEW_ARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_ARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEW_FARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEW_FARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/*************************************/ +/* Managed Argoutview Array Typemaps */ +/*************************************/ + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim_temp) +{ + $1 = &data_temp; + $2 = &dim_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1) +{ + npy_intp dims[1] = { *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DATA_TYPE** ARGOUTVIEWM_ARRAY1) + (DIM_TYPE dim_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim_temp; + $2 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1) +{ + npy_intp dims[1] = { *$1 }; + PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$2), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$2), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) +{ + npy_intp dims[2] = { *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_ARRAY2) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2) +{ + npy_intp dims[2] = { *$1, *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$3), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) +{ + npy_intp dims[2] = { *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEWM_FARRAY2) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2) +{ + npy_intp dims[2] = { *$1, *$2 }; + PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$3), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[3] = { *$2, *$3, *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, + DATA_TYPE** ARGOUTVIEWM_ARRAY3) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_ARRAY3) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3) +{ + npy_intp dims[3] = { *$1, *$2, *$3 }; + PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$4), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[3] = { *$2, *$3, *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, + DATA_TYPE** ARGOUTVIEWM_FARRAY3) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DATA_TYPE** ARGOUTVIEWM_FARRAY3) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3) +{ + npy_intp dims[3] = { *$1, *$2, *$3 }; + PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$4), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEWM_ARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEWM_FARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEWM_ARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3, DIM_TYPE* DIM4) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 ) + (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; + $5 = &dim4_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4) +{ + npy_intp dims[4] = { *$2, *$3, *$4 , *$5 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, + DATA_TYPE** ARGOUTVIEWM_FARRAY4) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &dim4_temp; + $5 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4) +{ + npy_intp dims[4] = { *$1, *$2, *$3 , *$4 }; + PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5)); + PyArrayObject* array = (PyArrayObject*) obj; + + if (!array || !require_fortran(array)) SWIG_fail; + +%#ifdef SWIGPY_USE_CAPSULE + PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap); +%#else + PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free); +%#endif + +%#if NPY_API_VERSION < 0x00000007 + PyArray_BASE(array) = cap; +%#else + PyArray_SetBaseObject(array,cap); +%#endif + + $result = SWIG_Python_AppendOutput($result,obj); +} + +/**************************************/ +/* In-Place Array Typemap - flattened */ +/**************************************/ + +/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT) + (PyArrayObject* array=NULL, int i=1) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_c_or_f_contiguous(array) + || !require_native(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = 1; + for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i); +} + +%enddef /* %numpy_typemaps() macro */ +/* *************************************************************** */ + +/* Concrete instances of the %numpy_typemaps() macro: Each invocation + * below applies all of the typemaps above to the specified data type. + */ +%numpy_typemaps(signed char , NPY_BYTE , int) +%numpy_typemaps(unsigned char , NPY_UBYTE , int) +%numpy_typemaps(short , NPY_SHORT , int) +%numpy_typemaps(unsigned short , NPY_USHORT , int) +%numpy_typemaps(int , NPY_INT , int) +%numpy_typemaps(unsigned int , NPY_UINT , int) +%numpy_typemaps(long , NPY_LONG , int) +%numpy_typemaps(unsigned long , NPY_ULONG , int) +%numpy_typemaps(long long , NPY_LONGLONG , int) +%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int) +%numpy_typemaps(float , NPY_FLOAT , int) +%numpy_typemaps(double , NPY_DOUBLE , int) +%numpy_typemaps(int8_t , NPY_INT8 , int) +%numpy_typemaps(int16_t , NPY_INT16 , int) +%numpy_typemaps(int32_t , NPY_INT32 , int) +%numpy_typemaps(int64_t , NPY_INT64 , int) +%numpy_typemaps(uint8_t , NPY_UINT8 , int) +%numpy_typemaps(uint16_t , NPY_UINT16 , int) +%numpy_typemaps(uint32_t , NPY_UINT32 , int) +%numpy_typemaps(uint64_t , NPY_UINT64 , int) + + +/* *************************************************************** + * The follow macro expansion does not work, because C++ bool is 4 + * bytes and NPY_BOOL is 1 byte + * + * %numpy_typemaps(bool, NPY_BOOL, int) + */ + +/* *************************************************************** + * On my Mac, I get the following warning for this macro expansion: + * 'swig/python detected a memory leak of type 'long double *', no destructor found.' + * + * %numpy_typemaps(long double, NPY_LONGDOUBLE, int) + */ + +#ifdef __cplusplus + +%include + +%numpy_typemaps(std::complex, NPY_CFLOAT , int) +%numpy_typemaps(std::complex, NPY_CDOUBLE, int) + +#endif + +#endif /* SWIGPYTHON */ From 8da3b3ced8367b80ad190559487a636b15763e46 Mon Sep 17 00:00:00 2001 From: deseilligny Date: Tue, 18 May 2021 15:52:27 +0200 Subject: [PATCH 25/25] Reord MMVII_all --- MMVII/include/MMVII_Mappings.h | 73 +++++++++++++++++++ MMVII/include/MMVII_all.h | 3 +- MMVII/src/Mappings/MappingSymDer.cpp | 42 ++--------- MMVII/src/Mappings/cLeastSqComputeMaps.cpp | 82 ++++++++++++++++++++++ 4 files changed, 163 insertions(+), 37 deletions(-) create mode 100644 MMVII/src/Mappings/cLeastSqComputeMaps.cpp diff --git a/MMVII/include/MMVII_Mappings.h b/MMVII/include/MMVII_Mappings.h index a494b2849c..9d8e6dcfd5 100644 --- a/MMVII/include/MMVII_Mappings.h +++ b/MMVII/include/MMVII_Mappings.h @@ -379,6 +379,50 @@ template class cMappingIdentity : public cDataMappin const tVecPt & Values(tVecPt &,const tVecPt & ) const override; }; +template + class cDataMapCalcSymbDer : public cDataMapping +{ + public : + typedef typename NS_SymbolicDerivative::cCalculator tCalc; + typedef cDataMapping tDataMap; + + using typename tDataMap::tVecIn; + using typename tDataMap::tVecOut; + using typename tDataMap::tCsteResVecJac; + using typename tDataMap::tResVecJac; + using typename tDataMap::tVecJac; + using typename tDataMap::tPtIn; + using typename tDataMap::tPtOut; + + const tVecOut & Values(tVecOut &,const tVecIn & ) const override; //V2 + tCsteResVecJac Jacobian(tResVecJac,const tVecIn &) const override; //J2 + + cDataMapCalcSymbDer(tCalc * aCalcVal,tCalc * aCalcDer,const std::vector & aVObs); + void SetObs(const std::vector &); + + private : + void CheckDim(tCalc *,bool Derive); + tCalc * mCalcVal; + tCalc * mCalcDer; + std::vector mVObs; +}; + +/** + Sometime we want to manipulate "small" maping directly, with no virtual interface, + an after reuse these code in global mappings, this is possible if the "small" mapping + complies with the following "contract" : + + define the type : typedef Type TheType; + degines its dimension : static constexpr int TheDim=2; + defines its degree of freedom : static const int NbDOF() {return 4;} + defiens direct mapping : inline tPt Value(const tPt & aP) + defines inverst mapping for a point : inline tPt Inverse(const tPt & aP) + defines global invert map : cSim2D MapInverse() const + + See class cSim2D for an example of elementary mapping. + +*/ + template class cInvertMappingFromElem : public cDataInvertibleMapping { @@ -403,6 +447,35 @@ template class cInvertMappingFromElem : public cIMapElem mIMap; // Map inverse }; +/** + We have a set of function F1, .. Fp R^k => R ^n + + We have samples Km , Nm + + We want to solve by lest square : + Sum Al Fl (Km) = Nm +*/ +template class cLeastSqComputeMaps +{ + public : + typedef cPtxd tPtOut; + typedef cPtxd tPtIn; + typedef std::vector tVecIn; + typedef std::vector tVecOut; + + cLeastSqComputeMaps(size_t aNbFunc); + void AddObs(const tPtIn & aPt,const tPtOut & aValue,const tPtOut & aPds); + void AddObs(const tPtIn & aPt,const tPtOut & aValue,const Type & aPds); + void AddObs(const tPtIn & aPt,const tPtOut & aValue); + private : + virtual void ComputeValFuncsBase(tVecOut &,const tPtIn & aPt) = 0; + size_t mNbFunc; + cLeasSqtAA mLSQ; + cDenseVect mCoeffs; + tVecOut mBufPOut; +}; + + /* diff --git a/MMVII/include/MMVII_all.h b/MMVII/include/MMVII_all.h index 12c47c182f..fead425bbf 100644 --- a/MMVII/include/MMVII_all.h +++ b/MMVII/include/MMVII_all.h @@ -42,6 +42,8 @@ #include "MMVII_util.h" +// Must be here : after general class, used in case WITH_MMVII, before class using cCalculator +#include "SymbDer/SymbDer_Common.h" // Les class cPtxd, cPt1d, cPt2d #include "MMVII_Ptxd.h" @@ -76,7 +78,6 @@ #include "MMVII_MMV1Compat.h" // #include "MMVII_Derivatives.h" => not include by default now, requires => time consuming -#include "SymbDer/SymbDer_Common.h" #include "../kapture/kapture.h" #include "MMVII_PhgrDist.h" diff --git a/MMVII/src/Mappings/MappingSymDer.cpp b/MMVII/src/Mappings/MappingSymDer.cpp index 8679522cf4..fc70b52dee 100644 --- a/MMVII/src/Mappings/MappingSymDer.cpp +++ b/MMVII/src/Mappings/MappingSymDer.cpp @@ -7,44 +7,9 @@ namespace MMVII { /* ============================================= */ -/* cDataMapping */ +/* cDataMapCalcSymbDer */ /* ============================================= */ -template - class cDataMapCalcSymbDer : public cDataMapping -{ - public : - typedef cCalculator tCalc; - typedef cDataMapping tDataMap; - - using typename tDataMap::tVecIn; - using typename tDataMap::tVecOut; - using typename tDataMap::tCsteResVecJac; - using typename tDataMap::tResVecJac; - using typename tDataMap::tVecJac; - using typename tDataMap::tPtIn; - using typename tDataMap::tPtOut; -/* - typedef typename tDataMap::tVecIn tVecIn; - typedef typename tDataMap::tPtIn tPtIn; - typedef typename tDataMap::tPtOut tPtOut; - typedef typename tDataMap::tVecOut tVecOut; - typedef typename tDataMap::tCsteResVecJac tCsteResVecJac; - typedef typename tDataMap::tResVecJac tResVecJac; -*/ - - const tVecOut & Values(tVecOut &,const tVecIn & ) const override; //V2 - tCsteResVecJac Jacobian(tResVecJac,const tVecIn &) const override; //J2 - - cDataMapCalcSymbDer(tCalc * aCalcVal,tCalc * aCalcDer,const std::vector & aVObs); - void SetObs(const std::vector &); - - private : - void CheckDim(tCalc *,bool Derive); - tCalc * mCalcVal; - tCalc * mCalcDer; - std::vector mVObs; -}; template void cDataMapCalcSymbDer::CheckDim(tCalc * aCalc,bool Derive) @@ -164,6 +129,11 @@ template class cDataDistCloseId : cDataIterInvertMap }; */ + +/* ============================================= */ +/* TEST */ +/* ============================================= */ + bool BUGINVMAP =false; void TestJacob(cDataMapCalcSymbDer * aMCS,const cPt2dr & aP) diff --git a/MMVII/src/Mappings/cLeastSqComputeMaps.cpp b/MMVII/src/Mappings/cLeastSqComputeMaps.cpp new file mode 100644 index 0000000000..00cce7bf3f --- /dev/null +++ b/MMVII/src/Mappings/cLeastSqComputeMaps.cpp @@ -0,0 +1,82 @@ +#include "include/MMVII_all.h" + +namespace MMVII +{ + +/* ============================================= */ +/* cLeastSqComputeMaps */ +/* ============================================= */ + +template + cLeastSqComputeMaps::cLeastSqComputeMaps(size_t aNbFunc) : + mNbFunc (aNbFunc), + mLSQ (aNbFunc), + mCoeffs (aNbFunc), + mBufPOut (aNbFunc) +{ +} + +template + void cLeastSqComputeMaps::AddObs + (const tPtIn & aPtIn,const tPtOut & aValue,const tPtOut & aPds) +{ + ComputeValFuncsBase(mBufPOut,aPtIn); + cDataIm1D & aDIm = mCoeffs.DIm(); + + for (size_t aD=0 ; aD + void cLeastSqComputeMaps::AddObs + (const tPtIn & aPtIn,const tPtOut & aValue,const Type & aPds) +{ + AddObs(aPtIn,aValue,tPtOut::PCste(aPds)); +} + +template + void cLeastSqComputeMaps::AddObs + (const tPtIn & aPtIn,const tPtOut & aValue) +{ + AddObs(aPtIn,aValue,1.0); +} + + +/* ===================================================== */ +/* ===== INSTANTIATION ===== */ +/* ===================================================== */ + +#define INSTANTIATE_LSQMAP(TYPE,DIMIN,DIMOUT)\ +template class cLeastSqComputeMaps; + +INSTANTIATE_LSQMAP(tREAL8,3,2) + +/* +#define INSTANTIATE_OPMulMatVect(T1,T2)\ +template cDenseVect operator * (const cDenseVect & aVL,const cUnOptDenseMatrix& aMat);\ +template cDenseVect operator * (const cUnOptDenseMatrix& aVC,const cDenseVect & aMat);\ +template cDenseVect operator * (const cDenseVect & aVL,const cDenseMatrix& aMat);\ +template cDenseVect operator * (const cDenseMatrix& aVC,const cDenseVect & aMat);\ + + +#define INSTANTIATE_DENSE_MATRICES(Type)\ +template class cUnOptDenseMatrix;\ +template class cDenseMatrix;\ +template cDenseMatrix operator * (const cDenseMatrix &,const cDenseMatrix&);\ +template cUnOptDenseMatrix operator * (const cUnOptDenseMatrix &,const cUnOptDenseMatrix&);\ +INSTANTIATE_OPMulMatVect(Type,Type)\ + + +INSTANTIATE_DENSE_MATRICES(tREAL4) +INSTANTIATE_DENSE_MATRICES(tREAL8) +INSTANTIATE_DENSE_MATRICES(tREAL16) +*/ + + +};