preprocessor: add absolute value and signum

issue#70
Houtan Bastani 2011-08-12 13:20:53 +02:00
parent 7a23e4e332
commit 973105ace3
8 changed files with 87 additions and 1 deletions

View File

@ -188,6 +188,8 @@ enum UnaryOpcode
oAsinh,
oAtanh,
oSqrt,
oAbs,
oSign,
oSteadyState,
oSteadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter
oSteadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter

View File

@ -401,6 +401,28 @@ DataTree::AddSqrt(expr_t iArg1)
return Zero;
}
expr_t
DataTree::AddAbs(expr_t iArg1)
{
if (iArg1 == Zero)
return Zero;
if (iArg1 == One)
return One;
else
return AddUnaryOp(oAbs, iArg1);
}
expr_t
DataTree::AddSign(expr_t iArg1)
{
if (iArg1 == Zero)
return Zero;
if (iArg1 == One)
return One;
else
return AddUnaryOp(oSign, iArg1);
}
expr_t
DataTree::AddErf(expr_t iArg1)
{

View File

@ -176,6 +176,10 @@ public:
expr_t AddAtanh(expr_t iArg1);
//! Adds "sqrt(arg)" to model tree
expr_t AddSqrt(expr_t iArg1);
//! Adds "abs(arg)" to model tree
expr_t AddAbs(expr_t iArg1);
//! Adds "sign(arg)" to model tree
expr_t AddSign(expr_t iArg1);
//! Adds "erf(arg)" to model tree
expr_t AddErf(expr_t iArg1);
//! Adds "max(arg1,arg2)" to model tree

View File

@ -108,7 +108,7 @@ class ParsingDriver;
%token LABELS LAPLACE LIK_ALGO LIK_INIT LINEAR LOAD_IDENT_FILES LOAD_MH_FILE LOAD_PARAMS_AND_STEADY_STATE LOGLINEAR
%token MARKOWITZ MARGINAL_DENSITY MAX
%token MFS MH_DROP MH_INIT_SCALE MH_JSCALE MH_MODE MH_NBLOCKS MH_REPLIC MH_RECOVER MIN MINIMAL_SOLVING_PERIODS
%token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS
%token MODE_CHECK MODE_COMPUTE MODE_FILE MODEL MODEL_COMPARISON MODEL_INFO MSHOCKS ABS SIGN
%token MODIFIEDHARMONICMEAN MOMENTS_VARENDO DIFFUSE_FILTER
%token <string_val> NAME
%token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NOCORR NODIAGNOSTIC NOFUNCTIONS
@ -459,6 +459,10 @@ expression : '(' expression ')'
{ $$ = driver.add_atan($3); }
| SQRT '(' expression ')'
{ $$ = driver.add_sqrt($3); }
| ABS '(' expression ')'
{ $$ = driver.add_abs($3); }
| SIGN '(' expression ')'
{ $$ = driver.add_sign($3); }
| MAX '(' expression COMMA expression ')'
{ $$ = driver.add_max($3, $5); }
| MIN '(' expression COMMA expression ')'
@ -613,6 +617,10 @@ hand_side : '(' hand_side ')'
{ $$ = driver.add_atan($3); }
| SQRT '(' hand_side ')'
{ $$ = driver.add_sqrt($3); }
| ABS '(' hand_side ')'
{ $$ = driver.add_abs($3); }
| SIGN '(' hand_side ')'
{ $$ = driver.add_sign($3); }
| MAX '(' hand_side COMMA hand_side ')'
{ $$ = driver.add_max($3, $5); }
| MIN '(' hand_side COMMA hand_side ')'

View File

@ -511,6 +511,8 @@ string eofbuff;
<DYNARE_STATEMENT,DYNARE_BLOCK>sqrt {return token::SQRT;}
<DYNARE_STATEMENT,DYNARE_BLOCK>max {return token::MAX;}
<DYNARE_STATEMENT,DYNARE_BLOCK>min {return token::MIN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>abs {return token::ABS;}
<DYNARE_STATEMENT,DYNARE_BLOCK>sign {return token::SIGN;}
<DYNARE_STATEMENT,DYNARE_BLOCK>normcdf {return token::NORMCDF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>normpdf {return token::NORMPDF;}
<DYNARE_STATEMENT,DYNARE_BLOCK>erf {return token::ERF;}

View File

@ -1323,6 +1323,11 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id)
case oSqrt:
t11 = datatree.AddPlus(this, this);
return datatree.AddDivide(darg, t11);
case oAbs:
t11 = datatree.AddSign(arg);
return datatree.AddTimes(t11, darg);
case oSign:
return datatree.Zero;
case oSteadyState:
if (datatree.isDynamic())
{
@ -1406,6 +1411,7 @@ UnaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) cons
switch (op_code)
{
case oUminus:
case oSign:
return cost + 70;
case oExp:
return cost + 160;
@ -1437,6 +1443,7 @@ UnaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) cons
case oAtanh:
return cost + 350;
case oSqrt:
case oAbs:
return cost + 570;
case oSteadyState:
case oSteadyStateParamDeriv:
@ -1449,6 +1456,7 @@ UnaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) cons
switch (op_code)
{
case oUminus:
case oSign:
return cost + 3;
case oExp:
case oAcosh:
@ -1477,6 +1485,7 @@ UnaryOpNode::cost(const temporary_terms_t &temporary_terms, bool is_matlab) cons
case oAtanh:
return cost + 150;
case oSqrt:
case oAbs:
return cost + 90;
case oSteadyState:
case oSteadyStateParamDeriv:
@ -1622,6 +1631,15 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
case oSqrt:
output << "sqrt";
break;
case oAbs:
output << "abs";
break;
case oSign:
if (output_type == oCDynamicModel)
output << "copysign";
else
output << "sign";
break;
case oSteadyState:
ExprNodeOutputType new_output_type;
switch (output_type)
@ -1692,6 +1710,8 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
&& arg->precedence(output_type, temporary_terms) < precedence(output_type, temporary_terms)))
{
output << LEFT_PAR(output_type);
if (op_code == oSign && output_type == oCDynamicModel)
output << "1.0,";
close_parenthesis = true;
}
@ -1763,6 +1783,10 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, Ev
return (atanh(v));
case oSqrt:
return (sqrt(v));
case oAbs:
return (abs(v));
case oSign:
return (v > 0) ? 1 : ((v < 0) ? -1 : 0);
case oSteadyState:
return (v);
case oSteadyStateParamDeriv:
@ -1901,6 +1925,10 @@ UnaryOpNode::normalizeEquation(int var_endo, vector<pair<int, pair<expr_t, expr_
return (make_pair(0, datatree.AddAtanh(New_expr_t)));
case oSqrt:
return (make_pair(0, datatree.AddSqrt(New_expr_t)));
case oAbs:
return (make_pair(0, datatree.AddAbs(New_expr_t)));
case oSign:
return (make_pair(0, datatree.AddSign(New_expr_t)));
case oSteadyState:
return (make_pair(0, datatree.AddSteadyState(New_expr_t)));
case oErf:
@ -1960,6 +1988,10 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con
return alt_datatree.AddAtanh(alt_arg);
case oSqrt:
return alt_datatree.AddSqrt(alt_arg);
case oAbs:
return alt_datatree.AddAbs(alt_arg);
case oSign:
return alt_datatree.AddSign(alt_arg);
case oSteadyState:
return alt_datatree.AddSteadyState(alt_arg);
case oSteadyStateParamDeriv:

View File

@ -1746,6 +1746,18 @@ ParsingDriver::add_sqrt(expr_t arg1)
return data_tree->AddSqrt(arg1);
}
expr_t
ParsingDriver::add_abs(expr_t arg1)
{
return data_tree->AddAbs(arg1);
}
expr_t
ParsingDriver::add_sign(expr_t arg1)
{
return data_tree->AddSign(arg1);
}
expr_t
ParsingDriver::add_max(expr_t arg1, expr_t arg2)
{

View File

@ -485,6 +485,10 @@ public:
expr_t add_atanh(expr_t arg1);
//! Writes token "sqrt(arg1)" to model tree
expr_t add_sqrt(expr_t arg1);
//! Writes token "abs(arg1)" to model tree
expr_t add_abs(expr_t arg1);
//! Writes token "sign(arg1)" to model tree
expr_t add_sign(expr_t arg1);
//! Writes token "max(arg1,arg2)" to model tree
expr_t add_max(expr_t arg1, expr_t arg2);
//! Writes token "min(arg1,arg2)" to model tree