GiNaC::lst VectorField::FindVarsInEx(const GiNaC::ex &e) { unsigned k; GiNaC::lst vlist; for (k = 0; k < varname_list.nops(); ++k) { if (e.has(varname_list[k])) vlist.append(varname_list[k]); } return vlist; }
double Attribute::EvalCompiledExpression (double const val, std::string const attrib ) { //cout << GetPrototype()->GetName() << " ?? at pointer num " << m_cur_fp << " -> compiled = " << m_compiled.at(m_cur_fp) << endl; if (!m_compiled.at(m_cur_fp)) { //substitute all attributes with numbers in GiNaC expression, except the attribute //which serves as the free parameter for runtime compilation GiNaC::lst symlist; GiNaC::lst numlist; for (unsigned int i=0; i<m_subjects.size() ; i++) { Attribute* a = m_subjects.at(i); if (a->GetName() == attrib) continue; symlist.append( get_symbol(a->GetSymbol()) ); if (a->GetTypeID()==typeid( double*).name()) { numlist.append(a->GetMember <double>() ); continue; } if (a->GetTypeID()==typeid( int*).name()) { numlist.append(a->GetMember <int>() ); continue; } if (a->GetTypeID()==typeid( long*).name()) { numlist.append(a->GetMember <long>() ); continue; } if (a->GetTypeID()==typeid(unsigned*).name()) { numlist.append(a->GetMember<unsigned>() ); continue; } if (a->GetTypeID()==typeid( bool*).name()) { numlist.append(a->GetMember <bool>() ); continue; } } GiNaC::ex e = GiNaC::evalf((symlist.nops()==0)?m_expression:m_expression.subs(symlist,numlist)); //add function pointers m_fp.push_back(NULL); m_fpi.push_back(NULL); //compile the GiNaC expression try { //fairly easy for real valued expressions if (!m_complex) { compile_ex(e, get_symbol(GetPrototype()->GetAttribute(attrib)->GetSymbol()), m_fp.at(m_num_fp)); } //more work to do, since GiNaC::realsymbol does not behave as expected (and it is therefore not used at all) else { stringstream se; se << e; std::string formula = se.str(); std::string sym = GetPrototype()->GetAttribute(attrib)->GetSymbol(); std::string asym = "abs(VarForEvalCompiledExpression)"; Prototype::ReplaceString(formula,sym,asym); GiNaC::lst symlist; symlist.append( get_symbol("VarForEvalCompiledExpression") ); GiNaC::ex ea = GiNaC::ex(formula,symlist); symlist.remove_all(); symlist.append( get_symbol(sym) ); GiNaC::ex ear = ea.real_part(); stringstream ser; ser << ear; formula = ser.str(); if ( Prototype::ReplaceString(formula,asym,sym) ) { ear = GiNaC::ex(formula,symlist); compile_ex(ear, get_symbol(GetPrototype()->GetAttribute(attrib)->GetSymbol()), m_fp.at(m_num_fp)); } GiNaC::ex eai = ea.imag_part(); stringstream sei; sei << eai; formula = sei.str(); if ( Prototype::ReplaceString(formula,asym,sym) ) { eai = GiNaC::ex(formula,symlist); compile_ex(eai, get_symbol(GetPrototype()->GetAttribute(attrib)->GetSymbol()), m_fpi.at(m_num_fp)); } } //cout << " compiling expression " << e << " of attribute " << GetName() << " in module " << GetPrototype()->GetName() << endl; m_num_fp++; } catch (exception &p) { cout << " Warning: attribute " << GetName() << " of module " << GetPrototype()->GetName() << endl << endl << " function Attribute::EvalCompiledExpression" << endl << " No external runtime compiler available: " << p.what() << endl << " Falling back to (slow) analytic evaluation!" << endl << endl << " Hint: if you have a shell and gcc on your system, create the one-liner " << endl << endl << " #!/bin/sh" << endl << " gcc -x c -fPIC -shared -o $1.so $1" << endl << endl << " name it \"ginac-excompiler\", and put it somewhere in your search path." << endl << endl; m_ginac_excomp = false; } m_compiled.at(m_cur_fp) = true; //even if compilation failed, as we don't have to try a second time! } //if compilation failed, invoke slow analytic evaluation if (!m_ginac_excomp ) { *((double*) GetPrototype()->GetAttribute(attrib)-> GetAddress()) = val; EvalExpression(); return *((double*) GetAddress()); } //invoke fast runtime compiled routines if (m_fpi.at(m_cur_fp) != NULL ) m_imaginary = m_fpi.at(m_cur_fp)(val); if ( m_fp.at(m_cur_fp) != NULL ) return m_fp.at(m_cur_fp)(val); return 0.0; }
double Attribute::EvalCompiledNLGExpression (double const x, double const y ,double const z, double const g ) { //cout << GetPrototype()->GetName() << " ?? at pointer num " << m_cur_fp << " -> compiled = " << m_compiled.at(m_cur_fp) << endl; if (m_nlgfp == NULL && m_ginac_excomp) { //substitute all attributes with numbers in GiNaC expression, except the attribute //which serves as the free parameter for runtime compilation GiNaC::lst symlist; GiNaC::lst numlist; for (unsigned int i=0; i<m_subjects.size() ; i++) { Attribute* a = m_subjects.at(i); if (a->GetName() == "NLG_posX") continue; if (a->GetName() == "NLG_posY") continue; if (a->GetName() == "NLG_posZ") continue; if (a->GetName() == "NLG_value") continue; symlist.append( get_symbol(a->GetSymbol()) ); if (a->GetTypeID()==typeid( double*).name()) { numlist.append(a->GetMember <double>() ); continue; } if (a->GetTypeID()==typeid( int*).name()) { numlist.append(a->GetMember <int>() ); continue; } if (a->GetTypeID()==typeid( long*).name()) { numlist.append(a->GetMember <long>() ); continue; } if (a->GetTypeID()==typeid(unsigned*).name()) { numlist.append(a->GetMember<unsigned>() ); continue; } if (a->GetTypeID()==typeid( bool*).name()) { numlist.append(a->GetMember <bool>() ); continue; } } GiNaC::ex e = GiNaC::evalf((symlist.nops()==0)?m_expression:m_expression.subs(symlist,numlist)); try { compile_ex (e, get_symbol(GetPrototype()->GetAttribute("NLG_posX")->GetSymbol()), get_symbol(GetPrototype()->GetAttribute("NLG_posY")->GetSymbol()), get_symbol(GetPrototype()->GetAttribute("NLG_posZ")->GetSymbol()), get_symbol(GetPrototype()->GetAttribute("NLG_value")->GetSymbol()), m_nlgfp); //cout << " compiling attribute " << GetName() << " of module " << GetPrototype()->GetName() << endl; } catch (exception &p) { cout << " Warning: attribute " << GetName() << " of module " << GetPrototype()->GetName() << endl << endl << " function Attribute::EvalCompiledNLGExpression" << endl << " No external runtime compiler available: " << p.what() << endl << " Falling back to (slow) analytic evaluation!" << endl << endl << " Hint: if you have a shell and gcc on your system, create the one-liner " << endl << endl << " #!/bin/sh" << endl << " gcc -x c -fPIC -shared -o $1.so $1" << endl << endl << " name it \"ginac-excompiler\", and put it somewhere in your search path." << endl << endl; m_ginac_excomp = false; } } //if compilation failed, invoke slow analytic evaluation if (!m_ginac_excomp ) { *((double*) GetPrototype()->GetAttribute("NLG_posX")-> GetAddress()) = x; *((double*) GetPrototype()->GetAttribute("NLG_posY")-> GetAddress()) = y; *((double*) GetPrototype()->GetAttribute("NLG_posZ")-> GetAddress()) = z; *((double*) GetPrototype()->GetAttribute("NLG_value")-> GetAddress()) = g; EvalExpression(); return *((double*) GetAddress()); } //invoke fast runtime compiled routines if ( m_nlgfp != NULL ) return m_nlgfp(x,y,z,g); return 0.0; }
void Attribute::EvalExpression () { if (m_formula.empty()) return; //strings: simply replace attribute symbol by its value if (GetTypeID()==typeid(std::string*).name()) { std::string expr = m_formula; for (unsigned int i=0; i<m_subjects.size() ; i++) { Attribute* a = m_subjects.at(i); stringstream key; if (a->GetTypeID()==typeid( double*).name()) key << a->GetMember <double>() ; if (a->GetTypeID()==typeid( int*).name()) key << a->GetMember <int>() ; if (a->GetTypeID()==typeid( long*).name()) key << a->GetMember <long>() ; if (a->GetTypeID()==typeid(unsigned*).name()) key << a->GetMember<unsigned>() ; if (a->GetTypeID()==typeid( bool*).name()) key << a->GetMember <bool>() ; std::string SymbolName = a->GetPrototype()->GetName() + "x" + a->GetName(); Prototype::ReplaceString(expr,SymbolName,key.str()); } WriteMember(expr); //if (GetName()=="Filename") cout << " Eval: " << expr << endl; return; } //collect symbols and corresponding member-values from observed attributes GiNaC::lst numlist; for (unsigned int i=0; i<m_subjects.size() ; i++) { Attribute* a = m_subjects.at(i); if (a->GetTypeID()==typeid( double*).name()) { numlist.append(a->GetMember <double>() ); continue; } if (a->GetTypeID()==typeid( int*).name()) { numlist.append(a->GetMember <int>() ); continue; } if (a->GetTypeID()==typeid( long*).name()) { numlist.append(a->GetMember <long>() ); continue; } if (a->GetTypeID()==typeid(unsigned*).name()) { numlist.append(a->GetMember<unsigned>() ); continue; } if (a->GetTypeID()==typeid( bool*).name()) { numlist.append(a->GetMember <bool>() ); continue; } } //numeric evaluation of GiNaC expression GiNaC::ex e = m_expression.subs(m_symlist,numlist); m_static_vector = m_prototype->GetVector(); // static pointer to evaluate the Vector function e = GiNaC::evalf(e); double d = 0.0; if (GiNaC::is_a<GiNaC::numeric>(e)) { if ( m_complex ) m_imaginary = -0.5 * GiNaC::ex_to<GiNaC::numeric>( (e-e.conjugate())*GiNaC::I ).to_double(); d = GiNaC::ex_to<GiNaC::numeric>( e ).to_double();//default is real-part } //overwrite private member if (m_datatype==typeid( double*).name() ) WriteMember((double) d ); if (m_datatype==typeid( int*).name() ) WriteMember((int) d ); if (m_datatype==typeid( long*).name() ) WriteMember((long) d ); if (m_datatype==typeid(unsigned*).name() ) WriteMember((unsigned) d ); if (m_datatype==typeid( bool*).name() ) WriteMember((bool) d ); // for dynamic change of runtime compiled attributes after notification! if (m_ginac_excomp && m_cur_fp==m_num_fp && m_num_fp>0) { //cout << "!!! " << GetName() << " : NFP =" << GetNumberFunctionPointers() << endl; //cout << "!!! " << GetName() << " : CFP =" << GetCurrentFunctionPointer() << endl; //cout << "!!! " << GetName() << " : size=" << m_compiled.size() << endl; if (m_compiled.size() == m_cur_fp ) m_compiled.push_back(false); } }