Skip to content

Commit

Permalink
Fixes #148 NaNs in boolean formulas (also in If-Formulas and MinMax-F…
Browse files Browse the repository at this point in the history
…ormulas) (#154)

Co-authored-by: Yuri05 <[email protected]>
  • Loading branch information
Yuri05 and Yuri05 authored Oct 21, 2022
1 parent 2eca67a commit 5b57055
Show file tree
Hide file tree
Showing 8 changed files with 534 additions and 121 deletions.
135 changes: 72 additions & 63 deletions src/OSPSuite.SimModelNative/include/SimModel/BooleanFormula.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef _BooleanFormula_H_
#define _BooleanFormula_H_

#include <functional>

#include "SimModel/Formula.h"

namespace SimModelNative
Expand All @@ -10,151 +12,158 @@ class BooleanFormula :
public Formula
{
protected:
Formula * m_SecondOperandFormula;
Formula * m_FirstOperandFormula;
Formula * m_SecondOperandFormula;
Formula * m_FirstOperandFormula;

std::vector <double> SwitchTimePointFromComparisonFormula();
std::vector <double> SwitchTimePointFromComparisonFormula() const;

//this function is called by all logical formulas with 2 arguments
// it checks if one of the arguments is NaN and returns NaN in such a case;
// otherwise it performs the logical operation passed as the last argument
double calculate_binaryOperation(const double* y, const double time, ScaleFactorUsageMode scaleFactorMode, const std::function<double(double,double)> & logicalOperation) const;

//same as calculate_binaryOperation, but for logical formulas with ONE argument
double calculate_unaryOperation(const double* y, const double time, ScaleFactorUsageMode scaleFactorMode, const std::function<double(double)>& logicalOperation) const;

public:
BooleanFormula ();
virtual ~BooleanFormula ();
BooleanFormula ();
virtual ~BooleanFormula ();

virtual void LoadFromXMLNode (const XMLNode & pNode);
virtual void XMLFinalizeInstance (const XMLNode & pNode, Simulation * sim);
virtual void SetQuantityReference (const QuantityReference & quantityReference);
virtual void DE_Jacobian (double * * jacobian, const double * y, const double time, const int iEquation, const double preFactor);
virtual Formula * DE_Jacobian(const int iEquation);
virtual Formula * clone() = 0;
virtual Formula * RecursiveSimplify();
void setFormula(Formula* FirstOperandFormula, Formula* SecondOperandFormula);
virtual void LoadFromXMLNode (const XMLNode & pNode);
virtual void XMLFinalizeInstance (const XMLNode & pNode, Simulation * sim);
virtual void SetQuantityReference (const QuantityReference & quantityReference);
virtual void DE_Jacobian (double * * jacobian, const double * y, const double time, const int iEquation, const double preFactor);
virtual Formula * DE_Jacobian(const int iEquation);
virtual Formula * clone() = 0;
virtual Formula * RecursiveSimplify();
void setFormula(Formula* FirstOperandFormula, Formula* SecondOperandFormula);

virtual void Finalize();
virtual void Finalize();

virtual std::vector <double> SwitchTimePoints();
virtual std::vector <double> SwitchTimePoints();

virtual bool IsZero(void);
virtual bool IsZero(void);

virtual void AppendUsedVariables(std::set<int> & usedVariablesIndices, const std::set<int> & variablesIndicesUsedInSwitchAssignments);
virtual void AppendUsedParameters(std::set<int> & usedParameterIDs);
void SwitchFormulaFromComparisonFormula(std::vector<Formula*> &vecExplicit, std::vector<Formula*> &vecImplicit);
virtual void AppendUsedVariables(std::set<int> & usedVariablesIndices, const std::set<int> & variablesIndicesUsedInSwitchAssignments);
virtual void AppendUsedParameters(std::set<int> & usedParameterIDs);
void SwitchFormulaFromComparisonFormula(std::vector<Formula*> &vecExplicit, std::vector<Formula*> &vecImplicit) const;

virtual void UpdateIndicesOfReferencedVariables();
virtual void UpdateIndicesOfReferencedVariables();
};

class AndFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual bool IsZero(void); //special treatment for the AND-formula
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual bool IsZero(void); //special treatment for the AND-formula

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class EqualFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class GreaterEqualFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class GreaterFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class LessEqualFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class LessFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class NotFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class OrFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

class UnequalFormula :
public BooleanFormula
{
public:
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();
virtual double DE_Compute (const double * y, const double time, ScaleFactorUsageMode scaleFactorMode);
virtual Formula* clone();
virtual std::vector <double> SwitchTimePoints();

protected:
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
virtual void WriteFormulaMatlabCode (std::ostream & mrOut);
virtual void WriteFormulaCppCode (std::ostream & mrOut);
};

}//.. end "namespace SimModelNative"
Expand Down
Loading

0 comments on commit 5b57055

Please sign in to comment.