]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Also update the parsing of all other builtin functions. 65/head
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Thu, 7 Aug 2014 11:50:03 +0000 (06:50 -0500)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Thu, 7 Aug 2014 12:44:57 +0000 (07:44 -0500)
source/base/function_parser.cc
tests/base/function_parser_07.cc
tests/base/function_parser_07.with_muparser=true.output

index 4c764f8279f936425261b7a968796ce3f6c844b1..7ec61316b7941fccddae3f76dbb2518459287f4f 100644 (file)
@@ -147,62 +147,105 @@ void FunctionParser<dim>:: init_muparser() const
   
   fp.get().resize(this->n_components);
   vars.get().resize(var_names.size());
-  for (unsigned int i=0; i<this->n_components; ++i)
+  for (unsigned int component=0; component<this->n_components; ++component)
     {
       for (std::map< std::string, double >::const_iterator constant = constants.begin();
           constant != constants.end(); ++constant)
         {
-         fp.get()[i].DefineConst(constant->first.c_str(), constant->second);
+         fp.get()[component].DefineConst(constant->first.c_str(), constant->second);
        }
 
       for (unsigned int iv=0;iv<var_names.size();++iv)
-       fp.get()[i].DefineVar(var_names[iv].c_str(), &vars.get()[iv]);
+       fp.get()[component].DefineVar(var_names[iv].c_str(), &vars.get()[iv]);
 
       // define some compatibility functions:
-      fp.get()[i].DefineFun("if",internal::mu_if, true);
-      fp.get()[i].DefineOprt("|", internal::mu_or, 1);
-      fp.get()[i].DefineOprt("&", internal::mu_and, 2);
-      fp.get()[i].DefineFun("int", internal::mu_int, true);
-      fp.get()[i].DefineFun("ceil", internal::mu_ceil, true);
-      fp.get()[i].DefineFun("cot", internal::mu_cot, true);
-      fp.get()[i].DefineFun("csc", internal::mu_csc, true);
-      fp.get()[i].DefineFun("floor", internal::mu_floor, true);
-      fp.get()[i].DefineFun("sec", internal::mu_sec, true);
-      fp.get()[i].DefineFun("log", internal::mu_log, true);
+      fp.get()[component].DefineFun("if",internal::mu_if, true);
+      fp.get()[component].DefineOprt("|", internal::mu_or, 1);
+      fp.get()[component].DefineOprt("&", internal::mu_and, 2);
+      fp.get()[component].DefineFun("int", internal::mu_int, true);
+      fp.get()[component].DefineFun("ceil", internal::mu_ceil, true);
+      fp.get()[component].DefineFun("cot", internal::mu_cot, true);
+      fp.get()[component].DefineFun("csc", internal::mu_csc, true);
+      fp.get()[component].DefineFun("floor", internal::mu_floor, true);
+      fp.get()[component].DefineFun("sec", internal::mu_sec, true);
+      fp.get()[component].DefineFun("log", internal::mu_log, true);
       
       try
        {
-          // muparser expects that user defined functions have no
+          // muparser expects that functions have no
           // space between the name of the function and the opening
           // parenthesis. this is awkward because it is not backward
           // compatible to the library we used to use before muparser
           // (the fparser library) but also makes no real sense.
           // consequently, in the expressions we set, remove any space
           // we may find after function names
-          std::string transformed_expression = expressions[i];
-          std::string::size_type pos = 0;
-          while (true)
+          std::string transformed_expression = expressions[component];
+
+          const char *function_names[] = {
+                                           // functions predefined by muparser
+                                           "sin",
+                                           "cos",
+                                           "tan",
+                                           "asin",
+                                           "acos",
+                                           "atan",
+                                           "sinh",
+                                           "cosh",
+                                           "tanh",
+                                           "asinh",
+                                           "acosh",
+                                           "atanh",
+                                           "atan2",
+                                           "log2",
+                                           "log10",
+                                           "log",
+                                           "ln",
+                                           "exp",
+                                           "sqrt",
+                                           "sign",
+                                           "rint",
+                                           "abs",
+                                           "min",
+                                           "max",
+                                           "sum",
+                                           "avg",
+                                           // functions we define ourselves above
+                                           "if",
+                                           "int",
+                                           "ceil",
+                                           "cot",
+                                           "csc",
+                                           "floor",
+                                           "sec"  };
+          for (unsigned int f=0; f<sizeof(function_names)/sizeof(function_names[0]); ++f)
             {
-              // try to find any occurrences of 'if'
-              pos = transformed_expression.find ("if", pos);
-              if (pos == std::string::npos)
-                break;
-
-              // replace whitespace until there no longer is any
-              while ((pos+2<transformed_expression.size())
-                     &&
-                     ((transformed_expression[pos+2] == ' ')
-                      ||
-                      (transformed_expression[pos+2] == '\t')))
-                transformed_expression.erase (pos+2, pos+3);
-
-              // move the current search position by the size of the
-              // actual 'if'
-              pos += 2;
+              const std::string  function_name        = function_names[f];
+              const unsigned int function_name_length = function_name.size();
+
+              std::string::size_type pos = 0;
+              while (true)
+                {
+                  // try to find any occurrences of the function name
+                  pos = transformed_expression.find (function_name, pos);
+                  if (pos == std::string::npos)
+                    break;
+
+                  // replace whitespace until there no longer is any
+                  while ((pos+function_name_length<transformed_expression.size())
+                      &&
+                      ((transformed_expression[pos+function_name_length] == ' ')
+                          ||
+                          (transformed_expression[pos+function_name_length] == '\t')))
+                    transformed_expression.erase (transformed_expression.begin()+pos+function_name_length);
+
+                  // move the current search position by the size of the
+                  // actual function name
+                  pos += function_name_length;
+                }
             }
 
           // now use the transformed expression
-         fp.get()[i].SetExpr(transformed_expression);
+         fp.get()[component].SetExpr(transformed_expression);
        }
       catch (mu::ParserError &e)
        {
index 8e6e5b5dd4cc1fe0e4622904bdae301ab2a66c00..571256c3ae4c4648f4f4f59a0a8c8cbfefcb90f3 100644 (file)
@@ -63,39 +63,39 @@ void test()
   double x,y;
   x=1.0;
   y=-3.1;
-  eval("atan2(x,y)",Point<2>(x,y), atan2(x,y));
+  eval("atan2 (x,y)",Point<2>(x,y), atan2(x,y));
   x=-1.0;
   y=3.1;
-  eval("atan2(x,y)",Point<2>(x,y), atan2(x,y));
+  eval("atan2 (x,y)",Point<2>(x,y), atan2(x,y));
 
   eval("if   (x==1.0,0,y)",Point<2>(1.0,-2.0), 0.0);  
   eval("if   (x==1.0,0,y)",Point<2>(1.1,-2.0), -2.0);
 
-  eval("int(2.1)",Point<2>(1.1,-2.0), 2.0);
-  eval("int(-3.8)",Point<2>(1.1,-2.0), -4.0);
-
-  eval("abs(-2.3)",Point<2>(0,0), 2.3);
-  eval("acos(0.5)",Point<2>(0,0), acos(0.5));
-  eval("acosh(0.5)",Point<2>(0,0), acosh(0.5));
-  eval("asin(0.5)",Point<2>(0,0), asin(0.5));
-  eval("asinh(0.5)",Point<2>(0,0), asinh(0.5));
-  eval("atan(0.5)",Point<2>(0,0), atan(0.5));
-  eval("atanh(0.5)",Point<2>(0,0), atanh(0.5));
-  eval("ceil(0.5)",Point<2>(0,0), ceil(0.5));
-  eval("cos(0.5)",Point<2>(0,0), cos(0.5));
-  eval("cosh(0.5)",Point<2>(0,0), cosh(0.5));
-  eval("cot(0.5)",Point<2>(0,0), 1.0/tan(0.5));
-  eval("csc(0.5)",Point<2>(0,0), 1.0/sin(0.5));
-  eval("exp(0.5)",Point<2>(0,0), exp(0.5));
-  eval("floor(0.5)",Point<2>(0,0), floor(0.5));
-  eval("log(0.5)",Point<2>(0,0), log(0.5));
-  eval("log10(0.5)",Point<2>(0,0), log(0.5)/log(10.0));
-  eval("sec(0.5)",Point<2>(0,0), 1.0/cos(0.5));
-  eval("sin(0.5)",Point<2>(0,0), sin(0.5));
-  eval("sinh(0.5)",Point<2>(0,0), sinh(0.5));
-  eval("sqrt(0.5)",Point<2>(0,0), sqrt(0.5));
-  eval("tan(0.5)",Point<2>(0,0), tan(0.5));
-  eval("tanh(0.5)",Point<2>(0,0), tanh(0.5));
+  eval("int (2.1)",Point<2>(1.1,-2.0), 2.0);
+  eval("int (-3.8)",Point<2>(1.1,-2.0), -4.0);
+
+  eval("abs (-2.3)",Point<2>(0,0), 2.3);
+  eval("acos (0.5)",Point<2>(0,0), acos(0.5));
+  eval("acosh (0.5)",Point<2>(0,0), acosh(0.5));
+  eval("asin (0.5)",Point<2>(0,0), asin(0.5));
+  eval("asinh (0.5)",Point<2>(0,0), asinh(0.5));
+  eval("atan (0.5)",Point<2>(0,0), atan(0.5));
+  eval("atanh (0.5)",Point<2>(0,0), atanh(0.5));
+  eval("ceil (0.5)",Point<2>(0,0), ceil(0.5));
+  eval("cos (0.5)",Point<2>(0,0), cos(0.5));
+  eval("cosh (0.5)",Point<2>(0,0), cosh(0.5));
+  eval("cot (0.5)",Point<2>(0,0), 1.0/tan(0.5));
+  eval("csc (0.5)",Point<2>(0,0), 1.0/sin(0.5));
+  eval("exp (0.5)",Point<2>(0,0), exp(0.5));
+  eval("floor (0.5)",Point<2>(0,0), floor(0.5));
+  eval("log (0.5)",Point<2>(0,0), log(0.5));
+  eval("log10 (0.5)",Point<2>(0,0), log(0.5)/log(10.0));
+  eval("sec (0.5)",Point<2>(0,0), 1.0/cos(0.5));
+  eval("sin (0.5)",Point<2>(0,0), sin(0.5));
+  eval("sinh (0.5)",Point<2>(0,0), sinh(0.5));
+  eval("sqrt (0.5)",Point<2>(0,0), sqrt(0.5));
+  eval("tan (0.5)",Point<2>(0,0), tan(0.5));
+  eval("tanh (0.5)",Point<2>(0,0), tanh(0.5));
 
 
 }
index dfbec14eb1c0521430d388224f8d37d78c8203f6..4653eb2ed52bf7a6ac79bae69acdcf63a72ef45d 100644 (file)
@@ -7,31 +7,31 @@ DEAL::'if   (x<1.0 | y<1.0,0,y)' @ 1.50000 1.50000 is 1.50000 ( expected 1.50000
 DEAL::'if   (x<1.0 | y<1.0,0,y)' @ 1.50000 0.500000 is 0.00000 ( expected 0.00000 )
 DEAL::'if   (x<1.0 | y<1.0,0,y)' @ 0.500000 -2.00000 is 0.00000 ( expected 0.00000 )
 DEAL::'if   (x<1.0 & y<1.0,0,y)' @ 1.50000 -2.00000 is -2.00000 ( expected -2.00000 )
-DEAL::'atan2(x,y)' @ 1.00000 -3.10000 is 2.82955 ( expected 2.82955 )
-DEAL::'atan2(x,y)' @ -1.00000 3.10000 is -0.312042 ( expected -0.312042 )
+DEAL::'atan2 (x,y)' @ 1.00000 -3.10000 is 2.82955 ( expected 2.82955 )
+DEAL::'atan2 (x,y)' @ -1.00000 3.10000 is -0.312042 ( expected -0.312042 )
 DEAL::'if   (x==1.0,0,y)' @ 1.00000 -2.00000 is 0.00000 ( expected 0.00000 )
 DEAL::'if   (x==1.0,0,y)' @ 1.10000 -2.00000 is -2.00000 ( expected -2.00000 )
-DEAL::'int(2.1)' @ 1.10000 -2.00000 is 2.00000 ( expected 2.00000 )
-DEAL::'int(-3.8)' @ 1.10000 -2.00000 is -4.00000 ( expected -4.00000 )
-DEAL::'abs(-2.3)' @ 0.00000 0.00000 is 2.30000 ( expected 2.30000 )
-DEAL::'acos(0.5)' @ 0.00000 0.00000 is 1.04720 ( expected 1.04720 )
-DEAL::'acosh(0.5)' @ 0.00000 0.00000 is -nan ( expected -nan )
-DEAL::'asin(0.5)' @ 0.00000 0.00000 is 0.523599 ( expected 0.523599 )
-DEAL::'asinh(0.5)' @ 0.00000 0.00000 is 0.481212 ( expected 0.481212 )
-DEAL::'atan(0.5)' @ 0.00000 0.00000 is 0.463648 ( expected 0.463648 )
-DEAL::'atanh(0.5)' @ 0.00000 0.00000 is 0.549306 ( expected 0.549306 )
-DEAL::'ceil(0.5)' @ 0.00000 0.00000 is 1.00000 ( expected 1.00000 )
-DEAL::'cos(0.5)' @ 0.00000 0.00000 is 0.877583 ( expected 0.877583 )
-DEAL::'cosh(0.5)' @ 0.00000 0.00000 is 1.12763 ( expected 1.12763 )
-DEAL::'cot(0.5)' @ 0.00000 0.00000 is 1.83049 ( expected 1.83049 )
-DEAL::'csc(0.5)' @ 0.00000 0.00000 is 2.08583 ( expected 2.08583 )
-DEAL::'exp(0.5)' @ 0.00000 0.00000 is 1.64872 ( expected 1.64872 )
-DEAL::'floor(0.5)' @ 0.00000 0.00000 is 0.00000 ( expected 0.00000 )
-DEAL::'log(0.5)' @ 0.00000 0.00000 is -0.693147 ( expected -0.693147 )
-DEAL::'log10(0.5)' @ 0.00000 0.00000 is -0.301030 ( expected -0.301030 )
-DEAL::'sec(0.5)' @ 0.00000 0.00000 is 1.13949 ( expected 1.13949 )
-DEAL::'sin(0.5)' @ 0.00000 0.00000 is 0.479426 ( expected 0.479426 )
-DEAL::'sinh(0.5)' @ 0.00000 0.00000 is 0.521095 ( expected 0.521095 )
-DEAL::'sqrt(0.5)' @ 0.00000 0.00000 is 0.707107 ( expected 0.707107 )
-DEAL::'tan(0.5)' @ 0.00000 0.00000 is 0.546302 ( expected 0.546302 )
-DEAL::'tanh(0.5)' @ 0.00000 0.00000 is 0.462117 ( expected 0.462117 )
+DEAL::'int (2.1)' @ 1.10000 -2.00000 is 2.00000 ( expected 2.00000 )
+DEAL::'int (-3.8)' @ 1.10000 -2.00000 is -4.00000 ( expected -4.00000 )
+DEAL::'abs (-2.3)' @ 0.00000 0.00000 is 2.30000 ( expected 2.30000 )
+DEAL::'acos (0.5)' @ 0.00000 0.00000 is 1.04720 ( expected 1.04720 )
+DEAL::'acosh (0.5)' @ 0.00000 0.00000 is -nan ( expected -nan )
+DEAL::'asin (0.5)' @ 0.00000 0.00000 is 0.523599 ( expected 0.523599 )
+DEAL::'asinh (0.5)' @ 0.00000 0.00000 is 0.481212 ( expected 0.481212 )
+DEAL::'atan (0.5)' @ 0.00000 0.00000 is 0.463648 ( expected 0.463648 )
+DEAL::'atanh (0.5)' @ 0.00000 0.00000 is 0.549306 ( expected 0.549306 )
+DEAL::'ceil (0.5)' @ 0.00000 0.00000 is 1.00000 ( expected 1.00000 )
+DEAL::'cos (0.5)' @ 0.00000 0.00000 is 0.877583 ( expected 0.877583 )
+DEAL::'cosh (0.5)' @ 0.00000 0.00000 is 1.12763 ( expected 1.12763 )
+DEAL::'cot (0.5)' @ 0.00000 0.00000 is 1.83049 ( expected 1.83049 )
+DEAL::'csc (0.5)' @ 0.00000 0.00000 is 2.08583 ( expected 2.08583 )
+DEAL::'exp (0.5)' @ 0.00000 0.00000 is 1.64872 ( expected 1.64872 )
+DEAL::'floor (0.5)' @ 0.00000 0.00000 is 0.00000 ( expected 0.00000 )
+DEAL::'log (0.5)' @ 0.00000 0.00000 is -0.693147 ( expected -0.693147 )
+DEAL::'log10 (0.5)' @ 0.00000 0.00000 is -0.301030 ( expected -0.301030 )
+DEAL::'sec (0.5)' @ 0.00000 0.00000 is 1.13949 ( expected 1.13949 )
+DEAL::'sin (0.5)' @ 0.00000 0.00000 is 0.479426 ( expected 0.479426 )
+DEAL::'sinh (0.5)' @ 0.00000 0.00000 is 0.521095 ( expected 0.521095 )
+DEAL::'sqrt (0.5)' @ 0.00000 0.00000 is 0.707107 ( expected 0.707107 )
+DEAL::'tan (0.5)' @ 0.00000 0.00000 is 0.546302 ( expected 0.546302 )
+DEAL::'tanh (0.5)' @ 0.00000 0.00000 is 0.462117 ( expected 0.462117 )

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.