version 1.1, 2018/04/03 12:09:46 |
version 1.3, 2018/04/05 13:02:39 |
|
|
/* $OpenXM$ */ |
/* $OpenXM: OpenXM/src/ox_gsl/ox_eval.c,v 1.2 2018/04/05 05:53:52 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" |
|
|
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) |
|
|
memset(local_dic, 0, sizeof(entry)*LOCAL_DIC_SIZE); |
memset(local_dic, 0, sizeof(entry)*LOCAL_DIC_SIZE); |
} |
} |
|
|
|
void replace(int n, ...) |
|
{ |
|
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, entry *dic) |
static entry *find_entry(cmo *node, entry *dic) |
{ |
{ |
char *s; |
char *s; |
Line 198 static int eval_cmo_indeterminate(cmo_indeterminate *c |
|
Line 225 static int eval_cmo_indeterminate(cmo_indeterminate *c |
|
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),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; |
Line 226 int eval_cmo(cmo *c, double *retval) |
|
Line 330 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: |
/* 変換できない型 */ |
/* 変換できない型 */ |