Example #1
0
void VectorField::Delay2ODE_ConvertAndExtend(ex& f, int N, int p)
    {
    lst dlist;
    f.find(delay(wild(1),wild(2)),dlist);
    // dlist is now a ginac lst of expressions of the form delay(delayexpr,del)
    for (lst::const_iterator diter = dlist.begin(); diter != dlist.end(); ++diter)
        {
        // diter points to a ginac expression of the form delay(delayexpr,del).
        ex delayfunc = *diter;
        symbol tmpsymbol;
        ex lag = delayfunc.op(1);
        ex hist = delayfunc.op(0);
        Delay2ODE_ConvertExprToDefHist(hist);
        string delayed_var_name;
        ostringstream os_N_over_delta;
        os_N_over_delta << "(" << N << "/(" << lag << "))";
        string N_over_delta = os_N_over_delta.str();
        for (int k = 0; k < N; ++k)
            {
            if (p == 1)
                {
                string vstr1, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                ostringstream os_varformula;
                os_varformula << N_over_delta << "*(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << ")";
                var->Formula(os_varformula.str());
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                }
            else if (p == 2)
                {
                string vstr1,vstr2, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                vstr2 = tmpsymbol.get_name() + "_2_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                var->Formula(vstr2);
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                //
                var = new StateVariable(vstr2);
                ostringstream os_varformula;
                os_varformula << "2*" << N_over_delta << "*";
                os_varformula << "( -" << vstr2 << " + " << N_over_delta << "*";
                os_varformula << "(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << "))";
                var->Formula(os_varformula.str());
                ex icderiv = hist.diff(IndVar);
                ostringstream os_vardefic_deriv;
                os_vardefic_deriv << icderiv.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv.str());
                AddStateVariable(var);
                }
            else // p == 3
                {
                string vstr1,vstr2,vstr3, prev_vstr1;
                ostringstream os;
                os << k+1;
                vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                vstr2 = tmpsymbol.get_name() + "_2_" + os.str();
                vstr3 = tmpsymbol.get_name() + "_3_" + os.str();
                os.str("");
                os << k;
                prev_vstr1 = tmpsymbol.get_name() + "_1_" + os.str();
                //
                StateVariable *var = new StateVariable(vstr1);
                var->Formula(vstr2);
                ostringstream os_vardefic;
                os_vardefic << hist.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic.str());
                AddStateVariable(var);
                if (k == N-1)
                    delayed_var_name = var->Name();
                //
                var = new StateVariable(vstr2);
                var->Formula(vstr3);
                ex icderiv = hist.diff(IndVar);
                ostringstream os_vardefic_deriv;
                os_vardefic_deriv << icderiv.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv.str());
                AddStateVariable(var);
                //
                var = new StateVariable(vstr3);
                ostringstream os_varformula;
                os_varformula << N_over_delta << "*";
                os_varformula << "(-3*" << vstr3;
                os_varformula << " - 6*" << N_over_delta << "*";
                os_varformula << "(" << vstr2 << " - " << N_over_delta << "*";
                os_varformula << "(";
                if (k == 0)
                    os_varformula << delayfunc.op(0);
                else
                    os_varformula << prev_vstr1;
                os_varformula << " - " << vstr1 << ")))";
                var->Formula(os_varformula.str());
                ex icderiv2 = icderiv.diff(IndVar);
                ostringstream os_vardefic_deriv2;
                os_vardefic_deriv2 << icderiv2.subs(IndVar==-(k+1)*lag/N);
                var->DefaultInitialCondition(os_vardefic_deriv2.str());
                AddStateVariable(var);
                }                    
            } // end k loop
        symbol s(delayed_var_name);
        f = f.subs(delayfunc == s);
        } // end dlist loop
    }
int VectorField::ReadXML(string xmlfilename)
    {
    FILE *xmlfile;
    mxml_node_t *tree;
    mxml_node_t *node;
    bool bad_attr;

    xmlfile = fopen(xmlfilename.c_str(),"r");
    if (xmlfile == NULL)
       {
       // Failed to open the file.
       cerr << "Error: Unable to open " << xmlfilename << "\n";
       exit(-1);
       }
    tree = mxmlLoadFile(NULL,xmlfile,MXML_NO_CALLBACK);
    fclose(xmlfile);
    if (tree == NULL)
        {
        cerr << "Error: Unable to load the vector field from the file " << xmlfilename << ".\n";
        cerr << "There may be an error in the XML definition of the vector field.\n";
        mxmlDelete(tree);
        exit(-1);
        }

    node = mxmlFindElement(tree,tree,"VectorField",NULL,NULL,MXML_DESCEND);
    if (node == NULL)
        {
        cerr << "Error: No VectorField element found in XML defintion.\n";
        mxmlDelete(tree);
        exit(-1);
        }
    else
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "IndependentVariable" && attr != "Description")
                {
                cerr << "Error: The VectorField element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            exit(-1);
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: The VectorField element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The VectorField Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string s(attr);
            Name(s);
            }
        attr = mxmlElementGetAttr(node,"Description");
        if (attr != NULL)
            {
            string s(attr);
            Description(s);
            }
        attr = mxmlElementGetAttr(node,"IndependentVariable");
        if (attr == NULL)
            IndependentVariable = "t";
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The VectorField IndependentVariable \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string s(attr);
            IndependentVariable = s;
            }
        }

    //
    // Get the constants
    //
    for (node = mxmlFindElement(tree,tree,"Constant",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Constant",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Value" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: A Constant element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Constant attributes are: Name, Value, Description, Latex.\n";
            exit(-1);
            } 
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Constant element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Constant Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Constant *c = new Constant(name);
            AddConstant(c);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                c->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Value");
            if (attr == NULL)
                {
                cerr << "Error: The Constant element with Name=\"" << c->Name() << "\" has no Value attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string val(attr);
                c->Value(val);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                c->Latex(latex);
                }
            }
        }

    //
    // Get the parameters
    //
    for (node = mxmlFindElement(tree,tree,"Parameter",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Parameter",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "DefaultValue" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: A Parameter element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Parameter attributes are: Name, DefaultValue, Description, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Parameter element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Parameter Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Parameter *p = new Parameter(name);
            AddParameter(p);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                p->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"DefaultValue");
            if (attr != NULL)
                {
                string defval(attr);
                p->DefaultValue(defval);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                p->Latex(latex);
                }
            }
        }

    //
    // Get the auxiliary expressions
    //
    for (node = mxmlFindElement(tree,tree,"Expression",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Expression",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Formula" && attr != "Description" && attr != "Latex")
                {
                cerr << "Error: An Expression element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Expression attributes are: Name, Formula, Description, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: An Expression element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Expression Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Expression *e = new Expression(name);
            AddExpression(e);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                e->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The Expression with Name=\"" << e->Name() << "\" has no Formula attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                e->Formula(f);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                e->Latex(latex);
                }
            }
        }

    //
    // Get the state variables
    //
    for (node = mxmlFindElement(tree,tree,"StateVariable",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"StateVariable",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "DefaultInitialCondition" && attr != "Description"
                  && attr != "Formula" && attr != "PeriodFrom" && attr != "PeriodTo"
                  && attr != "DefaultHistory" && attr != "Latex")
                {
                cerr << "Error: A StateVariable element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid StateVariable attributes are: Name, Formula, Description, DefaultInitialCondition, DefaultHistory, PeriodFrom, PeriodTo, Latex.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A StateVariable element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The StateVariable Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            StateVariable *sv = new StateVariable(name);
            AddStateVariable(sv);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                sv->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has no Formula attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                sv->Formula(f);
                }
            attr = mxmlElementGetAttr(node,"PeriodFrom");
            if (attr != NULL)
                {
                string pfrom(attr);
                sv->PeriodicFrom(pfrom);
                }
            attr = mxmlElementGetAttr(node,"PeriodTo");
            if (attr != NULL)
                {
                string pto(attr);
                sv->PeriodicTo(pto);
                }
            if (sv->PeriodicFrom() != "" & sv->PeriodicTo() == "")
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has a PeriodicFrom attribute but no PeriodicTo attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            if (sv->PeriodicFrom() == "" & sv->PeriodicTo() != "")
                {
                cerr << "Error: The StateVariable with Name=\"" << sv->Name() << "\" has a PeriodTo attribute but no PeriodicFrom attribute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            attr = mxmlElementGetAttr(node,"DefaultInitialCondition");
            if (attr != NULL)
                {
                string ic(attr);
                sv->DefaultInitialCondition(ic);
                }
            attr = mxmlElementGetAttr(node,"DefaultHistory");
            if (attr != NULL)
                {
                string hist(attr);
                sv->DefaultHistory(hist);
                }
            attr = mxmlElementGetAttr(node,"Latex");
            if (attr != NULL)
                {
                string latex(attr);
                sv->Latex(latex);
                }
            }
        }

    //
    // Get the functions
    //
    for (node = mxmlFindElement(tree,tree,"Function",NULL,NULL,MXML_DESCEND);
         node != NULL;
         node = mxmlFindElement(node,tree,"Function",NULL,NULL,MXML_DESCEND))
        {
        bad_attr = false;
        for (int i = 0; i < node->value.element.num_attrs; ++i)
            {
            string attr = node->value.element.attrs[i].name;
            if (attr != "Name" && attr != "Formula" && attr != "Description")
                {
                cerr << "Error: A Function element has an unknown attribute: " << attr << endl;
                bad_attr = true;
                }
            }
        if (bad_attr)
            {
            cerr << "Valid Function attributes are: Name, Formula, Description.\n";
            exit(-1);
            }
        const char *attr;
        attr = mxmlElementGetAttr(node,"Name");
        if (attr == NULL)
            {
            cerr << "Error: A Function element has no Name attribute.\n";
            mxmlDelete(tree);
            exit(-1);
            }
        else
            {
            if (!isValidName(attr))
                {
                cerr << "Error: The Function Name \"" << attr << "\" is not valid.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            string name(attr);
            Function *func = new Function(name);
            AddFunction(func);
            attr = mxmlElementGetAttr(node,"Description");
            if (attr != NULL)
                {
                string descr(attr);
                func->Description(descr);
                }
            attr = mxmlElementGetAttr(node,"Formula");
            if (attr == NULL)
                {
                cerr << "Error: The Function element with Name=\"" << func->Name() << "\" has no Formula attibute.\n";
                mxmlDelete(tree);
                exit(-1);
                }
            else
                {
                string f(attr);
                func->Formula(f);
                }
            }
        }


    mxmlDelete(tree);
    return 0;
    }