Skip to content

Commit

Permalink
MMVII: Code generation: can add programmer's comments to generated code
Browse files Browse the repository at this point in the history
  • Loading branch information
meynardc committed Feb 29, 2024
1 parent 12e33bb commit a40d941
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 23 deletions.
36 changes: 31 additions & 5 deletions MMVII/Doc/Programmer/NonLinearOptim.tex
Original file line number Diff line number Diff line change
Expand Up @@ -297,19 +297,45 @@ \subsection{class for specifying the formulas}
single value, because in general, when we want to compute several values (like
$x$ and $y$ residual in BA) its more efficient and convenient to group
a multiple residual in a single formula that generating different formulas;
\item the commented lines show how to use {\tt SymbPrint()} and
{\tt SymbPrintDer()} to display at run time computed value of
expressions or parts of expression in the formula.
\item below this function, there is another version which is commented. It's showing
how to use {\tt SymbPrint()}, {\tt SymbPrintDer()}, {\tt SymbComment()} and
{\tt SymbCommentDer()} to document the generated code or to output (print)
values of expressions or parts of expression in the formula.
\begin{itemize}
\item {\tt SymbPrint(expr, mesg)} will display
\item {\tt SymbComment(expr, comment)} will place {\tt comment} as a comment
on the line in the generated code where a tempory variable will be assigned
the value of expr.
\item {\tt SymbCommentDer(expr, k, comment)} will place {\tt comment} as a comment
on the line in the generated code where a tempory variable will be assigned
the value of the derivative of expr with respect to the kth unknown.
\item {\tt SymbPrint(expr, mesg)} will generate code to display at runtime
"[i] mesg = (value of expr)", i being the current iteration of the loop
when multiple values are calculated simultaneously.
\item {\tt SymbPrintDer(expr, k, mesg)} will display
\item {\tt SymbPrintDer(expr, k, mesg)} will generate code to display at runtime
"[i] mesg = (value of derivative)", derivative being the derivative
of expr with respect to the kth Unknown.
\item to enable the output of this value, SetDebugEnabled(true) must be called
before on the calculator. See \ref{CreateCalc}
\end{itemize}
With this (commented) example formula, the generated code would look like this:
\begin{lstlisting}
<...>
double F31_ = (F30_ - 1); // f
double F28_ = (F27_ / F14_); // d(|v|)/d(p2.y)
double F18_ = (F17_ / F14_); // d(|v|)/d(p1.x)
double F33_ = (D * F18_);
double F39_ = (D * F28_);
double F34_ = (F33_ / F32_); // d(f)/d(p1.x)
double F40_ = (F39_ / F32_); // d(f)/d(p2.y)
if (IsDebugEnabled()) {
MMVII::StdOut()<< "[" << aK << "] Vx=" << F9_ << std::endl;
MMVII::StdOut()<< "[" << aK << "] Vy=" << F8_ << std::endl;
MMVII::StdOut()<< "[" << aK << "] Dist2DConst=" << F31_ << std::endl;
MMVII::StdOut()<< "[" << aK << "] d(dist2DConst)/d(p1.x)=" << F34_ << std::endl;
MMVII::StdOut()<< "[" << aK << "] d(Dist2DConst)/d(p2.y)=" << F40_ << std::endl;
}
<...>
\end{lstlisting}
\end{itemize}

As a slightly more complex example, the reader can investigate example {\tt cRatioDist2DConservation}
Expand Down
39 changes: 27 additions & 12 deletions MMVII/include/SymbDer/SymbolicDerivatives.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,10 @@ template <class TypeElem> class cCoordinatorF : public cCalculator<TypeElem> //
{
mVDebugF.emplace_back(aPF,aMesg);
}
const std::vector<tFormula>& VDebug() const {return mVDebugF;}
inline void AddComment(const tFormula& aPF, const std::string& aComment)
{
mVCommentF.emplace_back(aPF,aComment);
}


size_t NbCurFonc() const {return mVAllFormula.size();}
Expand Down Expand Up @@ -420,6 +423,7 @@ template <class TypeElem> class cCoordinatorF : public cCalculator<TypeElem> //
std::vector<tFormula> mVCurF; ///< Current evaluted formulas
std::vector<tFormula> mVReachedF; ///< Formula "reachable" i.e. necessary to comput mVCurF
std::vector<std::pair<tFormula,std::string>> mVDebugF; ///< Formula whose value must be displayed
std::vector<std::pair<tFormula,std::string>> mVCommentF; ///< Formula which will be commented in generated code

std::string mHeaderIncludeSymbDer; ///< Compilation environment may want to change it
std::string mDirGenCode; ///< Want to put generated code in a fixed folde ?
Expand Down Expand Up @@ -1166,9 +1170,16 @@ std::pair<std::string,std::string> cCoordinatorF<TypeElem>::GenCodeCommon(const
aOs << " " << aTypeName << " &" << aForm->GenCodeFormName() << " = " << aForm->GenCodeExpr() << ";\n";
}
for (const auto & aForm : mVReachedF) {
if (!aForm->isAtomic())
aOs << " " << aTypeName << " " << aForm->GenCodeFormName() << " = " << aForm->GenCodeExpr() << ";\n";
if (!aForm->isAtomic()) {
aOs << " " << aTypeName << " " << aForm->GenCodeFormName() << " = " << aForm->GenCodeExpr() << ";";
auto aCommentIt = std::find_if(mVCommentF.begin(),mVCommentF.end(),[&aForm](auto& aF) {return aF.first->GenCodeFormName() == aForm->GenCodeFormName();}) ;
if (aCommentIt != mVCommentF.end()) {
aOs << " // " << aCommentIt->second;
}
aOs << "\n";
}
}

if (mVDebugF.size())
aOs << " if (IsDebugEnabled()) {\n";
for (const auto & aDebugF: mVDebugF) {
Expand Down Expand Up @@ -1231,28 +1242,32 @@ inline std::string cCoordinatorF<TypeElem>::TypeElemName() const
// SymbPrintDer(aDist,1,"d(dist)/dy")


template <class T>
inline const T SymbPrint(const T & t, const std::string& aMesg)
template <class TypeElem>
inline const cFormula<TypeElem> SymbPrint(const cFormula<TypeElem> & aF, const std::string& aMesg)
{
return t;
aF->CoordF()->AddDebug(aF, aMesg);
return aF;
}

template <class T>
inline void SymbPrintDer(const T & t, int aK, const std::string& aMesg)
template <class TypeElem>
inline void SymbPrintDer(const cFormula<TypeElem> & aF, int aK, const std::string& aMesg)
{
aF->CoordF()->AddDebug(aF->Derivate(aK), aMesg);
}


template <class TypeElem>
inline const cFormula<TypeElem> SymbPrint(const cFormula<TypeElem> & aF, const std::string& aMesg)
inline const cFormula<TypeElem> SymbComment(const cFormula<TypeElem> & aF, const std::string& aComment)
{
aF->CoordF()->AddDebug(aF, aMesg);
aF->CoordF()->AddComment(aF, aComment);
return aF;
}

template <class TypeElem>
inline void SymbPrintDer(const cFormula<TypeElem> & aF, int aK, const std::string& aMesg)
inline const cFormula<TypeElem> SymbCommentDer(const cFormula<TypeElem> & aF, int aK, const std::string& aComment)
{
aF->CoordF()->AddDebug(aF->Derivate(aK), aMesg);
aF->CoordF()->AddComment(aF->Derivate(aK), aComment);
return aF;
}


Expand Down
52 changes: 46 additions & 6 deletions MMVII/src/SymbDerGen/Formulas_Geom2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class cDist2DConservation

std::string FormulaName() const { return "Dist2DCons";}

/*
template <typename tUk,typename tObs>
static std::vector<tUk> formula
(
Expand All @@ -78,19 +79,58 @@ class cDist2DConservation
cPtxd<tUk,2> p1 = VtoP2(aVUk,0);
cPtxd<tUk,2> p2 = VtoP2(aVUk,2);
cPtxd<tUk,2> v = p2-p1;
const auto & ObsDist = aVObs[0];
const auto aCst1 = CreateCste(1.0,p1.x()); // create a symbolic formula for constant 1
// SymbPrint(v,"v");
// SymbPrint(Norm2(v)/ObsDist - aCst1,"Dist2DConst");
// SymbPrintDer(Norm2(v)/ObsDist - aCst1,0,"d(Dist2DConst)/d(p1.x)");
// SymbPrintDer(Norm2(v)/ObsDist - aCst1,3,"d(Dist2DConst)/d(p2.y)");
const auto & ObsDist = aVObs[0];
const auto aCst1 = CreateCste(1.0,p1.x()); // create a symbolic formula for constant 1
return { Norm2(v)/ObsDist - aCst1 } ;
// return { sqrt(square(v.x())+square(v.y()))/ObsDist - aCst1 } ;
}
*/

// Alternate version of the same formula, showing use case of SymbPrint and SymbComment

template <typename tUk,typename tObs>
static std::vector<tUk> formula
(
const std::vector<tUk> & aVUk,
const std::vector<tObs> & aVObs
) // const
{
cPtxd<tUk,2> p1 = VtoP2(aVUk,0);
cPtxd<tUk,2> p2 = VtoP2(aVUk,2);
cPtxd<tUk,2> v = p2-p1;
SymbComment(v.x(),"Vx");
SymbComment(v.y(),"Vy");
SymbComment(Norm2(v),"|v|");
SymbCommentDer(Norm2(v),0,"d(|v|)/d(p1.x)");
SymbCommentDer(Norm2(v),1,"d(|v|)/d(p1.y)");
SymbCommentDer(Norm2(v),2,"d(|v|)/d(p2.x)");
SymbCommentDer(Norm2(v),3,"d(|v|)/d(p2.y)");

const auto & ObsDist = aVObs[0];
const auto aCst1 = CreateCste(1.0,p1.x()); // create a symbolic formula for constant 1

auto result = Norm2(v)/ObsDist - aCst1;

SymbComment(result,"f");
SymbCommentDer(result,0,"d(f)/d(p1.x)");
SymbCommentDer(result,1,"d(f)/d(p1.y)");
SymbCommentDer(result,2,"d(f)/d(p2.x)");
SymbCommentDer(result,3,"d(f)/d(p2.y)");

SymbPrint(v.x(),"Vx");
SymbPrint(v.y(),"Vy");
SymbPrint(result,"Dist2DConst");
SymbPrintDer(result,0,"d(dist2DConst)/d(p1.x)");
SymbPrintDer(result,3,"d(Dist2DConst)/d(p2.y)");

return { result } ;
// return { sqrt(square(v.x())+square(v.y()))/ObsDist - aCst1 } ;
}
};


/** Class for generating code relative to 2D-"RATIO of distance" */

class cRatioDist2DConservation
Expand Down

0 comments on commit a40d941

Please sign in to comment.