add cubic root to dynare language

issue#70
Houtan Bastani 2019-07-15 12:18:26 -04:00
parent deb41a2a8f
commit ae0a91256a
No known key found for this signature in database
GPG Key ID: 000094FB955BE169
8 changed files with 56 additions and 2 deletions

View File

@ -191,6 +191,7 @@ enum class UnaryOpcode
asinh,
atanh,
sqrt,
cbrt,
abs,
sign,
steadyState,

View File

@ -35,6 +35,7 @@ DataTree::initConstants()
Zero = AddNonNegativeConstant("0");
One = AddNonNegativeConstant("1");
Two = AddNonNegativeConstant("2");
Three = AddNonNegativeConstant("3");
MinusOne = AddUMinus(One);
@ -517,6 +518,17 @@ DataTree::AddSqrt(expr_t iArg1)
return Zero;
}
expr_t
DataTree::AddCbrt(expr_t iArg1)
{
if (iArg1 == Zero)
return Zero;
else if (iArg1 == One)
return One;
else
return AddUnaryOp(UnaryOpcode::cbrt, iArg1);
}
expr_t
DataTree::AddAbs(expr_t iArg1)
{

View File

@ -132,7 +132,7 @@ public:
DataTree & operator=(DataTree &&) = delete;
//! Some predefined constants
expr_t Zero, One, Two, MinusOne, NaN, Infinity, MinusInfinity, Pi;
expr_t Zero, One, Two, Three, MinusOne, NaN, Infinity, MinusInfinity, Pi;
//! Raised when a local parameter is declared twice
class LocalVariableException
@ -221,6 +221,8 @@ public:
expr_t AddAtanh(expr_t iArg1);
//! Adds "sqrt(arg)" to model tree
expr_t AddSqrt(expr_t iArg1);
//! Adds "cbrt(arg)" to model tree
expr_t AddCbrt(expr_t iArg1);
//! Adds "abs(arg)" to model tree
expr_t AddAbs(expr_t iArg1);
//! Adds "sign(arg)" to model tree

View File

@ -127,7 +127,7 @@ class ParsingDriver;
%precedence UMINUS UPLUS
%nonassoc POWER
%token EXP LOG LN LOG10 SIN COS TAN ASIN ACOS ATAN ERF DIFF ADL AUXILIARY_MODEL_NAME
%token SQRT NORMCDF NORMPDF STEADY_STATE EXPECTATION VAR_ESTIMATION
%token SQRT CBRT NORMCDF NORMPDF STEADY_STATE EXPECTATION VAR_ESTIMATION
/* GSA analysis */
%token DYNARE_SENSITIVITY MORRIS STAB REDFORM PPRIOR PRIOR_RANGE PPOST ILPTAU MORRIS_NLIV
%token MORRIS_NTRA NSAM LOAD_REDFORM LOAD_RMSE LOAD_STAB ALPHA2_STAB LOGTRANS_REDFORM THRESHOLD_REDFORM
@ -800,6 +800,8 @@ expression : '(' expression ')'
{ $$ = driver.add_atan($3); }
| SQRT '(' expression ')'
{ $$ = driver.add_sqrt($3); }
| CBRT '(' expression ')'
{ $$ = driver.add_cbrt($3); }
| ABS '(' expression ')'
{ $$ = driver.add_abs($3); }
| SIGN '(' expression ')'

View File

@ -830,6 +830,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2]))
<DYNARE_STATEMENT,DYNARE_BLOCK>acos {return token::ACOS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>atan {return token::ATAN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>sqrt {return token::SQRT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>cbrt {return token::CBRT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>max {return token::MAX;}
<DYNARE_STATEMENT,DYNARE_BLOCK>min {return token::MIN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>abs {return token::ABS;}

View File

@ -2171,6 +2171,10 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id)
case UnaryOpcode::sqrt:
t11 = datatree.AddPlus(this, this);
return datatree.AddDivide(darg, t11);
case UnaryOpcode::cbrt:
t11 = datatree.AddPower(arg, datatree.AddDivide(datatree.Two, datatree.Three));
t12 = datatree.AddTimes(datatree.Three, t11);
return datatree.AddDivide(darg, t12);
case UnaryOpcode::abs:
t11 = datatree.AddSign(arg);
return datatree.AddTimes(t11, darg);
@ -2313,6 +2317,7 @@ UnaryOpNode::cost(int cost, bool is_matlab) const
case UnaryOpcode::atanh:
return cost + 350;
case UnaryOpcode::sqrt:
case UnaryOpcode::cbrt:
case UnaryOpcode::abs:
return cost + 570;
case UnaryOpcode::steadyState:
@ -2361,6 +2366,7 @@ UnaryOpNode::cost(int cost, bool is_matlab) const
case UnaryOpcode::atanh:
return cost + 150;
case UnaryOpcode::sqrt:
case UnaryOpcode::cbrt:
case UnaryOpcode::abs:
return cost + 90;
case UnaryOpcode::steadyState:
@ -2500,6 +2506,9 @@ UnaryOpNode::writeJsonAST(ostream &output) const
case UnaryOpcode::sqrt:
output << "sqrt";
break;
case UnaryOpcode::cbrt:
output << "cbrt";
break;
case UnaryOpcode::abs:
output << "abs";
break;
@ -2618,6 +2627,9 @@ UnaryOpNode::writeJsonOutput(ostream &output,
case UnaryOpcode::sqrt:
output << "sqrt";
break;
case UnaryOpcode::cbrt:
output << "cbrt";
break;
case UnaryOpcode::abs:
output << "abs";
break;
@ -2774,6 +2786,9 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
case UnaryOpcode::sqrt:
output << "sqrt";
break;
case UnaryOpcode::cbrt:
output << "cbrt";
break;
case UnaryOpcode::abs:
output << "abs";
break;
@ -2957,6 +2972,8 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) noexcept(false)
return (atanh(v));
case UnaryOpcode::sqrt:
return (sqrt(v));
case UnaryOpcode::cbrt:
return (cbrt(v));
case UnaryOpcode::abs:
return (abs(v));
case UnaryOpcode::sign:
@ -3107,6 +3124,9 @@ UnaryOpNode::normalizeEquation(int var_endo, vector<tuple<int, expr_t, expr_t>>
case UnaryOpcode::sqrt:
List_of_Op_RHS.emplace_back(static_cast<int>(BinaryOpcode::power), nullptr, datatree.Two);
return { 1, nullptr };
case UnaryOpcode::cbrt:
List_of_Op_RHS.emplace_back(static_cast<int>(BinaryOpcode::power), nullptr, datatree.Three);
return { 1, nullptr };
case UnaryOpcode::abs:
return { 2, nullptr };
case UnaryOpcode::sign:
@ -3159,6 +3179,8 @@ UnaryOpNode::normalizeEquation(int var_endo, vector<tuple<int, expr_t, expr_t>>
return { 0, datatree.AddAtanh(New_expr_t) };
case UnaryOpcode::sqrt:
return { 0, datatree.AddSqrt(New_expr_t) };
case UnaryOpcode::cbrt:
return { 0, datatree.AddCbrt(New_expr_t) };
case UnaryOpcode::abs:
return { 0, datatree.AddAbs(New_expr_t) };
case UnaryOpcode::sign:
@ -3222,6 +3244,8 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con
return alt_datatree.AddAtanh(alt_arg);
case UnaryOpcode::sqrt:
return alt_datatree.AddSqrt(alt_arg);
case UnaryOpcode::cbrt:
return alt_datatree.AddCbrt(alt_arg);
case UnaryOpcode::abs:
return alt_datatree.AddAbs(alt_arg);
case UnaryOpcode::sign:
@ -3416,6 +3440,7 @@ UnaryOpNode::createAuxVarForUnaryOpNode() const
case UnaryOpcode::asinh:
case UnaryOpcode::atanh:
case UnaryOpcode::sqrt:
case UnaryOpcode::cbrt:
case UnaryOpcode::abs:
case UnaryOpcode::sign:
case UnaryOpcode::erf:
@ -3627,6 +3652,9 @@ UnaryOpNode::substituteUnaryOpNodes(DataTree &static_datatree, diff_table_t &nod
case UnaryOpcode::sqrt:
unary_op = "sqrt";
break;
case UnaryOpcode::cbrt:
unary_op = "cbrt";
break;
case UnaryOpcode::abs:
unary_op = "abs";
break;

View File

@ -2827,6 +2827,12 @@ ParsingDriver::add_sqrt(expr_t arg1)
return data_tree->AddSqrt(arg1);
}
expr_t
ParsingDriver::add_cbrt(expr_t arg1)
{
return data_tree->AddCbrt(arg1);
}
expr_t
ParsingDriver::add_abs(expr_t arg1)
{

View File

@ -778,6 +778,8 @@ public:
expr_t add_atanh(expr_t arg1);
//! Writes token "sqrt(arg1)" to model tree
expr_t add_sqrt(expr_t arg1);
//! Writes token "cbrt(arg1)" to model tree
expr_t add_cbrt(expr_t arg1);
//! Writes token "abs(arg1)" to model tree
expr_t add_abs(expr_t arg1);
//! Writes token "sign(arg1)" to model tree