1 /**************************/
3 /**************************/
4 /****************************************************************************/
6 /****************************************************************************/
17 /****************************************************************************/
19 /****************************************************************************/
22 #define __func__ "eqt_util"
25 /****************************************************************************/
27 /****************************************************************************/
51 eqt_ctx
*EQT_CONTEXT_HIERARCHY
[5]={NULL
, NULL
, NULL
, NULL
, NULL
};
52 ht
*eqt_ExprToNode
=NULL
;
55 extern int eqtparse();
56 //extern int eqtdebug;
57 eqt_ctx
*EQT_CTX
= NULL
;
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);
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
, ...);
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
);
119 /****************************************************************************/
120 /* functions for fast allocation */
121 /****************************************************************************/
123 static int EQT_GOT_RANDOM
=0;
124 static HeapAlloc
*eqt_heap
[7]={NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
126 /*char *eqt_lookup_expr(char *expr)
130 if (eqt_ExprToNode==NULL)
131 eqt_ExprToNode=addht(3000);
132 sn=sensitive_namealloc(expr);
136 static eqt_node
*eqt_loopup_node(eqt_ctx
*ctx
, char *expr
)
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
);
148 static int eqt_getheap_num(char what
)
151 if (eqt_heap
[0]==NULL
)
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]);
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;
177 void *eqt_alloc(char what
)
180 num
=eqt_getheap_num(what
);
181 return AddHeapItem(eqt_heap
[num
]);
184 void eqt_free(char what
, void *d
)
187 num
=eqt_getheap_num(what
);
188 DelHeapItem(eqt_heap
[num
], d
);
191 static long eqt_my_update(int nouveau
, long old_value
, void *my_data
)
196 *(double *)old_value
=*(double *)my_data
;
199 var_tmp
= eqt_alloc('d');
200 *var_tmp
=*(double *)my_data
;
201 return (long)var_tmp
;
204 /****************************************************************************/
206 /****************************************************************************/
208 /****************************************************************************/
212 /****************************************************************************/
213 void eqt_error(char *text
, ...)
218 fprintf(stderr
,"[EQT_ERR]");
222 vfprintf(stderr
,text
,arg
);
224 fprintf(stderr
,"\n");
229 /*}}}************************************************************************/
230 /*{{{ eqt_warning() */
233 /****************************************************************************/
234 void eqt_warning(char *text
, ...)
239 fprintf(stderr
,"[EQT_WAR]");
243 vfprintf(stderr
,text
,arg
);
245 fprintf(stderr
,"\n");
249 /*}}}************************************************************************/
250 /*{{{ eqt_set_father() */
253 /****************************************************************************/
254 void eqt_set_father(eqt_node
*child
, eqt_node
* father
)
257 child
->FATHER
= father
;
260 /*}}}************************************************************************/
264 /****************************************************************************/
265 static double Value(eqt_node
*node
)
267 return node
->UNODE
.VALUE
;
270 /*}}}************************************************************************/
274 /****************************************************************************/
275 static int IsValue(eqt_node
*node
)
277 return (node
->TYPE
== EQTVALUE_T
);
280 /*}}}************************************************************************/
284 /****************************************************************************/
285 static int IsVarname(eqt_node
*node
)
287 return (node
->TYPE
== EQTVARNAME_T
);
290 /*}}}************************************************************************/
294 /****************************************************************************/
295 static char *Varname(eqt_node
*node
)
297 if (node
->TYPE
== EQTVARNAME_T
)
298 return node
->UNODE
.VARNAME
;
303 /*}}}************************************************************************/
307 /****************************************************************************/
308 static eqt_node
*Oper1(eqt_node
*node
)
313 return node
->UNODE
.UNOP
->OPERAND
;
315 return node
->UNODE
.BINOP
->OPERAND1
;
317 return node
->UNODE
.TERNOP
->OPERAND1
;
323 /*}}}************************************************************************/
327 /****************************************************************************/
328 static eqt_node
*Oper2(eqt_node
*node
)
333 return node
->UNODE
.UNOP
->OPERAND
;
335 return node
->UNODE
.BINOP
->OPERAND2
;
337 return node
->UNODE
.TERNOP
->OPERAND2
;
343 /*}}}************************************************************************/
347 /****************************************************************************/
348 static eqt_node
*Oper3(eqt_node
*node
)
353 return node
->UNODE
.UNOP
->OPERAND
;
355 return node
->UNODE
.TERNOP
->OPERAND3
;
361 /*}}}************************************************************************/
365 /****************************************************************************/
366 static eqt_node
*Oper(eqt_node
*node
)
371 return node
->UNODE
.UNOP
->OPERAND
;
377 /*}}}************************************************************************/
381 /****************************************************************************/
382 static long Operator(eqt_node
*node
)
388 return node
->UNODE
.UNOP
->OPERATOR
;
390 return node
->UNODE
.BINOP
->OPERATOR
;
392 return node
->UNODE
.TERNOP
->OPERATOR
;
400 /*}}}************************************************************************/
401 /*{{{ NewVarname() */
404 /****************************************************************************/
405 static void NewVarname(eqt_node
*node
, char *varname
)
410 node
->UNODE
.VARNAME
= varname
;
414 /*}}}************************************************************************/
418 /****************************************************************************/
419 static void NewValue(eqt_node
*node
, double value
)
424 node
->UNODE
.VALUE
= value
;
426 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
427 // eqt_error(__func__);
430 /*}}}************************************************************************/
431 /*{{{ NewOperator() */
434 /****************************************************************************/
435 static void NewOperator(eqt_node
*node
, long operator)
441 node
->UNODE
.UNOP
->OPERATOR
= operator;
443 node
->UNODE
.BINOP
->OPERATOR
= operator;
445 node
->UNODE
.TERNOP
->OPERATOR
= operator;
451 /*}}}************************************************************************/
455 /****************************************************************************/
456 static void NewOper1(eqt_node
*node
,eqt_node
*n1
)
461 node
->UNODE
.TERNOP
->OPERAND1
= n1
;
462 eqt_set_father(n1
,node
);
465 node
->UNODE
.BINOP
->OPERAND1
= n1
;
466 eqt_set_father(n1
,node
);
475 /*}}}************************************************************************/
479 /****************************************************************************/
480 static void NewOper2(eqt_node
*node
,eqt_node
*n2
)
485 node
->UNODE
.TERNOP
->OPERAND2
= n2
;
486 eqt_set_father(n2
,node
);
489 node
->UNODE
.BINOP
->OPERAND2
= n2
;
490 eqt_set_father(n2
,node
);
499 /*}}}************************************************************************/
503 /****************************************************************************/
504 static void NewOper3(eqt_node
*node
,eqt_node
*n3
)
509 node
->UNODE
.TERNOP
->OPERAND3
= n3
;
510 eqt_set_father(n3
,node
);
519 /*}}}************************************************************************/
523 /****************************************************************************/
524 static void NewOper(eqt_node
*node
,eqt_node
*n
)
529 node
->UNODE
.UNOP
->OPERAND
= n
;
530 eqt_set_father(n
,node
);
536 /*}}}************************************************************************/
537 /*{{{ eqt_freenode() */
540 /****************************************************************************/
541 void eqt_freenode(eqt_node
*node
)
553 eqt_freenode(Oper(node
));
557 eqt_freenode(Oper1(node
));
558 eqt_freenode(Oper2(node
));
562 eqt_freenode(Oper1(node
));
563 eqt_freenode(Oper2(node
));
564 eqt_freenode(Oper3(node
));
570 for (cl
=node
->UNODE
.FUNCOP
->ARGS
; cl
!=NULL
; cl
=cl
->NEXT
)
571 eqt_freenode((eqt_node
*)cl
->DATA
);
577 /*}}}************************************************************************/
578 /*{{{ eqt_delnode() */
581 /****************************************************************************/
582 void eqt_delnode(eqt_node
*node
)
594 eqt_free('u',node
->UNODE
.UNOP
);
598 eqt_free('b',node
->UNODE
.BINOP
);
602 eqt_free('t',node
->UNODE
.TERNOP
);
606 freechain(node
->UNODE
.FUNCOP
->ARGS
);
612 /*}}}************************************************************************/
613 /*{{{ SubstN1ByN2() */
616 /****************************************************************************/
617 static void SubstN1ByN2(eqt_node
*n1
,eqt_node
*n2
, char mode
)
626 if (Oper(n1
) != n2
&& mode
== 'Y')
627 eqt_freenode(Oper(n1
));
628 eqt_free('u', n1
->UNODE
.UNOP
);
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
);
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
);
648 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
649 // eqt_error(__func__);
655 NewValue(n1
,Value(n2
));
658 NewVarname(n1
,Varname(n2
));
661 n1
->UNODE
.UNOP
= eqt_alloc('u');
662 NewOper(n1
,Oper(n2
));
665 n1
->UNODE
.UNOP
= eqt_alloc('b');
666 NewOper1(n1
,Oper1(n2
));
667 NewOper2(n1
,Oper2(n2
));
670 n1
->UNODE
.UNOP
= eqt_alloc('t');
671 NewOper1(n1
,Oper1(n2
));
672 NewOper2(n1
,Oper2(n2
));
673 NewOper3(n1
,Oper3(n2
));
677 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
678 // eqt_error(__func__);
683 /*}}}************************************************************************/
684 /*{{{ Basics allocations */
685 /****************************************************************************/
686 /*{{{ eqt_addvarname() */
689 /****************************************************************************/
690 eqt_node
*eqt_addvarname (char *name
)
694 new_node
= (eqt_node
*) eqt_alloc('n');
696 new_node
->TYPE
= EQTVARNAME_T
;
697 new_node
->UNODE
.VARNAME
= namealloc(name
);
698 new_node
->FATHER
= NULL
;
703 /*}}}************************************************************************/
704 /*{{{ eqt_addvalue() */
707 /****************************************************************************/
708 eqt_node
*eqt_addvalue (double value
)
712 new_node
= (eqt_node
*) eqt_alloc('n');
714 new_node
->TYPE
= EQTVALUE_T
;
715 new_node
->UNODE
.VALUE
= value
;
716 new_node
->FATHER
= NULL
;
721 /*}}}************************************************************************/
722 /*{{{ eqt_addunarynode() */
725 /****************************************************************************/
726 eqt_node
*eqt_addunarynode (long operator, eqt_node
*operand
)
728 eqt_unary
*unary_node
;
731 unary_node
= (eqt_unary
*) eqt_alloc('u');
732 unary_node
->OPERATOR
= operator;
733 unary_node
->OPERAND
= operand
;
735 new_node
= (eqt_node
*) eqt_alloc('n');
736 new_node
->TYPE
= EQTUNOP_T
;
737 new_node
->UNODE
.UNOP
= unary_node
;
739 new_node
->FATHER
= NULL
;
740 eqt_set_father (operand
,new_node
);
744 /*}}}************************************************************************/
745 /*{{{ eqt_addbinarynode() */
748 /****************************************************************************/
749 eqt_node
*eqt_addbinarynode (long operator, eqt_node
*operand1
,
752 eqt_binary
*binary_node
;
755 binary_node
= (eqt_binary
*) eqt_alloc('b');
756 binary_node
->OPERATOR
= operator;
757 binary_node
->OPERAND1
= operand1
;
758 binary_node
->OPERAND2
= operand2
;
760 new_node
= (eqt_node
*) eqt_alloc('n');
761 new_node
->TYPE
= EQTBINOP_T
;
762 new_node
->UNODE
.BINOP
= binary_node
;
764 eqt_set_father (operand1
,new_node
);
765 eqt_set_father (operand2
,new_node
);
766 new_node
->FATHER
= NULL
;
771 /*}}}************************************************************************/
772 /*{{{ eqt_addternarynode() */
775 /****************************************************************************/
776 eqt_node
*eqt_addternarynode (long operator, eqt_node
*operand1
,
777 eqt_node
*operand2
, eqt_node
*operand3
)
779 eqt_ternary
*ternary_node
;
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
;
788 new_node
= (eqt_node
*) eqt_alloc('n');
789 new_node
->TYPE
= EQTTERNOP_T
;
790 new_node
->UNODE
.TERNOP
= ternary_node
;
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
;
800 eqt_node
*eqt_adddotfuncnode (char *name
, chain_list
*args
)
806 ef
= (eqt_func
*) eqt_alloc('t');
807 ef
->ARGS
= dupchainlst(args
);
808 ef
->FUNCNAME
= namealloc(name
);
810 new_node
= (eqt_node
*) eqt_alloc('n');
811 new_node
->TYPE
= EQTDOTFUNC_T
;
812 new_node
->UNODE
.FUNCOP
= ef
;
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
;
821 /*}}}************************************************************************/
822 /*}}}************************************************************************/
826 /****************************************************************************/
827 eqt_node
*eqt_dup(eqt_node
*n
)
835 res
= eqt_addvalue(Value(n
));
838 res
= eqt_addvarname(Varname(n
));
841 res
= eqt_addunarynode(Operator(n
),
845 res
= eqt_addbinarynode(Operator(n
),
850 res
= eqt_addternarynode(Operator(n
),
856 res
= eqt_adddotfuncnode(n
->UNODE
.FUNCOP
->FUNCNAME
, n
->UNODE
.FUNCOP
->ARGS
);
859 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
860 // eqt_error(__func__);
866 /*}}}************************************************************************/
868 double eqt_calcval (eqt_ctx
*ctx
, eqt_node
*node
)
871 ctx
->EQT_RES_CALC
= EQT_COMPLETE
;
872 ctx
->EQT_VAR_INVOLVED
= 0;
874 val
=eqt_calcval_rec (ctx
, node
);
875 ctx
->EQT_GOT_RANDOM
=EQT_GOT_RANDOM
;
879 eqt_func_entry
*eqt_getdotfunc (eqt_ctx
*ctx
, char *name
)
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
;
888 double eqt_execdotfunc(eqt_ctx
*ctx
, char *funcname
, chain_list
*args
, int quick
)
893 double oldval
, newval
;
901 if ((efe
=eqt_getdotfunc(ctx
, funcname
))!=NULL
)
903 if (countchain(args
)!=countchain(efe
->ARGS
))
905 avt_errmsg(EQT_ERRMSG
, "009", AVT_ERROR
, efe
->FUNCNAME
);
906 ctx
->EQT_RES_CALC
= EQT_INCOMPLETE
;
907 ctx
->FAULTY_VAR
= funcname
;
910 for (cl
=args
, ch
=efe
->ARGS
, i
=0; cl
!=NULL
; cl
=cl
->NEXT
, ch
=ch
->NEXT
, i
++)
913 savevar
[i
].newval
=eqt_calcval_rec(ctx
, (eqt_node
*)cl
->DATA
);
915 savevar
[i
].newval
=*(double *)cl
->DATA
;
917 if ((l
=gethtitem (ctx
->VAR_HT
, ch
->DATA
))!=EMPTYHT
)
918 savevar
[i
].oldval
=*(long *)l
, savevar
[i
].set
=1;
922 for (ch
=efe
->ARGS
, i
=0; ch
!=NULL
; ch
=ch
->NEXT
, i
++)
924 eqt_addvar(ctx
, (char *)ch
->DATA
, savevar
[i
].newval
);
927 value
=eqt_calcval_rec(ctx
, efe
->NODE_EXPR
);
929 for (ch
=efe
->ARGS
, i
=0; ch
!=NULL
; ch
=ch
->NEXT
, i
++)
932 eqt_addvar(ctx
, (char *)ch
->DATA
, savevar
[i
].oldval
);
934 delhtitem(ctx
->VAR_HT
, ch
->DATA
);
940 if (!quick
) avt_errmsg(EQT_ERRMSG
, "010", AVT_ERROR
, funcname
);
941 ctx
->EQT_RES_CALC
= EQT_INCOMPLETE
;
942 ctx
->FAULTY_VAR
= funcname
;
946 double eqt_execfunc123(eqt_ctx
*ctx
, int index
, void *arg1
, void *arg2
, void *arg3
, int quick
)
949 if ((eqt_getdotfunc(ctx
, ctx
->NAMETAB
[index
]))!=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
);
961 res
= ctx
->FUNCTAB3
[index
](*(double *)arg1
, *(double *)arg2
, *(double *)arg3
) ;
963 res
= ctx
->FUNCTAB2
[index
](*(double *)arg1
, *(double *)arg2
) ;
965 res
= ctx
->FUNCTAB
[index
](*(double *)arg1
) ;
967 avt_errmsg(EQT_ERRMSG
, "008", AVT_FATAL
, __func__
);
971 /****************************************************************************/
972 /*{{{ eqt_calcval_rec() */
975 /****************************************************************************/
976 double eqt_calcval_rec (eqt_ctx
*ctx
, eqt_node
*node
)
978 double arg1
, arg2
, arg3
;
984 return (Value(node
));
986 if (node
->TYPE
== EQTVARNAME_T
)
987 return (__eqt_getvar (ctx
, node
->UNODE
.VARNAME
, 0, 0));
989 if (node
->TYPE
== EQTUNOP_T
)
990 switch (op
=(Operator(node
) & 0xff))
993 return (double)(!(int)eqt_calcval_rec(ctx
, Oper(node
)) + 0.5);
995 return -eqt_calcval_rec(ctx
, Oper(node
));
997 return sqrt (eqt_calcval_rec(ctx
, Oper(node
)));
999 return exp (eqt_calcval_rec(ctx
, Oper(node
)));
1001 return log (eqt_calcval_rec(ctx
, Oper(node
)));
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)));
1007 return sin (eqt_calcval_rec(ctx
, Oper(node
)));
1009 return cos (eqt_calcval_rec(ctx
, Oper(node
)));
1011 return tan (eqt_calcval_rec(ctx
, Oper(node
)));
1013 return asin (eqt_calcval_rec(ctx
, Oper(node
)));
1015 return acos (eqt_calcval_rec(ctx
, Oper(node
)));
1017 return atan (eqt_calcval_rec(ctx
, Oper(node
)));
1019 return sinh (eqt_calcval_rec(ctx
, Oper(node
)));
1021 return cosh (eqt_calcval_rec(ctx
, Oper(node
)));
1023 return tanh (eqt_calcval_rec(ctx
, Oper(node
)));
1025 return log10(eqt_calcval_rec(ctx
, Oper(node
)));
1027 return ceil (eqt_calcval_rec(ctx
, Oper(node
)));
1029 return floor(eqt_calcval_rec(ctx
, Oper(node
)));
1031 return fabs (eqt_calcval_rec(ctx
, Oper(node
)));
1033 return fabs (eqt_calcval_rec(ctx
, Oper(node
)));
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
));
1041 return 1.0 / (eqt_calcval_rec(ctx
, Oper(node
)));
1044 if (node
->TYPE
== EQTBINOP_T
)
1045 switch (Operator(node
) & 0xff)
1048 return (double)((int)(eqt_calcval_rec(ctx
, Oper1(node
)) + 0.5)
1049 ^ (int)(eqt_calcval_rec(ctx
, Oper2(node
)) + 0.5));
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));
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));
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));
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));
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));
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));
1069 return (double)((int)(eqt_calcval_rec(ctx
, Oper1(node
)) + 0.5)
1070 || (int)(eqt_calcval_rec(ctx
, Oper2(node
)) + 0.5));
1072 return (double)((int)(eqt_calcval_rec(ctx
, Oper1(node
)) + 0.5)
1073 && (int)(eqt_calcval_rec(ctx
, Oper2(node
)) + 0.5));
1075 return (eqt_calcval_rec(ctx
, Oper1(node
))
1076 + eqt_calcval_rec(ctx
, Oper2(node
)));
1078 return (eqt_calcval_rec(ctx
, Oper1(node
))
1079 - eqt_calcval_rec(ctx
, Oper2(node
)));
1081 return (eqt_calcval_rec(ctx
, Oper1(node
))
1082 * eqt_calcval_rec(ctx
, Oper2(node
)));
1084 return (eqt_calcval_rec(ctx
, Oper1(node
))
1085 / eqt_calcval_rec(ctx
, Oper2(node
)));
1087 return pow(eqt_calcval_rec(ctx
, Oper1(node
)),
1088 eqt_calcval_rec(ctx
, Oper2(node
)));
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)));*/
1097 return atan2(eqt_calcval_rec(ctx
, Oper1(node
)),
1098 eqt_calcval_rec(ctx
, Oper2(node
)));
1101 if (node
->TYPE
== EQTTERNOP_T
)
1102 switch (node
->UNODE
.TERNOP
->OPERATOR
& 0xff)
1105 if (mbk_long_round(eqt_calcval_rec(ctx
, node
->UNODE
.TERNOP
->OPERAND1
))!=0)
1106 return eqt_calcval_rec(ctx
, node
->UNODE
.TERNOP
->OPERAND2
);
1108 return eqt_calcval_rec(ctx
, node
->UNODE
.TERNOP
->OPERAND3
);
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));*/
1120 if (node
->TYPE
== EQTDOTFUNC_T
)
1122 return eqt_execdotfunc(ctx
, node
->UNODE
.FUNCOP
->FUNCNAME
, node
->UNODE
.FUNCOP
->ARGS
, 0);
1127 /*}}}************************************************************************/
1128 /*{{{ eqt_reduce() */
1131 /* Warning node destroyed after effect */
1132 /****************************************************************************/
1133 void eqt_reduce(eqt_ctx
*ctx
, eqt_node
*node
)
1135 eqt_node
*n
, *n1
, *n2
;
1136 double res
, arg1
, arg2
;
1144 EvalVarname(ctx
, node
);
1147 eqt_reduce (ctx
, Oper(node
));
1149 if (IsValue(n
= Oper(node
)))
1151 switch (Operator(node
) & 0xff)
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;
1159 res
=eqt_execfunc123(ctx
, Operator(node
) >> 8, &arg1
, NULL
, NULL
, 1);
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;
1179 avt_errmsg(EQT_ERRMSG
, "008", AVT_FATAL
, __func__
);
1185 eqt_reduce (ctx
, Oper1(node
));
1186 eqt_reduce (ctx
, Oper2(node
));
1190 if ((IsValue(n1
)) && (IsValue(n2
)))
1192 switch (Operator(node
) & 0xff)
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;
1202 res
=eqt_execfunc123(ctx
, Operator(node
) >> 8, &arg1
, &arg2
, NULL
, 1);
1204 // res = ctx->FUNCTAB2[Operator(node) >> 8](Value(n1),Value(n2));break;
1205 case EQTATAN2
: res
= atan2((Value(n1
)), (Value(n2
)));break;
1208 SubstN1ByN2(node
,n1
,'Y');
1211 switch (Operator(node
))
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');
1224 n
= eqt_addunarynode(EQTINV
,n2
);
1225 NewOper2(node
,NULL
);
1226 SubstN1ByN2(node
,n
,'Y');
1228 else if (eqt_isOne(n2
))
1229 SubstN1ByN2(node
,n1
,'Y');
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
))))
1239 n
= Oper2(Oper2(node
));
1240 NewOper2(Oper2(node
),NULL
);
1241 SubstN1ByN2(node
,n2
,'Y');
1248 avt_errmsg(EQT_ERRMSG
, "004", AVT_ERROR
, __func__
);
1249 // eqt_error("%s : can't be done yet on ternary operators",__func__);
1253 /*}}}************************************************************************/
1254 /*{{{ EvalVarname() */
1257 /****************************************************************************/
1258 static void EvalVarname(eqt_ctx
*ctx
, eqt_node
*node
)
1262 if (node
&& IsVarname(node
))
1264 value
= gethtitem(ctx
->VAR_HT
, /*namealloc (*/Varname(node
)/*)*/);
1265 if ((value
!= EMPTYHT
) && (value
!= DELETEHT
))
1267 node
->TYPE
= EQTVALUE_T
;
1268 NewValue(node
,*((double*)value
));
1273 /*}}}************************************************************************/
1274 /*{{{ eqt_isZero() */
1277 /****************************************************************************/
1278 int eqt_isZero(eqt_node
*node
)
1280 return (IsValue(node
) && Value(node
) == 0.0);
1283 /*}}}************************************************************************/
1284 /*{{{ eqt_isOne() */
1287 /****************************************************************************/
1288 int eqt_isOne(eqt_node
*node
)
1290 return (IsValue(node
) && Value(node
) == 1.0);
1293 /*}}}************************************************************************/
1294 /*{{{ print_space() */
1297 /****************************************************************************/
1298 void print_space(int space
)
1302 for (i
= 0; i
< space
; i
++)
1303 fprintf(stdout
,"¦ ");
1306 /*}}}************************************************************************/
1307 /*{{{ eqt_initSpaceII() */
1310 /****************************************************************************/
1311 void eqt_initSpaceII(char *EQT_PRINTYES
)
1315 for (i
= 0; i
< 256; i
++ )
1316 EQT_PRINTYES
[i
] = 0;
1319 /*}}}************************************************************************/
1320 /*{{{ print_spaceII() */
1323 /****************************************************************************/
1324 void print_spaceII(char *EQT_PRINTYES
, int space
)
1328 for (i
= 0; i
< space
; i
++)
1329 fprintf(stdout
,"%c ",EQT_PRINTYES
[i
] ? ' ' : '¦');
1332 /*}}}************************************************************************/
1333 /*{{{ eqt_print() */
1336 /****************************************************************************/
1337 void eqt_print(eqt_ctx
*ctx
, eqt_node
*node
)
1339 int nb_space
= 0, op
;
1342 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
1343 // eqt_error("%s : Noeud vide",__func__);
1348 print_space(nb_space
);
1349 fprintf (stdout
," %5g\n", (Value(node
))); nb_space
++;
1352 print_space(nb_space
);
1353 fprintf (stdout
," %5s\n", (node
->UNODE
.VARNAME
));
1356 switch (op
=(Operator(node
) & 0xff))
1359 print_space(nb_space
);
1360 fprintf(stdout
, "! \n");
1362 eqt_print(ctx
, Oper(node
));
1365 print_space(nb_space
);
1366 fprintf(stdout
, "- \n");
1368 eqt_print(ctx
, Oper(node
));
1371 print_space(nb_space
);
1372 fprintf(stdout
, "SQRT \n");
1374 eqt_print(ctx
, Oper(node
));
1377 print_space(nb_space
);
1378 fprintf(stdout
, "EXP \n");
1380 eqt_print(ctx
, Oper(node
));
1383 print_space(nb_space
);
1384 fprintf(stdout
, "LOG \n");
1386 eqt_print(ctx
, Oper(node
));
1389 print_space(nb_space
);
1390 fprintf(stdout
, "%5s \n", ctx
->NAMETAB
[Operator(node
) >> 8]);
1392 eqt_print(ctx
, Oper(node
));
1395 print_space(nb_space
);
1396 fprintf(stdout
, "SIN \n");
1398 eqt_print(ctx
, Oper(node
));
1401 print_space(nb_space
);
1402 fprintf(stdout
, "COS \n");
1404 eqt_print(ctx
, Oper(node
));
1407 print_space(nb_space
);
1408 fprintf(stdout
, "TAN \n");
1410 eqt_print(ctx
, Oper(node
));
1413 print_space(nb_space
);
1414 fprintf(stdout
, "ASIN \n");
1416 eqt_print(ctx
, Oper(node
));
1419 print_space(nb_space
);
1420 fprintf(stdout
, "ACOS \n");
1422 eqt_print(ctx
, Oper(node
));
1425 print_space(nb_space
);
1426 fprintf(stdout
, "ATAN \n");
1428 eqt_print(ctx
, Oper(node
));
1431 print_space(nb_space
);
1432 fprintf(stdout
, "SINH \n");
1434 eqt_print(ctx
, Oper(node
));
1437 print_space(nb_space
);
1438 fprintf(stdout
, "COSH \n");
1440 eqt_print(ctx
, Oper(node
));
1443 print_space(nb_space
);
1444 fprintf(stdout
, "TANH \n");
1446 eqt_print(ctx
, Oper(node
));
1449 print_space(nb_space
);
1450 fprintf(stdout
, "LOG10 \n");
1452 eqt_print(ctx
, Oper(node
));
1455 print_space(nb_space
);
1456 fprintf(stdout
, "CEIL \n");
1458 eqt_print(ctx
, Oper(node
));
1461 print_space(nb_space
);
1462 fprintf(stdout
, "FLOOR \n");
1464 eqt_print(ctx
, Oper(node
));
1467 print_space(nb_space
);
1468 fprintf(stdout
, "FABS \n");
1470 eqt_print(ctx
, Oper(node
));
1473 print_space(nb_space
);
1474 fprintf(stdout
, "ABS \n");
1476 eqt_print(ctx
, Oper(node
));
1481 print_space(nb_space
);
1482 fprintf(stdout
, "%s(%s) \n", EQTSPECFUNC_NAME(op
), Varname(Oper(node
)));
1487 switch (Operator(node
) & 0xff)
1490 print_space(nb_space
);
1491 fprintf(stdout
, " + \n");
1492 eqt_print(ctx
, Oper1(node
));
1494 eqt_print(ctx
, Oper2(node
));
1497 print_space(nb_space
);
1498 fprintf(stdout
, " - \n");
1500 eqt_print(ctx
, Oper1(node
));
1501 eqt_print(ctx
, Oper2(node
));
1504 print_space(nb_space
);
1505 fprintf(stdout
, " * \n");
1506 nb_space
++ ; eqt_print(ctx
, Oper1(node
));
1507 eqt_print(ctx
, Oper2(node
));
1510 print_space(nb_space
);
1511 fprintf(stdout
, " / \n");
1513 eqt_print(ctx
, Oper1(node
));
1514 eqt_print(ctx
, Oper2(node
));
1517 print_space(nb_space
);
1518 fprintf(stdout
, " ^ \n");
1520 eqt_print(ctx
, Oper1(node
)),
1521 eqt_print(ctx
, Oper2(node
));
1524 print_space(nb_space
);
1525 fprintf(stdout
, "%5s \n", ctx
->NAMETAB
[Operator(node
) >> 8]);
1527 eqt_print(ctx
, Oper1(node
)) ,
1528 eqt_print(ctx
, Oper2(node
));
1531 print_space(nb_space
);
1532 fprintf(stdout
, " ATAN2 \n");
1534 eqt_print(ctx
, Oper1(node
));
1535 eqt_print(ctx
, Oper2(node
));
1539 switch (node
->UNODE
.TERNOP
->OPERATOR
& 0xff)
1542 print_space(nb_space
);
1543 fprintf(stdout
, "%5s \n", ctx
->NAMETAB
[node
->UNODE
.TERNOP
->OPERATOR
>> 8]);
1545 eqt_print(ctx
, node
->UNODE
.TERNOP
->OPERAND1
) ,
1546 eqt_print(ctx
, node
->UNODE
.TERNOP
->OPERAND2
) ,
1547 eqt_print(ctx
, node
->UNODE
.TERNOP
->OPERAND3
);
1554 print_space(nb_space
);
1555 fprintf(stdout
, "%5s \n",node
->UNODE
.FUNCOP
->FUNCNAME
);
1557 for (cl
=node
->UNODE
.FUNCOP
->ARGS
; cl
!=NULL
; cl
=cl
->NEXT
)
1558 eqt_print(ctx
, (eqt_node
*)cl
->DATA
);
1565 /*}}}************************************************************************/
1566 /****************************************************************************/
1568 int eqt_parse (eqt_ctx
*ctx
)
1573 // eqtrestart(NULL);
1575 EQT_CTX
->EQUA_NODE
=NULL
;
1583 eqt_node
*eqt_create (eqt_ctx
*ctx
, char *equa
)
1585 ctx
->EQT_MODE_CHOICE
= EQTNORMAL
;
1588 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
1589 // eqt_error(__func__);
1593 ctx
->EQUA_STR
= equa
;
1596 return ctx
->EQUA_NODE
;
1599 /****************************************************************************/
1600 void eqt_resetvars(eqt_ctx
*ctx
, int nbvars
)
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
);
1612 delht (ctx
->VAR_HT
);
1613 ctx
->VAR_HT
=addht(nbvars
);
1617 resetht(ctx
->VAR_HT
);
1623 void eqt_term (eqt_ctx
*ctx
)
1628 eqt_func_entry
*efe
;
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
);
1637 delht (ctx
->VAR_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
);
1645 delht (ctx
->UNIT_HT
);
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
);
1657 /****************************************************************************/
1659 eqt_ctx
*eqt_init (int nbvars
)
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
;
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
;
1676 ctx
->FUNCTIONS
=NULL
;
1681 /****************************************************************************/
1683 long eqt_dup_ctx_fn( long value
, void *unused
)
1687 pt
= eqt_alloc('d');
1688 *pt
= *((double*)value
);
1694 eqt_ctx
*eqt_dup_ctx (eqt_ctx
*ctx
)
1699 eqt_func_entry
*efe
;
1701 if (!ctx
) return NULL
;
1703 dupctx
= (eqt_ctx
*) eqt_alloc('c');
1705 dupctx
->EQUA_NODE
= NULL
;
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
;
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
];
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
);
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
);
1734 dupctx
->UNIT_HT
= NULL
;
1736 dupctx
->USE_SPICE_UNITS
=ctx
->USE_SPICE_UNITS
;
1741 /****************************************************************************/
1743 extern void eqt_free_param (eqt_param
*param
)
1746 mbkfree (param
->EBI
);
1747 // mbkfree (param->VAL);
1752 /****************************************************************************/
1753 chain_list
*eqt_export_func(chain_list
*old
, eqt_ctx
*ctx
)
1755 chain_list
*cl
, *ch
, *pold
=old
;
1756 eqt_func_entry
*efe
;
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
) ;
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
);
1770 void eqt_import_func(chain_list
*old
, eqt_ctx
*ctx
)
1772 chain_list
*cl
, *ch
;
1773 eqt_func_entry
*efe
;
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
) ;
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
);
1787 extern eqt_param
*eqt_export_vars (eqt_ctx
*ctx
)
1790 eqt_param
*param
= NULL
;
1791 chain_list
*head
, *chain
;
1795 head
= GetAllHTElems( ctx
->VAR_HT
);
1796 for( chain
= head
; chain
; chain
= chain
->NEXT
) j
++ ;
1800 param
= (eqt_param
*)mbkalloc (sizeof (struct eqt_param
));
1801 param
->EBI
= mbkalloc ( j
* sizeof (eqt_biinfo
));
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
;
1810 scanhtkey( ctx
->VAR_HT
, 0, &nextkey
, &nextitem
);
1816 eqt_param
*eqt_dupvars (eqt_param
*sourceparam
)
1818 eqt_param
*param
=NULL
;
1820 if (sourceparam
!=NULL
&& sourceparam
->NUMBER
!=0)
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
));
1831 /****************************************************************************/
1833 void eqt_import_vars (eqt_ctx
*to
, eqt_param
*from
)
1838 for (i
= 0; i
< from
->NUMBER
; i
++) eqt_addimportedvar (to
, from
->EBI
[i
].NAME
, from
->EBI
[i
].VAL
);
1841 void eqt_display_vars (eqt_param
*params
)
1845 if (!params
) return;
1846 for (i
= 0; i
< params
->NUMBER
; i
++) printf("%s = %g\n", params
->EBI
[i
].NAME
, params
->EBI
[i
].VAL
);
1849 /****************************************************************************/
1851 void eqt_addunit (eqt_ctx
*ctx
, char *unit_name
, double factor
)
1855 downstr (unit_name
, buf
);
1857 controlled_addhtitem(ctx
->UNIT_HT
, c
, eqt_my_update
, (void *)&factor
);
1861 /****************************************************************************/
1863 double eqt_getunit (eqt_ctx
*ctx
, char *unit_name
)
1869 if (!unit_name
) return 1;
1872 downstr (unit_name
, buf
);
1874 htfactor
= gethtitem (ctx
->UNIT_HT
, namealloc (buf
));
1876 if (ctx
->USE_SPICE_UNITS
&& htfactor
==EMPTYHT
)
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
;
1883 if ((htfactor
!= EMPTYHT
) && (htfactor
!= DELETEHT
))
1884 return *(double*)htfactor
;
1886 avt_errmsg(EQT_ERRMSG
, "001", AVT_ERROR
, unit_name
);
1887 //fprintf (stderr, "[EQT WAR] Unknown unit '%s'\n", unit_name);
1892 /****************************************************************************/
1894 void eqt_addvar (eqt_ctx
*ctx
, char *var_name
, double value
)
1899 controlled_addhtitem(ctx
->VAR_HT
, name
, eqt_my_update
, (void *)&value
);
1902 /****************************************************************************/
1903 static void eqt_addimportedvar (eqt_ctx
*ctx
, char *var_name
, double value
)
1905 controlled_addhtitem(ctx
->VAR_HT
, var_name
, eqt_my_update
, (void *)&value
);
1908 /****************************************************************************/
1909 inline double __eqt_getvar (eqt_ctx
*ctx
, char *var_name
, int usenamealloc
, int ctxonly
)
1914 ctx
->EQT_VAR_INVOLVED
= 1;
1916 if (usenamealloc
) var_name
=namealloc(var_name
);
1920 for (i
=0; i
<5 && EQT_CONTEXT_HIERARCHY
[i
]!=NULL
; i
++)
1922 htvalue
= gethtitem (EQT_CONTEXT_HIERARCHY
[i
]->VAR_HT
, var_name
);
1923 if ((htvalue
!= EMPTYHT
) && (htvalue
!= DELETEHT
))
1924 return(*(double*)htvalue
);
1927 htvalue
= gethtitem (ctx
->VAR_HT
, var_name
);
1929 if ((htvalue
!= EMPTYHT
) && (htvalue
!= DELETEHT
))
1930 return(*(double*)htvalue
);
1932 ctx
->EQT_RES_CALC
= EQT_INCOMPLETE
;
1933 ctx
->FAULTY_VAR
= var_name
;
1937 int eqt_isdefined(eqt_ctx
*ctx
, char *varname
, int global
)
1943 for (i
=0; i
<5 && EQT_CONTEXT_HIERARCHY
[i
]!=NULL
; i
++)
1945 htvalue
= gethtitem (EQT_CONTEXT_HIERARCHY
[i
]->VAR_HT
, varname
);
1946 if ((htvalue
!= EMPTYHT
) && (htvalue
!= DELETEHT
))
1950 if (ctx
==NULL
) return 0;
1951 return gethtitem(ctx
->VAR_HT
, varname
)!=EMPTYHT
;
1954 double eqt_getvar (eqt_ctx
*ctx
, char *var_name
)
1956 return __eqt_getvar (ctx
, var_name
, 1, 0);
1958 double eqt_getvar_in_context_only (eqt_ctx
*ctx
, char *var_name
)
1960 return __eqt_getvar (ctx
, var_name
, 1, 1);
1963 /****************************************************************************/
1965 double eqt_eval (eqt_ctx
*ctx
, char *equa
, int choix
)
1970 ctx
->EQT_MODE_CHOICE
= choix
;
1971 n
= eqt_loopup_node(ctx
, equa
);
1973 d
= eqt_calcval (ctx
, n
);
1975 avt_errmsg(EQT_ERRMSG
, "002", AVT_ERROR
, equa
);
1978 switch (ctx
->EQT_MODE_CHOICE
) {
1980 // n = eqt_create (ctx, equa);
1981 n
= eqt_loopup_node(equa
);
1983 d
= eqt_calcval (ctx
, n
);
1984 // eqt_freenode (n);
1987 avt_errmsg(EQT_ERRMSG
, "002", AVT_ERROR
, equa
);
1988 // eqt_error("%s : can't evaluate '%s'",__func__,equa);
1991 ctx
->EQUA_STR
= equa
;
1992 ctx
->EQT_RES_CALC
= EQT_COMPLETE
;
1993 ctx
->EQT_VAR_INVOLVED
= 0;
1995 if (eqt_parse (ctx
) == 0)
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);
2008 /****************************************************************************/
2010 int eqt_resistrue (eqt_ctx
*ctx
)
2012 return ctx
->EQT_RES_CALC
== EQT_COMPLETE
? 1 : 0;
2015 int eqt_resisrandom (eqt_ctx
*ctx
)
2017 return ctx
->EQT_GOT_RANDOM
!=0;
2019 void eqt_set_failedres (eqt_ctx
*ctx
)
2021 ctx
->EQT_RES_CALC
=EQT_INCOMPLETE
;
2024 /****************************************************************************/
2026 int eqt_var_involved (eqt_ctx
*ctx
)
2028 return ctx
->EQT_VAR_INVOLVED
;
2031 /****************************************************************************/
2033 void eqt_addfunction (eqt_ctx
*ctx
, char *name
, double (*function
) (double))
2035 if (ctx
->EQTINDEX
>= EQTMAXNFUNC
)
2037 avt_errmsg(EQT_ERRMSG
, "003", AVT_WARNING
);
2038 // eqt_warning("too much user defined functions");
2041 ctx
->NAMETAB
[ctx
->EQTINDEX
] = namealloc (name
);
2042 ctx
->FUNCTAB
[ctx
->EQTINDEX
] = function
;
2046 /****************************************************************************/
2048 int eqt_getindex (eqt_ctx
*ctx
, char *name
)
2052 for (i
= 0 ; i
< EQTMAXNFUNC
; i
++)
2054 if (ctx
->NAMETAB
[i
] == name
)
2062 /****************************************************************************/
2064 void eqt_addfunction2 (eqt_ctx
*ctx
, char *name
, double (*function
) (double, double))
2066 if (ctx
->EQTINDEX
>= EQTMAXNFUNC
)
2068 avt_errmsg(EQT_ERRMSG
, "003", AVT_WARNING
);
2069 // eqt_warning("too much user defined functions");
2072 ctx
->NAMETAB
[ctx
->EQTINDEX
] = namealloc (name
);
2073 ctx
->FUNCTAB2
[ctx
->EQTINDEX
] = function
;
2077 /****************************************************************************/
2079 void eqt_addfunction3 (eqt_ctx
*ctx
, char *name
, double (*function
) (double, double, double))
2081 if (ctx
->EQTINDEX
>= EQTMAXNFUNC
)
2083 avt_errmsg(EQT_ERRMSG
, "003", AVT_WARNING
);
2084 // eqt_warning("too much user defined functions");
2087 ctx
->NAMETAB
[ctx
->EQTINDEX
] = namealloc (name
);
2088 ctx
->FUNCTAB3
[ctx
->EQTINDEX
] = function
;
2092 int eqt_adddotfunc (eqt_ctx
*ctx
, char *name
, chain_list
*args
, char *expr
)
2094 eqt_func_entry
*efe
;
2097 name
=namealloc(name
);
2098 for (cl
=ctx
->FUNCTIONS
; cl
!=NULL
&& ((eqt_func_entry
*)cl
->DATA
)->FUNCNAME
!=name
; cl
=cl
->NEXT
) ;
2101 efe
=(eqt_func_entry
*)cl
->DATA
;
2102 eqt_freenode(efe
->NODE_EXPR
);
2103 freechain(efe
->ARGS
);
2107 efe
=(eqt_func_entry
*)eqt_alloc('f');
2108 ctx
->FUNCTIONS
=addchain(ctx
->FUNCTIONS
, efe
);
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
);
2118 /****************************************************************************/
2119 chain_list
*eqt_NodeToAbl(eqt_node
*node
)
2126 avt_errmsg(EQT_ERRMSG
, "005", AVT_ERROR
);
2127 // eqt_error("empty node can't make ABL");
2131 if (IsValue(node
)) {
2132 value
= (int)(Value(node
));
2134 abl
= createAtom ( "'0'" );
2135 else if ( value
== 1 )
2136 abl
= createAtom ( "'1'" );
2138 avt_errmsg(EQT_ERRMSG
, "006", AVT_ERROR
);
2139 // eqt_error("eqt error: integer value in ABL to make");
2145 if (node
->TYPE
== EQTVARNAME_T
) {
2146 abl
= createAtom ( node
->UNODE
.VARNAME
);
2150 if (node
->TYPE
== EQTUNOP_T
)
2151 switch (Operator(node
) & 0xff) {
2153 abl
= notExpr ( eqt_NodeToAbl (Oper(node
) ) );
2158 if (node
->TYPE
== EQTBINOP_T
)
2159 switch (Operator(node
) & 0xff) {
2162 abl
= createBinExpr ( OR
,
2163 eqt_NodeToAbl (Oper1(node
)) ,
2164 eqt_NodeToAbl (Oper2(node
)) );
2169 abl
= createBinExpr ( AND
,
2170 eqt_NodeToAbl ( Oper1(node
) ),
2171 eqt_NodeToAbl ( Oper2(node
) ));
2176 abl
= createBinExpr ( XOR
,
2177 eqt_NodeToAbl ( Oper1(node
) ),
2178 eqt_NodeToAbl ( Oper2(node
) ));
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__);
2189 /****************************************************************************/
2190 chain_list
*eqt_StrToAbl(eqt_ctx
*ctx
, char *str
)
2195 node
= eqt_create (ctx
, str
);
2197 avt_errmsg(EQT_ERRMSG
, "007", AVT_ERROR
);
2198 // eqt_error("node NULL");
2202 abl
= eqt_NodeToAbl ( node
);
2203 eqt_freenode( node
);
2208 /****************************************************************************/
2209 /* FUNCTION : eqt_ReduceSpace */
2210 /* Object : reduce all consecutive white space in a string */
2211 /****************************************************************************/
2212 char *eqt_ReduceSpace(char *str
)
2215 char finalbuf
[1024];
2216 char flag
= 'N' ; /* space flag */
2220 sprintf(initbuf
,"%s",str
);
2221 length
= strlen(str
);
2223 for (i
= 0; i
< length
; i
++)
2225 if ((initbuf
[i
]) != ' ')
2227 finalbuf
[j
] = initbuf
[i
];
2231 else if ((initbuf
[i
]) == ' ' && flag
== 'N')
2233 finalbuf
[j
] = initbuf
[i
];
2240 return mbkstrdup(finalbuf
);
2243 /****************************************************************************/
2244 /* FUNCTION : eqt_IsSpecialCar */
2245 /* Object : Test if the car is special */
2246 /****************************************************************************/
2247 int eqt_IsSpecialCar(char str
, char pos
)
2249 /* pos : D = Droite de l espace */
2250 /* pos : G = Gauche de l espace */
2254 if ((str
== '(') && (pos
== 'D'))
2256 else if ((str
== ')') && (pos
== 'G'))
2258 else if ((str
== '!') && (pos
== 'D'))
2260 else if ((str
== '~') && (pos
== 'D'))
2262 else if ((str
== '\'') && (pos
== 'G'))
2264 else if (isalnum((int)str
) != 0) {
2271 /****************************************************************************/
2272 /* FUNCTION : eqt_ConvertStr */
2273 /* Object : Replace the good white space by a '&' car */
2274 /****************************************************************************/
2275 char *eqt_ConvertStr(char *str
)
2277 char *string
, *sreduce
;
2282 sreduce
= eqt_ReduceSpace ( str
);
2284 string
= (char*)mbkalloc ((2*strlen(pt
))+1);
2286 while ( *pt
!= '\0' ) {
2288 case ' ' : res1
= eqt_IsSpecialCar(*(pt
-1),'G');
2289 res2
= eqt_IsSpecialCar(*(pt
+1),'D');
2294 case '!' : if (pt
>sreduce
) {
2295 res1
= eqt_IsSpecialCar(*(pt
-1),'G');
2296 res2
= eqt_IsSpecialCar(*(pt
+1),'D');
2298 if (((res1
==4)||(res1
==2)) && ((res2
==4)||(res2
==1))) {
2299 *ptres
= '&'; ptres
++;
2304 case '\'' : if (*(pt
+1) != '\0') {
2305 res1
= eqt_IsSpecialCar(*(pt
-1),'G');
2306 res2
= eqt_IsSpecialCar(*(pt
+1),'D');
2308 if (((res1
==4)||(res1
==2)) && ((res2
==4)||(res2
==1))) {
2309 *ptres
= *pt
; ptres
++;
2314 default : *ptres
= *pt
;
2326 /*{{{ eqt_get_brother() */
2329 /****************************************************************************/
2330 eqt_node
*eqt_get_brother(eqt_node
*node
)
2332 eqt_node
*father
= node
->FATHER
;
2334 if (father
->TYPE
== EQTBINOP_T
)
2336 if (Oper2(father
) == node
)
2337 return Oper1(father
);
2339 return Oper2(father
);
2345 /*}}}************************************************************************/
2346 /*{{{ eqt_adopt_brother() */
2349 /****************************************************************************/
2350 void eqt_adopt_brother(eqt_node
*node
,eqt_node
*brother
)
2352 eqt_node
*father
= node
->FATHER
;
2354 if (father
->TYPE
== EQTBINOP_T
)
2356 if (Oper2(father
) == node
)
2357 NewOper1(father
,brother
);
2359 NewOper2(father
,brother
);
2363 /*}}}************************************************************************/
2364 /*{{{ eqt_DelMinDiv() */
2367 /****************************************************************************/
2368 eqt_node
*eqt_DelMinDiv(eqt_node
*node
)
2372 case EQTVALUE_T
: case EQTVARNAME_T
:
2375 if (IsValue(Oper(node
)) && Operator(node
) == EQTMIN
)
2379 res
= eqt_NegNode(Oper(node
));
2384 NewOper(node
,eqt_DelMinDiv(Oper(node
)));
2387 if (Operator(node
) == EQTMIN
)
2389 NewOperator(node
,EQTPLUS
);
2390 NewOper2(node
,eqt_NegNode(Oper2(node
)));
2392 else if (Operator(node
) == EQTDIV
)
2394 NewOperator(node
,EQTMULT
);
2395 NewOper2(node
,eqt_InvNode(Oper2(node
)));
2397 NewOper1(node
,eqt_DelMinDiv(Oper1(node
)));
2398 NewOper2(node
,eqt_DelMinDiv(Oper2(node
)));
2403 /*}}}************************************************************************/
2404 /*{{{ eqt_NegNode() */
2407 /****************************************************************************/
2408 eqt_node
*eqt_NegNode(eqt_node
*node
)
2413 node
->UNODE
.VALUE
= -(Value(node
));
2416 return eqt_addunarynode(EQTMIN
,node
);
2418 if (Operator(node
) == EQTMIN
)
2428 NewOper(node
,eqt_NegNode(Oper(node
)));
2432 switch (Operator(node
))
2435 NewOperator(node
,EQTPLUS
);
2436 NewOper1(node
,eqt_NegNode(Oper1(node
)));
2439 NewOper2(node
,eqt_NegNode(Oper2(node
)));
2440 NewOper1(node
,eqt_NegNode(Oper1(node
)));
2443 if (IsValue(Oper1(node
)))
2444 NewOper1(node
,eqt_NegNode(Oper1(node
)));
2446 NewOper2(node
,eqt_NegNode(Oper2(node
)));
2449 NewOper1(node
,eqt_NegNode(Oper1(node
)));
2455 /*}}}************************************************************************/
2456 /*{{{ eqt_InvNode() */
2459 /****************************************************************************/
2460 eqt_node
*eqt_InvNode(eqt_node
*node
)
2465 if (Value(node
) == 1.0)
2468 return eqt_addunarynode(EQTINV
,node
);
2470 if (Operator(node
) == EQTINV
)
2480 NewOper(node
,eqt_InvNode(Oper(node
)));
2484 if (Operator(node
) == EQTDIV
)
2486 NewOper1(node
,eqt_InvNode(Oper1(node
)));
2487 NewOperator(node
,EQTMULT
);
2489 else if (Operator(node
) == EQTMULT
)
2491 NewOper1(node
,eqt_InvNode(Oper1(node
)));
2492 NewOper2(node
,eqt_InvNode(Oper2(node
)));
2495 node
= eqt_addunarynode(EQTINV
,node
);
2500 /*}}}************************************************************************/
2501 /*{{{ eqt_DelNeutral() */
2504 /****************************************************************************/
2505 eqt_node
*eqt_DelNeutral(eqt_node
*node
)
2508 eqt_node
*res
, *father
;
2510 father
= node
->FATHER
;
2513 case EQTVALUE_T
: case EQTVARNAME_T
:
2516 if (Operator(node
) == EQTMIN
)
2518 else if (Operator(node
) == EQTINV
)
2523 && IsValue(Oper(node
)) && Value(Oper(node
)) == neutral
)
2526 res
->FATHER
= father
;
2529 return eqt_DelNeutral(res
);
2531 NewOper(node
,eqt_DelNeutral(Oper(node
)));
2535 if (Operator(node
) == EQTPLUS
)
2537 else if (Operator(node
) == EQTMULT
)
2543 if ( IsValue(Oper1(node
)) && Value(Oper1(node
)) == neutral
)
2546 res
->FATHER
= father
;
2547 eqt_delnode(Oper1(node
));
2550 return eqt_DelNeutral(res
);
2551 // NewOper2(node,NULL);
2552 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2556 // negative form of neutral element
2557 else if ( IsValue(Oper1(node
)) && Value(Oper1(node
)) == -neutral
)
2559 res
= eqt_NegNode(Oper2(node
));
2560 res
->FATHER
= father
;
2561 eqt_delnode(Oper1(node
));
2564 return eqt_DelNeutral(res
);
2565 // NewOper2(node,NULL);
2566 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2570 else if ( IsValue(Oper2(node
)) && Value(Oper2(node
)) == neutral
)
2573 res
->FATHER
= father
;
2574 eqt_delnode(Oper2(node
));
2577 return eqt_DelNeutral(res
);
2578 // NewOper1(node,NULL);
2579 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2583 // negative form of neutral element
2584 else if ( IsValue(Oper2(node
)) && Value(Oper2(node
)) == -neutral
)
2586 res
= eqt_NegNode(Oper1(node
));
2587 res
->FATHER
= father
;
2588 eqt_delnode(Oper2(node
));
2591 return eqt_DelNeutral(res
);
2592 // NewOper1(node,NULL);
2593 // SubstN1ByN2(node,eqt_DelNeutral(res),'Y');
2598 NewOper1(node
,eqt_DelNeutral(Oper1(node
)));
2599 NewOper2(node
,eqt_DelNeutral(Oper2(node
)));
2605 /*}}}************************************************************************/
2606 /*{{{ eqt_ToStr() */
2609 /****************************************************************************/
2610 char *eqt_ToStr(eqt_node
*node
)
2613 char *operand1
, *operand2
, *operator;
2616 par
= eqt_needParenthesis(node
);
2621 sprintf(buf
,"(%g)",Value(node
));
2623 sprintf(buf
,"%g",Value(node
));
2624 return mbkstrdup(buf
);
2626 sprintf(buf
,"%s",node
->UNODE
.VARNAME
);
2627 return mbkstrdup(buf
);
2629 operator = eqt_operToStr(Operator(node
));
2630 operand1
= eqt_ToStr(Oper(node
));
2634 sprintf(buf
,"%s(%s)",operator,operand1
);
2637 sprintf(buf
,"(%s%s)",operator,operand1
);
2640 sprintf(buf
,"%s%s",operator,operand1
);
2645 return mbkstrdup(buf
);
2647 if (Operator(node
) == EQTPLUS
&& IsNeg(Oper2(node
)))
2648 operator = mbkstrdup("");
2650 operator = eqt_operToStr(Operator(node
));
2651 operand2
= eqt_ToStr(Oper2(node
));
2652 operand1
= eqt_ToStr(Oper1(node
));
2654 sprintf(buf
,"(%s%s%s)",operand1
,operator,operand2
);
2656 sprintf(buf
,"%s%s%s",operand1
,operator,operand2
);
2660 return mbkstrdup(buf
);
2665 static chain_list
*__eqt_GetVariables(eqt_ctx
*ctx
, eqt_node
*node
, chain_list
*list
, int all
)
2674 for (cl
=list
; cl
!=NULL
&& cl
->DATA
!=node
->UNODE
.VARNAME
; cl
=cl
->NEXT
) ;
2677 if (all
|| !eqt_isdefined(ctx
, node
->UNODE
.VARNAME
, 1))
2678 list
=addchain(list
, node
->UNODE
.VARNAME
);
2682 list
= __eqt_GetVariables(ctx
, Oper(node
), list
, all
);
2686 if (eqt_getdotfunc(ctx
, node
->UNODE
.FUNCOP
->FUNCNAME
)==NULL
)
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
);
2691 for (cl
=node
->UNODE
.FUNCOP
->ARGS
; cl
!=NULL
; cl
=cl
->NEXT
)
2692 list
=__eqt_GetVariables(ctx
, (eqt_node
*)cl
->DATA
, list
, all
);
2696 list
= __eqt_GetVariables(ctx
, Oper3(node
), list
, all
);
2698 list
= __eqt_GetVariables(ctx
, Oper2(node
), list
, all
);
2699 list
= __eqt_GetVariables(ctx
, Oper1(node
), list
, all
);
2705 chain_list
*eqt_GetVariables(eqt_ctx
*ctx
, char *equa
, int all
)
2708 chain_list
*cl
=NULL
;
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);
2718 /*}}}************************************************************************/
2719 /*{{{ eqt_ToIntStr() */
2722 /****************************************************************************/
2723 char *eqt_ToIntStr(eqt_node
*node
)
2726 char *operand1
, *operand2
, *operator;
2729 par
= eqt_needParenthesis(node
);
2734 sprintf(buf
,"(%ld)",(long)Value(node
));
2736 sprintf(buf
,"%ld",(long)Value(node
));
2737 return mbkstrdup(buf
);
2739 sprintf(buf
,"%s",node
->UNODE
.VARNAME
);
2740 return mbkstrdup(buf
);
2742 operator = eqt_operToStr(Operator(node
));
2743 operand1
= eqt_ToIntStr(Oper(node
));
2747 sprintf(buf
,"%s(%s)",operator,operand1
);
2750 sprintf(buf
,"(%s%s)",operator,operand1
);
2753 sprintf(buf
,"%s%s",operator,operand1
);
2758 return mbkstrdup(buf
);
2760 if (Operator(node
) == EQTPLUS
&& IsNeg(Oper2(node
)))
2761 operator = mbkstrdup("");
2763 operator = eqt_operToStr(Operator(node
));
2764 operand2
= eqt_ToIntStr(Oper2(node
));
2765 operand1
= eqt_ToIntStr(Oper1(node
));
2767 sprintf(buf
,"(%s%s%s)",operand1
,operator,operand2
);
2769 sprintf(buf
,"%s%s%s",operand1
,operator,operand2
);
2773 return mbkstrdup(buf
);
2777 /*}}}************************************************************************/
2781 /****************************************************************************/
2782 static int IsNeg(eqt_node
*node
)
2787 return (Value(node
) < 0.0);
2789 return (Operator(node
) == EQTMIN
);
2795 /*}}}************************************************************************/
2796 /*{{{ eqt_needParenthesis() */
2799 /****************************************************************************/
2800 int eqt_needParenthesis(eqt_node
*node
)
2804 father
= node
->FATHER
;
2808 switch (Operator(node
))
2811 if (Operator(father
) == EQTPLUS
)
2819 switch (Operator(node
))
2821 case EQTMULT
: case EQTDIV
:
2826 switch (Operator(father
))
2829 return eqt_isOperand2(node
);
2833 return (Operator(father
) != Operator(node
));
2839 if (Operator(father
) == EQTPLUS
)
2842 return (Value(node
) < 0.0);
2848 return (node
== NULL
);
2851 /*}}}************************************************************************/
2852 /*{{{ eqt_drive() */
2855 /****************************************************************************/
2856 void eqt_drive(eqt_node
*node
)
2860 str
= eqt_ToStr(node
);
2861 fprintf(stdout
,"%s\n",str
);
2865 /*}}}************************************************************************/
2866 /*{{{ eqt_operToStr() */
2869 /****************************************************************************/
2870 char *eqt_operToStr(long operator)
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");
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("");
2903 /*}}}************************************************************************/
2904 /*{{{ eqt_linearise() */
2906 /* return invert child */
2907 /****************************************************************************/
2908 int eqt_linearise(eqt_node
*node
)
2914 case EQTVALUE_T
: case EQTVARNAME_T
: case EQTUNOP_T
:
2917 eqt_linearise(Oper1(node
));
2918 if ( (father
= node
->FATHER
) )
2920 if ( Operator(father
) == Operator(node
) )
2922 if (! eqt_isOperand2(node
) )
2924 NewOper1(father
, Oper1(node
));
2925 NewOper1(node
, Oper2(father
));
2926 eqt_invertChild(node
);
2927 NewOper2(father
,node
);
2928 eqt_linearise(Oper1(node
));
2932 else if ( eqt_isOperand2(node
) )
2934 eqt_invertChild(father
);
2940 eqt_linearise(Oper2(node
));
2943 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
2944 // eqt_error(__func__);
2949 /*}}}************************************************************************/
2950 /*{{{ eqt_addNeutral() */
2953 /****************************************************************************/
2954 int eqt_addNeutral(eqt_node
*node
)
2956 eqt_node
*nodex
, *father
, *neutral
;
2961 case EQTVALUE_T
: case EQTVARNAME_T
: case EQTUNOP_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
))
2970 neutral
= eqt_getNeutralNode(operator);
2971 father
= nodex
->FATHER
;
2973 NewOper2(father
,eqt_addbinarynode(operator,nodex
,neutral
));
2981 /*}}}************************************************************************/
2982 /*{{{ eqt_getNeutralNode() */
2985 /****************************************************************************/
2986 static eqt_node
*eqt_getNeutralNode(int operator)
2988 return eqt_addvalue(eqt_get_neutral(operator));
2991 /*}}}************************************************************************/
2992 /*{{{ eqt_printTree() */
2995 /****************************************************************************/
2996 void eqt_printTree(eqt_node
*node
,int deep
)
2999 char EQT_PRINTYES
[255];
3002 eqt_initSpaceII(EQT_PRINTYES
);
3006 fprintf(stdout
," %g\n",Value(node
));
3009 fprintf(stdout
," %s\n",Varname(node
));
3012 operator = eqt_operToStr(Operator(node
));
3013 fprintf(stdout
,"(%s)\n",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;
3022 operator = eqt_operToStr(Operator(node
));
3023 fprintf(stdout
,"(%s)\n",operator);
3025 print_spaceII(EQT_PRINTYES
, deep
);
3026 if (eqt_isRealLeaf(Oper1(node
)))
3027 fprintf(stdout
,"+--1:");
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:");
3036 fprintf(stdout
,"`-+2:");
3037 eqt_printTree(Oper2(node
),deep
+1);
3038 EQT_PRINTYES
[deep
] = 0;
3042 /*}}}************************************************************************/
3043 /*{{{ eqt_sortBranch() */
3046 /****************************************************************************/
3047 void eqt_sortBranch(eqt_node
*node
)
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
:
3061 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
3062 // eqt_error(__func__);
3067 /*}}}************************************************************************/
3068 /*{{{ eqt_sortGetSortedNode() */
3071 /****************************************************************************/
3072 void eqt_sortGetSortedNode(eqt_node
*node
, eqt_node
**table
)
3077 for (nodex
= node
, i
= 0; nodex
; nodex
= Oper2(nodex
), i
++)
3079 if (!eqt_isLeaf(Oper2(nodex
)))
3080 NewOper1(nodex
,table
[i
]);
3086 NewOper1(nodex
,table
[i
]);
3087 operator = Operator(nodex
);
3088 neutral
= eqt_get_neutral(operator);
3089 if (neutral
>= 0.0 && !IsValue(table
[i
+1]))
3093 tmp
= eqt_addbinarynode(operator,table
[i
+1],eqt_addvalue(neutral
));
3094 NewOper2(nodex
,tmp
);
3097 NewOper2(nodex
,table
[i
+1]);
3104 /*}}}************************************************************************/
3105 /*{{{ eqt_get_neutral() */
3108 /****************************************************************************/
3109 double eqt_get_neutral(long operator)
3113 case EQTPLUS
: return 0.0;
3114 case EQTMULT
: return 1.0;
3115 default : return -1.0;
3119 /*}}}************************************************************************/
3120 /*{{{ eqt_sortDoTable() */
3123 /****************************************************************************/
3124 eqt_node
**eqt_sortDoTable(eqt_node
*node
,int cpt
,int *nb
)
3128 if (eqt_isLeaf(node
))
3131 int eltsize
= sizeof(eqt_node
*);
3133 table
= (eqt_node
**)mbkalloc((cpt
+1)*eltsize
);
3142 table
= eqt_sortDoTable(Oper2(node
),cpt
+1,nb
);
3143 eqt_sortBranch(Oper1(node
));
3144 table
[cpt
] = Oper1(node
);
3149 /*}}}************************************************************************/
3150 /*{{{ eqt_sortCompareNode() */
3153 /****************************************************************************/
3154 int eqt_sortCompareNode(const void *node1
, const void *node2
)
3156 eqt_node
*n1
= *(eqt_node
**) node1
;
3157 eqt_node
*n2
= *(eqt_node
**) node2
;
3160 if (n1
->TYPE
== n2
->TYPE
)
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
)));
3169 else if (IsVarname(Oper1(n2
)))
3175 else if (IsValue(n1
))
3177 else if (IsVarname(n1
))
3179 else if ((leafres
= eqt_isLeaf(n1
)))
3184 else if (IsVarname(n2
))
3186 else if (IsValue(n2
))
3188 else if ((leafres
== -eqt_isLeaf(n2
)))
3191 return (Operator(n1
) - Operator(n2
));
3194 /*}}}************************************************************************/
3195 /*{{{ eqt_associate() */
3198 /****************************************************************************/
3199 eqt_node
*eqt_associate(eqt_node
*node
)
3201 eqt_node
*res
, *father
;
3203 father
= node
->FATHER
;
3206 case EQTVALUE_T
: case EQTVARNAME_T
:
3209 NewOper(node
,eqt_associate(Oper(node
)));
3212 if (Operator(node
) == EQTPLUS
)
3214 if (IsVarname(Oper1(node
)))
3215 if (eqt_findSimpleAssoc(Oper2(node
),Varname(Oper1(node
)),1.0))
3218 res
->FATHER
= father
;
3219 eqt_delnode(Oper1(node
));
3221 node
= eqt_associate(res
);
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))
3231 res
->FATHER
= father
;
3232 eqt_delnode(Oper(Oper1(node
)));
3233 eqt_delnode(Oper1(node
));
3235 node
= eqt_associate(res
);
3240 NewOper2(node
,eqt_associate(Oper2(node
)));
3243 NewOper2(node
,eqt_associate(Oper2(node
)));
3247 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
3248 // eqt_error(__func__);
3254 /*}}}************************************************************************/
3255 /*{{{ eqt_assocVar() */
3258 /****************************************************************************/
3259 void eqt_assocVar(eqt_node
*node
)
3261 chain_list
*var
, *lastvar
, *chainx
;
3262 eqt_node
*nodex
, *next
;
3265 if (Operator(node
) == EQTPLUS
&& Operator(Oper1(node
)) == EQTMULT
)
3268 for (nodex
= node
; Operator(nodex
) == EQTPLUS
; nodex
= Oper2(nodex
))
3270 var
= eqt_assocGetVar(Oper1(nodex
));
3272 for ( ; lastvar
; lastvar
= delchain(lastvar
,lastvar
))
3274 for ( chainx
= var
; chainx
; chainx
= chainx
->NEXT
)
3275 if (lastvar
->DATA
== chainx
->DATA
)
3277 next
= nodex
->FATHER
;
3278 eqt_assocFather(nodex
,chainx
->DATA
);
3280 var
= delchain(var
,chainx
);
3295 /*}}}************************************************************************/
3296 /*{{{ eqt_assocFather() */
3299 /****************************************************************************/
3300 static void eqt_assocFather(eqt_node
*node
, char *var
)
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)));
3316 /*}}}************************************************************************/
3317 /*{{{ eqt_assocPutVarTop() */
3320 /****************************************************************************/
3321 static void eqt_assocPutVarTop(eqt_node
*node
,char *var
)
3325 for (nodex
= Oper1(node
); Varname(Oper1(nodex
))!= var
; nodex
= Oper2(nodex
))
3327 if (nodex
!= Oper1(node
))
3329 NewOper2(nodex
->FATHER
,Oper2(nodex
));
3330 NewOper2(nodex
,Oper1(node
));
3331 NewOper1(node
,nodex
);
3335 /*}}}************************************************************************/
3336 /*{{{ eqt_assocGetVar() */
3339 /****************************************************************************/
3340 static chain_list
*eqt_assocGetVar(eqt_node
*node
)
3342 if (IsValue(node
) || !IsVarname(Oper1(node
)))
3345 return addchain(eqt_assocGetVar(Oper2(node
)),Varname(Oper1(node
)));
3348 /*}}}************************************************************************/
3349 /*{{{ eqt_findSimpleAssoc() */
3352 /****************************************************************************/
3353 int eqt_findSimpleAssoc(eqt_node
*node
, char* var
, double nb
)
3359 else if (eqt_isLeaf(Oper1(node
)))
3361 if (IsVarname(Oper1(node
)))
3363 if (Varname(Oper1(node
)) == var
)
3365 NewOper2(node
->FATHER
,Oper2(node
));
3366 eqt_delnode(Oper1(node
));
3367 res
= 1 + eqt_findSimpleAssoc(Oper2(node
),var
,nb
+1.0);
3372 return eqt_findSimpleAssoc(Oper2(node
),var
,nb
);
3374 else if (Operator(Oper1(node
)) == EQTMIN
)
3376 if (IsVarname(Oper(Oper1(node
)))
3377 && Varname(Oper(Oper1(node
))) == var
)
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);
3387 return eqt_findSimpleAssoc(Oper2(node
),var
,nb
);
3390 return eqt_findSimpleAssoc(Oper2(node
),var
,nb
);
3396 tmp
= eqt_addbinarynode(EQTMULT
,eqt_addvarname(var
),eqt_addvalue(nb
));
3397 eqt_insertOperation(node
,tmp
);
3403 /*}}}************************************************************************/
3404 /*{{{ eqt_insertOperation() */
3407 /****************************************************************************/
3408 eqt_node
*eqt_insertOperation(eqt_node
*node
, eqt_node
*operation
)
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
);
3420 tmp
= eqt_addbinarynode(Operator(father
),Oper1(node
),Oper2(node
));
3422 NewOper1(node
,operation
);
3428 /*}}}************************************************************************/
3429 /*{{{ eqt_isRealLeaf() */
3432 /****************************************************************************/
3433 int eqt_isRealLeaf(eqt_node
*node
)
3437 case EQTVALUE_T
: case EQTVARNAME_T
:
3444 /*}}}************************************************************************/
3445 /*{{{ eqt_invertChild() */
3448 /****************************************************************************/
3449 void eqt_invertChild(eqt_node
*node
)
3456 node1
= Oper1(node
);
3457 NewOper1(node
,Oper2(node
));
3458 NewOper2(node
,node1
);
3465 /*}}}************************************************************************/
3466 /*{{{ eqt_isLeaf() */
3469 /****************************************************************************/
3470 int eqt_isLeaf(eqt_node
*node
)
3479 return eqt_isLeaf(Oper(node
));
3485 /*}}}************************************************************************/
3486 /*{{{ eqt_isOperand2() */
3489 /****************************************************************************/
3490 int eqt_isOperand2(eqt_node
*node
)
3492 eqt_node
*father
= node
->FATHER
;
3500 return (Oper2(father
) == node
);
3508 /*}}}************************************************************************/
3509 /*{{{ eqt_getEvaluedEquation() */
3512 /****************************************************************************/
3513 char *eqt_getEvaluedEquation(eqt_ctx
*ctx
, char *equation
)
3515 eqt_node
*node
= NULL
;
3518 node
= eqt_create(ctx
, equation
);
3520 avt_errmsg(EQT_ERRMSG
, "008", AVT_ERROR
, __func__
);
3521 // eqt_error(__func__);
3524 node
= eqt_DelMinDiv(node
);
3525 eqt_linearise(node
);
3526 eqt_addNeutral(node
);
3527 eqt_sortBranch(node
);
3528 node
= eqt_associate(node
);
3530 eqt_reduce(ctx
, node
);
3531 node
= eqt_DelNeutral(node
);
3532 res
= eqt_ToIntStr(node
);
3538 /*}}}************************************************************************/
3539 /*{{{ eqt_getSimpleEquation() */
3542 /****************************************************************************/
3543 char *eqt_getSimpleEquation(char *equation
)
3548 ctx
= eqt_init(EQT_NB_VARS
);
3549 res
= eqt_getEvaluedEquation(ctx
, equation
);
3556 /*}}}************************************************************************/
3558 static double sum (double p
, double q
)
3564 static double dmax(double p
, double q
)
3574 /******************************************************************************/
3575 /******************************************************************************/
3576 static double dmin(double p
, double q
)
3586 /******************************************************************************/
3587 /******************************************************************************/
3588 static double v2(double p
, double q
)
3595 /******************************************************************************/
3596 static double valif(double a
, double b
, double c
)
3598 return (int)(a
+ 0.5) ? b
: c
;
3601 static double eqt_trunc(double val
)
3603 if (val
>=0) return floor(val
);
3607 static double spi_trunc (double val
)
3609 return (double)(int)val
;
3612 static double ppar (double val
)
3617 static double eqt_sgn(double x
)
3624 static double eqt_pow(double x
, double y
)
3626 return pow(x
, eqt_trunc(y
));
3629 static double eqt_pwr(double x
, double y
)
3631 return copysign(pow(fabs(x
), y
), x
);
3634 static double eqt_sign(double x
, double y
)
3636 return copysign(x
, y
);
3638 static double eqt_e(double a
, double b
)
3640 return a
*pow(10, b
);
3643 static int doneseed
=0, displayseed
=1 ;
3644 static unsigned int eqt_seedp
=0, eqt_seedp_save
=0;
3646 void eqt_srand(unsigned int seed
)
3652 void eqt_initseed(int mode
, unsigned int value
)
3654 if (mode
) eqt_seedp
=mbk_get_a_seed();
3655 else eqt_seedp
=value
;
3658 eqt_seedp_save
=eqt_seedp
;
3660 unsigned int eqt_getinitseed()
3662 return eqt_seedp_save
;
3665 static double ranf() /* ranf() is uniform in 0..1 */
3673 sprintf(buf
, "info:Main monte-carlo seed = %u", eqt_seedp
);
3674 avt_log(-1, 0, "%s\n", &buf
[5]);
3676 mbk_sendmsg( MBK_COM_DATA
, buf
, strlen(buf
)+1);
3680 return ((double)mbk_rand_r(&eqt_seedp
) / (double)MBK_RAND_MAX
);
3683 unsigned int eqt_get_current_srand_seed()
3687 eqt_initseed(1, 0) ;
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
;
3697 static int use_last
= 0;
3700 if( V_BOOL_TAB
[ __AVT_ENABLE_STAT
].VALUE
) {
3704 if (use_last
) /* use value from previous call */
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 );
3717 w
= sqrt( (-2.0 * log( w
) ) / w
);
3720 // commente pour que le seed fonctionne bien
3723 } while (fabs(y1
)>6);
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
;
3729 if( r >= m-d/2 && r <= m+d/2 )
3733 r = floor( ( r-(m+d/2) )/d )*d + (m+d/2.0) ;
3735 r = ceil( ( r-(m-d/2) )/d )*d + (m-d/2.0) ;
3746 static double eqt_limit(double nom
, double var
)
3748 if( V_BOOL_TAB
[ __AVT_ENABLE_STAT
].VALUE
) {
3750 if (mbk_rand_r(&eqt_seedp
)>MBK_RAND_MAX
/2)
3758 static double eqt_unif(double nom
, double rel
)
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
);
3767 static double eqt_aunif(double nom
, double rel
)
3769 if( V_BOOL_TAB
[ __AVT_ENABLE_STAT
].VALUE
) {
3770 double a
=nom
-rel
, b
=nom
+rel
;
3771 return a
+ranf()*(b
-a
);
3776 static double eqt_agauss(double m
, double s
, double sigma_level
)
3778 return box_muller(m
, s
/sigma_level
);
3781 static double eqt_gauss(double m
, double s
, double sigma_level
)
3783 return box_muller(m
, s
*m
/sigma_level
);
3786 static double eqt_lognorm(double nom
, double var
, double sigma_level
)
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
);
3792 static double eqt_alognorm(double nom
, double var
, double sigma_level
)
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
);
3799 void eqt_add_spice_extension(eqt_ctx
*ctx
)
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
);
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
) ;
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)");
3825 cl
=addchain(NULL
, "d");
3826 cl
=addchain(cl
, "c");
3827 cl
=addchain(cl
, "b");
3828 cl
=addchain(cl
, "a");
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
) ;
3844 ctx
->USE_SPICE_UNITS
= 1;
3847 void eqt_setspecialfunc(eqt_ctx
*ctx
, int index
, double (*func
)(char *var
))
3849 ctx
->SPECIAL_FUNC
[index
]=func
;