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; }