Mathematical expression
Keywords: main

Subsections

- Library
- Description
- Dialog Box
- Default properties
- Interfacing function
- Computational function (type 4)

##
Mathematical expression

### Library

Others

### Description

The Expression block allows the definition of a formula in terms of u1,u2,u3... The u's can be scalar inputs of the block or scalar components of the unique input vector. The formula must be defined in Scilab syntax using elementary operators and the following functions: sin, cos, tan, exp, log, sinh, cosh, tanh, int, round, ceil, floor, sign, abs, max, min, asin, acos, atan, asinh, acosh, atanh, atan2, log10.

### Dialog Box

Give a scalar scilab expression using inputs u1, u2,... |
ex: (dd*u1+sin(u2)0)*u3 |
Note that here dd must be defined in context |
number of inputs | 2
scilab expression | (u10)*sin(u2)2
use zero-crossing (0: no, 1 yes) | 1

- number of inputs: Block input can be a scalar or vector.
- scilab expression: The Scilab expression applied to the input.
- use zero-crossing :Select to enable zero crossing detection.

### Default properties

- always active: no
- direct-feedthrough: yes
- zero-crossing: yes
- mode: yes
- number/sizes of inputs: 2 / 1 1
- number/sizes of outputs: 1 / 1
- number/sizes of activation inputs: 0 /
- number/sizes of activation outputs: 0 /
- continuous-time state: no
- discrete-time state: no
- name of computational function: evaluate_expr

### Interfacing function

`scilab/macros/scicos_blocks/misc/EXPRESSION.sci`

### Computational function (type 4)

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

    /* atanh(x)
     *      For x>=0.5
     *                  1              2x                          x
     *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
     *                  2             1 - x                      1 - x
     *
     * 	For x<0.5
     *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
     *
     */

    double atanh(double x)
    {
    	if (x >=0.5)
    	{
    		return 0.5*log((1+x)/(1-x));
    	}
    	else
    	{
    		return 0.5*log((2*x)+(2*x)*x/(1-x));
    	}

    }
    #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 (flag==9) {
    	    block->g[nzcr]=stack[bottom];
    	    if(phase==1) {
    	      block->mode[nzcr]=(0.0==stack[bottom]);
    	    }
    	  }
    	  if(block->ng>0) nzcr=nzcr+1;
    	  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=floor(stack[bottom]);
    	    }else{
    	      i=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=floor(stack[bottom]+.5);
    	    }else{
    	      i=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=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=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];
        }
      }
    }