/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void satur(scicos_block *block,int flag) { /* rpar[0]:upper limit, rpar[1]:lower limit */ if (flag==1) { if (get_phase_simulation()==1||block->ng==0) { if (*block->inptr[0]>=block->rpar[0]) { block->outptr[0][0]=block->rpar[0]; } else if (*block->inptr[0]<=block->rpar[1]) { block->outptr[0][0]=block->rpar[1]; } else { block->outptr[0][0]=block->inptr[0][0]; } } else { if (block->mode[0]==1) { block->outptr[0][0]=block->rpar[0]; } else if(block->mode[0]==2) { block->outptr[0][0]=block->rpar[1] ; } else { block->outptr[0][0]=block->inptr[0][0]; } } } else if (flag==9) { block->g[0]=*block->inptr[0]-(block->rpar[0]); block->g[1]=*block->inptr[0]-(block->rpar[1]); if (get_phase_simulation()==1) { if (block->g[0]>=0) { block->mode[0]=1; } else if (block->g[1]<=0) { block->mode[0]=2; } else { block->mode[0]=3; } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void hystheresis(scicos_block *block,int flag) { if (flag==1){ if (get_phase_simulation()==1||block->ng==0) { if (*block->inptr[0]>=block->rpar[0]){ block->outptr[0][0]=block->rpar[2]; }else if (*block->inptr[0]<=block->rpar[1]){ block->outptr[0][0]=block->rpar[3]; }else if ((block->outptr[0][0]!=block->rpar[3])&&(block->outptr[0][0]!=block->rpar[2])){ block->outptr[0][0]=block->rpar[3]; /* Handling sitauations where all zero-crossings are suppressed in discrete models. In this case, initial state is initialised to OFF*/ } }else{ /* compatibility with simulink: when input value is located between two margines the OFF state is selected. Initial Mode is OFF (mode==0)*/ if (block->mode[0]==2){ block->outptr[0][0]=block->rpar[2]; }else{ block->outptr[0][0]=block->rpar[3]; } } } else if (flag==9){ block->g[0]=*block->inptr[0]-(block->rpar[0]); block->g[1]=*block->inptr[0]-(block->rpar[1]); if (get_phase_simulation()==1) { if (block->g[0]>=0){ block->mode[0]=2; }else if (block->g[1]<=0){ block->mode[0]=1; } } } }
/*--------------------------------------------------------------------------*/ int sci_phase_simulation(char *fname,unsigned long fname_len) { int isrun = C2F(cosim).isrun; if (!isrun) { Scierror(999, _("%s: scicosim is not running.\n"),fname); } else { int one = 1, l1 = 0; CheckRhs(-1,0); CheckLhs(1,1); CreateVar(1, MATRIX_OF_INTEGER_DATATYPE,(one=1,&one),(one=1,&one),&l1); *istk(l1) = get_phase_simulation(); LhsVar(1) = 1; PutLhsVar(); } return 0; }
/*--------------------------------------------------------------------------*/ void sciblk4(scicos_block *Blocks, int flag) { /*counter and address variable declaration*/ int i = 0, j = 0, k = 0, topsave = 0; int ierr = 0; int kfun = 0; int *header = NULL, ne1 = 0; double *le111 = NULL; int *il_xd = NULL, *il_res = NULL, *il_out = NULL, *il_outptr = NULL; int *il_xprop = NULL; int *il_z = NULL, *il_oz = NULL, *il_ozptr = NULL, *il_x = NULL; int *il_mode = NULL, *il_evout = NULL, *il_g = NULL; double *l_mode = NULL; double *l_xprop = NULL; /* variable for output typed port */ int nout = 0; int nv = 0, mv = 0; int *ptr = NULL, *funtyp = NULL; /* set number of left and right hand side parameters */ int mlhs = 1, mrhs = 2; /* Save Top counter */ topsave = Top; /* Retrieve block number */ kfun = get_block_number(); /* Retrieve funtyp by import structure */ strcpy(C2F(cha1).buf, "funtyp"); ierr = getscicosvarsfromimport(C2F(cha1).buf, (void**)&ptr, &nv, &mv); if (ierr == 0) { goto err; } funtyp = (int *) ptr; /**************************** * create scilab tlist Blocks ****************************/ if ((createblklist(&Blocks[0], &ierr, (i = -1), funtyp[kfun - 1])) == 0) { goto err; } /* * flag * */ C2F(itosci)(&flag, (i = 1, &i), (j = 1, &j)); if (C2F(scierr)() != 0) { goto err; } /********************** * Call scilab function **********************/ C2F(scifunc)(&mlhs, &mrhs); if (C2F(scierr)() != 0) { goto err; } /*************************** * Update C block structure **************************/ /* get header of output variable Blocks of sciblk4 */ header = (int *) stk(*Lstk(Top)); /* switch to appropriate flag */ switch (flag) { /************************** * update continuous state **************************/ case 0 : { if (Blocks[0].nx != 0) { /* 14 - xd */ il_xd = (int *) listentry(header, 14); ierr = sci2var(il_xd, Blocks[0].xd, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } if ((funtyp[kfun - 1] == 10004) || (funtyp[kfun - 1] == 10005)) { /* 15 - res */ il_res = (int *) listentry(header, 15); ierr = sci2var(il_res, Blocks[0].res, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } } break; /********************** * update output state **********************/ case 1 : { /* 21 - outptr */ if (Blocks[0].nout != 0) { il_out = (int*) listentry(header, 21); nout = il_out[1]; for (j = 0; j < nout; j++) { il_outptr = (int *) listentry(il_out, j + 1); ierr = sci2var(il_outptr, Blocks[0].outptr[j], Blocks[0].outsz[2 * nout + j]); if (ierr != 0) { goto err; } } } } break; /*********************** * update discrete state ***********************/ case 2 : { /* 7 - z */ if (Blocks[0].nz != 0) { il_z = (int *) listentry(header, 7); if (Blocks[0].scsptr > 0) { le111 = (double *) listentry(header, 7); ne1 = header[7 + 2] - header[7 + 1]; C2F(unsfdcopy)(&ne1, le111, (i = -1, &i), Blocks[0].z, (j = -1, &j)); } else { ierr = sci2var(il_z, Blocks[0].z, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } /* 11 - oz */ if (Blocks[0].noz != 0) { il_oz = (int *) listentry(header, 11); /* C blocks : extract */ if ((funtyp[kfun - 1] == 4) || (funtyp[kfun - 1] == 10004)) { for (j = 0; j < Blocks[0].noz; j++) { il_ozptr = (int *) listentry(il_oz, j + 1); if (Blocks[0].oztyp[j] == SCSUNKNOW_N) { ne1 = Blocks[0].ozsz[j]; C2F(unsfdcopy)(&ne1, (double *)il_ozptr, \ (i = 1, &i), (double *)Blocks[0].ozptr[j], (k = 1, &k)); } else { ierr = sci2var(il_ozptr, Blocks[0].ozptr[j], Blocks[0].oztyp[j]); if (ierr != 0) { goto err; } } } } /* sci blocks : don't extract */ else if ((funtyp[kfun - 1] == 5) || (funtyp[kfun - 1] == 10005)) { ne1 = Blocks[0].ozsz[0]; C2F(unsfdcopy)(&ne1, (double *)il_oz, \ (i = 1, &i), (double *)Blocks[0].ozptr[0], (j = 1, &j)); } } if (Blocks[0].nx != 0) { /* 13 - x */ il_x = (int *) listentry(header, 13); ierr = sci2var(il_x, Blocks[0].x, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } /* 14 - xd */ il_xd = (int *) listentry(header, 14); ierr = sci2var(il_xd, Blocks[0].xd, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } break; /*************************** * update event output state ***************************/ case 3 : { /* 23 - evout */ il_evout = (int *) listentry(header, 23); ierr = sci2var(il_evout, Blocks[0].evout, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } break; /********************** * state initialisation **********************/ case 4 : { /* 7 - z */ if (Blocks[0].nz != 0) { il_z = (int *) listentry(header, 7); if (Blocks[0].scsptr > 0) { le111 = (double *) listentry(header, 7); ne1 = header[7 + 2] - header[7 + 1]; C2F(unsfdcopy)(&ne1, le111, (i = -1, &i), Blocks[0].z, (j = -1, &j)); } else { ierr = sci2var(il_z, Blocks[0].z, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } /* 11 - oz */ if (Blocks[0].noz != 0) { il_oz = (int *) listentry(header, 11); /* C blocks : extract */ if ((funtyp[kfun - 1] == 4) || (funtyp[kfun - 1] == 10004)) { for (j = 0; j < Blocks[0].noz; j++) { il_ozptr = (int *) listentry(il_oz, j + 1); if (Blocks[0].oztyp[j] == SCSUNKNOW_N) { ne1 = Blocks[0].ozsz[j]; C2F(unsfdcopy)(&ne1, (double *)il_ozptr, \ (i = 1, &i), (double *)Blocks[0].ozptr[j], (k = 1, &k)); } else { ierr = sci2var(il_ozptr, Blocks[0].ozptr[j], Blocks[0].oztyp[j]); if (ierr != 0) { goto err; } } } } /* sci blocks : don't extract */ else if ((funtyp[kfun - 1] == 5) || (funtyp[kfun - 1] == 10005)) { ne1 = Blocks[0].ozsz[0]; C2F(unsfdcopy)(&ne1, (double *)il_oz, \ (i = 1, &i), (double *)Blocks[0].ozptr[0], (j = 1, &j)); } } if (Blocks[0].nx != 0) { /* 13 - x */ il_x = (int *) listentry(header, 13); ierr = sci2var(il_x, Blocks[0].x, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } /* 14 - xd */ il_xd = (int *) listentry(header, 14); ierr = sci2var(il_xd, Blocks[0].xd, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } break; /********* * finish *********/ case 5 : { /* 7 - z */ if (Blocks[0].nz != 0) { il_z = (int *) listentry(header, 7); if (Blocks[0].scsptr > 0) { le111 = (double *) listentry(header, 7); ne1 = header[7 + 2] - header[7 + 1]; C2F(unsfdcopy)(&ne1, le111, (i = -1, &i), Blocks[0].z, (j = -1, &j)); } else { ierr = sci2var(il_z, Blocks[0].z, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } /* 11 - oz */ if (Blocks[0].noz != 0) { il_oz = (int *) listentry(header, 11); /* C blocks : extract */ if ((funtyp[kfun - 1] == 4) || (funtyp[kfun - 1] == 10004)) { for (j = 0; j < Blocks[0].noz; j++) { il_ozptr = (int *) listentry(il_oz, j + 1); if (Blocks[0].oztyp[j] == SCSUNKNOW_N) { ne1 = Blocks[0].ozsz[j]; C2F(unsfdcopy)(&ne1, (double *)il_ozptr, \ (i = 1, &i), (double *)Blocks[0].ozptr[j], (k = 1, &k)); } else { ierr = sci2var(il_ozptr, Blocks[0].ozptr[j], Blocks[0].oztyp[j]); if (ierr != 0) { goto err; } } } } /* sci blocks : don't extract */ else if ((funtyp[kfun - 1] == 5) || (funtyp[kfun - 1] == 10005)) { ne1 = Blocks[0].ozsz[0]; C2F(unsfdcopy)(&ne1, (double *)il_oz, \ (i = 1, &i), (double *)Blocks[0].ozptr[0], (j = 1, &j)); } } } break; /***************************** * output state initialisation *****************************/ case 6 : { /* 7 - z */ if (Blocks[0].nz != 0) { il_z = (int *) listentry(header, 7); if (Blocks[0].scsptr > 0) { le111 = (double *) listentry(header, 7); ne1 = header[7 + 2] - header[7 + 1]; C2F(unsfdcopy)(&ne1, le111, (i = -1, &i), Blocks[0].z, (j = -1, &j)); } else { ierr = sci2var(il_z, Blocks[0].z, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } /* 11 - oz */ if (Blocks[0].noz != 0) { il_oz = (int *) listentry(header, 11); /* C blocks : extract */ if ((funtyp[kfun - 1] == 4) || (funtyp[kfun - 1] == 10004)) { for (j = 0; j < Blocks[0].noz; j++) { il_ozptr = (int *) listentry(il_oz, j + 1); if (Blocks[0].oztyp[j] == SCSUNKNOW_N) { ne1 = Blocks[0].ozsz[j]; C2F(unsfdcopy)(&ne1, (double *)il_ozptr, \ (i = 1, &i), (double *)Blocks[0].ozptr[j], (k = 1, &k)); } else { ierr = sci2var(il_ozptr, Blocks[0].ozptr[j], Blocks[0].oztyp[j]); if (ierr != 0) { goto err; } } } } /* sci blocks : don't extract */ else if ((funtyp[kfun - 1] == 5) || (funtyp[kfun - 1] == 10005)) { ne1 = Blocks[0].ozsz[0]; C2F(unsfdcopy)(&ne1, (double *)il_oz, \ (i = 1, &i), (double *)Blocks[0].ozptr[0], (j = 1, &j)); } } if (Blocks[0].nx != 0) { /* 13 - x */ il_x = (int *) listentry(header, 13); ierr = sci2var(il_x, Blocks[0].x, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } /* 14 - xd */ il_xd = (int *) listentry(header, 14); ierr = sci2var(il_xd, Blocks[0].xd, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } /* 21 - outptr */ if (Blocks[0].nout != 0) { il_out = (int *) listentry(header, 21); nout = il_out[1]; for (j = 0; j < nout; j++) { il_outptr = (int *) listentry(il_out, j + 1); ierr = sci2var(il_outptr, Blocks[0].outptr[j], Blocks[0].outsz[2 * nout + j]); if (ierr != 0) { goto err; } } } } break; /******************************************* * define property of continuous time states * (algebraic or differential states) *******************************************/ case 7 : { if (Blocks[0].nx != 0) { /* 40 - x */ il_xprop = (int *) listentry(header, 40); l_xprop = (double *)(il_xprop + 4); for (nv = 0; nv < Blocks[0].nx; nv++) { Blocks[0].xprop[nv] = (int) l_xprop[nv]; } } } break; /**************************** * zero crossing computation ****************************/ case 9 : { /* 33 - g */ il_g = (int *) listentry(header, 33); ierr = sci2var(il_g, Blocks[0].g, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } if (get_phase_simulation() == 1) { /* 39 - mode */ il_mode = (int *) listentry(header, 39); // Alan, 16/10/07 : fix : mode is an int array l_mode = (double *)(il_mode + 4); for (nv = 0; nv < (il_mode[1]*il_mode[2]); nv++) { Blocks[0].mode[nv] = (int) l_mode[nv]; } //ierr=sci2var(il_mode,Blocks[0].mode,SCSINT_N); /* int */ //if (ierr!=0) goto err; } } break; /********************** * Jacobian computation **********************/ case 10 : { if ((funtyp[kfun - 1] == 10004) || (funtyp[kfun - 1] == 10005)) { /* 15 - res */ il_res = (int *) listentry(header, 15); ierr = sci2var(il_res, Blocks[0].res, SCSREAL_N); /* double */ if (ierr != 0) { goto err; } } } break; } /* Restore initial position Top */ Top = topsave; return; /* if error then restore initial position Top * and set_block_error with flag -1 */ err: Top = topsave; if (ierr != 0) /*var2sci or sci2var error*/ { /* Please update me !*/ if (ierr < 1000) /*var2sci error*/ { switch (ierr) { case 1 : Scierror(888, _("%s: error %d. Stack is full.\n"), "var2sci", ierr); break; case 2 : Scierror(888, _("%s: error %d. No more space on the stack for new data.\n"), "var2sci", ierr); break; default : Scierror(888, _("%s: error %d. Undefined error.\n"), "var2sci", ierr); break; } } else /*sci2var error*/ { switch (ierr) { case 1001 : Scierror(888, _("%s: error %d. Only int or double object are accepted.\n"), "sci2var", ierr); break; case 1002 : Scierror(888, _("%s: error %d. Bad double object sub_type.\n"), "sci2var", ierr); break; case 1003 : Scierror(888, _("%s: error %d. Bad int object sub_type.\n"), "sci2var", ierr); break; case 1004 : Scierror(888, _("%s: error %d. A type of a scilab object has changed.\n"), "sci2var", ierr); break; default : Scierror(888, _("%s: error %d. Undefined error.\n"), "sci2var", ierr); break; } } } set_block_error(-1); }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void relational_op_i32(scicos_block *block, int flag) { int k = 0, i = 0; int m = GetInPortRows(block, 1); int n = GetInPortCols(block, 1); long *u1 = Getint32InPortPtrs(block, 1); long *u2 = Getint32InPortPtrs(block, 2); long *y = Getint32OutPortPtrs(block, 1); int *ipar = GetIparPtrs(block); if (flag == 1) { if ((block->ng != 0) & (get_phase_simulation() == 2)) { for (i = 0; i < m * n; i++) { *(y + i) = block->mode[i] - 1; } } else { for (i = 0; i < m * n; i++) { y[i] = 0; } k = ipar[0]; switch (k) { case 0: for (i = 0; i < m * n; i++) { if (u1[i] == u2[i]) { y[i] = 1; } } break; case 1: for (i = 0; i < m * n; i++) { if (u1[i] != u2[i]) { y[i] = 1; } } break; case 2: for (i = 0; i < m * n; i++) { if (u1[i] < u2[i]) { y[i] = 1; } } break; case 3: for (i = 0; i < m * n; i++) { if (u1[i] <= u2[i]) { y[i] = 1; } } break; case 4: for (i = 0; i < m * n; i++) { if (u1[i] > u2[i]) { y[i] = 1; } } break; case 5: for (i = 0; i < m * n; i++) { if (u1[i] >= u2[i]) { y[i] = 1; } } break; } } } else if (flag == 9) { for (i = 0; i < (m * n); i++) { block->g[i] = (double)(*(u1 + i) - * (u2 + i)); } if (get_phase_simulation() == 1) { for (i = 0; i < m * n; i++) { block->mode[i] = (int)1; } k = ipar[0]; switch (k) { case 0: for (i = 0; i < m * n; i++) { if (u1[i] == u2[i]) { block->mode[i] = (int)2; } } break; case 1: for (i = 0; i < m * n; i++) { if (u1[i] != u2[i]) { block->mode[i] = (int)2; } } break; case 2: for (i = 0; i < m * n; i++) { if (u1[i] < u2[i]) { block->mode[i] = (int)2; } } break; case 3: for (i = 0; i < m * n; i++) { if (u1[i] <= u2[i]) { block->mode[i] = (int)2; } } break; case 4: for (i = 0; i < m * n; i++) { if (u1[i] > u2[i]) { block->mode[i] = (int)2; } } break; case 5: for (i = 0; i < m * n; i++) { if (u1[i] >= u2[i]) { block->mode[i] = (int)2; } } break; } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void integralz_func(scicos_block *block, int flag) { int i = 0; double *ur = NULL, *ui = NULL; double *yr = NULL, *yi = NULL; ur = GetRealInPortPtrs(block, 1); ui = GetImagInPortPtrs(block, 1); yr = GetRealOutPortPtrs(block, 1); yi = GetImagOutPortPtrs(block, 1); if (flag == 0) { if (block->ng > 0) { for (i = 0; i < (block->nx) / 2; ++i) { if (block->mode[i] == 3) { block->xd[i] = ur[i]; block->xd[i + (block->nx) / 2] = ui[i]; } else { block->xd[i] = 0.0; block->xd[i + (block->nx) / 2] = 0.0; } } } else { for (i = 0; i < (block->nx) / 2; ++i) { block->xd[i] = ur[i]; block->xd[i + (block->nx) / 2] = ui[i]; } } } else if (flag == 1 || flag == 6) { for (i = 0; i < (block->nx) / 2; ++i) { yr[i] = block->x[i]; yi[i] = block->x[i + (block->nx) / 2]; } } else if (flag == 2 && block->nevprt == 1) { for (i = 0; i < (block->nx) / 2; ++i) { block->x[i] = ur[i]; block->x[i + (block->nx) / 2] = ui[i]; } } else if (flag == 9) { for (i = 0; i < (block->nx) / 2; ++i) { if (block->mode[i] == 3) { block->g[i] = (block->x[i] - (block->rpar[i])) * (block->x[i] - (block->rpar[(block->nx) / 2 + i])); block->g[i + (block->nx) / 2] = (block->x[i + (block->nx) / 2] - (block->rpar[i + (block->nx)])) * (block->x[i + (block->nx) / 2] - (block->rpar[3 * (block->nx) / 2 + i])); } else { block->g[i] = ur[i]; block->g[i + (block->nx) / 2] = ui[i]; } if (get_phase_simulation() == 1) { if ((ur[i] >= 0) && (block->x[i] >= block->rpar[i]) && (fpclassify(ui[i >= 0]) != FP_ZERO) && (block->x[i + (block->nx) / 2] >= block->rpar[i + (block->nx)])) { block->mode[i] = 1; } else if (ur[i] <= 0 && block->x[i] <= block->rpar[(block->nx) / 2 + i] && ui[i] <= 0 && block->x[i + (block->nx) / 2] <= block->rpar[3 * (block->nx) / 2 + i]) { block->mode[i] = 2; } else { block->mode[i] = 3; } } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void relational_op_i8(scicos_block *block,int flag) { int k = 0,i = 0; int m = GetInPortRows(block,1); int n = GetInPortCols(block,1); char *u1 = Getint8InPortPtrs(block,1); char *u2 = Getint8InPortPtrs(block,2); char *y = Getint8OutPortPtrs(block,1); int *ipar = GetIparPtrs(block); if (flag==1) { if ((block->ng!=0)&(get_phase_simulation()==2)) { for(i=0;i<m*n;i++) *(y+i)=(char)block->mode[i]-1; } else { for(i=0;i<m*n;i++) y[i]=0; k=ipar[0]; switch(k) { case 0: for(i=0;i<m*n;i++) { if (u1[i]==u2[i]) y[i]=1; } break; case 1: for(i=0;i<m*n;i++) { if (u1[i]!=u2[i]) y[i]=1; } break; case 2: for(i=0;i<m*n;i++) { if (u1[i]<u2[i]) y[i]=1; } break; case 3: for(i=0;i<m*n;i++) { if (u1[i]<=u2[i]) y[i]=1; } break; case 4: for(i=0;i<m*n;i++) { if (u1[i]>u2[i]) y[i]=1; } break; case 5: for(i=0;i<m*n;i++) { if (u1[i]>=u2[i]) y[i]=1; } break; } } } else if (flag==9) { for(i=0;i<m*n;i++) block->g[i]=*(u1+i)-*(u2+i); if (get_phase_simulation()==1) { for(i=0;i<m*n;i++) block->mode[i]=(int)1; k=ipar[0]; switch(k) { case 0: for(i=0;i<m*n;i++) { if (u1[i]==u2[i]) block->mode[i]=(int)2; } break; case 1: for(i=0;i<m*n;i++) { if (u1[i]!=u2[i]) block->mode[i]=(int)2; } break; case 2: for(i=0;i<m*n;i++) { if (u1[i]<u2[i]) block->mode[i]=(int)2; } break; case 3: for(i=0;i<m*n;i++) { if (u1[i]<=u2[i]) block->mode[i]=(int)2; } break; case 4: for(i=0;i<m*n;i++) { if (u1[i]>u2[i]) block->mode[i]=(int)2; } break; case 5: for(i=0;i<m*n;i++) { if (u1[i]>=u2[i]) block->mode[i]=(int)2; } break; } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void evaluate_expr(scicos_block *block, int flag) { static double stack [1000]; static int count = 0, bottom = 0, nzcr = 0, i = 0, phase = 0; int j = 0; if (flag == 1 || flag == 6 || 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 _MSC_VER if (!_finite(stack[bottom]) || _isnan(stack[bottom])) { #else if (isinf(stack[bottom]) || isnan(stack[bottom])) { #endif if (flag == 6) { return; } set_block_error(-2); return; } else { block->outptr[0][0] = stack[bottom]; } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void minmax(scicos_block *block, int flag) { /*ipar[0]=1 -> min, ipar[0]=2 -> max */ int i = 0; double maxmin = 0.; int phase = get_phase_simulation(); if (flag == 1) { if (block->nin == 1) { if ((block->ng == 0) || (phase == 1)) { maxmin = block->inptr[0][0]; for (i = 1; i < block->insz[0]; ++i) { if (block->ipar[0] == 1) { if (block->inptr[0][i] < maxmin) { maxmin = block->inptr[0][i]; } } else { if (block->inptr[0][i] > maxmin) { maxmin = block->inptr[0][i]; } } } } else { maxmin = block->inptr[0][block->mode[0] - 1]; } block->outptr[0][0] = maxmin; } else if (block->nin == 2) { for (i = 0; i < block->insz[0]; ++i) { if ((block->ng == 0) || (phase == 1)) { if (block->ipar[0] == 1) { block->outptr[0][i] = Min(block->inptr[0][i], block->inptr[1][i]); } else { block->outptr[0][i] = Max(block->inptr[0][i], block->inptr[1][i]); } } else { block->outptr[0][i] = block->inptr[block->mode[0] - 1][i]; } } } } else if (flag == 9) { if (block->nin == 1) { if (phase == 2) { for (i = 0; i < block->insz[0]; ++i) { if (i != block->mode[0] - 1) { block->g[i] = block->inptr[0][i] - block->inptr[0][block->mode[0] - 1]; } else { block->g[i] = 1.0; } } } else if (phase == 1) { maxmin = block->inptr[0][0]; block->mode[0] = 1; for (i = 1; i < block->insz[0]; ++i) { if (block->ipar[0] == 1) { if (block->inptr[0][i] < maxmin) { maxmin = block->inptr[0][i]; block->mode[0] = i + 1; } } else { if (block->inptr[0][i] > maxmin) { maxmin = block->inptr[0][i]; block->mode[0] = i + 1; } } } } } else if (block->nin == 2) { for (i = 0; i < block->insz[0]; ++i) { block->g[i] = block->inptr[0][i] - block->inptr[1][i]; if (phase == 1) { if (block->ipar[0] == 1) { if (block->g[i] > 0) { block->mode[i] = 2; } else { block->mode[i] = 1; } } else { if (block->g[i] < 0) { block->mode[i] = 2; } else { block->mode[i] = 1; } } } } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void variable_delay(scicos_block *block, int flag) { /* rpar[0]=max delay, rpar[1]=init value, ipar[0]=buffer length */ double** work = (double**) block->work; double* pw = NULL, del = 0., t = 0., td = 0.; int* iw = NULL; int i = 0, j = 0, k = 0; if (flag == 4) /* the workspace is used to store previous values */ { if ((*work = (double*) scicos_malloc(sizeof(int) + sizeof(double) * block->ipar[0] * (1 + block->insz[0]))) == NULL ) { set_block_error(-16); return; } pw = *work; pw[0] = -block->rpar[0] * block->ipar[0]; for (i = 1; i < block->ipar[0]; i++) { pw[i] = pw[i - 1] + block->rpar[0]; for (j = 1; j < block->insz[0] + 1; j++) { pw[i + block->ipar[0]*j] = block->rpar[1]; } } iw = (int *) (pw + block->ipar[0] * (1 + block->insz[0])); *iw = 0; } else if (flag == 5) { scicos_free(*work); } else if (flag == 1) { if (get_phase_simulation() == 1) { do_cold_restart(); } pw = *work; iw = (int *) (pw + block->ipar[0] * (1 + block->insz[0])); t = get_scicos_time(); del = Min(Max(0, block->inptr[1][0]), block->rpar[0]); td = t - del; if (td < pw[*iw]) { scicos_print(_("delayed time=%f but last stored time=%f\n"), td, pw[*iw]); scicos_print(_("Consider increasing the length of buffer in variable delay block\n")); } if (t > pw[(block->ipar[0] + *iw - 1) % block->ipar[0]]) { for (j = 1; j < block->insz[0] + 1; j++) { pw[*iw + block->ipar[0]*j] = block->inptr[0][j - 1]; } pw[*iw] = t; *iw = (*iw + 1) % block->ipar[0]; } else { for (j = 1; j < block->insz[0] + 1; j++) { pw[(block->ipar[0] + *iw - 1) % block->ipar[0] + block->ipar[0]*j] = block->inptr[0][j - 1]; } pw[(block->ipar[0] + *iw - 1) % block->ipar[0]] = t; } i = 0; j = block->ipar[0] - 1; while (j - i > 1) { k = (i + j) / 2; if (td < pw[(k + *iw) % block->ipar[0]]) { j = k; } else if (td > pw[(k + *iw) % block->ipar[0]]) { i = k; } else { i = k; j = k; break; } } i = (i + *iw) % block->ipar[0]; j = (j + *iw) % block->ipar[0]; del = pw[j] - pw[i]; if (del != 0.0) { for (k = 1; k < block->insz[0] + 1; k++) { block->outptr[0][k - 1] = ((pw[j] - td) * pw[i + block->ipar[0] * k] + (td - pw[i]) * pw[j + block->ipar[0] * k]) / del; } } else { for (k = 1; k < block->insz[0] + 1; k++) { block->outptr[0][k - 1] = pw[i + block->ipar[0] * k]; } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void switch2(scicos_block *block, int flag) { int i = 0, j = 0, phase = 0; if (flag == 1) { phase = get_phase_simulation(); if (phase == 1 || block->ng == 0) { i = 2; if (*block->ipar == 0) { if (*block->inptr[1] >= *block->rpar) { i = 0; } } else if (*block->ipar == 1) { if (*block->inptr[1] > *block->rpar) { i = 0; } } else { if (*block->inptr[1] != *block->rpar) { i = 0; } } } else { if (block->mode[0] == 1) { i = 0; } else if (block->mode[0] == 2) { i = 2; } } for (j = 0; j < block->insz[0]; j++) { block->outptr[0][j] = block->inptr[i][j]; } } else if (flag == 9) { phase = get_phase_simulation(); block->g[0] = *block->inptr[1] - (*block->rpar); if (phase == 1) { i = 2; if (*block->ipar == 0) { if (block->g[0] >= 0.0) { i = 0; } } else if (*block->ipar == 1) { if (block->g[0] > 0.0) { i = 0; } } else { if (block->g[0] != 0.0) { i = 0; } } if (i == 0) { block->mode[0] = 1; } else { block->mode[0] = 2; } } } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void ratelimiter(scicos_block *block,int flag) { /* rpar[0]=rising rate limit, rpar[1]=falling rate limit */ double* pw = NULL; double rate = 0. , t = 0.; if (flag == 4) { /* the workspace is used to store previous values */ if ((*block->work = scicos_malloc(sizeof(double)*4))== NULL ) { set_block_error(-16); return; } pw=*block->work; pw[0]=0.0; pw[1]=0.0; pw[2]=0.0; pw[3]=0.0; } else if (flag == 5) { scicos_free(*block->work); } else if (flag==1) { if (get_phase_simulation()==1) do_cold_restart(); pw=*block->work; t=get_scicos_time(); if(t>pw[2]) { pw[0]=pw[2]; pw[1]=pw[3]; rate=(block->inptr[0][0]-pw[1])/(t-pw[0]); } else if(t<=pw[2]) { if(t>pw[0]) { rate=(block->inptr[0][0]-pw[1])/(t-pw[0]); } else { rate=0.0; } } if(rate>block->rpar[0]) { block->outptr[0][0]=(t-pw[0])*block->rpar[0]+pw[1]; } else if(rate<block->rpar[1]) { block->outptr[0][0]=(t-pw[0])*block->rpar[1]+pw[1]; } else { block->outptr[0][0]=block->inptr[0][0]; } pw[2]=t; pw[3]=block->outptr[0][0]; } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void relationalop(scicos_block *block, int flag) { int i = block->ipar[0]; if (flag == 1) { if ((block->ng != 0) & (get_phase_simulation() == 2)) { block->outptr[0][0] = block->mode[0] - 1.0; } else { switch (i) { case 0: if (block->inptr[0][0] == block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; case 1: if (block->inptr[0][0] != block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; case 2: if (block->inptr[0][0] < block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; case 3: if (block->inptr[0][0] <= block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; case 4: if (block->inptr[0][0] >= block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; case 5: if (block->inptr[0][0] > block->inptr[1][0]) { block->outptr[0][0] = 1.0; } else { block->outptr[0][0] = 0.0; } break; } } } else if (flag == 9) { block->g[0] = block->inptr[0][0] - block->inptr[1][0]; if (get_phase_simulation() == 1) { switch (i) { case 0: if (block->inptr[0][0] == block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; case 1: if (block->inptr[0][0] != block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; case 2: if (block->inptr[0][0] < block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; case 3: if (block->inptr[0][0] <= block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; case 4: if (block->inptr[0][0] >= block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; case 5: if (block->inptr[0][0] > block->inptr[1][0]) { block->mode[0] = (int)2.0; } else { block->mode[0] = (int)1.0; } break; } } } }