00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "UAPUtilities.hpp"
00025
00026 #include "AML/AMLUtilities.hpp"
00027 #include "antlr/ANTLRException.hpp"
00028 #include <algorithm>
00029 #include "ExpressionLexer.hpp"
00030 #include "ExpressionParser.hpp"
00031 #include "ExpressionTreeWalker.hpp"
00032 #include <iostream>
00033 #include "StringInputBuffer.hpp"
00034 #include "UAPNode.hpp"
00035
00036 using namespace std;
00037
00038 #if defined(_MSC_VER)
00039 #define snprintf _snprintf
00040 #endif
00041
00042 UAPUtilities::UAPUtilities(UAPNode* _UAPRootNode) : UAPRootNode(_UAPRootNode), seed(1L)
00043 {
00044 constants.insert(std::make_pair("pi", 3.14159265358979323844));
00045 constants.insert(std::make_pair("e", 2.71828182845904523536));
00046 constants.insert(std::make_pair("twopi", 6.28318530717958647688));
00047 constants.insert(std::make_pair("fourpi", 12.56637061435917295376));
00048 constants.insert(std::make_pair("sqrt_2", 1.41421356237309504880));
00049 constants.insert(std::make_pair("degrees", 0.01745329251994329576));
00050 constants.insert(std::make_pair("Hz", 6.28318530717958647688));
00051 constants.insert(std::make_pair("m_electron", 0.51099906e6));
00052 constants.insert(std::make_pair("m_proton", 0.938271998e9));
00053 constants.insert(std::make_pair("c_light", 2.99792458e8));
00054 constants.insert(std::make_pair("r_e", 2.8179380e-15));
00055 constants.insert(std::make_pair("r_p", 1.5346980e-18));
00056 constants.insert(std::make_pair("e_charge", 1.6021892e-19));
00057 constants.insert(std::make_pair("h_planck", 6.626196e-34));
00058 constants.insert(std::make_pair("h_bar_planck", 1.054591e-34));
00059 }
00060
00061 UAPUtilities::~UAPUtilities() { }
00062
00063 void UAPUtilities::setUAPRootNode(UAPNode* _UAPRootNode)
00064 {
00065 UAPRootNode = _UAPRootNode;
00066 }
00067
00068 UAPNode* UAPUtilities::getUAPRootNode()
00069 {
00070 return UAPRootNode;
00071 }
00072
00073 int UAPUtilities::getParameterValue(UAPNode* node, string& param_name, string& param_value)
00074 {
00075 if (!node)
00076 return 0;
00077
00078 for(NodeVecIter it=node->getChildren().begin(); it!=node->getChildren().end(); ++it)
00079 if(getParameterValue(*it, param_name, param_value))
00080 return -1;
00081
00082 if((node->getName() == "parameter" || node->getName()=="controller") && node->getAttributeString("name") == param_name) {
00083 param_value = node->getAttributeString("value");
00084 return -1;
00085 } else if (node->getName() == "constant" && node->getAttributeString("name") == param_name) {
00086 param_value = node->getAttributeString("design");
00087 return -1;
00088 }
00089
00090 return 0;
00091 }
00092
00093 int UAPUtilities::evaluate()
00094 {
00095 return evaluate(UAPRootNode);
00096 }
00097
00098 int UAPUtilities::evaluate(UAPNode* node, UAPNode* context)
00099 {
00100 list<UAPException*> exceptions;
00101
00102 if (!AMLUtilities::inAMLNameSpace(node))
00103 return -1;
00104
00105 if (node->getName() == "element")
00106 context = node;
00107
00108 char new_xpr[20];
00109 UAPAttribute* attrib;
00110 try{
00111 attrib = node->getAttribute("design");
00112 if (attrib) {
00113 snprintf(new_xpr,sizeof(new_xpr),"%.8g",evaluate(attrib->getValue(),context));
00114 attrib->setValue(new_xpr);
00115 }
00116 attrib = node->getAttribute("err");
00117 if (attrib) {
00118 snprintf(new_xpr,sizeof(new_xpr),"%.8g",evaluate(attrib->getValue(),context));
00119 attrib->setValue(new_xpr);
00120 }
00121 attrib = node->getAttribute("value");
00122 if (attrib) {
00123 snprintf(new_xpr,sizeof(new_xpr),"%.8g",evaluate(attrib->getValue(),context));
00124 attrib->setValue(new_xpr);
00125 }
00126 attrib = node->getAttribute("coef");
00127 if (attrib) {
00128 snprintf(new_xpr,sizeof(new_xpr),"%.8g",evaluate(attrib->getValue(),context));
00129 attrib->setValue(new_xpr);
00130 }
00131 } catch (UAPParserException& e) {
00132 exceptions.push_back(new UAPException(e));
00133 }
00134
00135 for(NodeVecIter it=node->getChildren().begin(); it!=node->getChildren().end(); ++it)
00136 evaluate(*it, context);
00137
00138 context = NULL;
00139
00140 for (list<UAPException*>::const_iterator itt = exceptions.begin(); itt != exceptions.end(); ++itt){
00141 (*itt)->printStackTrace();
00142 delete *itt;
00143 }
00144
00145 return -1;
00146 }
00147
00148 double UAPUtilities::evaluate(UAPAttribute& attrib, UAPNode* context) throw(UAPParserException)
00149 {
00150 return evaluate(attrib.getValue(), context);
00151 }
00152
00153 double UAPUtilities::evaluate(const string attrib, UAPNode* context) throw(UAPParserException)
00154 {
00156 double result = 0;
00158 UAPException* missingParams = NULL;
00159 string end_marker = ";";
00160 string xpr = attrib;
00161 try {
00162 int nsymbols = -1;
00163 for(int pass=0; pass<100; ++pass){
00164 string istr = xpr+end_marker;
00165 StringInputBuffer ib(istr);
00166 ExpressionLexer xprLexer(ib);
00167 ExpressionParser xprParser(xprLexer);
00168 xprParser.setFilename(attrib);
00169 nsymbols = xprParser.expr();
00170 RefAST xprt = RefAST(xprParser.getAST());
00171 ExpressionTreeWalker xprWalker;
00172 xprWalker.setUtilities(this);
00173 xprWalker.setMathConstants(constants);
00174 xprWalker.setContext(context);
00175 if(nsymbols > 0){
00176 string new_xpr = xprWalker.subs_params(xprt);
00177 int fail1 = new_xpr.find("#") + 1;
00178 if(fail1 > 0){
00179 while(fail1 > 0){
00180 int n = new_xpr.find("@",fail1) - fail1;
00181 if (missingParams) {
00182 missingParams = new UAPParameterNotFoundException("error: '"+new_xpr.substr(fail1,n)+"' undeclared", *missingParams);
00183 } else
00184 missingParams = new UAPParameterNotFoundException("error: '"+new_xpr.substr(fail1,n)+"' undeclared");
00185 fail1 = new_xpr.find("#",fail1) + 1;
00186 }
00187 }
00188 if (missingParams)
00189 throw UAPException(*missingParams);
00190 xpr = new_xpr;
00191 } else {
00192 result = xprWalker.evaluate(xprt);
00193 break;
00194 }
00195 if (xprParser.getIdentifiers().empty())
00196
00197 pass += 10;
00198 }
00199 if (nsymbols > 0)
00200 throw UAPInvalidExpressionException("error: evalution of the constant value for '"+attrib+"' involves a circular definition.");
00201 } catch (UAPException& e) {
00202 if (missingParams)
00203 delete missingParams;
00204 throw UAPParserException("error: failed to evaluate: "+attrib, e);
00205 }
00206 return result;
00207 }
00208
00209 void UAPUtilities::addConstant(const string& name, double value, bool allow_overwrite)
00210 {
00211 map<string, double>::iterator it = constants.find(name);
00212 if (it != constants.end() && allow_overwrite)
00213 it->second = value;
00214 else
00215 constants.insert(std::make_pair(name, value));
00216
00217 }
00218
00219 int UAPUtilities::removeConstant(const string& name)
00220 {
00221 map<string, double>::iterator it = constants.find(name);
00222 if (it == constants.end())
00223 return 0;
00224 constants.erase(it);
00225 return -1;
00226 }
00227
00228 list<string> UAPUtilities::parseIdentifiers(const string& expr) throw(UAPParserException)
00229 {
00230 string istr = expr+";";
00231 try {
00232 StringInputBuffer ib(istr);
00233 ExpressionLexer xprLexer(ib);
00234 ExpressionParser xprParser(xprLexer);
00235 xprParser.setFilename(expr);
00236 int nsymbols = xprParser.expr();
00237 return xprParser.getIdentifiers();
00238 } catch (UAPException& e) {
00239 throw UAPParserException("error: failed to parse: "+expr, e);
00240 }
00241 }
00242
00243 double UAPUtilities::nextGaussian()
00244 {
00245 return static_cast<double>(gasdev(&seed));
00246 }
00247
00248 double UAPUtilities::nextDouble()
00249 {
00250 return static_cast<double>(ran1(&seed));
00251 }
00252
00253 float UAPUtilities::gasdev(long* idum)
00254 {
00255 static int iset = 0;
00256 static float gset;
00257 float fac, rsq, v1, v2;
00258
00259 if (*idum < 0) iset=0;
00260 if (iset == 0){
00261 do{
00262 v1 = 2.0*ran1(idum)-1.0;
00263 v2 = 2.0*ran1(idum)-1.0;
00264 rsq = v1*v1+v2*v2;
00265 } while (rsq >= 1.0 || rsq == 0.0);
00266 fac = sqrt(-2.0*log(rsq)/rsq);
00267 gset = v1*fac;
00268 iset = 1;
00269 return v2*fac;
00270 }else{
00271 iset = 0;
00272 return gset;
00273 }
00274 }
00275
00276 float UAPUtilities::ran1(long* idum)
00277 {
00278 int j;
00279 long k;
00280 static long iy = 0;
00281 static long iv[NTAB];
00282 float temp;
00283
00284 if (*idum <= 0 || !iy){
00285 if (-(*idum) < 1) *idum = 1;
00286 else *idum = -(*idum);
00287 for (j=NTAB+7;j>=0;j--){
00288 k = (*idum)/IQ;
00289 *idum = IA*(*idum-k*IQ)-IR*k;
00290 if (*idum < 0) *idum += IM;
00291 if (j < NTAB) iv[j] = *idum;
00292 }
00293 iy = iv[0];
00294 }
00295 k = (*idum)/IQ;
00296 *idum = IA*(*idum-k*IQ)-IQ*k;
00297 if (*idum < 0) *idum += IM;
00298 j = iy/NDIV;
00299 iy = iv[j];
00300 iv[j] = *idum;
00301 if ((temp = AM*iy) > RNMX) return static_cast<float>(RNMX);
00302 else return temp;
00303 }