1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #ifndef _RWCOX_PARSER_HEADER_
8 #define _RWCOX_PARSER_HEADER_
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <math.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 
16 #ifdef  __cplusplus
17 extern "C" {                    /* care of Greg Balls    7 Aug 2006 [rickr] */
18 #endif
19 
20 #define MAX_PARCODE 9999
21 
22 typedef struct {
23    int num_code ;
24    char c_code[8*MAX_PARCODE] ;
25 } PARSER_code ;
26 
27 extern void PARSER_set_printout( int ) ;
28 
29 extern PARSER_code * PARSER_generate_code( char * ) ;
30 
31 extern double PARSER_evaluate_one( PARSER_code *, double atoz[] ) ;
32 
33 extern void PARSER_evaluate_vector( PARSER_code * pc, double  * atoz[],
34                                     int nv, double vout[] ) ;
35 
36 extern int PARSER_has_symbol( char * sym , PARSER_code * pc ) ;
37 extern void PARSER_mark_symbols( PARSER_code * pc , int * sl ) ;
38 
39 extern int PARSER_1deval( char *, int, float, float, float * ) ; /* 17 Nov 1999 */
40 extern int PARSER_1dtran( char *, int, float * ) ;               /* 16 Jun 2009 */
41 
42 extern double PARSER_strtod( char *expr ) ;
43 
44 extern float * PARSER_fitter( int nval, float *indval, float *depval,   /* 26 Jan 2016 */
45                        char *expr, char *indet,
46                        float *parbot, float *partop, float *parout, int meth, float *wtar ) ;
47 
48 #ifdef  __cplusplus
49 }
50 #endif
51 
52 #ifdef NEED_PARSER_INTERNALS
53 #include "f2c.h"
54 
55 #ifdef  __cplusplus
56 extern "C" {                    /* care of Greg Balls    7 Aug 2006 [rickr] */
57 #endif
58 
59 extern int parser_(char *c_expr__, logical *l_print__,
60                    integer * num_code__, char *c_code__,
61                    ftnlen c_expr_len, ftnlen c_code_len) ;
62 
63 extern doublereal pareval_(integer *num_code__, char *c_code__,
64                            doublereal *r8val, ftnlen c_code_len) ;
65 
66 extern int parevec_(integer *num_code__, char *c_code__,
67                     doublereal *va, doublereal *vb, doublereal *vc,
68           doublereal *vd, doublereal *ve, doublereal *vf,
69           doublereal *vg, doublereal *vh, doublereal *vi,
70           doublereal *vj, doublereal *vk, doublereal *vl,
71           doublereal *vm, doublereal *vn, doublereal *vo,
72           doublereal *vp, doublereal *vq, doublereal *vr,
73           doublereal *vs, doublereal *vt, doublereal *vu,
74           doublereal *vv, doublereal *vw, doublereal *vx,
75           doublereal *vy, doublereal *vz, integer *lvec ,
76           doublereal *vout, ftnlen c_code_len) ;
77 
78 extern doublereal dbesj0_( doublereal * ) ;
79 extern doublereal dbesj1_( doublereal * ) ;
80 extern doublereal dbesy0_( doublereal * ) ;
81 extern doublereal dbesy1_( doublereal * ) ;
82 
83 extern doublereal derf_ ( doublereal * ) ;
84 extern doublereal derfc_( doublereal * ) ;
85 
86 extern doublereal unif_( doublereal * ) ;
87 
88 #ifdef  __cplusplus
89 }
90 #endif
91 
92 #endif /* NEED_PARSER_INTERNALS */
93 
94 /*-------------------------------------------------------------------------*/
95 
96 #ifdef  __cplusplus
97 extern "C" {                    /* care of Greg Balls    7 Aug 2006 [rickr] */
98 #endif
99 
100 #undef  PARSER_HELP_STRING
101 #define PARSER_HELP_STRING                                                     \
102   " Arithmetic expressions are allowed, using + - * / ** ^ and parentheses.\n" \
103   " C relational, boolean, and conditional expressions are NOT implemented!\n" \
104   "* Note that the expression evaluator is designed not to fail;  illegal  *\n" \
105   "* operations like 'sqrt(-1)' are changed to legal ones to avoid crashes.*\n" \
106   " Built in functions include:\n"                                             \
107   "\n"                                                                         \
108   "    sin  , cos  , tan  , asin  , acos  , atan  , atan2,       \n"           \
109   "    sinh , cosh , tanh , asinh , acosh , atanh , exp  ,       \n"           \
110   "    log  , log10, abs  , int   , sqrt  , max   , min  ,       \n"           \
111   "    J0   , J1   , Y0   , Y1    , erf   , erfc  , qginv, qg ,  \n"           \
112   "    rect , step , astep, bool  , and   , or    , mofn ,       \n"           \
113   "    sind , cosd , tand , median, lmode , hmode , mad  ,       \n"           \
114   "    gran , uran , iran , eran  , lran  , orstat, mod  ,       \n"           \
115   "    mean , stdev, sem  , Pleg  , cbrt  , rhddc2, hrfbk4,hrfbk5\n"           \
116   "    minabove, maxbelow, extreme, absextreme    , acfwxm\n"                  \
117   "    gamp , gampq\n"                                                         \
118   "\n"                                                                         \
119   " where some of the less obvious funcions are:\n"                            \
120   " * qg(x)    = reversed cdf of a standard normal distribution\n"             \
121   " * qginv(x) = inverse function to qg\n"                                     \
122   " * min, max, atan2 each take 2 arguments ONLY\n"                            \
123   " * J0, J1, Y0, Y1 are Bessel functions (see the holy book: Watson)\n"       \
124   " * Pleg(m,x) is the m'th Legendre polynomial evaluated at x\n"              \
125   " * erf, erfc are the error and complementary error functions\n"             \
126   " * sind, cosd, tand take arguments in degrees (vs. radians)\n"              \
127   " * median(a,b,c,...) computes the median of its arguments\n"                \
128   " * mad(a,b,c,...) computes the MAD of its arguments\n"                      \
129   " * mean(a,b,c,...) computes the mean of its arguments\n"                    \
130   " * stdev(a,b,c,...) computes the standard deviation of its arguments\n"     \
131   " * sem(a,b,c,...) computes standard error of the mean of its arguments,\n"  \
132   "                  where sem(n arguments) = stdev(same)/sqrt(n)\n"           \
133   " * orstat(n,a,b,c,...) computes the n-th order statistic of\n"              \
134   "    {a,b,c,...} - that is, the n-th value in size, starting\n"              \
135   "    at the bottom (e.g., orstat(1,a,b,c) is the minimum)\n"                 \
136   " * minabove(X,a,b,c,...) computes the smallest value amongst {a,b,c,...}\n" \
137   "    that is LARGER than the first argument X; if all values are smaller\n"  \
138   "    than X, then X will be returned\n"                                      \
139   " * maxbelow(X,a,b,c,...) similarly returns the largest value amongst\n"     \
140   "    {a,b,c,...} that is SMALLER than the first argument X.\n"               \
141   " * extreme(a,b,c,...) finds the largest absolute value amongst\n"           \
142   "    {a,b,c,...} returning one of the original a,b,c,... values.\n"          \
143   " * absextreme(a,b,c,...) finds the largest absolute value amongst\n"        \
144   "    {a,b,c,...} returning the maximum absolute value of a,b,c,... values.\n"\
145   " * lmode(a,b,c,...) and hmode(a,b,c,...) compute the mode\n"                \
146   "    of their arguments - lmode breaks ties by choosing the\n"               \
147   "    smallest value with the maximal count, hmode breaks ties by\n"          \
148   "    choosing the largest value with the maximal count\n"                    \
149   "    [\"a,b,c,...\" indicates a variable number of arguments]\n"             \
150   " * gran(m,s) returns a Gaussian deviate with mean=m, stdev=s\n"             \
151   " * uran(r)   returns a uniform deviate in the range [0,r]\n"                \
152   " * iran(t)   returns a random integer in the range [0..t]\n"                \
153   " * eran(s)   returns an exponentially distributed deviate\n"                \
154   "               with parameter s; mean=s\n"                                  \
155   " * lran(t)   returns a logistically distributed deviate\n"                  \
156   "               with parameter t; mean=0, stdev=t*1.814\n"                   \
157   " * mod(a,b)  returns (a modulo b) = a - b*int(a/b)\n"                       \
158   " * hrfbk4(t,L) and hrfbk5(t,L) are the BLOCK4 and BLOCK5 hemodynamic\n"     \
159   "    response functions from 3dDeconvolve (L=stimulus duration in sec,\n"    \
160   "    and t is the time in sec since start of stimulus); for example:\n"      \
161   " 1deval -del 0.1 -num 400 -expr 'hrfbk5(t-2,20)' | 1dplot -stdin -del 0.1\n"\
162   "    These HRF functions are scaled to return values in the range [0..1]\n"  \
163   "\n"                                                                         \
164   " * ACFWXM(a,b,c,x) returns the Full Width at X Maximum for the mixed\n"     \
165   "   model ACF function\n"                                                    \
166   "     f(r) = a*expr(-r*r/(2*b*b))+(1-a)*exp(-r/c)\n"                         \
167   "   for X between 0 and 1 (not inclusive).  This is the model function\n"    \
168   "   estimated in program 3dFWHMx.\n"                                         \
169   " * gamp(peak,fwhm) returns the parameter p in the formula\n"                \
170   "      g(t) = (t/(p*q))^p * exp(p-t/q)\n"                                    \
171   "   that gives the peak value of g(t) occuring at t=peak when the\n"         \
172   "   FWHM of g(t) is given by fwhm; gamq(peak,fwhm) gives the q parameter.\n" \
173   "   These functions are largely used for creating FMRI hemodynamic shapes.\n"\
174   "\n"                                                                         \
175   " You may use the symbol 'PI' to refer to the constant of that name.\n"      \
176   " This is the only 2 letter symbol defined; all variables are\n"             \
177   " referred to by 1 letter symbols.  The case of the expression is\n"         \
178   " ignored (in fact, it is converted to uppercase as the first step\n"        \
179   " in the parsing algorithm).\n"                                              \
180   "\n"                                                                         \
181   " The following functions are designed to help implement logical\n"          \
182   " functions, such as masking of 3D volumes against some criterion:\n"        \
183   "       step(x)    = {1 if x>0           , 0 if x<=0},\n"                    \
184   "       posval(x)  = {x if x>0           , 0 if x<=0},\n"                    \
185   "       astep(x,y) = {1 if abs(x) > y    , 0 otherwise} = step(abs(x)-y)\n"  \
186   "  within(x,MI,MX) = {1 if MI <= x <= MX , 0 otherwise},\n"                  \
187   "       rect(x)    = {1 if abs(x)<=0.5, 0 if abs(x)>0.5},\n"                 \
188   "       bool(x)    = {1 if x != 0.0   , 0 if x == 0.0},\n"                   \
189   "    notzero(x)    = bool(x),\n"                                             \
190   "     iszero(x)    = 1-bool(x) = { 0 if x != 0.0, 1 if x == 0.0 },\n"        \
191   "        not(x)    = same as iszero(x)\n"                                    \
192   "     equals(x,y)  = 1-bool(x-y) = { 1 if x == y , 0 if x != y },\n"         \
193   "   ispositive(x)  = { 1 if x > 0; 0 if x <= 0 },\n"                         \
194   "   isnegative(x)  = { 1 if x < 0; 0 if x >= 0 },\n"                         \
195   "   ifelse(x,t,f)  = { t if x != 0; f if x == 0 },\n"                        \
196   "        not(x)    = same as iszero(x) = Boolean negation\n"                 \
197   "   and(a,b,...,c) = {1 if all arguments are nonzero, 0 if any are zero}\n"  \
198   "    or(a,b,...,c) = {1 if any arguments are nonzero, 0 if all are zero}\n"  \
199   "  mofn(m,a,...,c) = {1 if at least 'm' arguments are nonzero, else 0 }\n"   \
200   "  argmax(a,b,...) = index of largest argument; = 0 if all args are 0\n"     \
201   "  argnum(a,b,...) = number of nonzero arguments\n"                          \
202   "  pairmax(a,b,...)= finds the 'paired' argument that corresponds to the\n"  \
203   "                    maximum of the first half of the input arguments;\n"    \
204   "                    for example, pairmax(a,b,c,p,q,r) determines which\n"   \
205   "                    of {a,b,c} is the max, then returns corresponding\n"    \
206   "                    value from {p,q,r}; requires even number of args.\n"    \
207   "  pairmin(a,b,...)= Similar to pairmax, but for minimum; for example,\n"    \
208   "                    pairmin(a,b,c,p,q,r} finds the minimum of {a,b,c}\n"    \
209   "                    and returns the corresponding value from {p,q,r};\n"    \
210   "                      pairmin(3,2,7,5,-1,-2,-3,-4) = -2\n"                  \
211   "                    (The 'pair' functions are Lukas Pezawas specials!)\n"   \
212   "  amongst(a,b,...)= Return value is 1 if any of the b,c,... values\n"       \
213   "                    equals the a value; otherwise, return value is 0.\n"    \
214   " choose(n,a,b,...)= chooses the n-th value from the a,b,... values.\n"      \
215   "                    (e.g., choose(2,a,b,c) is b)\n"                         \
216   "  isprime(n)      = 1 if n is a positive integer and a prime number\n"      \
217   "                    0 if n is a positive integer and not a prime number\n"  \
218   "                   -1 if n is not a positive integer\n"                     \
219   "                   or if n is bigger than 2^31-1\n"                         \
220   "\n"                                                                         \
221   "  [These last 9 functions take a variable number of arguments.]\n"          \
222   "\n"                                                                         \
223   " The following 27 functions are used for statistical conversions,\n"        \
224   " as in the program 'cdf':\n"                                                \
225   "   fico_t2p(t,a,b,c), fico_p2t(p,a,b,c), fico_t2z(t,a,b,c),\n"              \
226   "   fitt_t2p(t,a)    , fitt_p2t(p,a)    , fitt_t2z(t,a)    ,\n"              \
227   "   fift_t2p(t,a,b)  , fift_p2t(p,a,b)  , fift_t2z(t,a,b)  ,\n"              \
228   "   fizt_t2p(t)      , fizt_p2t(p)      , fizt_t2z(t)      ,\n"              \
229   "   fict_t2p(t,a)    , fict_p2t(p,a)    , fict_t2z(t,a)    ,\n"              \
230   "   fibt_t2p(t,a,b)  , fibt_p2t(p,a,b)  , fibt_t2z(t,a,b)  ,\n"              \
231   "   fibn_t2p(t,a,b)  , fibn_p2t(p,a,b)  , fibn_t2z(t,a,b)  ,\n"              \
232   "   figt_t2p(t,a,b)  , figt_p2t(p,a,b)  , figt_t2z(t,a,b)  ,\n"              \
233   "   fipt_t2p(t,a)    , fipt_p2t(p,a)    , fipt_t2z(t,a)    .\n"              \
234   "\n"                                                                         \
235   " See the output of 'cdf -help' for documentation on the meanings of\n"      \
236   " and arguments to these functions.  The two functions below use the\n"      \
237   " NIfTI-1 statistical codes to map between statistical values and\n"         \
238   " cumulative distribution values:\n"                                         \
239   "   cdf2stat(val,code,p1,p2,p3) -- val is between 0 and 1\n"                 \
240   "   stat2cdf(val,code,p1,p2,p3) -- val is legal for the given distribution\n"\
241   " where code is\n"                                                           \
242   "   2 = correlation statistic     p1 = DOF\n"                                \
243   "   3 = t statistic (central)     p1 = DOF\n"                                \
244   "   4 = F statistic (central)     p1 = num DOF, p2 = den DOF\n"              \
245   "   5 = N(0,1) statistic          no parameters (p1=p2=p3=0)\n"              \
246   "   6 = Chi-squared (central)     p1 = DOF\n"                                \
247   "   7 = Beta variable (central)   p1 = a , p2 = b\n"                         \
248   "   8 = Binomial variable         p1 = #trials, p2 = prob per trial\n"       \
249   "   9 = Gamma distribution        p1 = shape, p2 = scale\n"                  \
250   "  10 = Poisson distribution      p1 = mean\n"                               \
251   "  11 = N(mu,variance) normal     p1 = mean, p2 = scale\n"                   \
252   "  12 = noncentral F statistic    p1 = num DOF, p2 = den DOF, p3 = noncen\n" \
253   "  13 = noncentral chi-squared    p1 = DOF, p2 = noncentrality parameter\n"  \
254   "  14 = Logistic distribution     p1 = mean, p2 = scale\n"                   \
255   "  15 = Laplace distribution      p1 = mean, p2 = scale\n"                   \
256   "  16 = Uniform distribution      p1 = min, p2 = max\n"                      \
257   "  17 = noncentral t statistic    p1 = DOF, p2 = noncentrality parameter\n"  \
258   "  18 = Weibull distribution      p1 = location, p2 = scale, p3 = power\n"   \
259   "  19 = Chi statistic (central)   p1 = DOF\n"                                \
260   "  20 = inverse Gaussian variable p1 = mu, p2 = lambda\n"                    \
261   "  21 = Extreme value type I      p1 = location, p2 = scale\n"               \
262   "  22 = 'p-value'                 no parameters\n"                           \
263   "  23 = -ln(p)                    no parameters\n"                           \
264   "  24 = -log10(p)                 no parameters\n"                           \
265   "When fewer than 3 parameters are needed, the values for later parameters\n" \
266   "are still required, but will be ignored.  An extreme case is code=5,\n"     \
267   "where the correct call is (e.g.) cdf2stat(p,5,0,0,0)\n"                     \
268   "\n"                                                                         \
269   "Finally, note that the expression evaluator is designed not to crash, or\n" \
270   "to return NaN or Infinity.  Illegal operations, such as division by 0,\n"   \
271   "logarithm of negative value, etc., are intercepted and something else\n"    \
272   "(usually 0) will be returned.  To find out what that 'something else'\n"    \
273   "is in any specific case, you should play with the ccalc program.\n"
274 
275 #ifdef  __cplusplus
276 }
277 #endif
278 
279 #endif /* _RWCOX_PARSER_HEADER_ */
280