libformula-calc.c
Go to the documentation of this file.
1 // Simple mathematical formula processing library
2 // Written by Atsushi Watanabe
3 // Intelligent Robot Laboratory, University of Tsukuba
4 //
5 // Copyright 2011 Atsushi Watanabe, All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright notice,
13 // this list of conditions and the following disclaimer in the documentation
14 // and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 // EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <math.h>
31 #include <ctype.h>
32 #include <sys/time.h>
33 
34 #include <formula-calc.h>
35 #include <formula.h>
36 
37 double math_b_and(double **val)
38 {
39  return (*val[0] > 0) && (*val[1] > 0);
40 }
41 
42 double math_b_or(double **val)
43 {
44  return (*val[0] > 0) || (*val[1] > 0);
45 }
46 
47 double math_b_not(double **val)
48 {
49  return !(*val[0] > 0);
50 }
51 
52 double math_eq(double **val)
53 {
54  return *val[0] == *val[1];
55 }
56 
57 double math_neq(double **val)
58 {
59  return *val[0] != *val[1];
60 }
61 
62 double math_gtr(double **val)
63 {
64  return *val[0] > *val[1];
65 }
66 
67 double math_geq(double **val)
68 {
69  return *val[0] >= *val[1];
70 }
71 
72 double math_lss(double **val)
73 {
74  return *val[0] < *val[1];
75 }
76 
77 double math_leq(double **val)
78 {
79  return *val[0] <= *val[1];
80 }
81 
82 double math_add(double **val)
83 {
84  return *val[0] + *val[1];
85 }
86 
87 double math_sub(double **val)
88 {
89  return *val[0] - *val[1];
90 }
91 
92 double math_mul(double **val)
93 {
94  return *val[0] * *val[1];
95 }
96 
97 double math_div(double **val)
98 {
99  return *val[0] / *val[1];
100 }
101 
102 double math_pow(double **val)
103 {
104  return pow(*val[0], *val[1]);
105 }
106 
107 double math_sin(double **val)
108 {
109  return sin(*val[0]);
110 }
111 
112 double math_cos(double **val)
113 {
114  return cos(*val[0]);
115 }
116 
117 double math_tan(double **val)
118 {
119  return tan(*val[0]);
120 }
121 
122 double math_sinh(double **val)
123 {
124  return sinh(*val[0]);
125 }
126 
127 double math_cosh(double **val)
128 {
129  return cosh(*val[0]);
130 }
131 
132 double math_tanh(double **val)
133 {
134  return tanh(*val[0]);
135 }
136 
137 double math_atan(double **val)
138 {
139  return atan(*val[0]);
140 }
141 
142 double math_asin(double **val)
143 {
144  return asin(*val[0]);
145 }
146 
147 double math_acos(double **val)
148 {
149  return acos(*val[0]);
150 }
151 
152 double math_atan2(double **val)
153 {
154  return atan2(*val[0], *val[1]);
155 }
156 
157 double math_sqrt(double **val)
158 {
159  return sqrt(*val[0]);
160 }
161 
162 double math_exp(double **val)
163 {
164  return exp(*val[0]);
165 }
166 
167 double math_let(double **val)
168 {
169  return *val[0] = *val[1];
170 }
171 
172 double math_sign(double **val)
173 {
174  if (*val[0] < 0)
175  return -1;
176  return 1;
177 }
178 
179 double math_fabs(double **val)
180 {
181  return fabs(*val[0]);
182 }
183 
184 double math_log10(double **val)
185 {
186  return log10(*val[0]);
187 }
188 
189 double math_ln(double **val)
190 {
191  return log(*val[0]);
192 }
193 
194 double math_pi(double **val)
195 {
196  return M_PI;
197 }
198 
199 double math_e(double **val)
200 {
201  return M_E;
202 }
203 
204 double math_mod(double **val)
205 {
206  return fmod(*val[0], *val[1]);
207 }
208 
209 double math_round(double **val)
210 {
211  return round(*val[0]);
212 }
213 
214 #define OPERATION_MUL 11
216  {
217  { "==", 4, TYPE_OP, math_eq, 2 },
218  { "=", 1, TYPE_OP, math_let, 2 },
219  { "||", 2, TYPE_OP, math_b_or, 2 },
220  { "&&", 3, TYPE_OP, math_b_and, 2 },
221  { "!=", 4, TYPE_OP, math_neq, 2 },
222  { "<=", 5, TYPE_OP, math_leq, 2 },
223  { ">=", 5, TYPE_OP, math_geq, 2 },
224  { "<", 5, TYPE_OP, math_lss, 2 },
225  { ">", 5, TYPE_OP, math_gtr, 2 },
226  { "+", 7, TYPE_OP, math_add, 2 },
227  { "-", 7, TYPE_OP, math_sub, 2 },
228  { "*", 8, TYPE_OP, math_mul, 2 },
229  { "/", 8, TYPE_OP, math_div, 2 },
230  { "!", 11, TYPE_OP, math_b_not, 1 },
231  { "pi", 17, TYPE_MATH, math_pi, 0 },
232  { "e", 17, TYPE_MATH, math_e, 0 },
233  { "log10", 17, TYPE_MATH, math_log10, 1 },
234  { "ln", 17, TYPE_MATH, math_ln, 1 },
235  { "sin", 17, TYPE_MATH, math_sin, 1 },
236  { "cos", 17, TYPE_MATH, math_cos, 1 },
237  { "tan", 17, TYPE_MATH, math_tan, 1 },
238  { "sinh", 17, TYPE_MATH, math_sinh, 1 },
239  { "cosh", 17, TYPE_MATH, math_cosh, 1 },
240  { "tanh", 17, TYPE_MATH, math_tanh, 1 },
241  { "asin", 17, TYPE_MATH, math_asin, 1 },
242  { "acos", 17, TYPE_MATH, math_acos, 1 },
243  { "atan2", 17, TYPE_MATH, math_atan2, 2 },
244  { "atan", 17, TYPE_MATH, math_atan, 1 },
245  { "exp", 17, TYPE_MATH, math_exp, 1 },
246  { "sqrt", 17, TYPE_MATH, math_sqrt, 1 },
247  { "abs", 17, TYPE_MATH, math_fabs, 1 },
248  { "sign", 17, TYPE_MATH, math_sign, 1 },
249  { "round", 17, TYPE_MATH, math_round, 1 },
250  { "mod", 17, TYPE_MATH, math_mod, 2 },
251  { "pow", 17, TYPE_MATH, math_pow, 2 },
252  { "", -1, TYPE_MAX, NULL, 0 }
253  };
254 
255 struct rpf_t *rpf_last(struct rpf_t *rpf)
256 {
257  for (; rpf->next; rpf = rpf->next)
258  ;
259 
260  return rpf;
261 }
262 
263 struct rpf_t *rpf_push(struct rpf_t *rpf, struct stack_t *obj)
264 {
265  rpf->next = malloc(sizeof(struct rpf_t));
266  rpf->next->type = obj->type;
267  rpf->next->value = obj->value;
268  rpf->next->next = NULL;
269 
270  return rpf->next;
271 }
272 
273 struct rpf_t *rpf_join(struct rpf_t *rpf, struct rpf_t *rpf2)
274 {
275  rpf->next = rpf2;
276  for (; rpf->next; rpf = rpf->next)
277  ;
278 
279  return rpf;
280 }
281 
282 int rpf_count_num(struct rpf_t *rpf)
283 {
284  int count;
285 
286  count = 0;
287  for (; rpf; rpf = rpf->next)
288  {
289  count++;
290  }
291 
292  return count;
293 }
294 
295 struct rpf_t *formula_output(struct stack_t *num, int *sp_num, struct stack_t *op, int *sp_op, int rank)
296 {
297  /*{
298  int i;
299  printf(" op ");
300  for(i = 0; i < *sp_op; i++)
301  printf("%s ", ((struct operation_t*)op[i].value)->op);
302  printf("\n num ");
303  for(i = 0; i < *sp_num; i++)
304  {
305  if(num[i].type == TYPE_RPF)
306  printf("rpf ");
307  else
308  printf("%f ", *((double*)num[i].value));
309  }
310  printf("\n");
311  }*/
312 
313  int sp_op2;
314  for (sp_op2 = *sp_op - 1; sp_op2 >= 0; sp_op2--)
315  {
316  struct rpf_t rpf2, *rpf2_tmp;
317  int sp_num2;
318 
319  rpf2_tmp = &rpf2;
320  rpf2.type = TYPE_START;
321 
322  int num_cnt;
323  num_cnt = ((struct operation_t *)op[sp_op2].value)->narg;
324  if (num_cnt > *sp_num)
325  return NULL;
326  for (sp_num2 = *sp_num - num_cnt; sp_num2 < *sp_num; sp_num2++)
327  {
328  switch (num[sp_num2].type)
329  {
330  case TYPE_RPF:
331  rpf2_tmp = rpf_join(rpf2_tmp, num[sp_num2].value);
332  //printf(" rpf");
333  break;
334  default:
335  rpf2_tmp = rpf_push(rpf2_tmp, &num[sp_num2]);
336  //printf("%f ", *((double*)num[sp_num2].value));
337  break;
338  }
339  }
340  //printf("\n");
341  (*sp_num) -= num_cnt;
342  rpf2_tmp = rpf_push(rpf2_tmp, &op[sp_op2]);
343  (*sp_op)--;
344 
345  num[*sp_num].rank = 0;
346  num[*sp_num].type = TYPE_RPF;
347  num[*sp_num].value = rpf2.next;
348  (*sp_num)++;
349 
350  //formula_print(stdout, &rpf2);
351  //printf("\n");
352  }
353  return num[*sp_num - 1].value;
354 }
355 
356 int formula(const char *expr, struct rpf_t **rpf, const struct variables_t *variable)
357 {
358  int i;
359  struct stack_t op[256];
360  struct stack_t num[256];
361  int sp_op, sp_num;
362  struct rpf_t rpf_start;
363  struct rpf_t *rpf_tmp;
364  *rpf = NULL;
365  int op_cont;
366 
367  sp_num = 0;
368  sp_op = 0;
369  op_cont = 0;
370  for (; *expr; expr++)
371  {
372  //printf( "[o%d/n%d] %s\n", sp_op, sp_num, expr );
373  if (*expr == '(')
374  {
375  const char *end;
376  int rank2;
377  struct rpf_t *rpf2;
378 
379  rank2 = 0;
380  for (; isspace(*expr); expr++)
381  ;
382  for (end = expr; *end; end++)
383  {
384  if (*end == '(')
385  rank2++;
386  if (*end == ')')
387  rank2--;
388  if (rank2 == 0)
389  break;
390  }
391  if (rank2 || !(*end))
392  return 0;
393  if (formula(expr + 1, &rpf2, variable) == 0)
394  return 0;
395  if (rpf2)
396  {
397  num[sp_num].rank = 0;
398  num[sp_num].type = TYPE_RPF;
399  num[sp_num].value = rpf2;
400  sp_num++;
401  }
402 
403  expr = end;
404  op_cont = 0;
405  continue;
406  }
407  else if (*expr == ')')
408  {
409  op_cont = 0;
410  break;
411  }
412  else if (*expr == ',')
413  {
414  if (formula_output(num, &sp_num, op, &sp_op, 0) == NULL)
415  return 0;
416  op_cont = 0;
417  continue;
418  }
419  else if (isspace(*expr))
420  {
421  op_cont = 0;
422  continue;
423  }
424  for (i = 0; operation[i].type != TYPE_MAX; i++)
425  {
426  if (strstr(expr, operation[i].op) == expr)
427  {
428  if (sp_op > 0 && op[sp_op - 1].rank == operation[i].rank)
429  {
430  int sp_op2;
431  sp_op2 = 1;
432  if (formula_output(num, &sp_num, op + sp_op - 1, &sp_op2, operation[i].rank) == NULL)
433  return 0;
434  sp_op--;
435  }
436  else if (sp_op > 0 && op[sp_op - 1].rank > operation[i].rank)
437  {
438  if (formula_output(num, &sp_num, op, &sp_op, operation[i].rank) == NULL)
439  return 0;
440  }
441  expr += strlen(operation[i].op);
442  for (; isspace(*expr); expr++)
443  ;
444 
445  if (sp_num == 0 && operation[i].func == math_sub)
446  {
447  // Case: start with -
448  num[sp_num].rank = 0;
449  num[sp_num].type = TYPE_VALUE;
450  num[sp_num].value = malloc(sizeof(double));
451  *((double *)num[sp_num].value) = -1;
452  sp_num++;
453  op[sp_op].rank = operation[OPERATION_MUL].rank;
454  op[sp_op].type = operation[OPERATION_MUL].type;
455  op[sp_op].value = &operation[OPERATION_MUL];
456  sp_op++;
457  op_cont = 0;
458  expr--;
459  break;
460  }
461  else if (op_cont == 1 && operation[i].type != TYPE_MATH)
462  {
463  if (operation[i].func == math_sub)
464  {
465  // Case: x*-y
466  num[sp_num].rank = 0;
467  num[sp_num].type = TYPE_VALUE;
468  num[sp_num].value = malloc(sizeof(double));
469  *((double *)num[sp_num].value) = -1;
470  sp_num++;
471  op[sp_op].rank = operation[OPERATION_MUL].rank;
472  op[sp_op].type = operation[OPERATION_MUL].type;
473  op[sp_op].value = &operation[OPERATION_MUL];
474  sp_op++;
475  op_cont = 0;
476  expr--;
477  break;
478  }
479  else
480  {
481  // Case: x*/y (Error)
482  return 0;
483  }
484  }
485 
486  if (operation[i].type != TYPE_MATH)
487  {
488  op_cont = 1;
489  }
490  else
491  {
492  op[sp_op].rank = operation[i].rank;
493  op[sp_op].type = operation[i].type;
494  op[sp_op].value = &operation[i];
495  sp_op++;
496  op_cont = 0;
497  if (operation[i].narg > 0)
498  {
499  const char *end;
500  int rank2;
501  struct rpf_t *rpf2;
502 
503  rank2 = 0;
504 
505  for (end = expr; *end; end++)
506  {
507  if (*end == '(')
508  rank2++;
509  if (*end == ')')
510  rank2--;
511  if (rank2 == 0)
512  break;
513  }
514  if (rank2 || !(*end))
515  return 0;
516  if (formula(expr + 1, &rpf2, variable) == 0)
517  return 0;
518  if (!rpf2)
519  return 0;
520 
521  num[sp_num].rank = 0;
522  num[sp_num].type = TYPE_RPF;
523  num[sp_num].value = rpf2;
524  rpf_push(rpf_last(rpf2), &op[sp_op - 1]);
525  sp_op--;
526  sp_num++;
527  expr = end + 1;
528  }
529  }
530  if (operation[i].type != TYPE_MATH)
531  {
532  op[sp_op].rank = operation[i].rank;
533  op[sp_op].type = operation[i].type;
534  op[sp_op].value = &operation[i];
535  sp_op++;
536  }
537  expr--;
538 
539  break;
540  }
541  }
542  if (operation[i].type != TYPE_MAX)
543  continue;
544  op_cont = 0;
545  if (isalpha(*expr))
546  {
547  const char *end;
548  char variable_name[256];
549  int i;
550 
551  if (!variable)
552  return 0;
553 
554  i = 0;
555  for (end = expr; *end; end++)
556  {
557  if (!(isalnum(*end) || *end == '_' || *end == '[' || *end == ']'))
558  break;
559  variable_name[i++] = *end;
560  }
561  variable_name[i] = 0;
562 
563  for (i = 0; variable[i].name; i++)
564  {
565  if (strcmp(variable[i].name, variable_name) == 0)
566  {
567  num[sp_num].rank = 0;
568  num[sp_num].type = TYPE_VARIABLE;
569  num[sp_num].value = variable[i].pointer;
570  sp_num++;
571  break;
572  }
573  }
574  if (!variable[i].name)
575  return 0;
576  expr = end - 1;
577  }
578  else
579  {
580  const char *end;
581 
582  for (end = expr; *end; end++)
583  {
584  if (!(isdigit(*end) || (end == expr && *end == '-') || *end == '.'))
585  break;
586  }
587  num[sp_num].rank = 0;
588  num[sp_num].type = TYPE_VALUE;
589  num[sp_num].value = malloc(sizeof(double));
590  *((double *)num[sp_num].value) = strtod(expr, NULL);
591  sp_num++;
592  expr = end - 1;
593  }
594  }
595  if (formula_output(num, &sp_num, op, &sp_op, 0) == NULL)
596  return 0;
597  if (sp_num < 0 || sp_op != 0)
598  return 0;
599 
600  rpf_start.type = TYPE_START;
601  rpf_tmp = &rpf_start;
602  for (sp_num--; sp_num >= 0; sp_num--)
603  {
604  switch (num[sp_num].type)
605  {
606  case TYPE_RPF:
607  rpf_tmp = rpf_join(rpf_tmp, num[sp_num].value);
608  break;
609  default:
610  rpf_tmp = rpf_push(rpf_tmp, &num[sp_num]);
611  break;
612  }
613  }
614  *rpf = rpf_start.next;
615  return 1;
616 }
617 
618 void formula_free(struct rpf_t *rpf)
619 {
620  for (; rpf;)
621  {
622  struct rpf_t *tmp;
623  switch (rpf->type)
624  {
625  case TYPE_VALUE:
626  free(rpf->value);
627  break;
628  case TYPE_VARIABLE:
629  break;
630  default:
631  break;
632  }
633  tmp = rpf->next;
634  free(rpf);
635  rpf = tmp;
636  }
637 }
638 
639 double formula_eval(struct rpf_t *rpf)
640 {
641  double _stack[512];
642  double *stack[512];
643  int sp;
644  struct operation_t *op;
645  double tmp;
646 
647  sp = 0;
648  for (; rpf; rpf = rpf->next)
649  {
650  switch (rpf->type)
651  {
652  case TYPE_VALUE:
653  case TYPE_VARIABLE:
654  stack[sp] = ((double *)rpf->value);
655  sp++;
656  break;
657  default:
658  op = (struct operation_t *)rpf->value;
659  tmp = (op->func)(&stack[sp - op->narg]);
660  sp -= op->narg;
661  stack[sp] = &_stack[sp];
662  _stack[sp] = tmp;
663  sp++;
664  break;
665  }
666  }
667  return *stack[0];
668 }
669 
670 struct rpf_t *formula_optimize(struct rpf_t *rpf_orig)
671 {
672  double *stack[512];
673  struct rpf_t *rpf_st[512];
674  int fixed[512];
675  int sp;
676  struct rpf_t *rpf_new;
677  struct rpf_t rpf_new_st;
678  int i;
679  struct rpf_t *rpf = rpf_orig;
680 
681  sp = 0;
682  for (; rpf; rpf = rpf->next)
683  {
684  struct operation_t *op;
685  double tmp;
686  switch (rpf->type)
687  {
688  case TYPE_VALUE:
689  case TYPE_VARIABLE:
690  fixed[sp] = 0;
691  rpf_st[sp] = malloc(sizeof(struct rpf_t));
692  *(rpf_st[sp]) = *rpf;
693  if (rpf->type == TYPE_VALUE)
694  {
695  stack[sp] = malloc(sizeof(double));
696  *(stack[sp]) = *((double *)rpf->value);
697  rpf_st[sp]->value = stack[sp];
698  fixed[sp] = 1;
699  }
700  else
701  {
702  stack[sp] = NULL;
703  fixed[sp] = 0;
704  }
705  sp++;
706  break;
707  default:
708  op = (struct operation_t *)rpf->value;
709  for (i = 0; i < op->narg; i++)
710  {
711  if (!fixed[sp - 1 - i])
712  break;
713  }
714  if (i == op->narg)
715  {
716  tmp = (op->func)(&stack[sp - op->narg]);
717  for (i = 0; i < op->narg; i++)
718  {
719  if (stack[sp - 1 - i])
720  free(stack[sp - 1 - i]);
721  free(rpf_st[sp - 1 - i]);
722  }
723  sp -= op->narg;
724  stack[sp] = malloc(sizeof(double));
725  *(stack[sp]) = tmp;
726  fixed[sp] = 1;
727 
728  rpf_st[sp] = malloc(sizeof(struct rpf_t));
729  rpf_st[sp]->type = TYPE_VALUE;
730  rpf_st[sp]->value = stack[sp];
731  sp++;
732  }
733  else
734  {
735  rpf_st[sp] = malloc(sizeof(struct rpf_t));
736  *(rpf_st[sp]) = *rpf;
737  fixed[sp] = 0;
738  sp++;
739  }
740  break;
741  }
742  }
743 
744  rpf_new = &rpf_new_st;
745  rpf_new->type = TYPE_START;
746  for (i = 0; i < sp; i++)
747  {
748  rpf_new->next = rpf_st[i];
749  rpf_new->next->next = NULL;
750  rpf_new = rpf_new->next;
751  }
752  return rpf_new_st.next;
753 }
754 
755 void formula_print(FILE *stream, struct rpf_t *rpf)
756 {
757  for (; rpf; rpf = rpf->next)
758  {
759  switch (rpf->type)
760  {
761  case TYPE_VALUE:
762  fprintf(stream, "%f ", *(double *)rpf->value);
763  break;
764  case TYPE_VARIABLE:
765  fprintf(stream, "VARIABLE ");
766  break;
767  default:
768  fprintf(stream, "%s ", ((struct operation_t *)rpf->value)->op);
769  break;
770  }
771  }
772 }
struct rpf_t * formula_optimize(struct rpf_t *rpf_orig)
double math_eq(double **val)
double math_cos(double **val)
int rank
Definition: formula.h:42
double math_sinh(double **val)
int narg
Definition: formula.h:45
double math_sub(double **val)
double math_geq(double **val)
struct rpf_t * formula_output(struct stack_t *num, int *sp_num, struct stack_t *op, int *sp_op, int rank)
double math_atan(double **val)
void formula_print(FILE *stream, struct rpf_t *rpf)
double math_mul(double **val)
struct rpf_t * rpf_push(struct rpf_t *rpf, struct stack_t *obj)
struct rpf_t * next
Definition: formula-calc.h:54
double math_e(double **val)
double math_b_not(double **val)
double math_add(double **val)
double math_sin(double **val)
double math_div(double **val)
int formula(const char *expr, struct rpf_t **rpf, const struct variables_t *variable)
struct rpf_t * rpf_join(struct rpf_t *rpf, struct rpf_t *rpf2)
double math_tan(double **val)
double math_ln(double **val)
#define OPERATION_MUL
double math_exp(double **val)
double math_acos(double **val)
char op[8]
Definition: formula.h:41
double math_pow(double **val)
double math_neq(double **val)
enum rpf_type_t type
Definition: formula-calc.h:52
void formula_free(struct rpf_t *rpf)
double math_lss(double **val)
double math_let(double **val)
struct operation_t operation[]
int rpf_count_num(struct rpf_t *rpf)
double math_mod(double **val)
double math_round(double **val)
int rank
Definition: formula.h:34
double math_asin(double **val)
double math_leq(double **val)
double formula_eval(struct rpf_t *rpf)
double(* func)(double **)
Definition: formula.h:44
struct rpf_t * rpf_last(struct rpf_t *rpf)
double math_log10(double **val)
void * value
Definition: formula-calc.h:53
double math_b_or(double **val)
double math_atan2(double **val)
double math_gtr(double **val)
void * value
Definition: formula.h:36
enum rpf_type_t type
Definition: formula.h:35
double math_sign(double **val)
const char * name
Definition: formula-calc.h:59
double math_sqrt(double **val)
double math_cosh(double **val)
double math_pi(double **val)
double math_fabs(double **val)
double math_tanh(double **val)
enum rpf_type_t type
Definition: formula.h:43
double * pointer
Definition: formula-calc.h:60
double math_b_and(double **val)


yp-spur
Author(s):
autogenerated on Sat May 11 2019 02:08:24