Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / eqt / eqt_util.c
1 /**************************/
2 /* eqt_util.c */
3 /**************************/
4 /****************************************************************************/
5 /* includes */
6 /****************************************************************************/
7
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <ctype.h>
11 #include <math.h>
12 #include <time.h>
13 #include AVT_H
14 #include EQT_H
15 #include MUT_H
16
17 /****************************************************************************/
18 /* defines */
19 /****************************************************************************/
20
21 #ifndef __func__
22 #define __func__ "eqt_util"
23 #endif
24
25 /****************************************************************************/
26 /* globals */
27 /****************************************************************************/
28 struct
29 {
30 char *prefix;
31 double value;
32 char size;
33 } basic_units[]=
34 {
35 {"meg", 1e+6, 3},
36 {"mil", 25.4e-6, 3},
37 {"mi", 25.4e+6, 2},
38 {"u", 1e-6, 1},
39 {"n", 1e-9, 1},
40 {"p", 1e-12, 1},
41 {"m", 1e-3, 1},
42 {"f", 1e-15, 1},
43 {"v", 1, 1},
44 {"s", 1, 1},
45 {"k", 1e+3, 1},
46 {"a", 1e-18, 1},
47 {"g", 1e+9, 1},
48 {"t", 1e+12, 1}
49 };
50
51 eqt_ctx *EQT_CONTEXT_HIERARCHY[5]={NULL, NULL, NULL, NULL, NULL};
52 ht *eqt_ExprToNode=NULL;
53
54
55 extern int eqtparse();
56 //extern int eqtdebug;
57 eqt_ctx *EQT_CTX = NULL;
58
59 extern eqt_node *eqt_NegNode (eqt_node *node);
60 extern eqt_node *eqt_InvNode (eqt_node *node);
61 extern eqt_node *eqt_DelMinDiv (eqt_node *node);
62 extern eqt_node *eqt_DelNeutral (eqt_node *node);
63 extern char *eqt_ToStr (eqt_node *node);
64 extern void eqt_drive (eqt_node *node);
65 extern char *eqt_operToStr (long operator);
66
67 double eqt_get_neutral (long operator);
68 void eqt_delnode (eqt_node *node);
69 eqt_node *eqt_insertOperation (eqt_node *node, eqt_node *operation);
70 int eqt_findSimpleAssoc (eqt_node *node, char* var, double nb);
71 eqt_node *eqt_associate (eqt_node *node);
72 int eqt_isLeaf (eqt_node *node);
73 int eqt_isOperand2 (eqt_node *node);
74 int eqt_isRealLeaf (eqt_node *node);
75 void eqt_invertChild (eqt_node *node);
76 eqt_node **eqt_sortDoTable (eqt_node *node,int cpt,int *nb);
77 int eqt_sortCompareNode (const void *node1, const void *node2);
78 void eqt_sortGetSortedNode (eqt_node *node, eqt_node **table);
79 void eqt_sortBranch (eqt_node *node);
80 void eqt_printTree (eqt_node *node,int deep);
81 int eqt_linearise (eqt_node *node);
82 int eqt_isZero (eqt_node *node);
83 int eqt_isOne (eqt_node *node);
84 int eqt_needParenthesis (eqt_node *node);
85 int eqt_findAssoc (eqt_node *node, char* var);
86 void eqt_assocVar (eqt_node *node);
87 int eqt_addNeutral (eqt_node *node);
88 void eqt_error (char *text, ...);
89 void eqt_warning (char *text, ...);
90
91
92 static eqt_node *Oper1 (eqt_node *node);
93 static eqt_node *Oper2 (eqt_node *node);
94 static eqt_node *Oper3 (eqt_node *node);
95 static eqt_node *Oper (eqt_node *node);
96 static void NewOper1 (eqt_node *node,eqt_node *n1);
97 static void NewOper2 (eqt_node *node,eqt_node *n2);
98 static void NewOper3 (eqt_node *node,eqt_node *n3);
99 static void NewOper (eqt_node *node,eqt_node *n);
100 static void NewOperator (eqt_node *node, long operator);
101 static char *Varname (eqt_node *node);
102 static double Value (eqt_node *node);
103 static void NewValue (eqt_node *node, double value);
104 static long Operator (eqt_node *node);
105 static int IsVarname (eqt_node *node);
106 static int IsValue (eqt_node *node);
107 static int IsNeg (eqt_node *node);
108 static eqt_node *eqt_getNeutralNode (int operator);
109 static chain_list *eqt_assocGetVar (eqt_node *node);
110 static void eqt_assocPutVarTop (eqt_node *node,char *var);
111 static void eqt_assocFather (eqt_node *node, char *var);
112 static void NewValue (eqt_node *node, double value);
113 static void NewVarname (eqt_node *node, char *varname);
114 static void SubstN1ByN2 (eqt_node *n1,eqt_node *n2, char mode);
115 static void EvalVarname (eqt_ctx *ctx, eqt_node *node);
116 static void eqt_addimportedvar (eqt_ctx *ctx, char *var_name, double value);
117 inline double __eqt_getvar (eqt_ctx *ctx, char *var_name, int usenamealloc, int ctxonly);
118
119 /****************************************************************************/
120 /* functions for fast allocation */
121 /****************************************************************************/
122
123 static int EQT_GOT_RANDOM=0;
124 static HeapAlloc *eqt_heap[7]={NULL, NULL, NULL, NULL, NULL, NULL, NULL};
125
126 /*char *eqt_lookup_expr(char *expr)
127 {
128 long l;
129 char *sn;
130 if (eqt_ExprToNode==NULL)
131 eqt_ExprToNode=addht(3000);
132 sn=sensitive_namealloc(expr);
133 return sn;
134 }*/
135
136 static eqt_node *eqt_loopup_node(eqt_ctx *ctx, char *expr)
137 {
138 long l;
139 eqt_node *node;
140 if (eqt_ExprToNode==NULL) eqt_ExprToNode=addht(3000);
141 if ((l=gethtitem(eqt_ExprToNode, expr))!=EMPTYHT)
142 return (eqt_node *)l;
143 node = eqt_create(ctx, expr);
144 addhtitem(eqt_ExprToNode, expr, (long)node);
145 return node;
146 }
147
148 static int eqt_getheap_num(char what)
149 {
150 int num;
151 if (eqt_heap[0]==NULL)
152 {
153 for (num=0; num<7; num++)
154 eqt_heap[num]=(HeapAlloc *)mbkalloc(sizeof(HeapAlloc));
155 CreateHeap(sizeof(double), 1024, eqt_heap[0]);
156 CreateHeap(sizeof(struct eqt_ctx), 128, eqt_heap[1]);
157 CreateHeap(sizeof(struct eqt_node), 1024, eqt_heap[2]);
158 CreateHeap(sizeof(struct eqt_unary), 1024, eqt_heap[3]);
159 CreateHeap(sizeof(struct eqt_binary), 1024, eqt_heap[4]);
160 CreateHeap(sizeof(struct eqt_ternary), 1024, eqt_heap[5]);
161 CreateHeap(sizeof(eqt_func_entry), 256, eqt_heap[6]);
162 }
163 switch(what)
164 {
165 case 'd' : num=0; break;
166 case 'c' : num=1; break;
167 case 'n' : num=2; break;
168 case 'u' : num=3; break;
169 case 'b' : num=4; break;
170 case 't' : num=5; break;
171 case 'f' : num=6; break;
172 default:
173 exit(1);
174 }
175 return num;
176 }
177 void *eqt_alloc(char what)
178 {
179 int num;
180 num=eqt_getheap_num(what);
181 return AddHeapItem(eqt_heap[num]);
182 }
183
184 void eqt_free(char what, void *d)
185 {
186 int num;
187 num=eqt_getheap_num(what);
188 DelHeapItem(eqt_heap[num], d);
189 }
190
191 static long eqt_my_update(int nouveau, long old_value, void *my_data)
192 {
193 double *var_tmp;
194 if (nouveau==0)
195 {
196 *(double *)old_value=*(double *)my_data;
197 return old_value;
198 }
199 var_tmp = eqt_alloc('d');
200 *var_tmp =*(double *)my_data;
201 return (long)var_tmp;
202 }
203
204 /****************************************************************************/
205 /* functions */
206 /****************************************************************************/
207
208 /****************************************************************************/
209 /*{{{ eqt_error() */
210 /* */
211 /* */
212 /****************************************************************************/
213 void eqt_error(char *text, ...)
214 {
215 va_list arg;
216
217 va_start(arg,text);
218 fprintf(stderr,"[EQT_ERR]");
219 if (text)
220 {
221 fprintf(stderr," ");
222 vfprintf(stderr,text,arg);
223 }
224 fprintf(stderr,"\n");
225 va_end(arg);
226
227 }
228
229 /*}}}************************************************************************/
230 /*{{{ eqt_warning() */
231 /* */
232 /* */
233 /****************************************************************************/
234 void eqt_warning(char *text, ...)
235 {
236 va_list arg;
237
238 va_start(arg,text);
239 fprintf(stderr,"[EQT_WAR]");
240 if (text)
241 {
242 fprintf(stderr," ");
243 vfprintf(stderr,text,arg);
244 }
245 fprintf(stderr,"\n");
246 va_end(arg);
247 }
248
249 /*}}}************************************************************************/
250 /*{{{ eqt_set_father() */
251 /* */
252 /* */
253 /****************************************************************************/
254 void eqt_set_father(eqt_node *child, eqt_node* father)
255 {
256 if (child)
257 child->FATHER = father;
258 }
259
260 /*}}}************************************************************************/
261 /*{{{ Value() */
262 /* */
263 /* */
264 /****************************************************************************/
265 static double Value(eqt_node *node)
266 {
267 return node->UNODE.VALUE;
268 }
269
270 /*}}}************************************************************************/
271 /*{{{ IsValue() */
272 /* */
273 /* */
274 /****************************************************************************/
275 static int IsValue(eqt_node *node)
276 {
277 return (node->TYPE == EQTVALUE_T);
278 }
279
280 /*}}}************************************************************************/
281 /*{{{ IsVarname() */
282 /* */
283 /* */
284 /****************************************************************************/
285 static int IsVarname(eqt_node *node)
286 {
287 return (node->TYPE == EQTVARNAME_T);
288 }
289
290 /*}}}************************************************************************/
291 /*{{{ Varname() */
292 /* */
293 /* */
294 /****************************************************************************/
295 static char *Varname(eqt_node *node)
296 {
297 if (node->TYPE == EQTVARNAME_T)
298 return node->UNODE.VARNAME;
299 else
300 return NULL;
301 }
302
303 /*}}}************************************************************************/
304 /*{{{ Oper1() */
305 /* */
306 /* */
307 /****************************************************************************/
308 static eqt_node *Oper1(eqt_node *node)
309 {
310 switch (node->TYPE)
311 {
312 case EQTUNOP_T :
313 return node->UNODE.UNOP->OPERAND;
314 case EQTBINOP_T :
315 return node->UNODE.BINOP->OPERAND1;
316 case EQTTERNOP_T :
317 return node->UNODE.TERNOP->OPERAND1;
318 default :
319 return NULL;
320 }
321 }
322
323 /*}}}************************************************************************/
324 /*{{{ Oper2() */
325 /* */
326 /* */
327 /****************************************************************************/
328 static eqt_node *Oper2(eqt_node *node)
329 {
330 switch (node->TYPE)
331 {
332 case EQTUNOP_T :
333 return node->UNODE.UNOP->OPERAND;
334 case EQTBINOP_T :
335 return node->UNODE.BINOP->OPERAND2;
336 case EQTTERNOP_T :
337 return node->UNODE.TERNOP->OPERAND2;
338 default :
339 return NULL;
340 }
341 }
342
343 /*}}}************************************************************************/
344 /*{{{ Oper3() */
345 /* */
346 /* */
347 /****************************************************************************/
348 static eqt_node *Oper3(eqt_node *node)
349 {
350 switch (node->TYPE)
351 {
352 case EQTUNOP_T :
353 return node->UNODE.UNOP->OPERAND;
354 case EQTTERNOP_T :
355 return node->UNODE.TERNOP->OPERAND3;
356 default :
357 return NULL;
358 }
359 }
360
361 /*}}}************************************************************************/
362 /*{{{ Oper() */
363 /* */
364 /* */
365 /****************************************************************************/
366 static eqt_node *Oper(eqt_node *node)
367 {
368 switch (node->TYPE)
369 {
370 case EQTUNOP_T :
371 return node->UNODE.UNOP->OPERAND;
372 default :
373 return NULL;
374 }
375 }
376
377 /*}}}************************************************************************/
378 /*{{{ Operator() */
379 /* */
380 /* */
381 /****************************************************************************/
382 static long Operator(eqt_node *node)
383 {
384 if (node)
385 switch (node->TYPE)
386 {
387 case EQTUNOP_T :
388 return node->UNODE.UNOP->OPERATOR;
389 case EQTBINOP_T :
390 return node->UNODE.BINOP->OPERATOR;
391 case EQTTERNOP_T :
392 return node->UNODE.TERNOP->OPERATOR;
393 default :
394 return 0;
395 }
396 else
397 return 0;
398 }
399
400 /*}}}************************************************************************/
401 /*{{{ NewVarname() */
402 /* */
403 /* */
404 /****************************************************************************/
405 static void NewVarname(eqt_node *node, char *varname)
406 {
407 if (node)
408 switch (node->TYPE)
409 case EQTVARNAME_T :
410 node->UNODE.VARNAME = varname;
411 return;
412 }
413
414 /*}}}************************************************************************/
415 /*{{{ NewValue() */
416 /* */
417 /* */
418 /****************************************************************************/
419 static void NewValue(eqt_node *node, double value)
420 {
421 if (node)
422 switch (node->TYPE)
423 case EQTVALUE_T :
424 node->UNODE.VALUE = value;
425 return;
426 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
427 // eqt_error(__func__);
428 }
429
430 /*}}}************************************************************************/
431 /*{{{ NewOperator() */
432 /* */
433 /* */
434 /****************************************************************************/
435 static void NewOperator(eqt_node *node, long operator)
436 {
437 if (node)
438 switch (node->TYPE)
439 {
440 case EQTUNOP_T :
441 node->UNODE.UNOP->OPERATOR = operator;
442 case EQTBINOP_T :
443 node->UNODE.BINOP->OPERATOR = operator;
444 case EQTTERNOP_T :
445 node->UNODE.TERNOP->OPERATOR = operator;
446 default :
447 ;
448 }
449 }
450
451 /*}}}************************************************************************/
452 /*{{{ NewOper1() */
453 /* */
454 /* */
455 /****************************************************************************/
456 static void NewOper1(eqt_node *node,eqt_node *n1)
457 {
458 switch (node->TYPE)
459 {
460 case EQTTERNOP_T :
461 node->UNODE.TERNOP->OPERAND1 = n1;
462 eqt_set_father(n1,node);
463 break;
464 case EQTBINOP_T :
465 node->UNODE.BINOP->OPERAND1 = n1;
466 eqt_set_father(n1,node);
467 break;
468 case EQTUNOP_T :
469 NewOper(node,n1);
470 break;
471 default : ;
472 }
473 }
474
475 /*}}}************************************************************************/
476 /*{{{ NewOper2() */
477 /* */
478 /* */
479 /****************************************************************************/
480 static void NewOper2(eqt_node *node,eqt_node *n2)
481 {
482 switch (node->TYPE)
483 {
484 case EQTTERNOP_T :
485 node->UNODE.TERNOP->OPERAND2 = n2;
486 eqt_set_father(n2,node);
487 break;
488 case EQTBINOP_T :
489 node->UNODE.BINOP->OPERAND2 = n2;
490 eqt_set_father(n2,node);
491 break;
492 case EQTUNOP_T :
493 NewOper(node,n2);
494 break;
495 default : ;
496 }
497 }
498
499 /*}}}************************************************************************/
500 /*{{{ NewOper3() */
501 /* */
502 /* */
503 /****************************************************************************/
504 static void NewOper3(eqt_node *node,eqt_node *n3)
505 {
506 switch (node->TYPE)
507 {
508 case EQTTERNOP_T :
509 node->UNODE.TERNOP->OPERAND3 = n3;
510 eqt_set_father(n3,node);
511 break;
512 case EQTUNOP_T :
513 NewOper(node,n3);
514 break;
515 default : ;
516 }
517 }
518
519 /*}}}************************************************************************/
520 /*{{{ NewOper() */
521 /* */
522 /* */
523 /****************************************************************************/
524 static void NewOper(eqt_node *node,eqt_node *n)
525 {
526 switch (node->TYPE)
527 {
528 case EQTUNOP_T :
529 node->UNODE.UNOP->OPERAND = n;
530 eqt_set_father(n,node);
531 break;
532 default : ;
533 }
534 }
535
536 /*}}}************************************************************************/
537 /*{{{ eqt_freenode() */
538 /* */
539 /* */
540 /****************************************************************************/
541 void eqt_freenode(eqt_node *node)
542 {
543 if (node)
544 switch (node->TYPE)
545 {
546 case EQTVALUE_T :
547 eqt_delnode (node);
548 break;
549 case EQTVARNAME_T :
550 eqt_delnode (node);
551 break;
552 case EQTUNOP_T :
553 eqt_freenode(Oper(node));
554 eqt_delnode (node);
555 break;
556 case EQTBINOP_T :
557 eqt_freenode(Oper1(node));
558 eqt_freenode(Oper2(node));
559 eqt_delnode (node);
560 break;
561 case EQTTERNOP_T :
562 eqt_freenode(Oper1(node));
563 eqt_freenode(Oper2(node));
564 eqt_freenode(Oper3(node));
565 eqt_delnode (node);
566 break;
567 case EQTDOTFUNC_T :
568 {
569 chain_list *cl;
570 for (cl=node->UNODE.FUNCOP->ARGS; cl!=NULL; cl=cl->NEXT)
571 eqt_freenode((eqt_node *)cl->DATA);
572 eqt_delnode (node);
573 }
574 }
575 }
576
577 /*}}}************************************************************************/
578 /*{{{ eqt_delnode() */
579 /* */
580 /* */
581 /****************************************************************************/
582 void eqt_delnode(eqt_node *node)
583 {
584 if (node)
585 switch (node->TYPE)
586 {
587 case EQTVALUE_T :
588 eqt_free('n',node);
589 break;
590 case EQTVARNAME_T :
591 eqt_free('n',node);
592 break;
593 case EQTUNOP_T :
594 eqt_free('u',node->UNODE.UNOP);
595 eqt_free('n',node);
596 break;
597 case EQTBINOP_T :
598 eqt_free('b',node->UNODE.BINOP);
599 eqt_free('n',node);
600 break;
601 case EQTTERNOP_T :
602 eqt_free('t',node->UNODE.TERNOP);
603 eqt_free('n',node);
604 break;
605 case EQTDOTFUNC_T :
606 freechain(node->UNODE.FUNCOP->ARGS);
607 eqt_free('n',node);
608 break;
609 }
610 }
611
612 /*}}}************************************************************************/
613 /*{{{ SubstN1ByN2() */
614 /* */
615 /* */
616 /****************************************************************************/
617 static void SubstN1ByN2(eqt_node *n1,eqt_node *n2, char mode)
618 {
619 switch (n1->TYPE)
620 {
621 case EQTVALUE_T :
622 break;
623 case EQTVARNAME_T :
624 break;
625 case EQTUNOP_T :
626 if (Oper(n1) != n2 && mode == 'Y')
627 eqt_freenode(Oper(n1));
628 eqt_free('u', n1->UNODE.UNOP);
629 break;
630 case EQTBINOP_T :
631 if (Oper1(n1) != n2 && mode == 'Y')
632 eqt_freenode(Oper1(n1));
633 if (Oper2(n1) != n2 && mode == 'Y')
634 eqt_freenode(Oper2(n1));
635 eqt_free('b',n1->UNODE.BINOP);
636 break;
637 case EQTTERNOP_T :
638 if (Oper1(n1) != n2 && mode == 'Y')
639 eqt_freenode(Oper1(n1));
640 if (Oper2(n1) != n2 && mode == 'Y')
641 eqt_freenode(Oper2(n1));
642 if (Oper3(n1) != n2 && mode == 'Y')
643 eqt_freenode(Oper3(n1));
644 eqt_free('t',n1->UNODE.TERNOP);
645 break;
646 case EQTDOTFUNC_T :
647 default :
648 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
649 // eqt_error(__func__);
650 }
651 n1->TYPE = n2->TYPE;
652 switch (n2->TYPE)
653 {
654 case EQTVALUE_T :
655 NewValue(n1,Value(n2));
656 break;
657 case EQTVARNAME_T :
658 NewVarname(n1,Varname(n2));
659 break;
660 case EQTUNOP_T :
661 n1->UNODE.UNOP = eqt_alloc('u');
662 NewOper(n1,Oper(n2));
663 break;
664 case EQTBINOP_T :
665 n1->UNODE.UNOP = eqt_alloc('b');
666 NewOper1(n1,Oper1(n2));
667 NewOper2(n1,Oper2(n2));
668 break;
669 case EQTTERNOP_T :
670 n1->UNODE.UNOP = eqt_alloc('t');
671 NewOper1(n1,Oper1(n2));
672 NewOper2(n1,Oper2(n2));
673 NewOper3(n1,Oper3(n2));
674 break;
675 case EQTDOTFUNC_T :
676 default :
677 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
678 // eqt_error(__func__);
679 }
680 eqt_delnode(n2);
681 }
682
683 /*}}}************************************************************************/
684 /*{{{ Basics allocations */
685 /****************************************************************************/
686 /*{{{ eqt_addvarname() */
687 /* */
688 /* */
689 /****************************************************************************/
690 eqt_node *eqt_addvarname (char *name)
691 {
692 eqt_node *new_node;
693
694 new_node = (eqt_node*) eqt_alloc('n');
695
696 new_node->TYPE = EQTVARNAME_T;
697 new_node->UNODE.VARNAME = namealloc(name);
698 new_node->FATHER = NULL;
699
700 return new_node;
701 }
702
703 /*}}}************************************************************************/
704 /*{{{ eqt_addvalue() */
705 /* */
706 /* */
707 /****************************************************************************/
708 eqt_node *eqt_addvalue (double value)
709 {
710 eqt_node *new_node;
711
712 new_node = (eqt_node*) eqt_alloc('n');
713
714 new_node->TYPE = EQTVALUE_T;
715 new_node->UNODE.VALUE = value;
716 new_node->FATHER = NULL;
717
718 return new_node;
719 }
720
721 /*}}}************************************************************************/
722 /*{{{ eqt_addunarynode() */
723 /* */
724 /* */
725 /****************************************************************************/
726 eqt_node *eqt_addunarynode (long operator, eqt_node *operand)
727 {
728 eqt_unary *unary_node;
729 eqt_node *new_node;
730
731 unary_node = (eqt_unary*) eqt_alloc('u');
732 unary_node->OPERATOR = operator;
733 unary_node->OPERAND = operand;
734
735 new_node = (eqt_node*) eqt_alloc('n');
736 new_node->TYPE = EQTUNOP_T;
737 new_node->UNODE.UNOP = unary_node;
738
739 new_node->FATHER = NULL;
740 eqt_set_father (operand,new_node);
741 return new_node;
742 }
743
744 /*}}}************************************************************************/
745 /*{{{ eqt_addbinarynode() */
746 /* */
747 /* */
748 /****************************************************************************/
749 eqt_node *eqt_addbinarynode (long operator, eqt_node *operand1,
750 eqt_node *operand2)
751 {
752 eqt_binary *binary_node;
753 eqt_node *new_node;
754
755 binary_node = (eqt_binary*) eqt_alloc('b');
756 binary_node->OPERATOR = operator;
757 binary_node->OPERAND1 = operand1;
758 binary_node->OPERAND2 = operand2;
759
760 new_node = (eqt_node*) eqt_alloc('n');
761 new_node->TYPE = EQTBINOP_T;
762 new_node->UNODE.BINOP = binary_node;
763
764 eqt_set_father (operand1,new_node);
765 eqt_set_father (operand2,new_node);
766 new_node->FATHER = NULL;
767
768 return new_node;
769 }
770
771 /*}}}************************************************************************/
772 /*{{{ eqt_addternarynode() */
773 /* */
774 /* */
775 /****************************************************************************/
776 eqt_node *eqt_addternarynode (long operator, eqt_node *operand1,
777 eqt_node *operand2, eqt_node *operand3)
778 {
779 eqt_ternary *ternary_node;
780 eqt_node *new_node;
781
782 ternary_node = (eqt_ternary*) eqt_alloc('t');
783 ternary_node->OPERATOR = operator;
784 ternary_node->OPERAND1 = operand1;
785 ternary_node->OPERAND2 = operand2;
786 ternary_node->OPERAND3 = operand3;
787
788 new_node = (eqt_node*) eqt_alloc('n');
789 new_node->TYPE = EQTTERNOP_T;
790 new_node->UNODE.TERNOP = ternary_node;
791
792 eqt_set_father (operand1,new_node);
793 eqt_set_father (operand2,new_node);
794 eqt_set_father (operand3,new_node);
795 new_node->FATHER = NULL;
796
797 return new_node;
798 }
799
800 eqt_node *eqt_adddotfuncnode (char *name, chain_list *args)
801 {
802 eqt_func *ef;
803 eqt_node *new_node;
804 chain_list *cl;
805
806 ef = (eqt_func*) eqt_alloc('t');
807 ef->ARGS = dupchainlst(args);
808 ef->FUNCNAME = namealloc(name);
809
810 new_node = (eqt_node*) eqt_alloc('n');
811 new_node->TYPE = EQTDOTFUNC_T;
812 new_node->UNODE.FUNCOP = ef;
813
814 for (cl=ef->ARGS; cl!=NULL; cl=cl->NEXT)
815 eqt_set_father ((eqt_node *)cl->DATA,new_node);
816 new_node->FATHER = NULL;
817
818 return new_node;
819 }
820
821 /*}}}************************************************************************/
822 /*}}}************************************************************************/
823 /*{{{ eqt_dup() */
824 /* */
825 /* */
826 /****************************************************************************/
827 eqt_node *eqt_dup(eqt_node *n)
828 {
829 eqt_node *res;
830
831 res->TYPE = n->TYPE;
832 switch (n->TYPE)
833 {
834 case EQTVALUE_T :
835 res = eqt_addvalue(Value(n));
836 break;
837 case EQTVARNAME_T :
838 res = eqt_addvarname(Varname(n));
839 break;
840 case EQTUNOP_T :
841 res = eqt_addunarynode(Operator(n),
842 eqt_dup(Oper1(n)));
843 break;
844 case EQTBINOP_T :
845 res = eqt_addbinarynode(Operator(n),
846 eqt_dup(Oper1(n)),
847 eqt_dup(Oper2(n)));
848 break;
849 case EQTTERNOP_T :
850 res = eqt_addternarynode(Operator(n),
851 eqt_dup(Oper1(n)),
852 eqt_dup(Oper2(n)),
853 eqt_dup(Oper3(n)));
854 break;
855 case EQTDOTFUNC_T :
856 res = eqt_adddotfuncnode(n->UNODE.FUNCOP->FUNCNAME, n->UNODE.FUNCOP->ARGS);
857 break;
858 default :
859 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
860 // eqt_error(__func__);
861 }
862
863 return res;
864 }
865
866 /*}}}************************************************************************/
867
868 double eqt_calcval (eqt_ctx *ctx, eqt_node *node)
869 {
870 double val;
871 ctx->EQT_RES_CALC = EQT_COMPLETE;
872 ctx->EQT_VAR_INVOLVED = 0;
873 EQT_GOT_RANDOM=0;
874 val=eqt_calcval_rec (ctx, node);
875 ctx->EQT_GOT_RANDOM=EQT_GOT_RANDOM;
876 return val;
877 }
878
879 eqt_func_entry *eqt_getdotfunc (eqt_ctx *ctx, char *name)
880 {
881 chain_list *cl;
882 name=namealloc(name);
883 for (cl=ctx->FUNCTIONS; cl!=NULL && ((eqt_func_entry *)cl->DATA)->FUNCNAME!=name; cl=cl->NEXT) ;
884 if (cl==NULL) return NULL;
885 return (eqt_func_entry *)cl->DATA;
886 }
887
888 double eqt_execdotfunc(eqt_ctx *ctx, char *funcname, chain_list *args, int quick)
889 {
890 eqt_func_entry *efe;
891 struct
892 {
893 double oldval, newval;
894 int set;
895 } savevar[32];
896 int i;
897 chain_list *cl, *ch;
898 long l;
899 double value;
900
901 if ((efe=eqt_getdotfunc(ctx, funcname))!=NULL)
902 {
903 if (countchain(args)!=countchain(efe->ARGS))
904 {
905 avt_errmsg(EQT_ERRMSG, "009", AVT_ERROR, efe->FUNCNAME);
906 ctx->EQT_RES_CALC = EQT_INCOMPLETE;
907 ctx->FAULTY_VAR = funcname;
908 return 0;
909 }
910 for (cl=args, ch=efe->ARGS, i=0; cl!=NULL; cl=cl->NEXT, ch=ch->NEXT, i++)
911 {
912 if (!quick)
913 savevar[i].newval=eqt_calcval_rec(ctx, (eqt_node *)cl->DATA);
914 else
915 savevar[i].newval=*(double *)cl->DATA;
916
917 if ((l=gethtitem (ctx->VAR_HT, ch->DATA))!=EMPTYHT)
918 savevar[i].oldval=*(long *)l, savevar[i].set=1;
919 else
920 savevar[i].set=0;
921 }
922 for (ch=efe->ARGS, i=0; ch!=NULL; ch=ch->NEXT, i++)
923 {
924 eqt_addvar(ctx, (char *)ch->DATA, savevar[i].newval);
925 }
926
927 value=eqt_calcval_rec(ctx, efe->NODE_EXPR);
928
929 for (ch=efe->ARGS, i=0; ch!=NULL; ch=ch->NEXT, i++)
930 {
931 if (savevar[i].set)
932 eqt_addvar(ctx, (char *)ch->DATA, savevar[i].oldval);
933 else
934 delhtitem(ctx->VAR_HT, ch->DATA);
935 }
936
937 return value;
938 }
939
940 if (!quick) avt_errmsg(EQT_ERRMSG, "010", AVT_ERROR, funcname);
941 ctx->EQT_RES_CALC = EQT_INCOMPLETE;
942 ctx->FAULTY_VAR = funcname;
943 return 0;
944 }
945
946 double eqt_execfunc123(eqt_ctx *ctx, int index, void *arg1, void *arg2, void *arg3, int quick)
947 {
948 double res;
949 if ((eqt_getdotfunc(ctx, ctx->NAMETAB[index]))!=NULL)
950 {
951 chain_list *cl=NULL;
952 if (arg3!=NULL) cl=addchain(cl, arg3);
953 if (arg2!=NULL) cl=addchain(cl, arg2);
954 if (arg1!=NULL) cl=addchain(cl, arg1);
955 res=eqt_execdotfunc(ctx, ctx->NAMETAB[index], cl, quick);
956 freechain(cl);
957 }
958 else
959 {
960 if (arg3!=NULL)
961 res= ctx->FUNCTAB3[index](*(double *)arg1, *(double *)arg2, *(double *)arg3) ;
962 else if (arg2!=NULL)
963 res= ctx->FUNCTAB2[index](*(double *)arg1, *(double *)arg2) ;
964 else if (arg1!=NULL)
965 res= ctx->FUNCTAB[index](*(double *)arg1) ;
966 else
967 avt_errmsg(EQT_ERRMSG, "008", AVT_FATAL, __func__);
968 }
969 return res;
970 }
971 /****************************************************************************/
972 /*{{{ eqt_calcval_rec() */
973 /* */
974 /* */
975 /****************************************************************************/
976 double eqt_calcval_rec (eqt_ctx *ctx, eqt_node *node)
977 {
978 double arg1, arg2, arg3;
979 int op;
980 if (!node)
981 return 0.0;
982
983 if (IsValue(node))
984 return (Value(node));
985
986 if (node->TYPE == EQTVARNAME_T)
987 return (__eqt_getvar (ctx, node->UNODE.VARNAME, 0, 0));
988
989 if (node->TYPE == EQTUNOP_T)
990 switch (op=(Operator(node) & 0xff))
991 {
992 case EQTNOT :
993 return (double)(!(int)eqt_calcval_rec(ctx, Oper(node)) + 0.5);
994 case EQTMIN :
995 return -eqt_calcval_rec(ctx, Oper(node));
996 case EQTSQRT :
997 return sqrt (eqt_calcval_rec(ctx, Oper(node)));
998 case EQTEXP :
999 return exp (eqt_calcval_rec(ctx, Oper(node)));
1000 case EQTLOG :
1001 return log (eqt_calcval_rec(ctx, Oper(node)));
1002 case EQTUSER :
1003 arg1=eqt_calcval_rec(ctx, Oper(node));
1004 return eqt_execfunc123(ctx, Operator(node) >> 8, &arg1, NULL, NULL, 1);
1005 // return ctx->FUNCTAB[Operator(node) >> 8] (eqt_calcval_rec(ctx, Oper(node)));
1006 case EQTSIN :
1007 return sin (eqt_calcval_rec(ctx, Oper(node)));
1008 case EQTCOS :
1009 return cos (eqt_calcval_rec(ctx, Oper(node)));
1010 case EQTTAN :
1011 return tan (eqt_calcval_rec(ctx, Oper(node)));
1012 case EQTASIN :
1013 return asin (eqt_calcval_rec(ctx, Oper(node)));
1014 case EQTACOS :
1015 return acos (eqt_calcval_rec(ctx, Oper(node)));
1016 case EQTATAN :
1017 return atan (eqt_calcval_rec(ctx, Oper(node)));
1018 case EQTSINH :
1019 return sinh (eqt_calcval_rec(ctx, Oper(node)));
1020 case EQTCOSH :
1021 return cosh (eqt_calcval_rec(ctx, Oper(node)));
1022 case EQTTANH :
1023 return tanh (eqt_calcval_rec(ctx, Oper(node)));
1024 case EQTLOG10:
1025 return log10(eqt_calcval_rec(ctx, Oper(node)));
1026 case EQTCEIL :
1027 return ceil (eqt_calcval_rec(ctx, Oper(node)));
1028 case EQTFLOOR:
1029 return floor(eqt_calcval_rec(ctx, Oper(node)));
1030 case EQTFABS :
1031 return fabs (eqt_calcval_rec(ctx, Oper(node)));
1032 case EQTABS :
1033 return fabs (eqt_calcval_rec(ctx, Oper(node)));
1034 case EQTNOMDEV :
1035 case EQTNOMMOD :
1036 case EQTNOMSUB :
1037 if (ctx->SPECIAL_FUNC[(int)(op-EQTSPECFUNC_BASE)]!=NULL)
1038 return ctx->SPECIAL_FUNC[(int)(op-EQTSPECFUNC_BASE)](Varname(Oper(node)));
1039 avt_errmsg(EQT_ERRMSG, "010", AVT_FATAL, EQTSPECFUNC_NAME(op));
1040 case EQTINV :
1041 return 1.0 / (eqt_calcval_rec(ctx, Oper(node)));
1042 }
1043
1044 if (node->TYPE == EQTBINOP_T)
1045 switch (Operator(node) & 0xff)
1046 {
1047 case EQTXOR :
1048 return (double)((int)(eqt_calcval_rec(ctx, Oper1(node)) + 0.5)
1049 ^ (int)(eqt_calcval_rec(ctx, Oper2(node)) + 0.5));
1050 case EQTNOTEQ :
1051 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)!=0;
1052 // return eqt_calcval_rec(ctx, Oper1(node)) != eqt_calcval_rec(ctx, Oper2(node));
1053 case EQTEQ :
1054 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)==0;
1055 // return eqt_calcval_rec(ctx, Oper1(node)) == eqt_calcval_rec(ctx, Oper2(node));
1056 case EQTINFEQ :
1057 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)<=0;
1058 // return eqt_calcval_rec(ctx, Oper1(node)) <= eqt_calcval_rec(ctx, Oper2(node));
1059 case EQTSUPEQ :
1060 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)>=0;
1061 // return eqt_calcval_rec(ctx, Oper1(node)) >= eqt_calcval_rec(ctx, Oper2(node));
1062 case EQTINF :
1063 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)<0;
1064 // return eqt_calcval_rec(ctx, Oper1(node)) < eqt_calcval_rec(ctx, Oper2(node));
1065 case EQTSUP :
1066 return mbk_cmpdouble(eqt_calcval_rec(ctx, Oper1(node)), eqt_calcval_rec(ctx, Oper2(node)), EQT_PRECISION)>0;
1067 // return eqt_calcval_rec(ctx, Oper1(node)) > eqt_calcval_rec(ctx, Oper2(node));
1068 case EQTOR :
1069 return (double)((int)(eqt_calcval_rec(ctx, Oper1(node)) + 0.5)
1070 || (int)(eqt_calcval_rec(ctx, Oper2(node)) + 0.5));
1071 case EQTAND :
1072 return (double)((int)(eqt_calcval_rec(ctx, Oper1(node)) + 0.5)
1073 && (int)(eqt_calcval_rec(ctx, Oper2(node)) + 0.5));
1074 case EQTPLUS :
1075 return (eqt_calcval_rec(ctx, Oper1(node))
1076 + eqt_calcval_rec(ctx, Oper2(node)));
1077 case EQTMIN :
1078 return (eqt_calcval_rec(ctx, Oper1(node))
1079 - eqt_calcval_rec(ctx, Oper2(node)));
1080 case EQTMULT :
1081 return (eqt_calcval_rec(ctx, Oper1(node))
1082 * eqt_calcval_rec(ctx, Oper2(node)));
1083 case EQTDIV :
1084 return (eqt_calcval_rec(ctx, Oper1(node))
1085 / eqt_calcval_rec(ctx, Oper2(node)));
1086 case EQTPOW :
1087 return pow(eqt_calcval_rec(ctx, Oper1(node)),
1088 eqt_calcval_rec(ctx, Oper2(node)));
1089 case EQTUSER :
1090 arg1=eqt_calcval_rec(ctx, Oper1(node));
1091 arg2=eqt_calcval_rec(ctx, Oper2(node));
1092 return eqt_execfunc123(ctx, Operator(node) >> 8, &arg1, &arg2, NULL, 1);
1093 /* return ctx->FUNCTAB2[Operator(node) >> 8]
1094 (eqt_calcval_rec(ctx, Oper1(node)),
1095 eqt_calcval_rec(ctx, Oper2(node)));*/
1096 case EQTATAN2 :
1097 return atan2(eqt_calcval_rec(ctx, Oper1(node)),
1098 eqt_calcval_rec(ctx, Oper2(node)));
1099 }
1100
1101 if (node->TYPE == EQTTERNOP_T)
1102 switch (node->UNODE.TERNOP->OPERATOR & 0xff)
1103 {
1104 case EQTIF :
1105 if (mbk_long_round(eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND1))!=0)
1106 return eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND2);
1107 else
1108 return eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND3);
1109 case EQTUSER :
1110 arg1=eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND1);
1111 arg2=eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND2);
1112 arg3=eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND3);
1113 return eqt_execfunc123(ctx, Operator(node) >> 8, &arg1, &arg2, &arg3, 1);
1114 /* return ctx->FUNCTAB3[node->UNODE.TERNOP->OPERATOR >> 8]
1115 (eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND1),
1116 eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND2),
1117 eqt_calcval_rec(ctx, node->UNODE.TERNOP->OPERAND3));*/
1118 }
1119
1120 if (node->TYPE == EQTDOTFUNC_T)
1121 {
1122 return eqt_execdotfunc(ctx, node->UNODE.FUNCOP->FUNCNAME, node->UNODE.FUNCOP->ARGS, 0);
1123 }
1124 return 0.0;
1125 }
1126
1127 /*}}}************************************************************************/
1128 /*{{{ eqt_reduce() */
1129 /* */
1130 /* */
1131 /* Warning node destroyed after effect */
1132 /****************************************************************************/
1133 void eqt_reduce(eqt_ctx *ctx, eqt_node *node)
1134 {
1135 eqt_node *n, *n1, *n2;
1136 double res, arg1, arg2;
1137
1138 if (node)
1139 switch (node->TYPE)
1140 {
1141 case EQTVALUE_T :
1142 break;
1143 case EQTVARNAME_T :
1144 EvalVarname(ctx, node);
1145 break;
1146 case EQTUNOP_T :
1147 eqt_reduce (ctx, Oper(node));
1148
1149 if (IsValue(n = Oper(node)))
1150 {
1151 switch (Operator(node) & 0xff)
1152 {
1153 case EQTMIN : res = -Value(n) ;break;
1154 case EQTSQRT : res = sqrt(Value(n)) ;break;
1155 case EQTEXP : res = exp(Value(n)) ;break;
1156 case EQTLOG : res = log(Value(n)) ;break;
1157 case EQTUSER :
1158 arg1=Value(n);
1159 res=eqt_execfunc123(ctx, Operator(node) >> 8, &arg1, NULL, NULL, 1);
1160 break;
1161 // res = ctx->FUNCTAB[Operator(node) >> 8](Value(n));break;
1162 case EQTSIN : res = sin(Value(n)) ;break;
1163 case EQTCOS : res = cos(Value(n)) ;break;
1164 case EQTTAN : res = tan(Value(n)) ;break;
1165 case EQTASIN : res = asin(Value(n)) ;break;
1166 case EQTACOS : res = acos(Value(n)) ;break;
1167 case EQTATAN : res = atan(Value(n)) ;break;
1168 case EQTSINH : res = sinh(Value(n)) ;break;
1169 case EQTCOSH : res = cosh(Value(n)) ;break;
1170 case EQTTANH : res = tanh(Value(n)) ;break;
1171 case EQTLOG10: res = log10(Value(n)) ;break;
1172 case EQTCEIL : res = ceil(Value(n)) ;break;
1173 case EQTFLOOR: res = floor(Value(n)) ;break;
1174 case EQTFABS : res = fabs(Value(n)) ;break;
1175 case EQTABS : res = fabs(Value(n)) ;break;
1176 case EQTNOMDEV :
1177 case EQTNOMMOD :
1178 case EQTNOMSUB :
1179 avt_errmsg(EQT_ERRMSG, "008", AVT_FATAL, __func__);
1180 }
1181 NewValue(n,res);
1182 }
1183 break;
1184 case EQTBINOP_T :
1185 eqt_reduce (ctx, Oper1(node));
1186 eqt_reduce (ctx, Oper2(node));
1187 n1 = Oper1(node);
1188 n2 = Oper2(node);
1189
1190 if ((IsValue(n1)) && (IsValue(n2)))
1191 {
1192 switch (Operator(node) & 0xff)
1193 {
1194 case EQTPLUS : res = Value(n1)+Value(n2) ;break;
1195 case EQTMIN : res = Value(n1)-Value(n2) ;break;
1196 case EQTMULT : res = Value(n1)*Value(n2) ;break;
1197 case EQTDIV : res = Value(n1)/Value(n2) ;break;
1198 case EQTPOW : res = pow((Value(n1)),(Value(n2))) ;break;
1199 case EQTUSER :
1200 arg1=Value(n1);
1201 arg2=Value(n2);
1202 res=eqt_execfunc123(ctx, Operator(node) >> 8, &arg1, &arg2, NULL, 1);
1203 break;
1204 // res = ctx->FUNCTAB2[Operator(node) >> 8](Value(n1),Value(n2));break;
1205 case EQTATAN2: res = atan2((Value(n1)), (Value(n2)));break;
1206 }
1207 NewValue(n1,res);
1208 SubstN1ByN2(node,n1,'Y');
1209 }
1210 else
1211 switch (Operator(node))
1212 {
1213 case EQTMULT :
1214 if (eqt_isOne(n1))
1215 SubstN1ByN2(node,n2,'Y');
1216 else if (eqt_isOne(n2))
1217 SubstN1ByN2(node,n1,'Y');
1218 else if (eqt_isZero(n1) || eqt_isZero(n2))
1219 SubstN1ByN2(node,eqt_addvalue(0.0),'Y');
1220 break;
1221 case EQTDIV :
1222 if (eqt_isOne(n1))
1223 {
1224 n = eqt_addunarynode(EQTINV,n2);
1225 NewOper2(node,NULL);
1226 SubstN1ByN2(node,n,'Y');
1227 }
1228 else if (eqt_isOne(n2))
1229 SubstN1ByN2(node,n1,'Y');
1230 break;
1231 case EQTPLUS :
1232 if ( eqt_isRealLeaf(Oper1(node))
1233 && Operator(n = Oper2(node)) == EQTPLUS
1234 && eqt_isLeaf(Oper1(n))
1235 && Operator(n = Oper2(n)) == EQTMIN
1236 && IsVarname(Oper(n))
1237 && strcmp(Varname(Oper(n)),Varname(Oper1(node))))
1238 {
1239 n = Oper2(Oper2(node));
1240 NewOper2(Oper2(node),NULL);
1241 SubstN1ByN2(node,n2,'Y');
1242 }
1243 break;
1244 }
1245 break;
1246 case EQTTERNOP_T :
1247 case EQTDOTFUNC_T :
1248 avt_errmsg(EQT_ERRMSG, "004", AVT_ERROR, __func__);
1249 // eqt_error("%s : can't be done yet on ternary operators",__func__);
1250 }
1251 }
1252
1253 /*}}}************************************************************************/
1254 /*{{{ EvalVarname() */
1255 /* */
1256 /* */
1257 /****************************************************************************/
1258 static void EvalVarname(eqt_ctx *ctx, eqt_node *node)
1259 {
1260 long value;
1261
1262 if (node && IsVarname(node))
1263 {
1264 value = gethtitem(ctx->VAR_HT, /*namealloc (*/Varname(node)/*)*/);
1265 if ((value != EMPTYHT) && (value != DELETEHT))
1266 {
1267 node->TYPE = EQTVALUE_T;
1268 NewValue(node,*((double*)value));
1269 }
1270 }
1271 }
1272
1273 /*}}}************************************************************************/
1274 /*{{{ eqt_isZero() */
1275 /* */
1276 /* */
1277 /****************************************************************************/
1278 int eqt_isZero(eqt_node *node)
1279 {
1280 return (IsValue(node) && Value(node) == 0.0);
1281 }
1282
1283 /*}}}************************************************************************/
1284 /*{{{ eqt_isOne() */
1285 /* */
1286 /* */
1287 /****************************************************************************/
1288 int eqt_isOne(eqt_node *node)
1289 {
1290 return (IsValue(node) && Value(node) == 1.0);
1291 }
1292
1293 /*}}}************************************************************************/
1294 /*{{{ print_space() */
1295 /* */
1296 /* */
1297 /****************************************************************************/
1298 void print_space(int space)
1299 {
1300 int i;
1301
1302 for (i = 0; i < space; i++)
1303 fprintf(stdout,"¦ ");
1304 }
1305
1306 /*}}}************************************************************************/
1307 /*{{{ eqt_initSpaceII() */
1308 /* */
1309 /* */
1310 /****************************************************************************/
1311 void eqt_initSpaceII(char *EQT_PRINTYES)
1312 {
1313 int i;
1314
1315 for (i = 0; i < 256; i ++ )
1316 EQT_PRINTYES[i] = 0;
1317 }
1318
1319 /*}}}************************************************************************/
1320 /*{{{ print_spaceII() */
1321 /* */
1322 /* */
1323 /****************************************************************************/
1324 void print_spaceII(char *EQT_PRINTYES, int space)
1325 {
1326 int i;
1327
1328 for (i = 0; i < space; i++)
1329 fprintf(stdout,"%c ",EQT_PRINTYES[i] ? ' ' : '¦');
1330 }
1331
1332 /*}}}************************************************************************/
1333 /*{{{ eqt_print() */
1334 /* */
1335 /* */
1336 /****************************************************************************/
1337 void eqt_print(eqt_ctx *ctx, eqt_node *node)
1338 {
1339 int nb_space = 0, op;
1340
1341 if (!node)
1342 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
1343 // eqt_error("%s : Noeud vide",__func__);
1344 else
1345 switch (node->TYPE)
1346 {
1347 case EQTVALUE_T :
1348 print_space(nb_space);
1349 fprintf (stdout," %5g\n", (Value(node))); nb_space++;
1350 break;
1351 case EQTVARNAME_T :
1352 print_space(nb_space);
1353 fprintf (stdout," %5s\n", (node->UNODE.VARNAME));
1354 break;
1355 case EQTUNOP_T :
1356 switch (op=(Operator(node) & 0xff))
1357 {
1358 case EQTNOT :
1359 print_space(nb_space);
1360 fprintf(stdout, "! \n");
1361 nb_space++;
1362 eqt_print(ctx, Oper(node));
1363 break;
1364 case EQTMIN :
1365 print_space(nb_space);
1366 fprintf(stdout, "- \n");
1367 nb_space++;
1368 eqt_print(ctx, Oper(node));
1369 break;
1370 case EQTSQRT:
1371 print_space(nb_space);
1372 fprintf(stdout, "SQRT \n");
1373 nb_space++;
1374 eqt_print(ctx, Oper(node));
1375 break;
1376 case EQTEXP :
1377 print_space(nb_space);
1378 fprintf(stdout, "EXP \n");
1379 nb_space++;
1380 eqt_print(ctx, Oper(node));
1381 break;
1382 case EQTLOG :
1383 print_space(nb_space);
1384 fprintf(stdout, "LOG \n");
1385 nb_space++;
1386 eqt_print(ctx, Oper(node));
1387 break;
1388 case EQTUSER :
1389 print_space(nb_space);
1390 fprintf(stdout, "%5s \n", ctx->NAMETAB[Operator(node) >> 8]);
1391 nb_space++;
1392 eqt_print(ctx, Oper(node));
1393 break;
1394 case EQTSIN :
1395 print_space(nb_space);
1396 fprintf(stdout, "SIN \n");
1397 nb_space++;
1398 eqt_print(ctx, Oper(node));
1399 break;
1400 case EQTCOS :
1401 print_space(nb_space);
1402 fprintf(stdout, "COS \n");
1403 nb_space++;
1404 eqt_print(ctx, Oper(node));
1405 break;
1406 case EQTTAN :
1407 print_space(nb_space);
1408 fprintf(stdout, "TAN \n");
1409 nb_space++;
1410 eqt_print(ctx, Oper(node));
1411 break;
1412 case EQTASIN :
1413 print_space(nb_space);
1414 fprintf(stdout, "ASIN \n");
1415 nb_space++;
1416 eqt_print(ctx, Oper(node));
1417 break;
1418 case EQTACOS :
1419 print_space(nb_space);
1420 fprintf(stdout, "ACOS \n");
1421 nb_space++;
1422 eqt_print(ctx, Oper(node));
1423 break;
1424 case EQTATAN :
1425 print_space(nb_space);
1426 fprintf(stdout, "ATAN \n");
1427 nb_space++;
1428 eqt_print(ctx, Oper(node));
1429 break;
1430 case EQTSINH :
1431 print_space(nb_space);
1432 fprintf(stdout, "SINH \n");
1433 nb_space++;
1434 eqt_print(ctx, Oper(node));
1435 break;
1436 case EQTCOSH :
1437 print_space(nb_space);
1438 fprintf(stdout, "COSH \n");
1439 nb_space++;
1440 eqt_print(ctx, Oper(node));
1441 break;
1442 case EQTTANH :
1443 print_space(nb_space);
1444 fprintf(stdout, "TANH \n");
1445 nb_space++;
1446 eqt_print(ctx, Oper(node));
1447 break;
1448 case EQTLOG10 :
1449 print_space(nb_space);
1450 fprintf(stdout, "LOG10 \n");
1451 nb_space++;
1452 eqt_print(ctx, Oper(node));
1453 break;
1454 case EQTCEIL :
1455 print_space(nb_space);
1456 fprintf(stdout, "CEIL \n");
1457 nb_space++;
1458 eqt_print(ctx, Oper(node));
1459 break;
1460 case EQTFLOOR :
1461 print_space(nb_space);
1462 fprintf(stdout, "FLOOR \n");
1463 nb_space++;
1464 eqt_print(ctx, Oper(node));
1465 break;
1466 case EQTFABS :
1467 print_space(nb_space);
1468 fprintf(stdout, "FABS \n");
1469 nb_space++;
1470 eqt_print(ctx, Oper(node));
1471 break;
1472 case EQTABS :
1473 print_space(nb_space);
1474 fprintf(stdout, "ABS \n");
1475 nb_space++;
1476 eqt_print(ctx, Oper(node));
1477 break;
1478 case EQTNOMDEV :
1479 case EQTNOMMOD :
1480 case EQTNOMSUB :
1481 print_space(nb_space);
1482 fprintf(stdout, "%s(%s) \n", EQTSPECFUNC_NAME(op), Varname(Oper(node)));
1483
1484 }
1485 break;
1486 case EQTBINOP_T :
1487 switch (Operator(node) & 0xff)
1488 {
1489 case EQTPLUS:
1490 print_space(nb_space);
1491 fprintf(stdout, " + \n");
1492 eqt_print(ctx, Oper1(node));
1493 nb_space++;
1494 eqt_print(ctx, Oper2(node));
1495 break;
1496 case EQTMIN :
1497 print_space(nb_space);
1498 fprintf(stdout, " - \n");
1499 nb_space++;
1500 eqt_print(ctx, Oper1(node));
1501 eqt_print(ctx, Oper2(node));
1502 break;
1503 case EQTMULT:
1504 print_space(nb_space);
1505 fprintf(stdout, " * \n");
1506 nb_space++ ; eqt_print(ctx, Oper1(node));
1507 eqt_print(ctx, Oper2(node));
1508 break;
1509 case EQTDIV :
1510 print_space(nb_space);
1511 fprintf(stdout, " / \n");
1512 nb_space++;
1513 eqt_print(ctx, Oper1(node));
1514 eqt_print(ctx, Oper2(node));
1515 break;
1516 case EQTPOW :
1517 print_space(nb_space);
1518 fprintf(stdout, " ^ \n");
1519 nb_space++;
1520 eqt_print(ctx, Oper1(node)),
1521 eqt_print(ctx, Oper2(node));
1522 break;
1523 case EQTUSER :
1524 print_space(nb_space);
1525 fprintf(stdout, "%5s \n", ctx->NAMETAB[Operator(node) >> 8]);
1526 nb_space++;
1527 eqt_print(ctx, Oper1(node)) ,
1528 eqt_print(ctx, Oper2(node));
1529 break;
1530 case EQTATAN2 :
1531 print_space(nb_space);
1532 fprintf(stdout, " ATAN2 \n");
1533 nb_space++;
1534 eqt_print(ctx, Oper1(node));
1535 eqt_print(ctx, Oper2(node));
1536 break;
1537 }
1538 case EQTTERNOP_T :
1539 switch (node->UNODE.TERNOP->OPERATOR & 0xff)
1540 {
1541 case EQTUSER :
1542 print_space(nb_space);
1543 fprintf(stdout, "%5s \n", ctx->NAMETAB[node->UNODE.TERNOP->OPERATOR >> 8]);
1544 nb_space++;
1545 eqt_print(ctx, node->UNODE.TERNOP->OPERAND1) ,
1546 eqt_print(ctx, node->UNODE.TERNOP->OPERAND2) ,
1547 eqt_print(ctx, node->UNODE.TERNOP->OPERAND3);
1548 break;
1549 }
1550 break;
1551 case EQTDOTFUNC_T :
1552 {
1553 chain_list *cl;
1554 print_space(nb_space);
1555 fprintf(stdout, "%5s \n",node->UNODE.FUNCOP->FUNCNAME);
1556 nb_space++;
1557 for (cl=node->UNODE.FUNCOP->ARGS; cl!=NULL; cl=cl->NEXT)
1558 eqt_print(ctx, (eqt_node *)cl->DATA);
1559 break;
1560 }
1561
1562 }
1563 }
1564
1565 /*}}}************************************************************************/
1566 /****************************************************************************/
1567
1568 int eqt_parse (eqt_ctx *ctx)
1569 {
1570 int res;
1571
1572 EQT_CTX = ctx;
1573 // eqtrestart(NULL);
1574 // eqtdebug = 1;
1575 EQT_CTX->EQUA_NODE=NULL;
1576 res = eqtparse ();
1577 ctx = EQT_CTX;
1578 EQT_CTX = NULL;
1579
1580 return res;
1581 }
1582
1583 eqt_node *eqt_create (eqt_ctx *ctx, char *equa)
1584 {
1585 ctx->EQT_MODE_CHOICE = EQTNORMAL;
1586
1587 if (!equa) {
1588 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
1589 // eqt_error(__func__);
1590 return NULL;
1591 }
1592
1593 ctx->EQUA_STR = equa;
1594 eqt_parse (ctx);
1595
1596 return ctx->EQUA_NODE;
1597 }
1598
1599 /****************************************************************************/
1600 void eqt_resetvars(eqt_ctx *ctx, int nbvars)
1601 {
1602 long nextitem ;
1603 void *nextkey ;
1604 if (ctx->VAR_HT) {
1605 scanhtkey( ctx->VAR_HT, 1, &nextkey, &nextitem );
1606 while( nextitem != EMPTYHT ) {
1607 eqt_free( 'd', (void *)nextitem );
1608 scanhtkey( ctx->VAR_HT, 0, &nextkey, &nextitem );
1609 }
1610 if (nbvars>0)
1611 {
1612 delht (ctx->VAR_HT);
1613 ctx->VAR_HT=addht(nbvars);
1614 }
1615 else
1616 {
1617 resetht(ctx->VAR_HT);
1618 }
1619
1620 }
1621 }
1622
1623 void eqt_term (eqt_ctx *ctx)
1624 {
1625 long nextitem ;
1626 void *nextkey ;
1627 chain_list *cl;
1628 eqt_func_entry *efe;
1629
1630 if ( !ctx ) return;
1631 if (ctx->VAR_HT) {
1632 scanhtkey( ctx->VAR_HT, 1, &nextkey, &nextitem );
1633 while( nextitem != EMPTYHT ) {
1634 eqt_free( 'd', (void *)nextitem );
1635 scanhtkey( ctx->VAR_HT, 0, &nextkey, &nextitem );
1636 }
1637 delht (ctx->VAR_HT);
1638 }
1639 if (ctx->UNIT_HT) {
1640 scanhtkey( ctx->UNIT_HT, 1, &nextkey, &nextitem );
1641 while( nextitem != EMPTYHT ) {
1642 eqt_free('d', (void *)nextitem );
1643 scanhtkey( ctx->UNIT_HT, 0, &nextkey, &nextitem );
1644 }
1645 delht (ctx->UNIT_HT);
1646 }
1647 for (cl=ctx->FUNCTIONS; cl!=NULL; cl=delchain(cl, cl)) {
1648 efe=(eqt_func_entry *)cl->DATA;
1649 eqt_freenode(efe->NODE_EXPR);
1650 freechain(efe->ARGS);
1651 eqt_free('f',efe);
1652 }
1653
1654 eqt_free('c',ctx);
1655 }
1656
1657 /****************************************************************************/
1658
1659 eqt_ctx *eqt_init (int nbvars)
1660 {
1661 eqt_ctx *ctx;
1662 int i;
1663
1664 ctx = (eqt_ctx*) eqt_alloc('c');
1665 ctx->VAR_HT = addht (nbvars);
1666 ctx->UNIT_HT = NULL; //addht (25);
1667 ctx->EQUA_NODE = NULL;
1668 ctx->EQTINDEX = 0;
1669 ctx->USE_SPICE_UNITS = 0;
1670 for (i = 0; i < EQTMAXNFUNC; i++) {
1671 ctx->NAMETAB[i] = NULL;
1672 ctx->FUNCTAB[i] = NULL;
1673 ctx->FUNCTAB2[i] = NULL;
1674 ctx->FUNCTAB3[i] = NULL;
1675 }
1676 ctx->FUNCTIONS=NULL;
1677
1678 return ctx;
1679 }
1680
1681 /****************************************************************************/
1682
1683 long eqt_dup_ctx_fn( long value, void *unused )
1684 {
1685 double *pt ;
1686
1687 pt = eqt_alloc('d');
1688 *pt = *((double*)value);
1689
1690 unused=NULL;
1691 return (long)pt ;
1692 }
1693
1694 eqt_ctx *eqt_dup_ctx (eqt_ctx *ctx)
1695 {
1696 eqt_ctx *dupctx;
1697 int i;
1698 chain_list *cl;
1699 eqt_func_entry *efe;
1700
1701 if (!ctx) return NULL;
1702
1703 dupctx = (eqt_ctx*) eqt_alloc('c');
1704
1705 dupctx->EQUA_NODE = NULL;
1706
1707 for (i = 0; i < EQTMAXNFUNC; i++) {
1708 dupctx->NAMETAB[i] = NULL;
1709 dupctx->FUNCTAB[i] = NULL;
1710 dupctx->FUNCTAB2[i] = NULL;
1711 dupctx->FUNCTAB3[i] = NULL;
1712 }
1713
1714 for (i = 0; i < ctx->EQTINDEX; i++) {
1715 dupctx->NAMETAB[i] = ctx->NAMETAB[i];
1716 dupctx->FUNCTAB[i] = ctx->FUNCTAB[i];
1717 dupctx->FUNCTAB2[i] = ctx->FUNCTAB2[i];
1718 dupctx->FUNCTAB3[i] = ctx->FUNCTAB3[i];
1719 }
1720
1721 dupctx->EQTINDEX = ctx->EQTINDEX;
1722 dupctx->FUNCTIONS=NULL;
1723 for (cl=ctx->FUNCTIONS; cl!=NULL; cl=cl->NEXT) {
1724 dupctx->FUNCTIONS=addchain(dupctx->FUNCTIONS, efe=(eqt_func_entry *)eqt_alloc('f'));
1725 memcpy(efe, cl->DATA, sizeof(eqt_func_entry));
1726 efe->NODE_EXPR=eqt_create(dupctx, efe->EXPR);
1727 efe->ARGS=dupchainlst(efe->ARGS);
1728 }
1729
1730 dupctx->VAR_HT = controlled_dupht( ctx->VAR_HT, eqt_dup_ctx_fn, NULL );
1731 if (ctx->UNIT_HT!=NULL)
1732 dupctx->UNIT_HT = controlled_dupht( ctx->UNIT_HT, eqt_dup_ctx_fn, NULL );
1733 else
1734 dupctx->UNIT_HT = NULL;
1735
1736 dupctx->USE_SPICE_UNITS=ctx->USE_SPICE_UNITS;
1737
1738 return dupctx;
1739 }
1740
1741 /****************************************************************************/
1742
1743 extern void eqt_free_param (eqt_param *param)
1744 {
1745 if ( param ) {
1746 mbkfree (param->EBI);
1747 // mbkfree (param->VAL);
1748 mbkfree (param);
1749 }
1750 }
1751
1752 /****************************************************************************/
1753 chain_list *eqt_export_func(chain_list *old, eqt_ctx *ctx)
1754 {
1755 chain_list *cl, *ch, *pold=old;
1756 eqt_func_entry *efe;
1757
1758 for (cl=ctx->FUNCTIONS; cl!=NULL; cl=cl->NEXT) {
1759 for (ch=pold; ch!=NULL && ((eqt_func_entry *)ch->DATA)->FUNCNAME!=((eqt_func_entry *)cl->DATA)->FUNCNAME; ch=ch->NEXT) ;
1760 if (ch==NULL)
1761 {
1762 old=addchain(old, efe=(eqt_func_entry *)eqt_alloc('f'));
1763 memcpy(efe, cl->DATA, sizeof(eqt_func_entry));
1764 efe->ARGS=dupchainlst(efe->ARGS);
1765 }
1766 }
1767 return old;
1768 }
1769
1770 void eqt_import_func(chain_list *old, eqt_ctx *ctx)
1771 {
1772 chain_list *cl, *ch;
1773 eqt_func_entry *efe;
1774
1775 for (cl=old; cl!=NULL; cl=cl->NEXT) {
1776 for (ch=ctx->FUNCTIONS; ch!=NULL && ((eqt_func_entry *)ch->DATA)->FUNCNAME!=((eqt_func_entry *)cl->DATA)->FUNCNAME; ch=ch->NEXT) ;
1777 if (ch==NULL)
1778 {
1779 ctx->FUNCTIONS=addchain(ctx->FUNCTIONS, efe=(eqt_func_entry *)eqt_alloc('f'));
1780 memcpy(efe, cl->DATA, sizeof(eqt_func_entry));
1781 efe->NODE_EXPR=eqt_create(ctx, efe->EXPR);
1782 efe->ARGS=dupchainlst(efe->ARGS);
1783 }
1784 }
1785 }
1786
1787 extern eqt_param *eqt_export_vars (eqt_ctx *ctx)
1788 {
1789 int j = 0;
1790 eqt_param *param = NULL;
1791 chain_list *head, *chain ;
1792 void* nextkey ;
1793 long nextitem ;
1794
1795 head = GetAllHTElems( ctx->VAR_HT );
1796 for( chain = head ; chain ; chain = chain->NEXT ) j++ ;
1797 freechain( head );
1798
1799 if( j ) {
1800 param = (eqt_param*)mbkalloc (sizeof (struct eqt_param));
1801 param->EBI= mbkalloc ( j * sizeof (eqt_biinfo));
1802 param->NUMBER = j;
1803
1804 j = 0;
1805 scanhtkey( ctx->VAR_HT, 1, &nextkey, &nextitem );
1806 while( nextitem != EMPTYHT ) {
1807 param->EBI[j].VAL = *(double*)(nextitem);
1808 param->EBI[j].NAME = nextkey;
1809 j++ ;
1810 scanhtkey( ctx->VAR_HT, 0, &nextkey, &nextitem );
1811 }
1812 }
1813
1814 return param;
1815 }
1816 eqt_param *eqt_dupvars (eqt_param *sourceparam)
1817 {
1818 eqt_param *param=NULL;
1819
1820 if (sourceparam!=NULL && sourceparam->NUMBER!=0)
1821 {
1822 param = (eqt_param*)mbkalloc (sizeof (struct eqt_param));
1823 param->EBI= mbkalloc ( sourceparam->NUMBER * sizeof (eqt_biinfo));
1824 param->NUMBER = sourceparam->NUMBER;
1825 memcpy(param->EBI, sourceparam->EBI, sourceparam->NUMBER * sizeof (eqt_biinfo));
1826 }
1827
1828 return param;
1829 }
1830
1831 /****************************************************************************/
1832
1833 void eqt_import_vars (eqt_ctx *to, eqt_param *from)
1834 {
1835 int i;
1836
1837 if (!from) return;
1838 for (i = 0; i < from->NUMBER; i++) eqt_addimportedvar (to, from->EBI[i].NAME, from->EBI[i].VAL);
1839 }
1840
1841 void eqt_display_vars (eqt_param *params)
1842 {
1843 int i;
1844
1845 if (!params) return;
1846 for (i = 0; i < params->NUMBER; i++) printf("%s = %g\n", params->EBI[i].NAME, params->EBI[i].VAL);
1847 }
1848
1849 /****************************************************************************/
1850
1851 void eqt_addunit (eqt_ctx *ctx, char *unit_name, double factor)
1852 {
1853 char buf[1024], *c;
1854
1855 downstr (unit_name, buf);
1856 c=namealloc (buf);
1857 controlled_addhtitem(ctx->UNIT_HT, c, eqt_my_update, (void *)&factor);
1858 }
1859
1860
1861 /****************************************************************************/
1862
1863 double eqt_getunit (eqt_ctx *ctx, char *unit_name)
1864 {
1865 long htfactor;
1866 char buf[1024];
1867 unsigned int i;
1868
1869 if (!unit_name) return 1;
1870
1871 htfactor=EMPTYHT;
1872 downstr (unit_name, buf);
1873 if (ctx->UNIT_HT)
1874 htfactor = gethtitem (ctx->UNIT_HT, namealloc (buf));
1875
1876 if (ctx->USE_SPICE_UNITS && htfactor==EMPTYHT)
1877 {
1878 for (i=0; i<sizeof(basic_units)/sizeof(*basic_units); i++)
1879 if (strncmp(buf, basic_units[i].prefix, basic_units[i].size)==0)
1880 return basic_units[i].value;
1881 }
1882
1883 if ((htfactor != EMPTYHT) && (htfactor != DELETEHT))
1884 return *(double*)htfactor;
1885 else {
1886 avt_errmsg(EQT_ERRMSG, "001", AVT_ERROR, unit_name);
1887 //fprintf (stderr, "[EQT WAR] Unknown unit '%s'\n", unit_name);
1888 return 1;
1889 }
1890 }
1891
1892 /****************************************************************************/
1893
1894 void eqt_addvar (eqt_ctx *ctx, char *var_name, double value)
1895 {
1896 char *name;
1897
1898 name=var_name;
1899 controlled_addhtitem(ctx->VAR_HT, name, eqt_my_update, (void *)&value);
1900 }
1901
1902 /****************************************************************************/
1903 static void eqt_addimportedvar (eqt_ctx *ctx, char *var_name, double value)
1904 {
1905 controlled_addhtitem(ctx->VAR_HT, var_name, eqt_my_update, (void *)&value);
1906 }
1907
1908 /****************************************************************************/
1909 inline double __eqt_getvar (eqt_ctx *ctx, char *var_name, int usenamealloc, int ctxonly)
1910 {
1911 long htvalue;
1912 int i;
1913
1914 ctx->EQT_VAR_INVOLVED = 1;
1915
1916 if (usenamealloc) var_name=namealloc(var_name);
1917
1918 if (!ctxonly)
1919 {
1920 for (i=0; i<5 && EQT_CONTEXT_HIERARCHY[i]!=NULL; i++)
1921 {
1922 htvalue = gethtitem (EQT_CONTEXT_HIERARCHY[i]->VAR_HT, var_name);
1923 if ((htvalue != EMPTYHT) && (htvalue != DELETEHT))
1924 return(*(double*)htvalue);
1925 }
1926 }
1927 htvalue = gethtitem (ctx->VAR_HT, var_name);
1928
1929 if ((htvalue != EMPTYHT) && (htvalue != DELETEHT))
1930 return(*(double*)htvalue);
1931
1932 ctx->EQT_RES_CALC = EQT_INCOMPLETE;
1933 ctx->FAULTY_VAR = var_name;
1934 return 0.0;
1935 }
1936
1937 int eqt_isdefined(eqt_ctx *ctx, char *varname, int global)
1938 {
1939 int i;
1940 long htvalue;
1941 if (global)
1942 {
1943 for (i=0; i<5 && EQT_CONTEXT_HIERARCHY[i]!=NULL; i++)
1944 {
1945 htvalue = gethtitem (EQT_CONTEXT_HIERARCHY[i]->VAR_HT, varname);
1946 if ((htvalue != EMPTYHT) && (htvalue != DELETEHT))
1947 return 1;
1948 }
1949 }
1950 if (ctx==NULL) return 0;
1951 return gethtitem(ctx->VAR_HT, varname)!=EMPTYHT;
1952 }
1953
1954 double eqt_getvar (eqt_ctx *ctx, char *var_name)
1955 {
1956 return __eqt_getvar (ctx, var_name, 1, 0);
1957 }
1958 double eqt_getvar_in_context_only (eqt_ctx *ctx, char *var_name)
1959 {
1960 return __eqt_getvar (ctx, var_name, 1, 1);
1961 }
1962
1963 /****************************************************************************/
1964
1965 double eqt_eval (eqt_ctx *ctx, char *equa, int choix)
1966 {
1967 double d = 0.0;
1968 eqt_node *n = NULL;
1969
1970 ctx->EQT_MODE_CHOICE = choix;
1971 n = eqt_loopup_node(ctx, equa);
1972 if (n!=NULL)
1973 d = eqt_calcval (ctx, n);
1974 else
1975 avt_errmsg(EQT_ERRMSG, "002", AVT_ERROR, equa);
1976
1977 #if 0
1978 switch (ctx->EQT_MODE_CHOICE) {
1979 case EQTNORMAL :
1980 // n = eqt_create (ctx, equa);
1981 n = eqt_loopup_node(equa);
1982 if (n) {
1983 d = eqt_calcval (ctx, n);
1984 // eqt_freenode (n);
1985 }
1986 else
1987 avt_errmsg(EQT_ERRMSG, "002", AVT_ERROR, equa);
1988 // eqt_error("%s : can't evaluate '%s'",__func__,equa);
1989 break;
1990 case EQTFAST :
1991 ctx->EQUA_STR = equa;
1992 ctx->EQT_RES_CALC = EQT_COMPLETE;
1993 ctx->EQT_VAR_INVOLVED = 0;
1994 EQT_GOT_RANDOM=0;
1995 if (eqt_parse (ctx) == 0)
1996 d = ctx->EQUA_VAL;
1997 else
1998 avt_errmsg(EQT_ERRMSG, "002", AVT_ERROR, equa);
1999 ctx->EQT_GOT_RANDOM=EQT_GOT_RANDOM;
2000 // eqt_error("%s : can't evaluate '%s'",__func__,equa);
2001 break;
2002
2003 }
2004 #endif
2005 return d;
2006 }
2007
2008 /****************************************************************************/
2009
2010 int eqt_resistrue (eqt_ctx *ctx)
2011 {
2012 return ctx->EQT_RES_CALC == EQT_COMPLETE ? 1 : 0;
2013 }
2014
2015 int eqt_resisrandom (eqt_ctx *ctx)
2016 {
2017 return ctx->EQT_GOT_RANDOM!=0;
2018 }
2019 void eqt_set_failedres (eqt_ctx *ctx)
2020 {
2021 ctx->EQT_RES_CALC=EQT_INCOMPLETE;
2022 }
2023
2024 /****************************************************************************/
2025
2026 int eqt_var_involved (eqt_ctx *ctx)
2027 {
2028 return ctx->EQT_VAR_INVOLVED;
2029 }
2030
2031 /****************************************************************************/
2032
2033 void eqt_addfunction (eqt_ctx *ctx, char *name, double (*function) (double))
2034 {
2035 if (ctx->EQTINDEX >= EQTMAXNFUNC)
2036 {
2037 avt_errmsg(EQT_ERRMSG, "003", AVT_WARNING);
2038 // eqt_warning("too much user defined functions");
2039 return;
2040 }
2041 ctx->NAMETAB[ctx->EQTINDEX] = namealloc (name);
2042 ctx->FUNCTAB[ctx->EQTINDEX] = function;
2043 ctx->EQTINDEX++;
2044 }
2045
2046 /****************************************************************************/
2047
2048 int eqt_getindex (eqt_ctx *ctx, char *name)
2049 {
2050 int i;
2051
2052 for (i = 0 ; i < EQTMAXNFUNC ; i++)
2053 {
2054 if (ctx->NAMETAB[i] == name)
2055 return i;
2056 }
2057
2058 return -1;
2059 }
2060
2061
2062 /****************************************************************************/
2063
2064 void eqt_addfunction2 (eqt_ctx *ctx, char *name, double (*function) (double, double))
2065 {
2066 if (ctx->EQTINDEX >= EQTMAXNFUNC)
2067 {
2068 avt_errmsg(EQT_ERRMSG, "003", AVT_WARNING);
2069 // eqt_warning("too much user defined functions");
2070 return;
2071 }
2072 ctx->NAMETAB [ctx->EQTINDEX] = namealloc (name);
2073 ctx->FUNCTAB2[ctx->EQTINDEX] = function;
2074 ctx->EQTINDEX++;
2075 }
2076
2077 /****************************************************************************/
2078
2079 void eqt_addfunction3 (eqt_ctx *ctx, char *name, double (*function) (double, double, double))
2080 {
2081 if (ctx->EQTINDEX >= EQTMAXNFUNC)
2082 {
2083 avt_errmsg(EQT_ERRMSG, "003", AVT_WARNING);
2084 // eqt_warning("too much user defined functions");
2085 return;
2086 }
2087 ctx->NAMETAB [ctx->EQTINDEX] = namealloc (name);
2088 ctx->FUNCTAB3[ctx->EQTINDEX] = function;
2089 ctx->EQTINDEX++;
2090 }
2091
2092 int eqt_adddotfunc (eqt_ctx *ctx, char *name, chain_list *args, char *expr)
2093 {
2094 eqt_func_entry *efe;
2095 chain_list *cl;
2096
2097 name=namealloc(name);
2098 for (cl=ctx->FUNCTIONS; cl!=NULL && ((eqt_func_entry *)cl->DATA)->FUNCNAME!=name; cl=cl->NEXT) ;
2099 if (cl!=NULL)
2100 {
2101 efe=(eqt_func_entry *)cl->DATA;
2102 eqt_freenode(efe->NODE_EXPR);
2103 freechain(efe->ARGS);
2104 }
2105 else
2106 {
2107 efe=(eqt_func_entry *)eqt_alloc('f');
2108 ctx->FUNCTIONS=addchain(ctx->FUNCTIONS, efe);
2109 }
2110 efe->FUNCNAME=name;
2111 efe->ARGS=dupchainlst(args);
2112 for (cl=efe->ARGS; cl!=NULL; cl=cl->NEXT) cl->DATA=namealloc((char *)cl->DATA);
2113 efe->EXPR=namealloc(expr); //?
2114 efe->NODE_EXPR=eqt_create(ctx, efe->EXPR);
2115 return 1;
2116 }
2117
2118 /****************************************************************************/
2119 chain_list *eqt_NodeToAbl(eqt_node *node)
2120 {
2121 chain_list *abl;
2122 int value;
2123
2124 if (!node)
2125 {
2126 avt_errmsg(EQT_ERRMSG, "005", AVT_ERROR);
2127 // eqt_error("empty node can't make ABL");
2128 return NULL;
2129 }
2130
2131 if (IsValue(node)) {
2132 value = (int)(Value(node));
2133 if ( value == 0 )
2134 abl = createAtom ( "'0'" );
2135 else if ( value == 1 )
2136 abl = createAtom ( "'1'" );
2137 else {
2138 avt_errmsg(EQT_ERRMSG, "006", AVT_ERROR);
2139 // eqt_error("eqt error: integer value in ABL to make");
2140 abl = NULL;
2141 }
2142 return abl;
2143 }
2144
2145 if (node->TYPE == EQTVARNAME_T) {
2146 abl = createAtom ( node->UNODE.VARNAME );
2147 return abl;
2148 }
2149
2150 if (node->TYPE == EQTUNOP_T)
2151 switch (Operator(node) & 0xff) {
2152 case EQTNOT :
2153 abl = notExpr ( eqt_NodeToAbl (Oper(node) ) );
2154 return abl;
2155 break;
2156 }
2157
2158 if (node->TYPE == EQTBINOP_T)
2159 switch (Operator(node) & 0xff) {
2160 case EQTOR:
2161 case EQTPLUS:
2162 abl = createBinExpr ( OR ,
2163 eqt_NodeToAbl (Oper1(node)) ,
2164 eqt_NodeToAbl (Oper2(node)) );
2165 return abl;
2166 break;
2167 case EQTAND:
2168 case EQTMULT:
2169 abl = createBinExpr ( AND,
2170 eqt_NodeToAbl ( Oper1(node) ),
2171 eqt_NodeToAbl ( Oper2(node) ));
2172 return abl;
2173 break;
2174 case EQTXOR:
2175 case EQTPOW:
2176 abl = createBinExpr ( XOR,
2177 eqt_NodeToAbl ( Oper1(node) ),
2178 eqt_NodeToAbl ( Oper2(node) ));
2179 return abl;
2180 break;
2181 }
2182 if (node->TYPE == EQTTERNOP_T || node->TYPE==EQTDOTFUNC_T)
2183 avt_errmsg(EQT_ERRMSG, "004", AVT_WARNING, __func__);
2184 // eqt_warning("%s can't be done yet on ternary operators",__func__);
2185
2186 return NULL;
2187 }
2188
2189 /****************************************************************************/
2190 chain_list *eqt_StrToAbl(eqt_ctx *ctx, char *str)
2191 {
2192 eqt_node *node;
2193 chain_list *abl;
2194
2195 node = eqt_create (ctx, str);
2196 if ( !node ) {
2197 avt_errmsg(EQT_ERRMSG, "007", AVT_ERROR);
2198 // eqt_error("node NULL");
2199 return NULL;
2200 }
2201 else {
2202 abl = eqt_NodeToAbl ( node );
2203 eqt_freenode( node );
2204 return abl;
2205 }
2206 }
2207
2208 /****************************************************************************/
2209 /* FUNCTION : eqt_ReduceSpace */
2210 /* Object : reduce all consecutive white space in a string */
2211 /****************************************************************************/
2212 char *eqt_ReduceSpace(char *str)
2213 {
2214 char initbuf[1024];
2215 char finalbuf[1024];
2216 char flag = 'N' ; /* space flag */
2217 int length;
2218 int i, j;
2219
2220 sprintf(initbuf,"%s",str);
2221 length = strlen(str);
2222 j = 0;
2223 for (i = 0; i < length ; i++)
2224 {
2225 if ((initbuf[i]) != ' ')
2226 {
2227 finalbuf[j] = initbuf[i];
2228 flag = 'N';
2229 j++;
2230 }
2231 else if ((initbuf[i]) == ' ' && flag == 'N')
2232 {
2233 finalbuf[j] = initbuf[i];
2234 flag = 'Y';
2235 j++;
2236 }
2237 }
2238 finalbuf[j] = '\0';
2239
2240 return mbkstrdup(finalbuf);
2241 }
2242
2243 /****************************************************************************/
2244 /* FUNCTION : eqt_IsSpecialCar */
2245 /* Object : Test if the car is special */
2246 /****************************************************************************/
2247 int eqt_IsSpecialCar(char str, char pos)
2248 {
2249 /* pos : D = Droite de l espace */
2250 /* pos : G = Gauche de l espace */
2251
2252 int res = 0;
2253
2254 if ((str == '(') && (pos == 'D'))
2255 res = 1;
2256 else if ((str == ')') && (pos == 'G'))
2257 res = 2;
2258 else if ((str == '!') && (pos == 'D'))
2259 res = 3;
2260 else if ((str == '~') && (pos == 'D'))
2261 res = 3;
2262 else if ((str == '\'') && (pos == 'G'))
2263 res = 3;
2264 else if (isalnum((int)str) != 0) {
2265 res = 4;
2266 }
2267
2268 return res;
2269 }
2270
2271 /****************************************************************************/
2272 /* FUNCTION : eqt_ConvertStr */
2273 /* Object : Replace the good white space by a '&' car */
2274 /****************************************************************************/
2275 char *eqt_ConvertStr(char *str)
2276 {
2277 char *string, *sreduce;
2278 char *pt, *ptres;
2279 int res1 = 0;
2280 int res2 = 0;
2281
2282 sreduce = eqt_ReduceSpace ( str );
2283 pt = sreduce;
2284 string = (char*)mbkalloc ((2*strlen(pt))+1);
2285 ptres = string;
2286 while ( *pt != '\0' ) {
2287 switch (*pt) {
2288 case ' ' : res1 = eqt_IsSpecialCar(*(pt-1),'G');
2289 res2 = eqt_IsSpecialCar(*(pt+1),'D');
2290 if ((res1 && res2))
2291 *ptres = '&';
2292 else *ptres = *pt;
2293 break;
2294 case '!' : if (pt>sreduce) {
2295 res1 = eqt_IsSpecialCar(*(pt-1),'G');
2296 res2 = eqt_IsSpecialCar(*(pt+1),'D');
2297 }
2298 if (((res1==4)||(res1==2)) && ((res2==4)||(res2==1))) {
2299 *ptres = '&'; ptres++;
2300 *ptres = *pt;
2301 }
2302 else *ptres = *pt;
2303 break;
2304 case '\'' : if (*(pt+1) != '\0') {
2305 res1 = eqt_IsSpecialCar(*(pt-1),'G');
2306 res2 = eqt_IsSpecialCar(*(pt+1),'D');
2307 }
2308 if (((res1==4)||(res1==2)) && ((res2==4)||(res2==1))) {
2309 *ptres = *pt; ptres++;
2310 *ptres = '&';
2311 }
2312 else *ptres = *pt;
2313 break;
2314 default : *ptres = *pt;
2315 break;
2316 }
2317 pt++;
2318 ptres++;
2319 }
2320 *ptres = '\0';
2321 mbkfree (sreduce);
2322 return string;
2323 }
2324
2325
2326 /*{{{ eqt_get_brother() */
2327 /* */
2328 /* */
2329 /****************************************************************************/
2330 eqt_node *eqt_get_brother(eqt_node *node)
2331 {
2332 eqt_node *father = node->FATHER;
2333
2334 if (father->TYPE == EQTBINOP_T)
2335 {
2336 if (Oper2(father) == node)
2337 return Oper1(father);
2338 else
2339 return Oper2(father);
2340 }
2341 else
2342 return NULL;
2343 }
2344
2345 /*}}}************************************************************************/
2346 /*{{{ eqt_adopt_brother() */
2347 /* */
2348 /* */
2349 /****************************************************************************/
2350 void eqt_adopt_brother(eqt_node *node,eqt_node *brother)
2351 {
2352 eqt_node *father = node->FATHER;
2353
2354 if (father->TYPE == EQTBINOP_T)
2355 {
2356 if (Oper2(father) == node)
2357 NewOper1(father,brother);
2358 else
2359 NewOper2(father,brother);
2360 }
2361 }
2362
2363 /*}}}************************************************************************/
2364 /*{{{ eqt_DelMinDiv() */
2365 /* */
2366 /* */
2367 /****************************************************************************/
2368 eqt_node *eqt_DelMinDiv(eqt_node *node)
2369 {
2370 switch (node->TYPE)
2371 {
2372 case EQTVALUE_T : case EQTVARNAME_T :
2373 return node;
2374 case EQTUNOP_T :
2375 if (IsValue(Oper(node)) && Operator(node) == EQTMIN)
2376 {
2377 eqt_node *res;
2378
2379 res = eqt_NegNode(Oper(node));
2380 eqt_delnode(node);
2381 node = res;
2382 }
2383 else
2384 NewOper(node,eqt_DelMinDiv(Oper(node)));
2385 return node;
2386 default :
2387 if (Operator(node) == EQTMIN)
2388 {
2389 NewOperator(node,EQTPLUS);
2390 NewOper2(node,eqt_NegNode(Oper2(node)));
2391 }
2392 else if (Operator(node) == EQTDIV)
2393 {
2394 NewOperator(node,EQTMULT);
2395 NewOper2(node,eqt_InvNode(Oper2(node)));
2396 }
2397 NewOper1(node,eqt_DelMinDiv(Oper1(node)));
2398 NewOper2(node,eqt_DelMinDiv(Oper2(node)));
2399 return node;
2400 }
2401 }
2402
2403 /*}}}************************************************************************/
2404 /*{{{ eqt_NegNode() */
2405 /* */
2406 /* */
2407 /****************************************************************************/
2408 eqt_node *eqt_NegNode(eqt_node *node)
2409 {
2410 switch (node->TYPE)
2411 {
2412 case EQTVALUE_T :
2413 node->UNODE.VALUE = -(Value(node));
2414 return node;
2415 case EQTVARNAME_T :
2416 return eqt_addunarynode(EQTMIN,node);
2417 case EQTUNOP_T :
2418 if (Operator(node) == EQTMIN)
2419 {
2420 eqt_node *res;
2421
2422 res = Oper(node);
2423 eqt_delnode(node);
2424 return res;
2425 }
2426 else
2427 {
2428 NewOper(node,eqt_NegNode(Oper(node)));
2429 return node;
2430 }
2431 default :
2432 switch (Operator(node))
2433 {
2434 case EQTMIN :
2435 NewOperator(node,EQTPLUS);
2436 NewOper1(node,eqt_NegNode(Oper1(node)));
2437 break;
2438 case EQTPLUS :
2439 NewOper2(node,eqt_NegNode(Oper2(node)));
2440 NewOper1(node,eqt_NegNode(Oper1(node)));
2441 break;
2442 case EQTMULT :
2443 if (IsValue(Oper1(node)))
2444 NewOper1(node,eqt_NegNode(Oper1(node)));
2445 else
2446 NewOper2(node,eqt_NegNode(Oper2(node)));
2447 break;
2448 default :
2449 NewOper1(node,eqt_NegNode(Oper1(node)));
2450 }
2451 return node;
2452 }
2453 }
2454
2455 /*}}}************************************************************************/
2456 /*{{{ eqt_InvNode() */
2457 /* */
2458 /* */
2459 /****************************************************************************/
2460 eqt_node *eqt_InvNode(eqt_node *node)
2461 {
2462 switch (node->TYPE)
2463 {
2464 case EQTVALUE_T :
2465 if (Value(node) == 1.0)
2466 return node;
2467 case EQTVARNAME_T :
2468 return eqt_addunarynode(EQTINV,node);
2469 case EQTUNOP_T :
2470 if (Operator(node) == EQTINV)
2471 {
2472 eqt_node *res;
2473
2474 res = Oper(node);
2475 eqt_delnode(node);
2476 return res;
2477 }
2478 else
2479 {
2480 NewOper(node,eqt_InvNode(Oper(node)));
2481 return node;
2482 }
2483 default :
2484 if (Operator(node) == EQTDIV)
2485 {
2486 NewOper1(node,eqt_InvNode(Oper1(node)));
2487 NewOperator(node,EQTMULT);
2488 }
2489 else if (Operator(node) == EQTMULT)
2490 {
2491 NewOper1(node,eqt_InvNode(Oper1(node)));
2492 NewOper2(node,eqt_InvNode(Oper2(node)));
2493 }
2494 else
2495 node = eqt_addunarynode(EQTINV,node);
2496 return node;
2497 }
2498 }
2499
2500 /*}}}************************************************************************/
2501 /*{{{ eqt_DelNeutral() */
2502 /* */
2503 /* */
2504 /****************************************************************************/
2505 eqt_node *eqt_DelNeutral(eqt_node *node)
2506 {
2507 double neutral;
2508 eqt_node *res, *father;
2509
2510 father = node->FATHER;
2511 switch (node->TYPE)
2512 {
2513 case EQTVALUE_T : case EQTVARNAME_T :
2514 return node;
2515 case EQTUNOP_T :
2516 if (Operator(node) == EQTMIN)
2517 neutral = 0.0;
2518 else if (Operator(node) == EQTINV)
2519 neutral = 1.0;
2520 else
2521 neutral = -1.0;
2522 if ( neutral >= 0.0
2523 && IsValue(Oper(node)) && Value(Oper(node)) == neutral)
2524 {
2525 res = Oper(node);
2526 res->FATHER = father;
2527 eqt_delnode(node);
2528
2529 return eqt_DelNeutral(res);
2530 }
2531 NewOper(node,eqt_DelNeutral(Oper(node)));
2532
2533 return node;
2534 default :
2535 if (Operator(node) == EQTPLUS)
2536 neutral = 0.0;
2537 else if (Operator(node) == EQTMULT)
2538 neutral = 1.0;
2539 else
2540 neutral = -1.0;
2541 if (neutral >= 0.0)
2542 {
2543 if ( IsValue(Oper1(node)) && Value(Oper1(node)) == neutral)
2544 {
2545 res = Oper2(node);
2546 res->FATHER = father;
2547 eqt_delnode(Oper1(node));
2548 eqt_delnode(node);
2549
2550 return eqt_DelNeutral(res);
2551 // NewOper2(node,NULL);
2552 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2553 //
2554 // return node;
2555 }
2556 // negative form of neutral element
2557 else if ( IsValue(Oper1(node)) && Value(Oper1(node)) == -neutral)
2558 {
2559 res = eqt_NegNode(Oper2(node));
2560 res->FATHER = father;
2561 eqt_delnode(Oper1(node));
2562 eqt_delnode(node);
2563
2564 return eqt_DelNeutral(res);
2565 // NewOper2(node,NULL);
2566 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2567 //
2568 // return node;
2569 }
2570 else if ( IsValue(Oper2(node)) && Value(Oper2(node)) == neutral)
2571 {
2572 res = Oper1(node);
2573 res->FATHER = father;
2574 eqt_delnode(Oper2(node));
2575 eqt_delnode(node);
2576
2577 return eqt_DelNeutral(res);
2578 // NewOper1(node,NULL);
2579 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2580 //
2581 // return node;
2582 }
2583 // negative form of neutral element
2584 else if ( IsValue(Oper2(node)) && Value(Oper2(node)) == -neutral)
2585 {
2586 res = eqt_NegNode(Oper1(node));
2587 res->FATHER = father;
2588 eqt_delnode(Oper2(node));
2589 eqt_delnode(node);
2590
2591 return eqt_DelNeutral(res);
2592 // NewOper1(node,NULL);
2593 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2594 //
2595 // return node;
2596 }
2597 }
2598 NewOper1(node,eqt_DelNeutral(Oper1(node)));
2599 NewOper2(node,eqt_DelNeutral(Oper2(node)));
2600
2601 return node;
2602 }
2603 }
2604
2605 /*}}}************************************************************************/
2606 /*{{{ eqt_ToStr() */
2607 /* */
2608 /* */
2609 /****************************************************************************/
2610 char *eqt_ToStr(eqt_node *node)
2611 {
2612 char buf[4096];
2613 char *operand1, *operand2, *operator;
2614 int par;
2615
2616 par = eqt_needParenthesis(node);
2617 switch (node->TYPE)
2618 {
2619 case EQTVALUE_T :
2620 if (par)
2621 sprintf(buf,"(%g)",Value(node));
2622 else
2623 sprintf(buf,"%g",Value(node));
2624 return mbkstrdup(buf);
2625 case EQTVARNAME_T :
2626 sprintf(buf,"%s",node->UNODE.VARNAME);
2627 return mbkstrdup(buf);
2628 case EQTUNOP_T :
2629 operator = eqt_operToStr(Operator(node));
2630 operand1 = eqt_ToStr(Oper(node));
2631 switch (par)
2632 {
2633 case 1 :
2634 sprintf(buf,"%s(%s)",operator,operand1);
2635 break;
2636 case 2 :
2637 sprintf(buf,"(%s%s)",operator,operand1);
2638 break;
2639 default :
2640 sprintf(buf,"%s%s",operator,operand1);
2641 break;
2642 }
2643 mbkfree(operator);
2644 mbkfree(operand1);
2645 return mbkstrdup(buf);
2646 default :
2647 if (Operator(node) == EQTPLUS && IsNeg(Oper2(node)))
2648 operator = mbkstrdup("");
2649 else
2650 operator = eqt_operToStr(Operator(node));
2651 operand2 = eqt_ToStr(Oper2(node));
2652 operand1 = eqt_ToStr(Oper1(node));
2653 if (par)
2654 sprintf(buf,"(%s%s%s)",operand1,operator,operand2);
2655 else
2656 sprintf(buf,"%s%s%s",operand1,operator,operand2);
2657 mbkfree(operator);
2658 mbkfree(operand1);
2659 mbkfree(operand2);
2660 return mbkstrdup(buf);
2661 }
2662 }
2663
2664
2665 static chain_list *__eqt_GetVariables(eqt_ctx *ctx, eqt_node *node, chain_list *list, int all)
2666 {
2667 chain_list *cl;
2668
2669 switch (node->TYPE)
2670 {
2671 case EQTVALUE_T :
2672 return list;
2673 case EQTVARNAME_T :
2674 for (cl=list; cl!=NULL && cl->DATA!=node->UNODE.VARNAME; cl=cl->NEXT) ;
2675 if (cl==NULL)
2676 {
2677 if (all || !eqt_isdefined(ctx, node->UNODE.VARNAME, 1))
2678 list=addchain(list, node->UNODE.VARNAME);
2679 }
2680 return list;
2681 case EQTUNOP_T :
2682 list = __eqt_GetVariables(ctx, Oper(node), list, all);
2683 return list;
2684 case EQTDOTFUNC_T:
2685 {
2686 if (eqt_getdotfunc(ctx, node->UNODE.FUNCOP->FUNCNAME)==NULL)
2687 {
2688 for (cl=list; cl!=NULL && cl->DATA!=node->UNODE.FUNCOP->FUNCNAME; cl=cl->NEXT) ;
2689 if (cl==NULL) list=addchain(list, node->UNODE.FUNCOP->FUNCNAME);
2690 }
2691 for (cl=node->UNODE.FUNCOP->ARGS; cl!=NULL; cl=cl->NEXT)
2692 list=__eqt_GetVariables(ctx, (eqt_node *)cl->DATA, list, all);
2693 return list;
2694 }
2695 case EQTTERNOP_T :
2696 list = __eqt_GetVariables(ctx, Oper3(node), list, all);
2697 case EQTBINOP_T :
2698 list = __eqt_GetVariables(ctx, Oper2(node), list, all);
2699 list = __eqt_GetVariables(ctx, Oper1(node), list, all);
2700 default :
2701 return list;
2702 }
2703 }
2704
2705 chain_list *eqt_GetVariables(eqt_ctx *ctx, char *equa, int all)
2706 {
2707 eqt_node *n;
2708 chain_list *cl=NULL;
2709
2710 ctx->EQT_MODE_CHOICE = EQTNORMAL;
2711 //n = eqt_create (ctx, equa);
2712 n = eqt_loopup_node(ctx, equa);
2713 if (n!=NULL) cl=__eqt_GetVariables(ctx, n, NULL, all);
2714 // eqt_freenode (n);
2715 return cl;
2716 }
2717
2718 /*}}}************************************************************************/
2719 /*{{{ eqt_ToIntStr() */
2720 /* */
2721 /* */
2722 /****************************************************************************/
2723 char *eqt_ToIntStr(eqt_node *node)
2724 {
2725 char buf[4096];
2726 char *operand1, *operand2, *operator;
2727 int par;
2728
2729 par = eqt_needParenthesis(node);
2730 switch (node->TYPE)
2731 {
2732 case EQTVALUE_T :
2733 if (par)
2734 sprintf(buf,"(%ld)",(long)Value(node));
2735 else
2736 sprintf(buf,"%ld",(long)Value(node));
2737 return mbkstrdup(buf);
2738 case EQTVARNAME_T :
2739 sprintf(buf,"%s",node->UNODE.VARNAME);
2740 return mbkstrdup(buf);
2741 case EQTUNOP_T :
2742 operator = eqt_operToStr(Operator(node));
2743 operand1 = eqt_ToIntStr(Oper(node));
2744 switch (par)
2745 {
2746 case 1 :
2747 sprintf(buf,"%s(%s)",operator,operand1);
2748 break;
2749 case 2 :
2750 sprintf(buf,"(%s%s)",operator,operand1);
2751 break;
2752 default :
2753 sprintf(buf,"%s%s",operator,operand1);
2754 break;
2755 }
2756 mbkfree(operator);
2757 mbkfree(operand1);
2758 return mbkstrdup(buf);
2759 default :
2760 if (Operator(node) == EQTPLUS && IsNeg(Oper2(node)))
2761 operator = mbkstrdup("");
2762 else
2763 operator = eqt_operToStr(Operator(node));
2764 operand2 = eqt_ToIntStr(Oper2(node));
2765 operand1 = eqt_ToIntStr(Oper1(node));
2766 if (par)
2767 sprintf(buf,"(%s%s%s)",operand1,operator,operand2);
2768 else
2769 sprintf(buf,"%s%s%s",operand1,operator,operand2);
2770 mbkfree(operator);
2771 mbkfree(operand1);
2772 mbkfree(operand2);
2773 return mbkstrdup(buf);
2774 }
2775 }
2776
2777 /*}}}************************************************************************/
2778 /*{{{ IsNeg() */
2779 /* */
2780 /* */
2781 /****************************************************************************/
2782 static int IsNeg(eqt_node *node)
2783 {
2784 switch (node->TYPE)
2785 {
2786 case EQTVALUE_T :
2787 return (Value(node) < 0.0);
2788 case EQTUNOP_T :
2789 return (Operator(node) == EQTMIN);
2790 default :
2791 return 0;
2792 }
2793 }
2794
2795 /*}}}************************************************************************/
2796 /*{{{ eqt_needParenthesis() */
2797 /* */
2798 /* */
2799 /****************************************************************************/
2800 int eqt_needParenthesis(eqt_node *node)
2801 {
2802 eqt_node *father;
2803
2804 father = node->FATHER;
2805 switch (node->TYPE)
2806 {
2807 case EQTUNOP_T :
2808 switch (Operator(node))
2809 {
2810 case EQTMIN :
2811 if (Operator(father) == EQTPLUS)
2812 return 0;
2813 else
2814 return 2;
2815 default :
2816 return 0;
2817 }
2818 case EQTBINOP_T :
2819 switch (Operator(node))
2820 {
2821 case EQTMULT : case EQTDIV :
2822 return 0;
2823 default :;
2824 }
2825 if (father)
2826 switch (Operator(father))
2827 {
2828 case EQTMIN :
2829 return eqt_isOperand2(node);
2830 case EQTDIV :
2831 return 1;
2832 default :
2833 return (Operator(father) != Operator(node));
2834 }
2835 else
2836 return 0;
2837 case EQTVALUE_T :
2838 if (father)
2839 if (Operator(father) == EQTPLUS)
2840 return 0;
2841 else
2842 return (Value(node) < 0.0);
2843 else
2844 return 0;
2845 default :
2846 return 0;
2847 }
2848 return (node == NULL);
2849 }
2850
2851 /*}}}************************************************************************/
2852 /*{{{ eqt_drive() */
2853 /* */
2854 /* */
2855 /****************************************************************************/
2856 void eqt_drive(eqt_node *node)
2857 {
2858 char *str;
2859
2860 str = eqt_ToStr(node);
2861 fprintf(stdout,"%s\n",str);
2862 mbkfree(str);
2863 }
2864
2865 /*}}}************************************************************************/
2866 /*{{{ eqt_operToStr() */
2867 /* */
2868 /* */
2869 /****************************************************************************/
2870 char *eqt_operToStr(long operator)
2871 {
2872 switch (operator)
2873 {
2874 case EQTPLUS : return mbkstrdup("+");
2875 case EQTMIN : return mbkstrdup("-");
2876 case EQTMULT : return mbkstrdup("*");
2877 case EQTDIV : return mbkstrdup("/");
2878 case EQTEXP : return mbkstrdup("e");
2879 case EQTSQRT : return mbkstrdup("sqrt");
2880 case EQTPOW : return mbkstrdup("^");
2881 case EQTLOG : return mbkstrdup("log");
2882 case EQTINV : return mbkstrdup("inv");
2883
2884 case EQTSIN : return mbkstrdup("sin");
2885 case EQTCOS : return mbkstrdup("cos");
2886 case EQTTAN : return mbkstrdup("tan");
2887 case EQTASIN : return mbkstrdup("");
2888 case EQTACOS : return mbkstrdup("");
2889 case EQTATAN : return mbkstrdup("");
2890 case EQTATAN2 : return mbkstrdup("");
2891 case EQTSINH : return mbkstrdup("");
2892 case EQTCOSH : return mbkstrdup("");
2893 case EQTTANH : return mbkstrdup("");
2894 case EQTLOG10 : return mbkstrdup("log10");
2895 case EQTCEIL : return mbkstrdup("");
2896 case EQTFLOOR : return mbkstrdup("");
2897 case EQTFABS : return mbkstrdup("fabs");
2898 case EQTABS : return mbkstrdup("abs");
2899 default : return mbkstrdup("");
2900 }
2901 }
2902
2903 /*}}}************************************************************************/
2904 /*{{{ eqt_linearise() */
2905 /* */
2906 /* return invert child */
2907 /****************************************************************************/
2908 int eqt_linearise(eqt_node *node)
2909 {
2910 eqt_node *father;
2911
2912 switch (node->TYPE)
2913 {
2914 case EQTVALUE_T : case EQTVARNAME_T : case EQTUNOP_T :
2915 return 0;
2916 case EQTBINOP_T :
2917 eqt_linearise(Oper1(node));
2918 if ( (father = node->FATHER) )
2919 {
2920 if ( Operator(father) == Operator(node) )
2921 {
2922 if (! eqt_isOperand2(node) )
2923 {
2924 NewOper1(father, Oper1(node));
2925 NewOper1(node, Oper2(father));
2926 eqt_invertChild(node);
2927 NewOper2(father,node);
2928 eqt_linearise(Oper1(node));
2929 return 0;
2930 }
2931 }
2932 else if ( eqt_isOperand2(node) )
2933 {
2934 eqt_invertChild(father);
2935 return 1;
2936 }
2937 else
2938 return 0;
2939 }
2940 eqt_linearise(Oper2(node));
2941 return 0;
2942 default :
2943 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
2944 // eqt_error(__func__);
2945 return 0;
2946 }
2947 }
2948
2949 /*}}}************************************************************************/
2950 /*{{{ eqt_addNeutral() */
2951 /* */
2952 /* */
2953 /****************************************************************************/
2954 int eqt_addNeutral(eqt_node *node)
2955 {
2956 eqt_node *nodex, *father, *neutral;
2957 int operator;
2958
2959 switch (node->TYPE)
2960 {
2961 case EQTVALUE_T : case EQTVARNAME_T : case EQTUNOP_T :
2962 return 1;
2963 case EQTBINOP_T :
2964 operator = Operator(node);
2965 for (nodex = node; Operator(nodex) == operator;
2966 nodex = Oper2(nodex))
2967 eqt_addNeutral(Oper1(nodex));
2968 if (!IsValue(nodex))
2969 {
2970 neutral = eqt_getNeutralNode(operator);
2971 father = nodex->FATHER;
2972 if (father)
2973 NewOper2(father,eqt_addbinarynode(operator,nodex,neutral));
2974 }
2975 return 1;
2976 default :
2977 return 0;
2978 }
2979 }
2980
2981 /*}}}************************************************************************/
2982 /*{{{ eqt_getNeutralNode() */
2983 /* */
2984 /* */
2985 /****************************************************************************/
2986 static eqt_node *eqt_getNeutralNode(int operator)
2987 {
2988 return eqt_addvalue(eqt_get_neutral(operator));
2989 }
2990
2991 /*}}}************************************************************************/
2992 /*{{{ eqt_printTree() */
2993 /* */
2994 /* */
2995 /****************************************************************************/
2996 void eqt_printTree(eqt_node *node,int deep)
2997 {
2998 char *operator;
2999 char EQT_PRINTYES[255];
3000
3001 if (deep == 0)
3002 eqt_initSpaceII(EQT_PRINTYES);
3003 switch (node->TYPE)
3004 {
3005 case EQTVALUE_T :
3006 fprintf(stdout," %g\n",Value(node));
3007 break;
3008 case EQTVARNAME_T :
3009 fprintf(stdout," %s\n",Varname(node));
3010 break;
3011 case EQTUNOP_T :
3012 operator = eqt_operToStr(Operator(node));
3013 fprintf(stdout,"(%s)\n",operator);
3014 mbkfree(operator);
3015 print_spaceII(EQT_PRINTYES, deep);
3016 fprintf(stdout,"`---:");
3017 EQT_PRINTYES[deep] = 1;
3018 eqt_printTree(Oper(node),deep+1);
3019 EQT_PRINTYES[deep] = 0;
3020 break;
3021 default :
3022 operator = eqt_operToStr(Operator(node));
3023 fprintf(stdout,"(%s)\n",operator);
3024 mbkfree(operator);
3025 print_spaceII(EQT_PRINTYES, deep);
3026 if (eqt_isRealLeaf(Oper1(node)))
3027 fprintf(stdout,"+--1:");
3028 else
3029 fprintf(stdout,"+-+1:");
3030 eqt_printTree(Oper1(node),deep+1);
3031 print_spaceII(EQT_PRINTYES, deep);
3032 EQT_PRINTYES[deep] = 1;
3033 if (eqt_isRealLeaf(Oper2(node)))
3034 fprintf(stdout,"`--2:");
3035 else
3036 fprintf(stdout,"`-+2:");
3037 eqt_printTree(Oper2(node),deep+1);
3038 EQT_PRINTYES[deep] = 0;
3039 }
3040 }
3041
3042 /*}}}************************************************************************/
3043 /*{{{ eqt_sortBranch() */
3044 /* */
3045 /* */
3046 /****************************************************************************/
3047 void eqt_sortBranch(eqt_node *node)
3048 {
3049 eqt_node **table;
3050 int size;
3051
3052 switch (node->TYPE)
3053 {
3054 case EQTBINOP_T :
3055 table = eqt_sortDoTable(node,0,&size);
3056 qsort(table,size,sizeof(eqt_node *),eqt_sortCompareNode);
3057 eqt_sortGetSortedNode(node,table);
3058 case EQTVARNAME_T : case EQTVALUE_T : case EQTUNOP_T :
3059 break;
3060 default :
3061 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
3062 // eqt_error(__func__);
3063 EXIT(0);
3064 }
3065 }
3066
3067 /*}}}************************************************************************/
3068 /*{{{ eqt_sortGetSortedNode() */
3069 /* */
3070 /* */
3071 /****************************************************************************/
3072 void eqt_sortGetSortedNode(eqt_node *node, eqt_node **table)
3073 {
3074 eqt_node *nodex;
3075 int i;
3076
3077 for (nodex = node, i = 0; nodex; nodex = Oper2(nodex), i ++)
3078 {
3079 if (!eqt_isLeaf(Oper2(nodex)))
3080 NewOper1(nodex,table[i]);
3081 else
3082 {
3083 long operator;
3084 double neutral;
3085
3086 NewOper1(nodex,table[i]);
3087 operator = Operator(nodex);
3088 neutral = eqt_get_neutral(operator);
3089 if (neutral >= 0.0 && !IsValue(table[i+1]))
3090 {
3091 eqt_node *tmp;
3092
3093 tmp = eqt_addbinarynode(operator,table[i+1],eqt_addvalue(neutral));
3094 NewOper2(nodex,tmp);
3095 }
3096 else
3097 NewOper2(nodex,table[i+1]);
3098 break;
3099 }
3100 }
3101 mbkfree(table);
3102 }
3103
3104 /*}}}************************************************************************/
3105 /*{{{ eqt_get_neutral() */
3106 /* */
3107 /* */
3108 /****************************************************************************/
3109 double eqt_get_neutral(long operator)
3110 {
3111 switch (operator)
3112 {
3113 case EQTPLUS : return 0.0;
3114 case EQTMULT : return 1.0;
3115 default : return -1.0;
3116 }
3117 }
3118
3119 /*}}}************************************************************************/
3120 /*{{{ eqt_sortDoTable() */
3121 /* */
3122 /* */
3123 /****************************************************************************/
3124 eqt_node **eqt_sortDoTable(eqt_node *node,int cpt,int *nb)
3125 {
3126 eqt_node **table;
3127
3128 if (eqt_isLeaf(node))
3129 if (cpt)
3130 {
3131 int eltsize = sizeof(eqt_node *);
3132
3133 table = (eqt_node**)mbkalloc((cpt+1)*eltsize);
3134 table[cpt] = node;
3135 *nb = cpt + 1;
3136 return table;
3137 }
3138 else
3139 return NULL;
3140 else
3141 {
3142 table = eqt_sortDoTable(Oper2(node),cpt+1,nb);
3143 eqt_sortBranch(Oper1(node));
3144 table[cpt] = Oper1(node);
3145 return table;
3146 }
3147 }
3148
3149 /*}}}************************************************************************/
3150 /*{{{ eqt_sortCompareNode() */
3151 /* */
3152 /* */
3153 /****************************************************************************/
3154 int eqt_sortCompareNode(const void *node1, const void *node2)
3155 {
3156 eqt_node *n1 = *(eqt_node **) node1;
3157 eqt_node *n2 = *(eqt_node **) node2;
3158 int leafres;
3159
3160 if (n1->TYPE == n2->TYPE)
3161 if (IsVarname(n1))
3162 return strcmp(Varname(n1),Varname(n2));
3163 else if (Operator (n1) != 0 && Operator(n1) == Operator(n2))
3164 if (IsVarname(Oper1(n1)))
3165 if (IsVarname(Oper1(n2)))
3166 return strcmp(Varname(Oper1(n1)),Varname(Oper1(n2)));
3167 else
3168 return -1;
3169 else if (IsVarname(Oper1(n2)))
3170 return 1;
3171 else
3172 return 0;
3173 else
3174 return 0;
3175 else if (IsValue(n1))
3176 return 1;
3177 else if (IsVarname(n1))
3178 return -1;
3179 else if ((leafres = eqt_isLeaf(n1)))
3180 if (IsVarname(n2))
3181 return 1;
3182 else
3183 return leafres;
3184 else if (IsVarname(n2))
3185 return 1;
3186 else if (IsValue(n2))
3187 return -1;
3188 else if ((leafres == -eqt_isLeaf(n2)))
3189 return leafres;
3190 else
3191 return (Operator(n1) - Operator(n2));
3192 }
3193
3194 /*}}}************************************************************************/
3195 /*{{{ eqt_associate() */
3196 /* */
3197 /* */
3198 /****************************************************************************/
3199 eqt_node *eqt_associate(eqt_node *node)
3200 {
3201 eqt_node *res, *father;
3202
3203 father = node->FATHER;
3204 switch (node->TYPE)
3205 {
3206 case EQTVALUE_T : case EQTVARNAME_T :
3207 return node;
3208 case EQTUNOP_T :
3209 NewOper(node,eqt_associate(Oper(node)));
3210 return node;
3211 case EQTBINOP_T:
3212 if (Operator(node) == EQTPLUS)
3213 {
3214 if (IsVarname(Oper1(node)))
3215 if (eqt_findSimpleAssoc(Oper2(node),Varname(Oper1(node)),1.0))
3216 {
3217 res = Oper2(node);
3218 res->FATHER = father;
3219 eqt_delnode(Oper1(node));
3220 eqt_delnode(node);
3221 node = eqt_associate(res);
3222 }
3223 else
3224 NewOper2(node,eqt_associate(Oper2(node)));
3225 else if (Operator(Oper1(node)) == EQTMIN
3226 && IsVarname(Oper(Oper1(node))))
3227 if (eqt_findSimpleAssoc(Oper2(node),
3228 Varname(Oper(Oper1(node))),-1.0))
3229 {
3230 res = Oper2(node);
3231 res->FATHER = father;
3232 eqt_delnode(Oper(Oper1(node)));
3233 eqt_delnode(Oper1(node));
3234 eqt_delnode(node);
3235 node = eqt_associate(res);
3236 }
3237 else
3238 {
3239 eqt_assocVar(node);
3240 NewOper2(node,eqt_associate(Oper2(node)));
3241 }
3242 else
3243 NewOper2(node,eqt_associate(Oper2(node)));
3244 }
3245 return node;
3246 default :
3247 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
3248 // eqt_error(__func__);
3249 return NULL;
3250 }
3251 }
3252
3253
3254 /*}}}************************************************************************/
3255 /*{{{ eqt_assocVar() */
3256 /* */
3257 /* */
3258 /****************************************************************************/
3259 void eqt_assocVar(eqt_node *node)
3260 {
3261 chain_list *var, *lastvar, *chainx;
3262 eqt_node *nodex, *next;
3263
3264 var = NULL;
3265 if (Operator(node) == EQTPLUS && Operator(Oper1(node)) == EQTMULT)
3266 {
3267 lastvar = NULL;
3268 for (nodex = node; Operator(nodex) == EQTPLUS; nodex = Oper2(nodex))
3269 {
3270 var = eqt_assocGetVar(Oper1(nodex));
3271 if (lastvar)
3272 for ( ; lastvar; lastvar = delchain(lastvar,lastvar))
3273 {
3274 for ( chainx = var; chainx; chainx = chainx->NEXT)
3275 if (lastvar->DATA == chainx->DATA)
3276 {
3277 next = nodex->FATHER;
3278 eqt_assocFather(nodex,chainx->DATA);
3279 nodex = next;
3280 var = delchain(var,chainx);
3281 break;
3282 }
3283 if (chainx)
3284 {
3285 freechain(lastvar);
3286 break;
3287 }
3288 }
3289 lastvar = var;
3290 }
3291 }
3292 freechain(var);
3293 }
3294
3295 /*}}}************************************************************************/
3296 /*{{{ eqt_assocFather() */
3297 /* */
3298 /* */
3299 /****************************************************************************/
3300 static void eqt_assocFather(eqt_node *node, char *var)
3301 {
3302 eqt_node *father;
3303
3304 father = node->FATHER;
3305 eqt_assocPutVarTop(node,var);
3306 eqt_assocPutVarTop(father,var);
3307 NewOper2(father,Oper2(node));
3308 NewOper2(node,Oper2(Oper1(node)));
3309 eqt_delnode(Oper1(Oper1(node)));
3310 eqt_delnode(Oper1(node));
3311 NewOper1(node,Oper2(Oper1(father)));
3312 NewOper2(Oper1(father),
3313 eqt_addbinarynode(EQTMULT,node,eqt_addvalue(1.0)));
3314 }
3315
3316 /*}}}************************************************************************/
3317 /*{{{ eqt_assocPutVarTop() */
3318 /* */
3319 /* */
3320 /****************************************************************************/
3321 static void eqt_assocPutVarTop(eqt_node *node,char *var)
3322 {
3323 eqt_node *nodex;
3324
3325 for (nodex = Oper1(node); Varname(Oper1(nodex))!= var; nodex = Oper2(nodex))
3326 ;
3327 if (nodex != Oper1(node))
3328 {
3329 NewOper2(nodex->FATHER,Oper2(nodex));
3330 NewOper2(nodex,Oper1(node));
3331 NewOper1(node,nodex);
3332 }
3333 }
3334
3335 /*}}}************************************************************************/
3336 /*{{{ eqt_assocGetVar() */
3337 /* */
3338 /* */
3339 /****************************************************************************/
3340 static chain_list *eqt_assocGetVar(eqt_node *node)
3341 {
3342 if (IsValue(node) || !IsVarname(Oper1(node)))
3343 return NULL;
3344 else
3345 return addchain(eqt_assocGetVar(Oper2(node)),Varname(Oper1(node)));
3346 }
3347
3348 /*}}}************************************************************************/
3349 /*{{{ eqt_findSimpleAssoc() */
3350 /* */
3351 /* */
3352 /****************************************************************************/
3353 int eqt_findSimpleAssoc(eqt_node *node, char* var, double nb)
3354 {
3355 int res;
3356
3357 if (IsValue(node))
3358 return 0;
3359 else if (eqt_isLeaf(Oper1(node)))
3360 {
3361 if (IsVarname(Oper1(node)))
3362 {
3363 if (Varname(Oper1(node)) == var)
3364 {
3365 NewOper2(node->FATHER,Oper2(node));
3366 eqt_delnode(Oper1(node));
3367 res = 1 + eqt_findSimpleAssoc(Oper2(node),var,nb+1.0);
3368 eqt_delnode(node);
3369 return res;
3370 }
3371 else
3372 return eqt_findSimpleAssoc(Oper2(node),var,nb);
3373 }
3374 else if (Operator(Oper1(node)) == EQTMIN)
3375 {
3376 if (IsVarname(Oper(Oper1(node)))
3377 && Varname(Oper(Oper1(node))) == var)
3378 {
3379 NewOper2(node->FATHER,Oper2(node));
3380 eqt_delnode(Oper(Oper1(node)));
3381 eqt_delnode(Oper1(node));
3382 res = 1 + eqt_findSimpleAssoc(Oper2(node),var,nb-1.0);
3383 eqt_delnode(node);
3384 return res;
3385 }
3386 else
3387 return eqt_findSimpleAssoc(Oper2(node),var,nb);
3388 }
3389 else
3390 return eqt_findSimpleAssoc(Oper2(node),var,nb);
3391 }
3392 else
3393 {
3394 eqt_node *tmp;
3395
3396 tmp = eqt_addbinarynode(EQTMULT,eqt_addvarname(var),eqt_addvalue(nb));
3397 eqt_insertOperation(node,tmp);
3398
3399 return 1;
3400 }
3401 }
3402
3403 /*}}}************************************************************************/
3404 /*{{{ eqt_insertOperation() */
3405 /* */
3406 /* */
3407 /****************************************************************************/
3408 eqt_node *eqt_insertOperation(eqt_node *node, eqt_node *operation)
3409 {
3410 eqt_node *tmp;
3411 eqt_node *father;
3412
3413 father = node->FATHER;
3414 if (IsVarname(Oper1(node)))
3415 NewOper2(node,eqt_insertOperation(Oper2(node),operation));
3416 else if (IsValue(node))
3417 node = eqt_addbinarynode(Operator(father),operation,node);
3418 else
3419 {
3420 tmp = eqt_addbinarynode(Operator(father),Oper1(node),Oper2(node));
3421 NewOper2(node,tmp);
3422 NewOper1(node,operation);
3423 }
3424
3425 return node;
3426 }
3427
3428 /*}}}************************************************************************/
3429 /*{{{ eqt_isRealLeaf() */
3430 /* */
3431 /* */
3432 /****************************************************************************/
3433 int eqt_isRealLeaf(eqt_node *node)
3434 {
3435 switch (node->TYPE)
3436 {
3437 case EQTVALUE_T : case EQTVARNAME_T :
3438 return 1;
3439 default :
3440 return 0;
3441 }
3442 }
3443
3444 /*}}}************************************************************************/
3445 /*{{{ eqt_invertChild() */
3446 /* */
3447 /* */
3448 /****************************************************************************/
3449 void eqt_invertChild(eqt_node *node)
3450 {
3451 eqt_node *node1;
3452
3453 switch (node->TYPE)
3454 {
3455 case EQTBINOP_T :
3456 node1 = Oper1(node);
3457 NewOper1(node,Oper2(node));
3458 NewOper2(node,node1);
3459 break;
3460 default :
3461 ;
3462 }
3463 }
3464
3465 /*}}}************************************************************************/
3466 /*{{{ eqt_isLeaf() */
3467 /* */
3468 /* */
3469 /****************************************************************************/
3470 int eqt_isLeaf(eqt_node *node)
3471 {
3472 switch (node->TYPE)
3473 {
3474 case EQTVALUE_T :
3475 return 1;
3476 case EQTVARNAME_T :
3477 return -1;
3478 case EQTUNOP_T :
3479 return eqt_isLeaf(Oper(node));
3480 default :
3481 return 0;
3482 }
3483 }
3484
3485 /*}}}************************************************************************/
3486 /*{{{ eqt_isOperand2() */
3487 /* */
3488 /* */
3489 /****************************************************************************/
3490 int eqt_isOperand2(eqt_node *node)
3491 {
3492 eqt_node *father = node->FATHER;
3493
3494 if (father)
3495 switch (node->TYPE)
3496 {
3497 case EQTUNOP_T :
3498 return 1;
3499 case EQTBINOP_T :
3500 return (Oper2(father) == node);
3501 default :
3502 return 0;
3503 }
3504 else
3505 return 0;
3506 }
3507
3508 /*}}}************************************************************************/
3509 /*{{{ eqt_getEvaluedEquation() */
3510 /* */
3511 /* */
3512 /****************************************************************************/
3513 char *eqt_getEvaluedEquation(eqt_ctx *ctx, char *equation)
3514 {
3515 eqt_node *node = NULL;
3516 char *res = NULL;
3517
3518 node = eqt_create(ctx, equation);
3519 if (!node)
3520 avt_errmsg(EQT_ERRMSG, "008", AVT_ERROR, __func__);
3521 // eqt_error(__func__);
3522 else
3523 {
3524 node = eqt_DelMinDiv(node);
3525 eqt_linearise(node);
3526 eqt_addNeutral(node);
3527 eqt_sortBranch(node);
3528 node = eqt_associate(node);
3529 eqt_assocVar(node);
3530 eqt_reduce(ctx, node);
3531 node = eqt_DelNeutral(node);
3532 res = eqt_ToIntStr(node);
3533 eqt_freenode(node);
3534 }
3535 return res;
3536 }
3537
3538 /*}}}************************************************************************/
3539 /*{{{ eqt_getSimpleEquation() */
3540 /* */
3541 /* */
3542 /****************************************************************************/
3543 char *eqt_getSimpleEquation(char *equation)
3544 {
3545 char *res = NULL;
3546 eqt_ctx *ctx;
3547
3548 ctx = eqt_init(EQT_NB_VARS);
3549 res = eqt_getEvaluedEquation(ctx, equation);
3550 eqt_term (ctx);
3551
3552 return res;
3553 }
3554
3555
3556 /*}}}************************************************************************/
3557
3558 static double sum (double p, double q)
3559 {
3560 return p + q ;
3561 }
3562
3563
3564 static double dmax(double p, double q)
3565 {
3566 double r ;
3567 if ( p >= q )
3568 r = p ;
3569 else
3570 r = q ;
3571 return r ;
3572 }
3573
3574 /******************************************************************************/
3575 /******************************************************************************/
3576 static double dmin(double p, double q)
3577 {
3578 double r ;
3579 if ( p <= q )
3580 r = p ;
3581 else
3582 r = q ;
3583 return r ;
3584 }
3585
3586 /******************************************************************************/
3587 /******************************************************************************/
3588 static double v2(double p, double q)
3589 {
3590 double r ;
3591 r = p - q ;
3592 return r ;
3593 }
3594
3595 /******************************************************************************/
3596 static double valif(double a, double b, double c)
3597 {
3598 return (int)(a + 0.5) ? b : c ;
3599 }
3600
3601 static double eqt_trunc(double val)
3602 {
3603 if (val>=0) return floor(val);
3604 return ceil(val);
3605 }
3606
3607 static double spi_trunc (double val)
3608 {
3609 return (double)(int)val;
3610 }
3611
3612 static double ppar (double val)
3613 {
3614 return val;
3615 }
3616
3617 static double eqt_sgn(double x)
3618 {
3619 if (x<0) return -1;
3620 if (x>0) return 1;
3621 return 0;
3622 }
3623
3624 static double eqt_pow(double x, double y)
3625 {
3626 return pow(x, eqt_trunc(y));
3627 }
3628
3629 static double eqt_pwr(double x, double y)
3630 {
3631 return copysign(pow(fabs(x), y), x);
3632 }
3633
3634 static double eqt_sign(double x, double y)
3635 {
3636 return copysign(x, y);
3637 }
3638 static double eqt_e(double a, double b)
3639 {
3640 return a*pow(10, b);
3641 }
3642
3643 static int doneseed=0, displayseed=1 ;
3644 static unsigned int eqt_seedp=0, eqt_seedp_save=0;
3645
3646 void eqt_srand(unsigned int seed)
3647 {
3648 eqt_seedp=seed;
3649 doneseed=1;
3650 }
3651
3652 void eqt_initseed(int mode, unsigned int value)
3653 {
3654 if (mode) eqt_seedp=mbk_get_a_seed();
3655 else eqt_seedp=value;
3656 displayseed=1;
3657 doneseed=1;
3658 eqt_seedp_save=eqt_seedp;
3659 }
3660 unsigned int eqt_getinitseed()
3661 {
3662 return eqt_seedp_save;
3663 }
3664
3665 static double ranf() /* ranf() is uniform in 0..1 */
3666 {
3667 if( !doneseed ) {
3668 eqt_initseed(1, 0);
3669 }
3670 if (displayseed)
3671 {
3672 char buf[256];
3673 sprintf(buf, "info:Main monte-carlo seed = %u", eqt_seedp);
3674 avt_log(-1, 0, "%s\n", &buf[5]);
3675 if (MBK_SOCK!=-1)
3676 mbk_sendmsg( MBK_COM_DATA, buf, strlen(buf)+1);
3677 displayseed=0;
3678 }
3679 EQT_GOT_RANDOM=1;
3680 return ((double)mbk_rand_r(&eqt_seedp) / (double)MBK_RAND_MAX);
3681 }
3682
3683 unsigned int eqt_get_current_srand_seed()
3684 {
3685 if (!doneseed)
3686 {
3687 eqt_initseed(1, 0) ;
3688 }
3689 return eqt_seedp;
3690 }
3691
3692 static double box_muller(double m, double s/*, double sigma_level*/) /* normal random variate generator */
3693 { /* mean m, standard deviation s */
3694 double x1, x2, w, y1;
3695 double d ;
3696 static double y2;
3697 static int use_last = 0;
3698 double r ;
3699
3700 if( V_BOOL_TAB[ __AVT_ENABLE_STAT ].VALUE ) {
3701 // s/=sigma_level;
3702 do
3703 {
3704 if (use_last) /* use value from previous call */
3705 {
3706 y1 = y2;
3707 use_last = 0;
3708 }
3709 else
3710 {
3711 do {
3712 x1 = 2.0 * ranf() - 1.0;
3713 x2 = 2.0 * ranf() - 1.0;
3714 w = x1 * x1 + x2 * x2;
3715 } while ( w >= 1.0 );
3716
3717 w = sqrt( (-2.0 * log( w ) ) / w );
3718 y1 = x1 * w;
3719 y2 = x2 * w;
3720 // commente pour que le seed fonctionne bien
3721 //use_last = 1;
3722 }
3723 } while (fabs(y1)>6);
3724 r = m + y1 * s ;
3725 if( V_INT_TAB[ __EQT_STATISTICAL_DISCRETISATION ].VALUE > 0 ) {
3726 d = 2*s/((double)V_INT_TAB[ __EQT_STATISTICAL_DISCRETISATION ].VALUE) ;
3727 r = d*floor( (r-(m-d/2.0))/d ) + m;
3728 /*
3729 if( r >= m-d/2 && r <= m+d/2 )
3730 r = m ;
3731 else {
3732 if( r>m )
3733 r = floor( ( r-(m+d/2) )/d )*d + (m+d/2.0) ;
3734 else
3735 r = ceil( ( r-(m-d/2) )/d )*d + (m-d/2.0) ;
3736 }
3737 */
3738 }
3739 }
3740 else
3741 r = m;
3742
3743 return r ;
3744 }
3745
3746 static double eqt_limit(double nom, double var)
3747 {
3748 if( V_BOOL_TAB[ __AVT_ENABLE_STAT ].VALUE ) {
3749 EQT_GOT_RANDOM=1;
3750 if (mbk_rand_r(&eqt_seedp)>MBK_RAND_MAX/2)
3751 return nom+var;
3752 else
3753 return nom-var;
3754 }
3755 return nom;
3756 }
3757
3758 static double eqt_unif(double nom, double rel)
3759 {
3760 if( V_BOOL_TAB[ __AVT_ENABLE_STAT ].VALUE ) {
3761 double a=nom*(1-rel), b=nom*(1+rel);
3762 return a+ranf()*(b-a);
3763 }
3764 return nom;
3765 }
3766
3767 static double eqt_aunif(double nom, double rel)
3768 {
3769 if( V_BOOL_TAB[ __AVT_ENABLE_STAT ].VALUE ) {
3770 double a=nom-rel, b=nom+rel;
3771 return a+ranf()*(b-a);
3772 }
3773 return nom;
3774 }
3775
3776 static double eqt_agauss(double m, double s, double sigma_level)
3777 {
3778 return box_muller(m, s/sigma_level);
3779 }
3780
3781 static double eqt_gauss(double m, double s, double sigma_level)
3782 {
3783 return box_muller(m, s*m/sigma_level);
3784 }
3785
3786 static double eqt_lognorm(double nom, double var, double sigma_level)
3787 {
3788 double m=log(nom), s=var*m/sigma_level;
3789 double u=nom*exp(s*s/2), sig=nom*sqrt(exp(2*s*s)-exp(s*s));
3790 return box_muller(u, sig);
3791 }
3792 static double eqt_alognorm(double nom, double var, double sigma_level)
3793 {
3794 double /*m=log(nom),*/ s=var/sigma_level;
3795 double u=nom*exp(s*s/2), sig=nom*sqrt(exp(2*s*s)-exp(s*s));
3796 return box_muller(u, sig);
3797 }
3798
3799 void eqt_add_spice_extension(eqt_ctx *ctx)
3800 {
3801 chain_list *cl;
3802
3803 eqt_addfunction3(ctx, "valif",&valif) ;
3804 eqt_addfunction2(ctx, "dmin",&dmin) ;
3805 eqt_addfunction2(ctx, "dmax",&dmax) ;
3806 eqt_addfunction2(ctx, "max",&dmax) ;
3807 eqt_addfunction2(ctx, "min",&dmin) ;
3808 eqt_addfunction2(ctx, "sum",&sum) ;
3809 // eqt_addfunction2(ctx, "v",&v2) ;
3810 eqt_addfunction (ctx, "trunc", &spi_trunc);
3811 eqt_addfunction (ctx, "int", &spi_trunc);
3812 eqt_addfunction (ctx, "ppar", &ppar);
3813
3814 eqt_addfunction(ctx, "sgn",&eqt_sgn) ;
3815 eqt_addfunction2(ctx, "pow",&eqt_pow) ;
3816 eqt_addfunction2(ctx, "pwr",&eqt_pwr) ;
3817 eqt_addfunction2(ctx, "sign",&eqt_sign) ;
3818
3819 cl=addchain(NULL, "c");
3820 cl=addchain(cl, "b");
3821 cl=addchain(cl, "a");
3822 eqt_adddotfunc(ctx, "symdistr", cl, "a-c*(b-a)");
3823 freechain(cl);
3824
3825 cl=addchain(NULL, "d");
3826 cl=addchain(cl, "c");
3827 cl=addchain(cl, "b");
3828 cl=addchain(cl, "a");
3829
3830 eqt_adddotfunc(ctx, "asymdistr", cl, "b+(1/(1+d*(c+a-2*b)/(c-a))-1)*2*(c-b)*(b-a)/(c+a-2*b)");
3831 eqt_adddotfunc(ctx, "skewcor", cl, "(d>0?1:0)*(b-a)*d+(d<=0?1:0)*(a-c)*d");
3832 eqt_adddotfunc(ctx, "distr", cl, "b+d*2*(c-b)*(a-b)/((c==b)||(b==a)||(c==a)?1:(c-a)+d*(c+a-2*b))");
3833 eqt_addfunction2(ctx, "limit",&eqt_limit) ;
3834 eqt_addfunction2(ctx, "e",&eqt_e) ;
3835 eqt_addfunction2(ctx, "aunif",&eqt_aunif) ;
3836 eqt_addfunction2(ctx, "unif",&eqt_unif) ;
3837 eqt_addfunction3(ctx, "gauss",&eqt_gauss) ;
3838 eqt_addfunction3(ctx, "agauss",&eqt_agauss) ;
3839 eqt_addfunction3(ctx, "alognorm",&eqt_alognorm) ;
3840 eqt_addfunction3(ctx, "lognorm",&eqt_lognorm) ;
3841
3842 freechain(cl);
3843
3844 ctx->USE_SPICE_UNITS = 1;
3845 }
3846
3847 void eqt_setspecialfunc(eqt_ctx *ctx, int index, double (*func)(char *var))
3848 {
3849 ctx->SPECIAL_FUNC[index]=func;
3850 }
3851
3852