DataFunc.cpp

Go to the documentation of this file.
00001 //DataFunc.cpp
00002 
00003 /*************************************************************/
00004 //
00005 // CDataFunc
00006 //
00007 // Function parser and evaluator
00008 //
00009 //-------------------------------------------------------------
00010 //
00011 // v 1.7 - 2007/03/27 - Top hat
00012 // v 1.6 - 2007/02/07 - More trig and log functions
00013 // v 1.5 - 2007/02/01 - Heavyside functions
00014 // v 1.4 - 2007/01/13 - Added comma to end of variable list
00015 // v 1.3 - 2006/11/17 - Fixed '-' presidence and ',' argument separator
00016 // v 1.2 - 2006/08/21 - Rewrote Infix -> RPN converter
00017 // v 1.1 - 2006/08/18 - Added plane equation
00018 // v 1.0 - 2006/04/19 - Initial release
00019 //
00020 // See LICENSE.txt for distribution and usage restrictions
00021 // Copyright (c) 2005-2007 Simon Chorley
00022 // www.mylaboratory.co.uk - greylab@mylaboratory.co.uk
00023 //
00024 /*************************************************************/
00025 
00026 
00027 ///Function parser and evaluator (Implementation)
00028 /**
00029  * Provides implementation of CDataFunc function parser and evaluator to process the data.
00030  * @file DataFunc.cpp
00031  * @version 1.7 - 2007/03/27
00032  */
00033 
00034 
00035 #include "DataFunc.h"
00036 
00037 #include <string>
00038 #include <cmath>
00039 #include <iostream>
00040 
00041 
00042 CDataFunc::op *(CDataFunc::ops) = NULL;         ///<List of operators.
00043 int CDataFunc::nOps = 0;                                        ///<Number of operators.
00044 int CDataFunc::instances = 0;                           ///<Number of instances of this class.
00045 
00046 
00047 #define BUILDOP(str, pres, lass, arg) ops[i].tag = new char[strlen(str)+1]; \
00048         strcpy(ops[i].tag, str); \
00049         ops[i].tag[strlen(str)] = '\0'; \
00050         ops[i].precedence = pres; \
00051         ops[i].lassociative = lass; \
00052         ops[i].args = arg; \
00053         ++i;
00054 
00055 ///Initialise CDataFunc
00056 /**
00057  * If there are no instances of the class then the array of available operators is built.
00058  */
00059 CDataFunc::CDataFunc()
00060 {
00061         valid = true;
00062         nValues = 0;
00063         nQueue = 0;
00064         values = NULL;
00065         queue = NULL;
00066         if (instances == 0)
00067         {
00068                 int i = 0;
00069                 ops = new op[100];
00070 //Build list of acceptable tokens
00071 //=================================================================
00072 //       String         Prese.  LAsso.  Args.   Name
00073 //=================================================================
00074 BUILDOP("r",            -1,             true,   0)      //Result
00075 BUILDOP("(",            12,             false,  0)      //Parentheses
00076 BUILDOP(")",            11,             true,   0)      //Parentheses
00077 //BUILDOP(",",          10,             true,   0)      //Argument separator
00078 BUILDOP("v",            -1,             true,   0)      //Value (a number)
00079 BUILDOP("-",            1,              true,   2)      //Subtract
00080 BUILDOP("+",            1,              true,   2)      //Add
00081 BUILDOP("*",            3,              true,   2)      //Multiply
00082 BUILDOP("/",            3,              true,   2)      //Divide
00083 BUILDOP("^",            4,              false,  2)      //Power
00084 BUILDOP("exp",          5,              false,  1)      //Exponential
00085 BUILDOP("cos",          6,              false,  1)      //Cosine
00086 BUILDOP("sin",          6,              false,  1)      //Sine
00087 BUILDOP("tan",          6,              false,  1)      //Tangent
00088 BUILDOP("pi",           -1,             true,   0)      //Pi
00089 BUILDOP("x",            -1,             true,   0)      //x channel value
00090 BUILDOP("y",            -1,             true,   0)      //Sweep variable value
00091 BUILDOP("z",            -1,             true,   0)      //Data point
00092 BUILDOP("abs",          6,              false,  1)      //Absolute
00093 BUILDOP("blend",        6,              false,  3)      //Blend (a,b,x) - blend a*(1-x)+bx
00094 BUILDOP("clamp",        6,              false,  3)      //Clamp (x,a,b) - clamp x to range a->b
00095 BUILDOP("large",        6,              false,  2)      //Large (x,y) - larger of x and y
00096 BUILDOP("small",        6,              false,  2)      //Small (x,y) - smaller of x and y
00097 BUILDOP("select",       6,              false,  4)      //Select (x,y,z,a) - select x if z <= a else y
00098 BUILDOP("int",          6,              false,  1)      //Integer
00099 BUILDOP("col",          9,              false,  1)      //Column data point
00100 BUILDOP("plane",        6,              false,  4)      //Z height on plane given by ax+by+cz+d=0
00101 BUILDOP("NEGATE",       0,              false,  1)      //Negative of argument
00102 BUILDOP("hsl",          6,              false,  1)      //Left heavyside
00103 BUILDOP("hsr",          6,              false,  1)      //Right heavyside
00104 BUILDOP("acos",         6,              false,  1)      //Arccosine
00105 BUILDOP("asin",         6,              false,  1)      //Arcsine
00106 BUILDOP("atan",         6,              false,  1)      //Arctangent
00107 BUILDOP("cosh",         6,              false,  1)      //Hyperbolic cosine
00108 BUILDOP("sinh",         6,              false,  1)      //Hyperbolic sine
00109 BUILDOP("tanh",         6,              false,  1)      //Hyperbolic tangent
00110 BUILDOP("log",          6,              false,  1)      //Base 10 log
00111 BUILDOP("ln",           6,              false,  1)      //Base e (natural) log
00112 BUILDOP("th",           6,              false,  2)      //Top hat (left side, right side)
00113 //=================================================================
00114                 nOps = i;
00115         }
00116         ++instances;
00117 }
00118 
00119 
00120 ///Destruct CDataFunc
00121 /**
00122  * If this is the last instances of the class then delete the array of available operators.
00123  */
00124 CDataFunc::~CDataFunc()
00125 {
00126         --instances;
00127         if (instances == 0)
00128         {
00129                 int i;
00130                 for (i = 0; i < nOps; ++i)
00131                         delete[] ops[i].tag;
00132                 delete[] ops;
00133         }
00134 //      if (nQueue != 0) delete[] queue;
00135 //      if (nValues != 0) delete[] values;
00136         if (queue != NULL) delete[] queue;
00137         if (values != NULL) delete[] values;
00138 }
00139 
00140 
00141 ///Searches the list of tokens for a particular tag
00142 /**
00143  * @param string Name of the operator to search for.
00144  * @return ID of the found tag or -1 if not found.
00145  */
00146 int CDataFunc::FindTagID(char *string)
00147 {
00148         int i;
00149         for (i = 0; i < nOps; ++i)
00150                 if (strcmp(string, ops[i].tag) == 0)
00151                         return(i);
00152         return(-1);
00153 }
00154 
00155 
00156 ///List of non-number characters.
00157 #define NONNUMBER " \n,abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ!\"£$%^&*()-=+:;\'@#~<>/?\\|`¬[]{}"
00158 ///Converts a infix string into RPN stack
00159 /**
00160  * @param input Input equation.
00161  * @remark The resulting RPN stack is in the array CDataFunc::queue.
00162  * @return Error code of the parsing as a CDataFunc::status.
00163  */
00164 CDataFunc::status CDataFunc::InfixToRPN(char *input)
00165 {
00166         nQueue = 0;
00167         nValues = 0;
00168         valid = false;
00169         char prevNonSpace = 0;
00170 
00171         token *stack;
00172         stack = new token;
00173         token *top = stack;
00174         top->tagid = -1;
00175         top->prev = NULL;
00176         top->next = NULL;
00177 
00178         token *opstack = new token;
00179         token *topop = opstack;
00180         topop->tagid = -1;
00181         topop->next = NULL;
00182         topop->prev = NULL;
00183 
00184         char *strptr = input;
00185 //std::cerr << "Start: \'" << strptr << "\'\n";
00186         while (strptr[0] != '\0')
00187         {
00188                 if (strptr[0] == '$')   //Variable
00189                 {
00190                         int eov = strcspn(&strptr[1], "+-/* ()^,");     //end of variable
00191                         char *readtag = new char[eov+1];
00192                         strncpy(readtag, &strptr[1], eov);
00193                         readtag[eov] = '\0';
00194 //std::cerr << '\'' << readtag << "\' var-> \'" << strptr << "\'\n";
00195                         top->next = new token;
00196                         top->next->next = NULL;
00197                         top->next->prev = top;
00198                         top = top->next;
00199                         top->value = 0.0;
00200                         top->tagid = FindTagID(readtag);
00201                         delete[] readtag;
00202                         if (top->tagid == -1) return(UNKNOWN_TAG);
00203                         prevNonSpace = strptr[eov];
00204                         strptr = &strptr[eov+1];
00205                         ++nValues;
00206                         ++nQueue;
00207                 }
00208                 else if (((strptr[0] >= '0') && (strptr[0] <= '9')) || (strptr[0] == '.'))      //Number
00209                 {
00210                         int eov = strcspn(&strptr[0], NONNUMBER);
00211                         if ((strptr[eov] == 'e') || (strptr[eov] == 'E'))
00212                         {
00213                                 if (strptr[eov+1] == '-')
00214                                         eov += 2+strcspn(&strptr[eov+2], NONNUMBER);    //negative exponential
00215                                 else if (strptr[eov+1] == '+')
00216                                         eov += 2+strcspn(&strptr[eov+2], NONNUMBER);    //positive exponential
00217                                 else if ((strptr[eov+1] >= '0') && (strptr[eov+1] <= '9'))
00218                                         eov += 1+strcspn(&strptr[eov+1], NONNUMBER);    //exponential
00219                         }
00220                         char *readtag = new char[eov+1];
00221                         strncpy(readtag, &strptr[0], eov);
00222                         readtag[eov] = '\0';
00223 //std::cerr << '\'' << readtag << "\' num-> \'" << strptr << "\'\n";
00224                         top->next = new token;
00225                         top->next->next = NULL;
00226                         top->next->prev = top;
00227                         top = top->next;
00228                         top->tagid = FindTagID("v\0");
00229                         top->value = atof(readtag);
00230                         delete[] readtag;
00231                         if (top->tagid == -1) return(UNKNOWN_TAG);
00232                         prevNonSpace = strptr[eov-1];
00233                         strptr = &strptr[eov];
00234                         ++nValues;
00235                         ++nQueue;
00236                 }
00237                 else if (strptr[0] == '(')      //(
00238                 {
00239                         topop->next = new token;
00240                         topop->next->next = NULL;
00241                         topop->next->prev = topop;
00242                         topop = topop->next;
00243                         topop->tagid = 1;
00244                         prevNonSpace = strptr[0];
00245                         strptr = &strptr[1];
00246                 }
00247                 else if (strptr[0] == ')')      //)
00248                 {
00249                         while (topop->tagid != 1)
00250                         {
00251                                 if (topop->tagid == -1) return(UNMATCHED_PARENTHESES);
00252                                 top->next = new token;
00253                                 top->next->next = NULL;
00254                                 top->next->prev = top;
00255                                 top = top->next;
00256                                 top->value = 0.0;
00257                                 top->tagid = topop->tagid;
00258                                 topop = topop->prev;
00259                                 delete topop->next;
00260                                 topop->next = NULL;
00261                         }
00262                         topop = topop->prev;
00263                         delete topop->next;
00264                         topop->next = NULL;
00265                         prevNonSpace = strptr[0];
00266                         strptr = &strptr[1];
00267                 }
00268                 else if (strcspn(&strptr[0], "+-*/^") == 0)     //operator
00269                 {
00270                         char *readtag = new char[2];
00271                         readtag[0] = strptr[0];
00272                         readtag[1] = '\0';
00273 
00274                         //detect negative numbers
00275                         if (readtag[0] == '-')
00276                         {
00277                                 if ((prevNonSpace == '(') || (prevNonSpace == ',') || (prevNonSpace == '*') || (prevNonSpace == '/') || (prevNonSpace == '^') || (prevNonSpace == 0))
00278                                 {
00279                                         delete[] readtag;
00280                                         readtag = new char[7];
00281                                         strcpy(readtag, "NEGATE");
00282 /*                                      delete[] readtag;
00283                                         int eov = 1+strcspn(&strptr[1], NONNUMBER);
00284                                         if ((strptr[eov+1] == 'e') || (strptr[eov+1] == 'E'))
00285                                                 if ((strptr[eov+2] >= '0') && (strptr[eov+2] <= '9'))
00286                                                         eov += 1+strcspn(&strptr[eov+2], NONNUMBER);    //exponential
00287                                         readtag = new char[eov+1];
00288                                         strncpy(readtag, &strptr[0], eov);
00289                                         readtag[eov] = '\0';
00290 std::cerr << '\'' << readtag << "\' num-> \'" << strptr << "\'\n";
00291                                         top->next = new token;
00292                                         top->next->next = NULL;
00293                                         top->next->prev = top;
00294                                         top = top->next;
00295                                         top->tagid = FindTagID("v\0");
00296                                         top->value = atof(readtag);
00297                                         delete[] readtag;
00298                                         if (top->tagid == -1) return(UNKNOWN_TAG);
00299                                         prevNonSpace = strptr[eov];
00300                                         strptr = &strptr[eov+1];
00301                                         ++nValues;
00302                                         ++nQueue;
00303                                         continue;*/
00304                                 }
00305                         }
00306                         
00307 //std::cerr << '\'' << readtag << "\' op-> \'" << strptr << "\'\n";
00308                         int tagid = FindTagID(readtag);
00309                         delete[] readtag;
00310                         if (tagid == -1) return(UNKNOWN_TAG);
00311 
00312                         while (((topop->tagid != -1) && (topop->tagid != 1) && (topop->tagid != 3)) &&
00313                                 (((ops[tagid].lassociative == true) && (ops[tagid].precedence <= ops[topop->tagid].precedence)) ||
00314                                         ((ops[tagid].lassociative == false) && (ops[tagid].precedence < ops[topop->tagid].precedence))))
00315                         {
00316                                 top->next = new token;
00317                                 top->next->next = NULL;
00318                                 top->next->prev = top;
00319                                 top = top->next;
00320                                 top->tagid = topop->tagid;
00321                                 top->value = topop->value;
00322                                 topop = topop->prev;
00323                                 delete topop->next;
00324                                 topop->next = NULL;
00325                         }
00326                         topop->next = new token;
00327                         topop->next->next = NULL;
00328                         topop->next->prev = topop;
00329                         topop = topop->next;
00330                         topop->value = 0.0;
00331                         topop->tagid = tagid;
00332                         prevNonSpace = strptr[0];
00333                         strptr = &strptr[1];
00334                         ++nQueue;
00335                 }
00336                 else if (strptr[0] == ',')                      //argument separator
00337                 {
00338                         while (topop->tagid != 1)
00339                         {
00340                                 if (topop->tagid == -1) return(INVALID_SEPARATOR);
00341                                 top->next = new token;
00342                                 top->next->next = NULL;
00343                                 top->next->prev = top;
00344                                 top = top->next;
00345                                 top->value = 0.0;
00346                                 top->tagid = topop->tagid;
00347                                 topop = topop->prev;
00348                                 delete topop->next;
00349                                 topop->next = NULL;
00350                         }
00351 //std::cerr << '\'' << strptr[0] << "\' sep-> \'" << strptr << "\'\n";
00352                         prevNonSpace = strptr[0];
00353                         strptr = &strptr[1];
00354                 }
00355                 else if ((strptr[0] != ' ') && (strptr[0] != '\t') && (strptr[0] != '\n'))                      //function
00356                 {
00357                         int eov = strcspn(&strptr[0], "0123456789. ()");
00358                         char *readtag = new char[eov+1];
00359                         strncpy(readtag, strptr, eov);
00360                         readtag[eov] = '\0';
00361 //std::cerr << '\'' << readtag << "\' func-> \'" << strptr << "\'\n";
00362                         int tagid = FindTagID(readtag);
00363                         delete[] readtag;
00364                         if (tagid == -1) return(UNKNOWN_TAG);
00365 
00366                         while (((topop->tagid != -1) && (topop->tagid != 1) && (topop->tagid != 3)) &&
00367                                 (((ops[tagid].lassociative == true) && (ops[tagid].precedence <= ops[topop->tagid].precedence)) ||
00368                                         ((ops[tagid].lassociative == false) && (ops[tagid].precedence < ops[topop->tagid].precedence))))
00369                         {
00370                                 top->next = new token;
00371                                 top->next->next = NULL;
00372                                 top->next->prev = top;
00373                                 top = top->next;
00374                                 top->tagid = topop->tagid;
00375                                 top->value = topop->value;
00376                                 topop = topop->prev;
00377                                 delete topop->next;
00378                                 topop->next = NULL;
00379                         }
00380                         topop->next = new token;
00381                         topop->next->next = NULL;
00382                         topop->next->prev = topop;
00383                         topop = topop->next;
00384                         topop->value = 0.0;
00385                         topop->tagid = tagid;
00386                         prevNonSpace = strptr[eov-1];
00387                         strptr = &strptr[eov];
00388                         ++nQueue;
00389                 }
00390                 else
00391                         strptr = &strptr[1];
00392         }
00393         while (topop->tagid != -1)
00394         {
00395                 if (topop->tagid == 1) return(UNMATCHED_PARENTHESES);
00396                 top->next = new token;
00397                 top->next->next = NULL;
00398                 top->next->prev = top;
00399                 top = top->next;
00400                 top->tagid = topop->tagid;
00401                 top->value = 0.0;
00402                 topop = topop->prev;
00403                 delete topop->next;
00404                 topop->next = NULL;
00405         }
00406         delete topop;
00407 //std::cerr << '\n';
00408 
00409         if (queue != NULL) delete[] queue;
00410         if (values != NULL) delete[] values;
00411         queue = NULL;
00412         values = NULL;
00413         if (nQueue != 0)
00414                 queue = new token[nQueue];
00415         if (nValues != 0)
00416         {
00417                 values = new real[nValues];
00418         }
00419         top = stack->next;
00420         int i;
00421         for (i = 0; i < nQueue; ++i)
00422         {
00423                 queue[i].tagid = top->tagid;
00424                 queue[i].value = top->value;
00425 //std::cerr << ops[top->tagid].tag << top->value << ' ';
00426                 top = top->next;
00427         }
00428         top = stack;
00429         while (top->next != NULL)
00430         {
00431                 top = top->next;
00432                 delete top->prev;
00433         }
00434         delete top;
00435         
00436         return(TestEvaluate());
00437 }
00438 
00439 
00440 ///Evaluates an RPN stack
00441 /**
00442  * Evaluates the RPN stack in CDataFunc::queue.
00443  * @param x X coordinate of the datapoint.
00444  * @param y Y coordinate of the datapoint.
00445  * @param z Z value of the datapoint.
00446  * @param cols Number of columns in coldata.
00447  * @param coldata Values in the other columns of the datapoint.
00448  * @return Evaluated value.
00449  */
00450 double CDataFunc::Evaluate(double x, double y, double z, int cols, double coldata[])
00451 {
00452         int val = 0, i;
00453         for (i = 0; i < nQueue; ++i)    //for all tokens
00454         {
00455                 switch (queue[i].tagid) //identify and adjust stack as required
00456                 {
00457                                         //"r"           Result
00458                                         //"("           Parentheses
00459                                         //")"           Parentheses
00460                 case 3:         //"v"           Value (a number)
00461                         {
00462                                 values[val] = queue[i].value;
00463                                 ++val;
00464                         }
00465                         break;
00466                 case 4:         //"-"           Subtract
00467                         {
00468                                 --val;
00469                                 values[val-1] = values[val-1]-values[val];
00470                         }
00471                         break;
00472                 case 5:         //"+"           Add
00473                         {
00474                                 --val;
00475                                 values[val-1] = values[val-1]+values[val];
00476                         }
00477                         break;
00478                 case 6:         //"*"           Multiply
00479                         {
00480                                 --val;
00481                                 values[val-1] = values[val-1]*values[val];
00482                         }
00483                         break;
00484                 case 7:         //"/"           Divide
00485                         {
00486                                 --val;
00487                                 values[val-1] = values[val-1]/values[val];
00488                         }
00489                         break;
00490                 case 8:         //"^"           Power
00491                         {
00492                                 --val;
00493                                 values[val-1] = pow(values[val-1], values[val]);
00494                         }
00495                         break;
00496                 case 9:         //"exp"         Exponential
00497                         {
00498                                 values[val-1] = exp(values[val-1]);
00499                         }
00500                         break;
00501                 case 10:        //"cos"         Cosine
00502                         {
00503                                 values[val-1] = cos(values[val-1]);
00504                         }
00505                         break;
00506                 case 11:        //"sin"         Sine
00507                         {
00508                                 values[val-1] = sin(values[val-1]);
00509                         }
00510                         break;
00511                 case 12:        //"tan"         Tangent
00512                         {
00513                                 values[val-1] = tan(values[val-1]);
00514                         }
00515                         break;
00516                 case 13:        //"pi"          Pi
00517                         {
00518                                 values[val] = PI;
00519                                 ++val;
00520                         }
00521                         break;
00522                 case 14:        //"x"           x channel value
00523                         {
00524                                 values[val] = x;
00525                                 ++val;
00526                         }
00527                         break;
00528                 case 15:        //"y"           y sd value
00529                         {
00530                                 values[val] = y;
00531                                 ++val;
00532                         }
00533                         break;
00534                 case 16:        //"z"           the data point
00535                         {
00536                                 values[val] = z;
00537                                 ++val;
00538                         }
00539                         break;
00540                 case 17:        //"abs"         Absolute
00541                         {
00542                                 values[val-1] = fabs(values[val-1]);
00543                         }
00544                         break;
00545                 case 18:        //"blend"       Blend (a,b,x) - blend a*(1-x)+bx
00546                         {
00547                                 val -= 2;
00548                                 values[val-1] = values[val-1]*(1-values[val+1])+values[val]*values[val+1];
00549                         }
00550                         break;
00551                 case 19:        //"clamp"       Clamp (x,a,b) - clamp x to range a->b
00552                         {
00553                                 val -= 2;
00554                                 if (values[val-1] < values[val])
00555                                         values[val-1] = values[val];
00556                                 else if (values[val-1] > values[val+1])
00557                                         values[val-1] = values[val+1];
00558 //                              else leave as is
00559                         }
00560                         break;
00561                 case 20:        //"large"       Large (x,y) - larger of x and y
00562                         {
00563                                 --val;
00564                                 if (values[val-1] < values[val])
00565                                         values[val-1] = values[val];
00566                         }
00567                         break;
00568                 case 21:        //"small"       Small (x,y) - smaller of x and y
00569                         {
00570                                 --val;
00571                                 if (values[val-1] > values[val])
00572                                         values[val-1] = values[val];
00573                         }
00574                         break;
00575                 case 22:        //"select"      Select (x,y,z,a) - select x if z <= a else y
00576                         {
00577                                 val -= 3;
00578                                 if (values[val+1] > values[val+2])
00579                                         values[val-1] = values[val];
00580                         }
00581                         break;
00582                 case 23:        //"int"         Integer
00583                         {
00584                                 values[val-1] = (real)((int)(values[val-1]));
00585                         }
00586                         break;
00587                 case 24:        //"col"         Column data point
00588                         {
00589                                 if (values[val-1] > (cols-1))
00590                                         return(1e-100);
00591                                 values[val-1] = coldata[(int)(values[val-1])];
00592                         }
00593                         break;
00594                 case 25:        //"plane"               Z of plane ax+by+cz+d=0
00595                         {
00596                                 val -= 3;
00597                                 values[val-1] = (0.0-values[val+2]-values[val-1]*x-values[val]*y)/values[val+1];
00598                         }
00599                         break;
00600                 case 26:        //"NEGATE"              Negative of argument
00601                         {
00602                                 values[val-1] = -values[val-1];
00603                         }
00604                         break;
00605                 case 27:        //"hsl"         Left heavyside
00606                         {
00607                                 if (values[val-1] <= 0.0)
00608                                         values[val-1] = 1.0;
00609                                 else
00610                                         values[val-1] = 0.0;
00611                         }
00612                         break;
00613                 case 28:        //"hsr"         Negative of argument
00614                         {
00615                                 if (values[val-1] >= 0.0)
00616                                         values[val-1] = 1.0;
00617                                 else
00618                                         values[val-1] = 0.0;
00619                         }
00620                         break;
00621                 case 29:        //"acos"        Arccossine
00622                         {
00623                                 values[val-1] = acos(values[val-1]);
00624                         }
00625                         break;
00626                 case 30:        //"asin"        Arcsine
00627                         {
00628                                 values[val-1] = asin(values[val-1]);
00629                         }
00630                         break;
00631                 case 31:        //"atan"        Arctangent
00632                         {
00633                                 values[val-1] = atan(values[val-1]);
00634                         }
00635                         break;
00636                 case 32:        //"cosh"        Hyperbolic cosine
00637                         {
00638                                 values[val-1] = cosh(values[val-1]);
00639                         }
00640                         break;
00641                 case 33:        //"sinh"        Hyperbolic sine
00642                         {
00643                                 values[val-1] = sinh(values[val-1]);
00644                         }
00645                         break;
00646                 case 34:        //"tanh"        Hyperbolic tangent
00647                         {
00648                                 values[val-1] = tanh(values[val-1]);
00649                         }
00650                         break;
00651                 case 35:        //"log" Base 10 log
00652                         {
00653                                 values[val-1] = log10(values[val-1]);
00654                         }
00655                         break;
00656                 case 36:        //"ln"  Base e (natural) log
00657                         {
00658                                 values[val-1] = log(values[val-1]);
00659                         }
00660                         break;
00661                 case 37:        //"th"  Top hat (x,y) - 1 if x > 0 and y < 0
00662                         {
00663                                 --val;
00664                                 if ((values[val-1] >= 0.0) && (values[val] <= 0))
00665                                         values[val-1] = 1.0;
00666                                 else
00667                                         values[val-1] = 0.0;
00668                         }
00669                         break;
00670                 }
00671         }
00672         return(values[val-1]);
00673 }
00674 
00675 
00676 ///Simple evaluation check
00677 /**
00678  * Checks that after evaluation we are just left with the answer on the stack.
00679  * @return Status of the test evaluation as a CDataFunc::status.
00680  */
00681 CDataFunc::status CDataFunc::TestEvaluate(void)
00682 {
00683         int val = 0, i;
00684         for (i = 0; i < nQueue; ++i)
00685         {
00686                 val -= ops[queue[i].tagid].args;
00687                 if (val < 0)
00688                         return(TOO_FEW_VARS);
00689                 ++val;
00690         }
00691         if (val < 1)
00692                 return(TOO_FEW_VARS);
00693         valid = true;
00694         return(OK);
00695 }

Generated on Mon Mar 10 13:55:44 2008 for GreyLab by  doxygen 1.5.3