[BACK]Return to ox_eval.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_gsl

Diff for /OpenXM/src/ox_gsl/ox_eval.c between version 1.1 and 1.5

version 1.1, 2018/04/03 12:09:46 version 1.5, 2018/04/13 16:51:42
Line 1 
Line 1 
 /* $OpenXM$ */  /* $OpenXM: OpenXM/src/ox_gsl/ox_eval.c,v 1.4 2018/04/06 10:44:51 ohara Exp $ */
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
   #include <stdarg.h>
 #include <string.h>  #include <string.h>
 #include <math.h>  #include <math.h>
 #include "ox_toolkit.h"  #include "ox_toolkit.h"
Line 10 
Line 11 
 Usage:  Usage:
   
 double d;  double d;
 init_dic();  replace(3,"x",1.25,"y",-2.0, "z", 2.1);
 register_entry("x",1.25);  
 register_entry("y",2.1);  
 if(eval_cmo(your_cmo_tree,&d)==0) goto_error();  if(eval_cmo(your_cmo_tree,&d)==0) goto_error();
 */  */
   
 #define FUNCTION_P(e)      (((e)!=NULL) && ((e)->f != NULL))  #define FUNCTION_P(e)      (((e)!=NULL) && ((e)->f != NULL))
 #define VALUE_P(e)         (((e)!=NULL) && ((e)->f == NULL))  #define VALUE_P(e)         (((e)!=NULL) && ((e)->f == NULL))
   
   #define FAILED  0
   #define SUCCEED 1
   
   void replace(int n, ...);
   void replace2(int n, char *s[], double v[]);
 int eval_cmo(cmo *c, double *retval);  int eval_cmo(cmo *c, double *retval);
   
 static double op_add(double x,double y)  static double op_add(double x,double y)
Line 63  typedef struct {
Line 67  typedef struct {
 entry global_dic[512] = {  entry global_dic[512] = {
     {"sin",0,sin,1},      {"sin",0,sin,1},
     {"cos",0,cos,1},      {"cos",0,cos,1},
       {"tan",0,tan,1},
       {"sinh",0,sinh,1},
       {"cosh",0,cosh,1},
       {"tanh",0,tanh,1},
       {"asin",0,asin,1},
       {"acos",0,acos,1},
       {"asinh",0,asinh,1},
       {"acosh",0,acosh,1},
       {"erf",0,erf,1},
     {"exp",0,exp,1},      {"exp",0,exp,1},
       {"exp2",0,exp2,1},
     {"log",0,log,1},      {"log",0,log,1},
     {"negative",0,op_negative,1},      {"log2",0,log2,1},
       {"log10",0,log10,1},
       {"gamma",0,gamma,1},
       {"lgamma",0,lgamma,1},
       {"sqrt",0,sqrt,1},
       {"cbrt",0,cbrt,1},
       {"fabs",0,fabs,1},
       {"j0",0,j0,1},
       {"j1",0,j1,1},
       {"y0",0,y0,1},
       {"y1",0,y1,1},
       {"-",  0,op_negative,1},
     {"+",  0,op_add,2},      {"+",  0,op_add,2},
     {"-",  0,op_sub,2},      {"-",  0,op_sub,2},
     {"*",  0,op_mul,2},      {"*",  0,op_mul,2},
     {"/",  0,op_div,2},      {"/",  0,op_div,2},
     {"^",  0,pow,2},      {"^",  0,pow,2},
     {"e",  M_E, NULL,0},      {"pow",  0,pow,2},
     {"pi", M_PI,NULL,0},      {"@e",  M_E, NULL,0},
       {"@pi", M_PI,NULL,0},
     {NULL,0,NULL,0}      {NULL,0,NULL,0}
 };  };
   
Line 105  void init_dic()
Line 131  void init_dic()
     memset(local_dic, 0, sizeof(entry)*LOCAL_DIC_SIZE);      memset(local_dic, 0, sizeof(entry)*LOCAL_DIC_SIZE);
 }  }
   
 static entry *find_entry(cmo *node, entry *dic)  void replace(int n, ...)
 {  {
     char *s;      char *s;
       double d;
       va_list ap;
       va_start(ap,n);
       for(init_dic(); n>0; n--) {
           s = va_arg(ap, char *);
           d = va_arg(ap, double);
           register_entry(s,d);
       }
       va_end(ap);
   }
   
   void replace2(int n, char *s[], double v[])
   {
       int i;
       init_dic();
       for(i=0; i<n; i++) {
           register_entry(s[i],v[i]);
       }
   }
   
   static entry *find_entry(cmo *node, int len, entry *dic)
   {
       char *s;
     entry *e;      entry *e;
     if(node->tag == CMO_STRING) {      if(node->tag == CMO_STRING) {
         s = ((cmo_string *)node)->s;          s = ((cmo_string *)node)->s;
Line 117  static entry *find_entry(cmo *node, entry *dic)
Line 166  static entry *find_entry(cmo *node, entry *dic)
         return NULL;          return NULL;
     }      }
     for(e=dic; e->name != NULL; e++) {      for(e=dic; e->name != NULL; e++) {
         if(strcmp(e->name,s)==0) {          if(strcmp(e->name,s)==0 && (len<0 || len==e->n_args)) {
             return e;              return e;
         }          }
     }      }
Line 180  int entry_value(entry *e, double *retval)
Line 229  int entry_value(entry *e, double *retval)
 */  */
 static int eval_cmo_tree(cmo_tree* t, double *retval)  static int eval_cmo_tree(cmo_tree* t, double *retval)
 {  {
     entry *e = find_entry((cmo *)t->name,global_dic);      entry *e = find_entry((cmo *)t->name,list_length(t->leaves),global_dic);
         if (FUNCTION_P(e)) {      if (FUNCTION_P(e)) {
                 return entry_function(e,t->leaves,retval);          return entry_function(e,t->leaves,retval);
         }else if (VALUE_P(e)) {      }else if (VALUE_P(e)) {
                 return entry_value(e, retval);          return entry_value(e, retval);
         }      }
     return 0;      return 0;
 }  }
   
 static int eval_cmo_indeterminate(cmo_indeterminate *c, double *retval)  static int eval_cmo_indeterminate(cmo_indeterminate *c, double *retval)
 {  {
     entry *e = find_entry((cmo *)c,local_dic);      entry *e = find_entry((cmo *)c,-1,local_dic);
     if (VALUE_P(e)) {      if (VALUE_P(e)) {
         return entry_value(e,retval);          return entry_value(e,retval);
     }      }
     return 0;      return 0;
 }  }
   
   static double mypow(double x, int n)
   {
       int i,k,f=0;
       double s,t;
       if (n==0) {
           return 1;
       }else if (n<0) {
           n=-n;
           f=1;
       }
       /* t=x^(2^i) */
       s=1;
       t=x;
       for(k=n; k!=0; k=k>>1) {
           if(k&1) {
               s*=t;
           }
           t=t*t;
       }
       if (f>0) {
           s = 1/s;
       }
       return s;
   }
   
   static int eval_cmo_polynomial_in_one_variable(cmo_polynomial_in_one_variable* c, double vars[], int n, double *retval)
   {
       int i;
       cell *cc;
       double r,s=0;
       double x = vars[c->var];
       double *d=(double *)calloc(c->length, sizeof(double));
       for(i=0; i<c->length; i++) {
           cc = list_nth_cell((cmo_list *)c, i);
           if (cc->cmo->tag == CMO_POLYNOMIAL_IN_ONE_VARIABLE) {
               if(eval_cmo_polynomial_in_one_variable((cmo_polynomial_in_one_variable*)cc->cmo,vars,n,&r)==0) {
                   return 0;
               }
           }else {
               if(eval_cmo(cc->cmo,&r)==0) {
                   return 0;
               }
           }
           s += mypow(x,cc->exp)*r;
       }
       *retval = s;
       return 1;
   }
   
   static int eval_cmo_recursive_polynomial(cmo_recursive_polynomial* c, double *retval)
   {
           int i,n;
           double *vars;
           entry *e;
           switch(c->coef->tag) {
           case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
                   n=list_length(c->ringdef);
                   if(local_dic_counter<n) {
                           return 0; /* 自由変数が残る */
                   }
                   vars=(double *)calloc(n,sizeof(double));
                   for(i=0; i<n; i++) {
                           e = find_entry(list_nth(c->ringdef,i),-1,local_dic);
                           if(e == NULL) {
                                   free(vars);
                                   return 0; /* failed */
                           }
                           entry_value(e, &vars[i]);
                   }
                   return eval_cmo_polynomial_in_one_variable((cmo_polynomial_in_one_variable*)c->coef,vars,n,retval);
           case CMO_DISTRIBUTED_POLYNOMIAL:
                   return 0; /* failed */
           default: /* cmo_zz, cmo_qq, cmo_double, ... */
                   return eval_cmo(c->coef,retval);
           }
   }
   
 int eval_cmo(cmo *c, double *retval)  int eval_cmo(cmo *c, double *retval)
 {  {
     int tag = c->tag;      int tag = c->tag;
     switch(c->tag) {      switch(c->tag) {
       case CMO_NULL:
     case CMO_ZERO:      case CMO_ZERO:
         *retval = 0;          *retval = 0;
         break;          break;
Line 226  int eval_cmo(cmo *c, double *retval)
Line 353  int eval_cmo(cmo *c, double *retval)
         break;          break;
         case CMO_INDETERMINATE:          case CMO_INDETERMINATE:
         return eval_cmo_indeterminate((cmo_indeterminate *)c,retval);          return eval_cmo_indeterminate((cmo_indeterminate *)c,retval);
           break;
           case CMO_RECURSIVE_POLYNOMIAL:
           return eval_cmo_recursive_polynomial((cmo_recursive_polynomial *)c,retval);
         break;          break;
     default:      default:
         /* 変換できない型 */          /* 変換できない型 */

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.5

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>