Esempio n. 1
0
void Function::reinit(const Eref &e, ProcPtr p)
{
    if (!_valid){
        cout << "Error: Function::reinit() - invalid parser state. Will do nothing." << endl;
        return;
    }
    if (trim(_parser.GetExpr(), " \t\n\r").length() == 0){
        cout << "Error: no expression set. Will do nothing." << endl;
        setExpr(e, "0.0");
        _valid = false;
    }
    _value = 0.0;
    _lastValue = 0.0;
    _rate = 0.0;
    switch (_mode){
        case 1: {
            valueOut()->send(e, _value);
            break;
        }
        case 2: {
            derivativeOut()->send(e, 0.0);
            break;
        }
        case 3: {
            rateOut()->send(e, _rate);
            break;
        }
        default: {
            valueOut()->send(e, _value);
            derivativeOut()->send(e, 0.0);
            rateOut()->send(e, _rate);
            break;
        }
    }
}
Esempio n. 2
0
void Func::process(const Eref &e, ProcPtr p)
{
    if (!_valid){
        return;
    }
    if (_mode & 1){
        valueOut()->send(e, getValue());
    }
    if (_mode & 2){
        derivativeOut()->send(e, getDerivative());
    }
}
Esempio n. 3
0
void Function::process(const Eref &e, ProcPtr p)
{
    if (!_valid){
        return;
    }
    vector < double > databuf;
    requestOut()->send(e, &databuf);
    for (unsigned int ii = 0;
         (ii < databuf.size()) && (ii < _pullbuf.size());
         ++ii){
        *_pullbuf[ii] = databuf[ii];        
    }
    _value = getValue();
    _rate = (_value - _lastValue) / p->dt;
    switch (_mode){
        case 1: {
            valueOut()->send(e, _value);
            break;
        }
        case 2: {
            derivativeOut()->send(e, getDerivative());
            break;
        }
        case 3: {
            rateOut()->send(e, _rate);
            break;
        }
        default: {
            valueOut()->send(e, _value);
            derivativeOut()->send(e, getDerivative());
            rateOut()->send(e, _rate);
            break;
        }
    }
    _lastValue = _value;
}
Esempio n. 4
0
const Cinfo * Func::initCinfo()
{
    ////////////////////////////////////////////////////////////
    // Value fields    
    ////////////////////////////////////////////////////////////
    static  ReadOnlyValueFinfo< Func, double > value("value",
                                                     "Result of the function evaluation with current variable values.",
                                                     &Func::getValue);
    static ReadOnlyValueFinfo< Func, double > derivative("derivative",
                                                         "Derivative of the function at given variable values.",
                                                         &Func::getDerivative);
    static ValueFinfo< Func, unsigned int > mode("mode",
                                                 "Mode of operation: \n"
                                                 " 1: only the function value will be calculated\n"
                                                 " 2: only the derivative will be calculated\n"
                                                 " 3: both function value and derivative at current variable values will be calculated.",
                                                 &Func::setMode,
                                                 &Func::getMode);
    static ValueFinfo< Func, string > expr("expr",
                                           "Mathematical expression defining the function. The underlying parser\n"
                                           "is muParser. Hence the available functions and operators are (from\n"
                                           "muParser docs):\n"
                                           "\nFunctions\n"
                                           "Name        args    explanation\n"
                                           "sin         1       sine function\n"
                                           "cos         1       cosine function\n"
                                           "tan         1       tangens function\n"
                                           "asin        1       arcus sine function\n"
                                           "acos        1       arcus cosine function\n"
                                           "atan        1       arcus tangens function\n"
                                           "sinh        1       hyperbolic sine function\n"
                                           "cosh        1       hyperbolic cosine\n"
                                           "tanh        1       hyperbolic tangens function\n"
                                           "asinh       1       hyperbolic arcus sine function\n"
                                           "acosh       1       hyperbolic arcus tangens function\n"
                                           "atanh       1       hyperbolic arcur tangens function\n"
                                           "log2        1       logarithm to the base 2\n"
                                           "log10       1       logarithm to the base 10\n"
                                           "log         1       logarithm to the base 10\n"
                                           "ln  1       logarithm to base e (2.71828...)\n"
                                           "exp         1       e raised to the power of x\n"
                                           "sqrt        1       square root of a value\n"
                                           "sign        1       sign function -1 if x<0; 1 if x>0\n"
                                           "rint        1       round to nearest integer\n"
                                           "abs         1       absolute value\n"
                                           "min         var.    min of all arguments\n"
                                           "max         var.    max of all arguments\n"
                                           "sum         var.    sum of all arguments\n"
                                           "avg         var.    mean value of all arguments\n"
                                           "\nOperators\n"
                                           "Op  meaning         prioroty\n"
                                           "=   assignement     -1\n"
                                           "&&  logical and     1\n"
                                           "||  logical or      2\n"
                                           "<=  less or equal   4\n"
                                           ">=  greater or equal        4\n"
                                           "!=  not equal       4\n"
                                           "==  equal   4\n"
                                           ">   greater than    4\n"
                                           "<   less than       4\n"
                                           "+   addition        5\n"
                                           "-   subtraction     5\n"
                                           "*   multiplication  6\n"
                                           "/   division        6\n"
                                           "^   raise x to the power of y       7\n"
                                           "\n"
                                           "?:  if then else operator   C++ style syntax\n",
                                           &Func::setExpr,
                                           &Func::getExpr);
    static LookupValueFinfo < Func, string, double > var("var",
                                                         "Lookup table for variable values.",
                                                         &Func::setVar,
                                                         &Func::getVar);
    static ReadOnlyValueFinfo< Func, vector<string> > vars("vars",
                                                           "Variable names in the expression",
                                                           &Func::getVars);
    static ValueFinfo< Func, double > x("x",
                                        "Value for variable named x. This is a shorthand. If the\n"
                                        "expression does not have any variable named x, this the first variable\n"
                                        "in the sequence `vars`.",
                                        &Func::setX,
                                        &Func::getX);
    static ValueFinfo< Func, double > y("y",
                                        "Value for variable named y. This is a utility for two/three\n"
                                        " variable functions where the y value comes from a source separate\n"
                                        " from that of x. This is a shorthand. If the\n"
                                        "expression does not have any variable named y, this the second\n"
                                        "variable in the sequence `vars`.",
                                        &Func::setY,
                                        &Func::getY);
    static ValueFinfo< Func, double > z("z",
                                        "Value for variable named z. This is a utility for three\n"
                                        " variable functions where the z value comes from a source separate\n"
                                        " from that of x or z. This is a shorthand. If the expression does not\n"
                                        " have any variable named z, this the third variable in the sequence `vars`.",
                                        &Func::setZ,
                                        &Func::getZ);
    ////////////////////////////////////////////////////////////
    // DestFinfos
    ////////////////////////////////////////////////////////////
    static DestFinfo varIn("varIn",
                           "Handle value for specified variable coming from other objects",
                           new OpFunc2< Func, string, double > (&Func::setVar));
    static DestFinfo xIn("xIn",
                         "Handle value for variable named x. This is a shorthand. If the\n"
                         "expression does not have any variable named x, this the first variable\n"
                         "in the sequence `vars`.",
                         new OpFunc1< Func, double > (&Func::setX));
    static DestFinfo yIn("yIn",
                         "Handle value for variable named y. This is a utility for two/three\n"
                         " variable functions where the y value comes from a source separate\n"
                         " from that of x. This is a shorthand. If the\n"
                         "expression does not have any variable named y, this the second\n"
                         "variable in the sequence `vars`.",
                         new OpFunc1< Func, double > (&Func::setY));
    static DestFinfo zIn("zIn",
                         "Handle value for variable named z. This is a utility for three\n"
                         " variable functions where the z value comes from a source separate\n"
                         " from that of x or y. This is a shorthand. If the expression does not\n"
                         " have any variable named y, this the second variable in the sequence `vars`.",
                         new OpFunc1< Func, double > (&Func::setZ));
    static DestFinfo xyIn("xyIn",
                          "Handle value for variables x and y for two-variable function",
                          new OpFunc2< Func, double, double > (&Func::setXY));
    static DestFinfo xyzIn("xyzIn",
                           "Handle value for variables x, y and z for three-variable function",
                           new OpFunc3< Func, double, double, double > (&Func::setXYZ));

    static DestFinfo setVars("setVars",
                             "Utility function to assign the variable values of the function.\n"
                             "Takes a list of variable names and a list of corresponding values.",
                             new OpFunc2< Func, vector< string >, vector< double > > (&Func::setVarValues));
    
    // TODO - a way to allow connect a source to a specific variable without the source knowing the variable name
    // simple case of x, [y, [z]] variables

    ///////////////////////////////////////////////////////////////////
    // Shared messages
    ///////////////////////////////////////////////////////////////////
    static DestFinfo process( "process",
                              "Handles process call, updates internal time stamp.",
                              new ProcOpFunc< Func >( &Func::process ) );
    static DestFinfo reinit( "reinit",
                             "Handles reinit call.",
                             new ProcOpFunc< Func >( &Func::reinit ) );
    static Finfo* processShared[] =
            {
		&process, &reinit
            };
    
    static SharedFinfo proc( "proc",
                             "This is a shared message to receive Process messages "
                             "from the scheduler objects."
                             "The first entry in the shared msg is a MsgDest "
                             "for the Process operation. It has a single argument, "
                             "ProcInfo, which holds lots of information about current "
                             "time, thread, dt and so on. The second entry is a MsgDest "
                             "for the Reinit operation. It also uses ProcInfo. ",
                             processShared, sizeof( processShared ) / sizeof( Finfo* )
                             );

    static Finfo *funcFinfos[] =
            {
                &value,
                &derivative,
                &mode,
                &expr,
                &var,
                &vars,
                &x,
                &y,
                &z,
                &varIn,
                &xIn,
                &yIn,
                &zIn,
                &xyIn,
                &xyzIn,
                &proc,
                valueOut(),
                derivativeOut(),
            };
    
    static string doc[] =
            {
                "Name", "Func",
                "Author", "Subhasis Ray",
                "Description",
                "Func: general purpose function calculator using real numbers. It can\n"
                "parse mathematical expression defining a function and evaluate it\n"                
                "and/or its derivative for specified variable values.\n"
                "The variables can be input from other moose objects. In case of\n"
                "arbitrary variable names, the source message must have the variable\n"
                "name as the first argument. For most common cases, input messages to\n"
                "set x, y, z and xy, xyz are made available without such\n"
                "requirement. This class handles only real numbers\n"
                "(C-double). Predefined constants are: pi=3.141592...,\n"
                "e=2.718281... \n"
            };
    
	static Dinfo< Func > dinfo;
    static Cinfo funcCinfo("Func",
                            Neutral::initCinfo(),
                            funcFinfos,
                            sizeof(funcFinfos) / sizeof(Finfo*),
							&dinfo,
                            doc,
                            sizeof(doc)/sizeof(string));
    return &funcCinfo;
                                                    
}
Esempio n. 5
0
const Cinfo * Function::initCinfo()
{
    ////////////////////////////////////////////////////////////
    // Value fields    
    ////////////////////////////////////////////////////////////
    static  ReadOnlyValueFinfo< Function, double > value(
        "value",
        "Result of the function evaluation with current variable values.",
        &Function::getValue);
    static ReadOnlyValueFinfo< Function, double > derivative(
        "derivative",
        "Derivative of the function at given variable values. This is calulated"
        " using 5-point stencil "
        " <http://en.wikipedia.org/wiki/Five-point_stencil> at current value of"
        " independent variable. Note that unlike hand-calculated derivatives,"
        " numerical derivatives are not exact.",
        &Function::getDerivative);
    static ReadOnlyValueFinfo< Function, double > rate(
        "rate",
        "Derivative of the function at given variable values. This is computed"
        " as the difference of the current and previous value of the function"
        " divided by the time step.",
        &Function::getRate);
    static ValueFinfo< Function, unsigned int > mode(
        "mode",
        "Mode of operation: \n"
        " 1: only the function value will be sent out.\n"
        " 2: only the derivative with respect to the independent variable will be sent out.\n"
        " 3: only rate (time derivative) will be sent out.\n"
        " anything else: all three, value, derivative and rate will be sent out.\n",
        &Function::setMode,
        &Function::getMode);
    static ElementValueFinfo< Function, string > expr(
        "expr",
        "Mathematical expression defining the function. The underlying parser\n"
        "is muParser. Hence the available functions and operators are (from\n"
        "muParser docs):\n"
        "\nFunctions\n"
        "Name        args    explanation\n"
        "sin         1       sine function\n"
        "cos         1       cosine function\n"
        "tan         1       tangens function\n"
        "asin        1       arcus sine function\n"
        "acos        1       arcus cosine function\n"
        "atan        1       arcus tangens function\n"
        "sinh        1       hyperbolic sine function\n"
        "cosh        1       hyperbolic cosine\n"
        "tanh        1       hyperbolic tangens function\n"
        "asinh       1       hyperbolic arcus sine function\n"
        "acosh       1       hyperbolic arcus tangens function\n"
        "atanh       1       hyperbolic arcur tangens function\n"
        "log2        1       logarithm to the base 2\n"
        "log10       1       logarithm to the base 10\n"
        "log         1       logarithm to the base 10\n"
        "ln  1       logarithm to base e (2.71828...)\n"
        "exp         1       e raised to the power of x\n"
        "sqrt        1       square root of a value\n"
        "sign        1       sign function -1 if x<0; 1 if x>0\n"
        "rint        1       round to nearest integer\n"
        "abs         1       absolute value\n"
        "min         var.    min of all arguments\n"
        "max         var.    max of all arguments\n"
        "sum         var.    sum of all arguments\n"
        "avg         var.    mean value of all arguments\n"
        "\nOperators\n"
        "Op  meaning         prioroty\n"
        "=   assignement     -1\n"
        "&&  logical and     1\n"
        "||  logical or      2\n"
        "<=  less or equal   4\n"
        ">=  greater or equal        4\n"
        "!=  not equal       4\n"
        "==  equal   4\n"
        ">   greater than    4\n"
        "<   less than       4\n"
        "+   addition        5\n"
        "-   subtraction     5\n"
        "*   multiplication  6\n"
        "/   division        6\n"
        "^   raise x to the power of y       7\n"
        "\n"
        "?:  if then else operator   C++ style syntax\n",
        &Function::setExpr,
        &Function::getExpr);

    static ValueFinfo< Function, unsigned int > numVars(
        "numVars",
        "Number of variables used by Function.",
        &Function::setNumVar,
        &Function::getNumVar);
    
    static FieldElementFinfo< Function, Variable > inputs(
        "x",
        "Input variables to the function. These can be passed via messages.",
        Variable::initCinfo(),
        &Function::getVar,
        &Function::setNumVar,
        &Function::getNumVar);

    static LookupValueFinfo < Function, string, double > constants(
        "c",
        "Constants used in the function. These must be assigned before"
        " specifying the function expression.",
        &Function::setConst,
        &Function::getConst);
    
    static ReadOnlyValueFinfo< Function, vector < double > > y(
        "y",
        "Variable values received from target fields by requestOut",
        &Function::getY);

    static ValueFinfo< Function, string > independent(
        "independent",
        "Index of independent variable. Differentiation is done based on this. Defaults"
        " to the first assigned variable.",
        &Function::setIndependent,
        &Function::getIndependent);

    ///////////////////////////////////////////////////////////////////
    // Shared messages
    ///////////////////////////////////////////////////////////////////
    static DestFinfo process( "process",
                              "Handles process call, updates internal time stamp.",
                              new ProcOpFunc< Function >( &Function::process ) );
    static DestFinfo reinit( "reinit",
                             "Handles reinit call.",
                             new ProcOpFunc< Function >( &Function::reinit ) );
    static Finfo* processShared[] =
            {
		&process, &reinit
            };
    
    static SharedFinfo proc( "proc",
                             "This is a shared message to receive Process messages "
                             "from the scheduler objects."
                             "The first entry in the shared msg is a MsgDest "
                             "for the Process operation. It has a single argument, "
                             "ProcInfo, which holds lots of information about current "
                             "time, thread, dt and so on. The second entry is a MsgDest "
                             "for the Reinit operation. It also uses ProcInfo. ",
                             processShared, sizeof( processShared ) / sizeof( Finfo* )
                             );

    static Finfo *functionFinfos[] =
            {
                &value,
                &rate,
                &derivative,
                &mode,
                &expr,
                &numVars,
                &inputs,
                &constants,
                &independent,
                &proc,
                requestOut(),
                valueOut(),
                rateOut(),
                derivativeOut(),
            };
    
    static string doc[] =
            {
                "Name", "Function",
                "Author", "Subhasis Ray",
                "Description",
                "General purpose function calculator using real numbers.\n"
                "It can parse mathematical expression defining a function and evaluate"
                " it and/or its derivative for specified variable values."
                "You can assign expressions of the form::\n"
                "\n"
                "f(c0, c1, ..., cM, x0, x1, ..., xN, y0,..., yP ) \n"
                "\n"
                " where `ci`'s are constants and `xi`'s and `yi`'s are variables."

                "The constants must be defined before setting the expression and"
                " variables are connected via messages. The constants can have any"
                " name, but the variable names must be of the form x{i} or y{i}"
                "  where i is increasing integer starting from 0.\n"
                " The variables can be input from other moose objects."
                " Such variables must be named `x{i}` in the expression and the source"
                " field is connected to Function.x[i]'s `input` destination field.\n"
                " In case the input variable is not available as a source field, but is"
                " a value field, then the value can be requested by connecting the"
                " `requestOut` message to the `get{Field}` destination on the target"
                " object. Such variables must be specified in the expression as y{i}"
                " and connecting the messages should happen in the same order as the"
                " y indices.\n"
                " This class handles only real numbers (C-double). Predefined constants"
                " are: pi=3.141592..., e=2.718281..."
            };
    
    static Dinfo< Function > dinfo;
    static Cinfo functionCinfo("Function",
                               Neutral::initCinfo(),
                               functionFinfos,
                               sizeof(functionFinfos) / sizeof(Finfo*),
                               &dinfo,
                               doc,
                               sizeof(doc)/sizeof(string));
    return &functionCinfo;
                                                    
}