3 * Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * See the file ./license.txt
21 /*--------------------------------------------------------------------------*/
32 #include "core_math.h"
33 #include "scicos_block.h"
34 #include "machine.h" /* isinf */
35 #include "dynlib_scicos_blocks.h"
36 /*--------------------------------------------------------------------------*/
39 arcsinh z = log (z+sqrt(1+z2))
41 double asinh(double x)
43 return log(x + sqrt(x * x + 1));
45 /*--------------------------------------------------------------------------*/
46 double acosh(double x)
48 return log(x + sqrt(x * x - 1));
50 /*--------------------------------------------------------------------------*/
52 Inverse hyperbolic tangent (Atanh(x)) Log((1 + x) / (1 x)) / 2
54 double atanh(double x)
56 return (double)(log ((1. + x) / (1. - x)) / 2);
59 /*--------------------------------------------------------------------------*/
60 SCICOS_BLOCKS_IMPEXP void evaluate_expr(scicos_block *block, int flag)
62 static double stack [1000];
63 static int count = 0, bottom = 0, nzcr = 0, i = 0, phase = 0;
65 if (flag == 1 || flag == 6 || flag == 9)
67 phase = get_phase_simulation();
71 while (count < block->nipar - 1)
74 switch (block->ipar[count])
86 stack[bottom] = block->inptr[block->ipar[count] - 1][0];
90 j = block->ipar[count] - 1;
91 if (j < block->insz[0])
93 stack[bottom] = block->inptr[0][block->ipar[count] - 1];
106 set_block_error(-16);
109 stack[bottom] = block->rpar[block->ipar[count] - 1];
113 /* invalid script : call a function without lhs */
120 switch (block->ipar[count])
123 stack[bottom - 1] = stack[bottom - 1] + stack[bottom];
127 stack[bottom - 1] = stack[bottom - 1] - stack[bottom];
131 stack[bottom - 1] = stack[bottom - 1] * stack[bottom];
135 stack[bottom - 1] = stack[bottom - 1] / stack[bottom];
139 stack[bottom - 1] = pow(stack[bottom - 1], stack[bottom]);
142 case 16: /* case == */
149 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
152 block->mode[nzcr] = (stack[bottom - 1] == stack[bottom]);
155 if (phase == 1 || block->ng == 0)
157 i = (stack[bottom - 1] == stack[bottom]);
161 i = block->mode[nzcr];
163 stack[bottom - 1] = (double)i;
174 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
177 block->mode[nzcr] = (stack[bottom - 1] < stack[bottom]);
180 if (phase == 1 || block->ng == 0)
182 i = (stack[bottom - 1] < stack[bottom]);
186 i = block->mode[nzcr];
188 stack[bottom - 1] = (double)i;
198 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
201 block->mode[nzcr] = (stack[bottom - 1] > stack[bottom]);
204 if (phase == 1 || block->ng == 0)
206 i = (stack[bottom - 1] > stack[bottom]);
210 i = block->mode[nzcr];
212 stack[bottom - 1] = (double)i;
222 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
225 block->mode[nzcr] = (stack[bottom - 1] <= stack[bottom]);
228 if (phase == 1 || block->ng == 0)
230 i = (stack[bottom - 1] <= stack[bottom]);
234 i = block->mode[nzcr];
236 stack[bottom - 1] = (double)i;
246 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
249 block->mode[nzcr] = (stack[bottom - 1] >= stack[bottom]);
252 if (phase == 1 || block->ng == 0)
254 i = (stack[bottom - 1] >= stack[bottom]);
258 i = block->mode[nzcr];
260 stack[bottom - 1] = (double)i;
270 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
273 block->mode[nzcr] = (stack[bottom - 1] != stack[bottom]);
276 if (phase == 1 || block->ng == 0)
278 i = (stack[bottom - 1] != stack[bottom]);
282 i = block->mode[nzcr];
284 stack[bottom - 1] = (double)i;
294 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
297 block->mode[nzcr] = ((int)stack[bottom - 1] || (int)stack[bottom]);
300 if (phase == 1 || block->ng == 0)
302 i = ((int)stack[bottom - 1] || (int)stack[bottom]);
306 i = block->mode[nzcr];
308 stack[bottom - 1] = (double)i;
318 block->g[nzcr] = stack[bottom - 1] - stack[bottom];
321 block->mode[nzcr] = ((int)stack[bottom - 1] && (int)stack[bottom]);
324 if (phase == 1 || block->ng == 0)
326 i = ((int)stack[bottom - 1] && (int)stack[bottom]);
330 i = block->mode[nzcr];
332 stack[bottom - 1] = (double)i;
343 block->g[nzcr] = stack[bottom];
346 block->mode[nzcr] = (0.0 == stack[bottom]);
349 if (phase == 1 || block->ng == 0)
351 i = (stack[bottom] == 0.0);
355 i = block->mode[nzcr];
367 stack[bottom] = -stack[bottom];
370 stack[bottom] = sin(stack[bottom]);
373 stack[bottom] = cos(stack[bottom]);
376 stack[bottom] = tan(stack[bottom]);
379 stack[bottom] = exp(stack[bottom]);
382 stack[bottom] = log(stack[bottom]);
385 stack[bottom] = sinh(stack[bottom]);
388 stack[bottom] = cosh(stack[bottom]);
391 stack[bottom] = tanh(stack[bottom]);
401 if (stack[bottom] > 0)
403 i = (int)floor(stack[bottom]);
407 i = (int)ceil(stack[bottom]);
411 block->g[nzcr] = (stack[bottom] - 1) * (stack[bottom] + 1);
415 block->g[nzcr] = (stack[bottom] - i - 1.) * (stack[bottom] - i);
419 block->g[nzcr] = (stack[bottom] - i) * (stack[bottom] - i + 1);
423 block->g[nzcr] = -block->g[nzcr];
427 block->mode[nzcr] = i;
430 if (phase == 1 || block->ng == 0)
432 if (stack[bottom] > 0)
434 stack[bottom] = floor(stack[bottom]);
438 stack[bottom] = ceil(stack[bottom]);
443 stack[bottom] = (double) block->mode[nzcr];
447 if (stack[bottom]>0) {
448 stack[bottom]=floor(stack[bottom]);
450 stack[bottom]=ceil(stack[bottom]);
460 if (stack[bottom] > 0)
462 i = (int)floor(stack[bottom] + .5);
466 i = (int)ceil(stack[bottom] - .5);
468 block->g[nzcr] = (stack[bottom] - i - .5) * (stack[bottom] - i + .5);
471 block->g[nzcr] = -block->g[nzcr];
475 block->mode[nzcr] = i;
478 if (phase == 1 || block->ng == 0)
480 if (stack[bottom] > 0)
482 stack[bottom] = floor(stack[bottom] + .5);
486 stack[bottom] = ceil(stack[bottom] - .5);
491 stack[bottom] = (double) block->mode[nzcr];
494 /* if (stack[bottom]>0) {
495 stack[bottom]=floor(stack[bottom]+.5);
497 stack[bottom]=ceil(stack[bottom]-.5);
506 i = (int)ceil(stack[bottom]);
507 block->g[nzcr] = (stack[bottom] - i) * (stack[bottom] - i + 1);
510 block->g[nzcr] = -block->g[nzcr];
514 block->mode[nzcr] = i;
517 if (phase == 1 || block->ng == 0)
519 stack[bottom] = ceil(stack[bottom]);
523 stack[bottom] = (double) block->mode[nzcr];
533 i = (int)floor(stack[bottom]);
534 block->g[nzcr] = (stack[bottom] - i - 1) * (stack[bottom] - i);
537 block->g[nzcr] = -block->g[nzcr];
541 block->mode[nzcr] = i;
544 if (phase == 1 || block->ng == 0)
546 stack[bottom] = floor(stack[bottom]);
550 stack[bottom] = (double) block->mode[nzcr];
560 if (stack[bottom] > 0)
564 else if (stack[bottom] < 0)
572 block->g[nzcr] = stack[bottom];
575 block->mode[nzcr] = i;
578 if (phase == 1 || block->ng == 0)
580 if (stack[bottom] > 0)
584 else if (stack[bottom] < 0)
586 stack[bottom] = -1.0;
595 stack[bottom] = (double) block->mode[nzcr];
598 /* if (stack[bottom]>0) {
600 }else if(stack[bottom]<0){
612 if (stack[bottom] > 0)
616 else if (stack[bottom] < 0)
624 block->g[nzcr] = stack[bottom];
627 block->mode[nzcr] = i;
630 if (phase == 1 || block->ng == 0)
632 if (stack[bottom] > 0)
634 /* stack[bottom] = stack[bottom]; */
638 stack[bottom] = -stack[bottom];
643 stack[bottom] = stack[bottom] * (block->mode[nzcr]);
646 /* if (stack[bottom]>0) {
647 stack[bottom]=stack[bottom];
649 stack[bottom]=-stack[bottom];
658 if (stack[bottom] > stack[bottom - 1])
666 block->g[nzcr] = stack[bottom] - stack[bottom - 1];
669 block->mode[nzcr] = i;
672 if (phase == 1 || block->ng == 0)
674 stack[bottom - 1] = Max(stack[bottom - 1], stack[bottom]);
678 stack[bottom - 1] = stack[bottom - block->mode[nzcr]];
689 if (stack[bottom] < stack[bottom - 1])
697 block->g[nzcr] = stack[bottom] - stack[bottom - 1];
700 block->mode[nzcr] = i;
703 if (phase == 1 || block->ng == 0)
705 stack[bottom - 1] = Min(stack[bottom - 1], stack[bottom]);
709 stack[bottom - 1] = stack[bottom - block->mode[nzcr]];
714 stack[bottom] = asin(stack[bottom]);
717 stack[bottom] = acos(stack[bottom]);
720 stack[bottom] = atan(stack[bottom]);
723 stack[bottom] = asinh(stack[bottom]);
726 stack[bottom] = acosh(stack[bottom]);
729 stack[bottom] = atanh(stack[bottom]);
732 stack[bottom - 1] = atan2(stack[bottom - 1], stack[bottom]);
737 stack[bottom] = log10(stack[bottom]);
748 if (!_finite(stack[bottom]) || _isnan(stack[bottom]))
751 if (isinf(stack[bottom]) || isnan(stack[bottom]))
763 block->outptr[0][0] = stack[bottom];
767 /*--------------------------------------------------------------------------*/