Fonction de calcul
fr

##
evaluate_expr

### Contenu du fichier

    #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];
        }
      }
    }