evaluate_expr
#include "scicos_block.h"
#include <math.h>
#if WIN32
#include <float.h>
#endif
#if defined(solaris)
#include <ieeefp.h>
int isinf(double x) { return !finite(x) && x==x; }
#endif
#if defined(__alpha)
int isinf(double x) { return !finite(x) && x==x; }
#endif
#ifndef min
#define min(a,b) ((a) <= (b) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif
#if WIN32
/*
arcsinh z = log (z+sqrt(1+z2))
*/
double asinh(double x)
{
return log(x+sqrt(x*x+1));
}
double acosh(double x)
{
return log(x+sqrt(x*x-1));
}
/*
Inverse hyperbolic tangent (Atanh(x)) Log((1 + x) / (1 – x)) / 2
*/
double atanh(double x)
{
return (double)(log ((1.+x)/(1.-x))/2);
}
#endif
void evaluate_expr(scicos_block *block,int flag)
{
static double stack [1000];
static int count,bottom,nzcr,i,phase;
int j;
if (flag==1||flag==9){
phase=get_phase_simulation();
bottom=-1;
count=-1;
nzcr=-1;
while (count<block->nipar-1){
count=count+1;
switch (block->ipar[count]) {
case 2:
count=count+1;
bottom=bottom+1;
if(bottom>999){
set_block_error(-16);
return;
}
if (block->nin>1){
stack[bottom]=block->inptr[block->ipar[count]-1][0];
}else{
j=block->ipar[count]-1;
if (j<block->insz[0]){
stack[bottom]=block->inptr[0][block->ipar[count]-1];
}else{
stack[bottom]=0.;
}
}
break;
case 6:
count=count+1;
bottom=bottom+1;
if(bottom>999){
set_block_error(-16);
return;
}
stack[bottom]=block->rpar[block->ipar[count]-1];
break;
case 5:
count=count+1;
switch (block->ipar[count]) {
case 1:
stack[bottom-1]=stack[bottom-1]+stack[bottom];
bottom=bottom-1;
break;
case 2:
stack[bottom-1]=stack[bottom-1]-stack[bottom];
bottom=bottom-1;
break;
case 3:
stack[bottom-1]=stack[bottom-1]*stack[bottom];
bottom=bottom-1;
break;
case 7:
stack[bottom-1]=stack[bottom-1]/stack[bottom];
bottom=bottom-1;
break;
case 15:
stack[bottom-1]=pow(stack[bottom-1],stack[bottom]);
bottom=bottom-1;
break;
case 16: /* case == */
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]==stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]==stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 17:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]<stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]<stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 18:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]>stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]>stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 19:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]<=stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]<=stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 20:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]>=stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]>=stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 21:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=(stack[bottom-1]!=stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom-1]!=stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 28:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=((int)stack[bottom-1]||(int)stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=((int)stack[bottom-1]||(int)stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 29:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom-1]-stack[bottom];
if(phase==1) {
block->mode[nzcr]=((int)stack[bottom-1]&&(int)stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=((int)stack[bottom-1]&&(int)stack[bottom]);
} else{
i=block->mode[nzcr];
}
stack[bottom-1]=(double)i;
bottom=bottom-1;
break;
case 30:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
block->g[nzcr]=stack[bottom];
if(phase==1) {
block->mode[nzcr]=(0.0==stack[bottom]);
}
}
if(phase==1||block->ng==0){
i=(stack[bottom]==0.0);
}else{
i=block->mode[nzcr];
}
if (i){
stack[bottom]=1.0;
}else{
stack[bottom]=0.0;
}
break;
case 99:
stack[bottom]=-stack[bottom];
break;
case 101:
stack[bottom]=sin(stack[bottom]);
break;
case 102:
stack[bottom]=cos(stack[bottom]);
break;
case 103:
stack[bottom]=tan(stack[bottom]);
break;
case 104:
stack[bottom]=exp(stack[bottom]);
break;
case 105:
stack[bottom]=log(stack[bottom]);
break;
case 106:
stack[bottom]=sinh(stack[bottom]);
break;
case 107:
stack[bottom]=cosh(stack[bottom]);
break;
case 108:
stack[bottom]=tanh(stack[bottom]);
break;
case 109:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]>0) {
i=(int)floor(stack[bottom]);
}else{
i=(int)ceil(stack[bottom]);
}
if(i==0) {
block->g[nzcr]=(stack[bottom]-1)*(stack[bottom]+1);
}else if(i>0){
block->g[nzcr]=(stack[bottom]-i-1.)*(stack[bottom]-i);
}else{
block->g[nzcr]=(stack[bottom]-i)*(stack[bottom]-i+1);
}
if(i%2) block->g[nzcr]=-block->g[nzcr];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
if (stack[bottom]>0) {
stack[bottom]=floor(stack[bottom]);
}else{
stack[bottom]=ceil(stack[bottom]);
}
}else{
stack[bottom]=(double) block->mode[nzcr];
}
break;
/*
if (stack[bottom]>0) {
stack[bottom]=floor(stack[bottom]);
}else{
stack[bottom]=ceil(stack[bottom]);
}*/
break;
case 110:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]>0) {
i=(int)floor(stack[bottom]+.5);
}else{
i=(int)ceil(stack[bottom]-.5);
}
block->g[nzcr]=(stack[bottom]-i-.5)*(stack[bottom]-i+.5);
if(i%2) block->g[nzcr]=-block->g[nzcr];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
if (stack[bottom]>0) {
stack[bottom]=floor(stack[bottom]+.5);
}else{
stack[bottom]=ceil(stack[bottom]-.5);
}
}else{
stack[bottom]=(double) block->mode[nzcr];
}
break;
/* if (stack[bottom]>0) {
stack[bottom]=floor(stack[bottom]+.5);
}else{
stack[bottom]=ceil(stack[bottom]-.5);
}*/
case 111:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
i=(int)ceil(stack[bottom]);
block->g[nzcr]=(stack[bottom]-i)*(stack[bottom]-i+1);
if(i%2) block->g[nzcr]=-block->g[nzcr];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
stack[bottom]=ceil(stack[bottom]);
}else{
stack[bottom]=(double) block->mode[nzcr];
}
break;
case 112:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
i=(int)floor(stack[bottom]);
block->g[nzcr]=(stack[bottom]-i-1)*(stack[bottom]-i);
if(i%2) block->g[nzcr]=-block->g[nzcr];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
stack[bottom]=floor(stack[bottom]);
}else{
stack[bottom]=(double) block->mode[nzcr];
}
break;
case 113:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]>0) {
i=1;
}else if (stack[bottom]<0){
i=-1;
}else{
i=0;
}
block->g[nzcr]=stack[bottom];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
if (stack[bottom]>0) {
stack[bottom]=1.0;
}else if(stack[bottom]<0){
stack[bottom]=-1.0;
}else{
stack[bottom]=0.0;
}
}else{
stack[bottom]=(double) block->mode[nzcr];
}
break;
/* if (stack[bottom]>0) {
stack[bottom]=1.0;
}else if(stack[bottom]<0){
stack[bottom]=-1.0;
}else{
stack[bottom]=0.0;
}*/
case 114: /* abs */
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]>0) {
i=1;
}else if (stack[bottom]<0){
i=-1;
}else{
i=0;
}
block->g[nzcr]=stack[bottom];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
if (stack[bottom]>0) {
stack[bottom]=stack[bottom];
}else {
stack[bottom]=-stack[bottom];
}
}else{
stack[bottom]=stack[bottom]*(block->mode[nzcr]);
}
break;
/* if (stack[bottom]>0) {
stack[bottom]=stack[bottom];
}else {
stack[bottom]=-stack[bottom];
}*/
case 115:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]>stack[bottom-1]) {
i=0;
}else {
i=1;
}
block->g[nzcr]=stack[bottom]-stack[bottom-1];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
stack[bottom-1]=max(stack[bottom-1],stack[bottom]);
}else{
stack[bottom-1]=stack[bottom-block->mode[nzcr]];
}
bottom=bottom-1;
break;
case 116:
if(block->ng>0) nzcr=nzcr+1;
if (flag==9) {
if (stack[bottom]<stack[bottom-1]) {
i=0;
}else {
i=1;
}
block->g[nzcr]=stack[bottom]-stack[bottom-1];
if(phase==1) block->mode[nzcr]=i;
}
if(phase==1||block->ng==0){
stack[bottom-1]=min(stack[bottom-1],stack[bottom]);
}else{
stack[bottom-1]=stack[bottom-block->mode[nzcr]];
}
bottom=bottom-1;
break;
case 117:
stack[bottom]=asin(stack[bottom]);
break;
case 118:
stack[bottom]=acos(stack[bottom]);
break;
case 119:
stack[bottom]=atan(stack[bottom]);
break;
case 120:
stack[bottom]=asinh(stack[bottom]);
break;
case 121:
stack[bottom]=acosh(stack[bottom]);
break;
case 122:
stack[bottom]=atanh(stack[bottom]);
break;
case 123:
stack[bottom-1]=atan2(stack[bottom-1],stack[bottom]);
bottom=bottom-1;
break;
case 124:
stack[bottom]=log10(stack[bottom]);
break;
}
}
}
#if WIN32
if(!_finite(stack[bottom])||_isnan(stack[bottom])){
#else
if(isinf(stack[bottom])||isnan(stack[bottom])){
#endif
set_block_error(-2);
return;
}else{
block->outptr[0][0]=stack[bottom];
}
}
}