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; }
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 }
void VectorField::PrintEVF(map<string,string> options) { // // This function adds variables to the vector field. // The vector field for the new variables is given by the // variational equations. // The code should probably check for a partial derivative being // zero and not bother generating the corresponding output. Or it // could create a ginac ex to hold the expression until all derivatives // have been added to it, then create the string in the new state variable. // Ginac would automatically drop the zero terms. I'll get around to // this some time... // // Note that this function MODIFIES THE OBJECT!!! // It then calls PrintXML to output the extended vector field to the // standard output in XML format. // int kpar = -1; symbol p; if (options.find("par") != options.end()) { // cerr << "The option par=" << options["par"] << " has been given.\n"; kpar = findpar(options["par"],Parameters); if (kpar == -1) { cerr << "Error: Unknown parameter \"" << options["par"] << "\"\n"; cerr << "The parameters are: "; for (unsigned j = 0; j < parname_list.nops(); ++j) { if (j != 0) { cerr << ", "; } cerr << parname_list[j]; } cerr << endl; exit(-1); } } if (kpar != -1) { // cerr << "parname_list[" << kpar << "] = " << parname_list[kpar] << endl; p = ex_to<symbol>(parname_list[kpar]); } ostringstream oss; int nv = varname_list.nops(); for (int i = 0; i < nv; ++i) { oss.str(""); ex f = iterated_subs(varvecfield_list[i],expreqn_list); int num_terms_output = 0; for (int j = 0; j < nv; ++j) { symbol v = ex_to<symbol>(varname_list[j]); ex df = f.diff(v); if (df != 0) { if (num_terms_output > 0) { oss << " + "; } if (df == 1) { oss << "d" << varname_list[j]; } else { oss << "(" << df << ")*d" << varname_list[j]; } num_terms_output = num_terms_output + 1; } } if (kpar != -1) { ex dfdp = f.diff(p); if (dfdp != 0) { if (num_terms_output > 0) { oss << " + "; } oss << "(" << dfdp << ")"; num_terms_output = num_terms_output + 1; } } if (num_terms_output == 0) { oss << "0"; } StateVariable *var = new StateVariable("d"+StateVariables[i]->Name()); var->Formula(oss.str()); AddStateVariable(var); } Name(Name()+"_evf"); PrintXML("evf"); }