src/thirdparty/mathexpr/mathexpr_c.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 mathexpr_c.cpp version 2.0
00004 
00005 Copyright Yann OLLIVIER 1997-2000
00006 
00007 This software may be freely distributed as is, including this whole notice.
00008 
00009 It may be modified, but any modification should include this whole 
00010 notice as is and a description of the changes made.
00011 
00012 This software may not be sold.
00013 
00014 This software or any modified version of it may be freely used in free
00015 programs. The program should include a copy of this whole notice.
00016 If you want to use it in a program you sell, contact me
00017 
00018 This software comes with absolutely no warranty.
00019 
00020 */
00021 
00022 #include"mathexpr_c.h"
00023 
00024 #ifndef __STD_COMPLEX_
00025 double_complex tan(double_complex z)
00026 {return sin(z)/cos(z);}
00027 double_complex acos(double_complex z)
00028 {return -double_complex(0,1)*log(z+double_complex(0,1)*sqrt(double_complex(1,0)-z*z));}
00029 double_complex asin(double_complex z)
00030 {return -double_complex(0,1)*log(double_complex(0,1)*z+sqrt(double_complex(1,0)-z*z));}
00031 double_complex atan(double_complex z)
00032 {return -double_complex(0,1)*log((double_complex(1,0)+double_complex(0,1)*z)/sqrt(double_complex(1,0)+z*z));}
00033 #endif
00034 
00035 char* MidStr(const char*s,int i1,int i2)
00036 {
00037     if(i1<0||i2>=(int)strlen(s)||i1>i2){
00038         char* cp = new char[1];
00039         cp[0] = '\0';
00040         return cp;
00041     }
00042     char*s1=new char[i2-i1+2];
00043     int i;
00044     for(i=i1;i<=i2;i++)s1[i-i1]=s[i];
00045     s1[i2-i1+1]=0;return s1;
00046 }
00047 
00048 char* CopyStr(const char*s)
00049 {char*s1=new char[strlen(s)+1];char*s12=s1;const char*s2=s;
00050     while((*s12++=*s2++));return s1;}
00051 
00052 void InsStr(char*&s,int n,char c)// Warning : deletes the old string
00053 {if(n<0||n>(int)strlen(s))return;
00054     char*s1=new char[strlen(s)+2];
00055     int i;
00056     for(i=0;i<n;i++)s1[i]=s[i];
00057     s1[n]=c;for(i=n+1;s[i-1];i++)s1[i]=s[i-1];
00058     s1[i]=0;
00059     delete[]s;s=s1;
00060 }
00061 
00062 signed char EqStr(const char*s,const char*s2)
00063 {if(strlen(s)!=strlen(s2))return 0;
00064     int i;
00065     for(i=0;i<s[i];i++)if(s[i]!=s2[i])return 0;
00066     return 1;
00067 }
00068 
00069 signed char CompStr(const char*s,int n,const char*s2)
00070 {if(n<0||n>=(int)strlen(s)||n+(int)strlen(s2)>(int)strlen(s))return 0;
00071     int i;
00072     for(i=0;s2[i];i++)if(s[i+n]!=s2[i])return 0;
00073     return 1;
00074 }
00075 
00076 void DelStr(char*&s,int n)//Deletes the old string
00077 {char*s1=new char[strlen(s)];
00078     int i;
00079     for(i=0;i<n;i++)s1[i]=s[i];
00080     for(i=n;s[i+1];i++)s1[i]=s[i+1];
00081     s1[i]=0;
00082     delete[]s;s=s1;
00083 }
00084 
00085 CVar::CVar(const CVar & rvarp)
00086 {if(this==&rvarp)return;pval=rvarp.pval;name=CopyStr(rvarp.name);
00087 }
00088 
00089 CVar::CVar(const char*namep,double_complex*pvalp)
00090 {pval=(double_complex*)pvalp;name=CopyStr(namep);}
00091 
00092 CVar::~CVar()
00093 {if(name!=NULL)delete[] name;}
00094 
00095 CFunction::CFunction()
00096 {
00097     type=-1;name=new char[1];name[0]=0;
00098     nvars=0;ppvar=NULL;pfuncval=NULL;op=ErrVal;buf=NULL;
00099 }
00100 
00101 CFunction::CFunction(double_complex ((*pfuncvalp)(double_complex)))
00102 {
00103     type=0;pfuncval=pfuncvalp;name=new char[1];name[0]=0;
00104     nvars=1;ppvar=NULL;op=ErrVal;buf=NULL;
00105 }
00106 
00107 CFunction::CFunction(const CFunction& rfunc)
00108 {
00109     if(this==&rfunc)return;
00110     type=rfunc.type;op=rfunc.op;
00111     pfuncval=rfunc.pfuncval;
00112     name=CopyStr(rfunc.name);
00113     nvars=rfunc.nvars;
00114     if(rfunc.ppvar!=NULL&&nvars){
00115         ppvar=new PCVar[nvars];
00116         int i;for(i=0;i<nvars;i++)ppvar[i]=rfunc.ppvar[i];
00117         buf=new double_complex[nvars];
00118     }else {ppvar=NULL;buf=NULL;}
00119 }
00120 
00121 CFunction::CFunction(const COperation& opp,CVar* pvarp):op(opp)
00122 {
00123     type=1;name=new char[1];name[0]=0;
00124     nvars=1;ppvar=new PCVar[1];ppvar[0]=pvarp;buf=new double_complex[1];
00125 }
00126 
00127 CFunction::CFunction(const COperation& opp, int nvarsp,CVar**ppvarp):op(opp)
00128 {
00129     type=1;name=new char[1];name[0]=0;
00130     nvars=nvarsp;
00131     if(nvars){
00132         ppvar=new PCVar[nvars];
00133         int i;for(i=0;i<nvars;i++)ppvar[i]=ppvarp[i];
00134         buf=new double_complex[nvars];
00135     }else {ppvar=NULL;buf=NULL;}
00136 }
00137 
00138 CFunction::~CFunction()
00139 {
00140     if(name!=NULL)delete[]name;
00141     if(ppvar!=NULL)delete[]ppvar;
00142     if(buf!=NULL)delete[]buf;
00143 }
00144 
00145 CFunction& CFunction::operator=(const CFunction& rfunc)
00146 {
00147     if(this==&rfunc)return *this;
00148     type=rfunc.type;op=rfunc.op;
00149     pfuncval=rfunc.pfuncval;
00150     delete[]name;
00151     name=CopyStr(rfunc.name);
00152     if(ppvar!=NULL)delete[]ppvar;
00153     ppvar=NULL;
00154     if(buf!=NULL)delete[]buf;
00155     buf=NULL;
00156     nvars=rfunc.nvars;
00157     if(type==1&&nvars){
00158         ppvar=new PCVar[nvars];buf=new double_complex[nvars];
00159         int i;for(i=0;i<nvars;i++)ppvar[i]=rfunc.ppvar[i];
00160     }
00161     return *this;
00162 }
00163 
00164 void CFunction::SetName(const char*s)
00165 {if(name!=NULL)delete[]name;name=CopyStr(s);}
00166 
00167 double_complex CFunction::Val(double_complex x) const
00168 {
00169     if(type==-1||nvars>=2)return ErrVal;
00170     if(type==0)return (*pfuncval)(x);
00171     double_complex xb=*(*ppvar)->pval,y;
00172     *(*ppvar)->pval=x;  // Warning : could cause trouble if this value is used in a parallel process
00173     y=op.Val();
00174     *(*ppvar)->pval=xb;
00175     return y;
00176 }
00177 
00178 double_complex CFunction::Val(double_complex*pv) const
00179 {
00180     if(type==-1)return ErrVal;
00181     if(type==0)return (*pfuncval)(*pv);
00182     double_complex y;
00183     int i;
00184     for(i=0;i<nvars;i++){
00185         buf[i]=*ppvar[i]->pval;
00186         // Warning : could cause trouble if this value is used in a parallel process
00187         *ppvar[i]->pval=pv[i];
00188     }
00189     y=op.Val();
00190     for(i=0;i<nvars;i++)*ppvar[i]->pval=buf[i];
00191     return y;
00192 }
00193 
00194 COperation::COperation()
00195 {op=ErrOp;mmb1=NULL;mmb2=NULL;ValC=ErrVal;pvar=NULL;pvarval=NULL;pfunc=NULL;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;BuildCode();}
00196 
00197 COperation::~COperation()
00198 {
00199     Destroy();
00200 }
00201 
00202 COperation::COperation(const COperation&COp)
00203 {
00204     op=COp.op;pvar=COp.pvar;pvarval=COp.pvarval;ValC=COp.ValC;pfunc=COp.pfunc;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00205     if(COp.mmb1!=NULL)mmb1=new COperation(*(COp.mmb1));else mmb1=NULL;
00206     if(COp.mmb2!=NULL)mmb2=new COperation(*(COp.mmb2));else mmb2=NULL;
00207     BuildCode();
00208 }
00209 
00210 COperation::COperation(double_complex x)
00211 {
00212     if(x==ErrVal){op=ErrOp;mmb1=NULL;mmb2=NULL;ValC=ErrVal;}
00213     else {op=Num;mmb1=NULL;mmb2=NULL;ValC=x;}
00214     pvar=NULL;pvarval=NULL;pfunc=NULL;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00215     BuildCode();
00216 }
00217 
00218 COperation::COperation(double x)
00219 {
00220     if(x==ErrVal){op=ErrOp;mmb1=NULL;mmb2=NULL;ValC=ErrVal;}
00221     else if(x>=0){op=Num;mmb1=NULL;mmb2=NULL;ValC=x;}
00222     else{op=Opp;mmb1=NULL;mmb2=new COperation(-x);ValC=ErrVal;}
00223     pvar=NULL;pvarval=NULL;pfunc=NULL;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00224     BuildCode();
00225 }
00226 
00227 COperation::COperation(const CVar& varp)
00228 {op=Var;mmb1=NULL;mmb2=NULL;ValC=ErrVal;pvar=&varp;pvarval=varp.pval;containfuncflag=0;pfunc=NULL;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;BuildCode();}
00229 
00230 COperation& COperation::operator=(const COperation& COp)
00231 {
00232     if(this==&COp)return *this;
00233     Destroy();
00234     op=COp.op;pvar=COp.pvar;pvarval=COp.pvarval;ValC=COp.ValC;pfunc=COp.pfunc;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00235     if(COp.mmb1!=NULL)mmb1=new COperation(*(COp.mmb1));else mmb1=NULL;
00236     if(COp.mmb2!=NULL)mmb2=new COperation(*(COp.mmb2));else mmb2=NULL;
00237     BuildCode();
00238     return *this;
00239 }
00240 
00241 int operator==(const COperation& op,const double v)
00242 {return(op.op==Num&&op.ValC==v);}
00243 
00244 int operator==(const COperation& op,const double_complex v)
00245 {return(op.op==Num&&op.ValC==v);}
00246 
00247 int operator==(const COperation& op1,const COperation& op2)
00248 {if(op1.op!=op2.op)return 0;
00249     if(op1.op==Var)return(*(op1.pvar)==*(op2.pvar));
00250     if(op1.op==Fun)return(op1.pfunc==op2.pfunc); // *op1.pfunc==*op2.pfunc could imply infinite loops in cases of self-dependence
00251     if(op1.op==Num)return(op1.ValC==op2.ValC);
00252     if(op1.mmb1==NULL&&op2.mmb1!=NULL)return 0;
00253     if(op1.mmb2==NULL&&op2.mmb2!=NULL)return 0;
00254     if(op2.mmb1==NULL&&op1.mmb1!=NULL)return 0;
00255     if(op2.mmb2==NULL&&op1.mmb2!=NULL)return 0;
00256     return(((op1.mmb1==NULL&&op2.mmb1==NULL)||(*(op1.mmb1)==*(op2.mmb1)))&&
00257            ((op1.mmb2==NULL&&op2.mmb2==NULL)||(*(op1.mmb2)==*(op2.mmb2))));
00258 }
00259 
00260 int operator!=(const COperation& op1,const COperation& op2)
00261 {
00262     if(op1.op!=op2.op)return 1;
00263     if(op1.op==Var)return(op1.pvar!=op2.pvar);
00264     if(op1.op==Fun)return(!(op1.pfunc==op2.pfunc)); // *op1.pfunc==*op2.pfunc could imply infinite loops in cases of self-dependence
00265     if(op1.op==Num)return(op1.ValC!=op2.ValC);
00266     if(op1.mmb1==NULL&&op2.mmb1!=NULL)return 1;
00267     if(op1.mmb2==NULL&&op2.mmb2!=NULL)return 1;
00268     if(op2.mmb1==NULL&&op1.mmb1!=NULL)return 1;
00269     if(op2.mmb2==NULL&&op1.mmb2!=NULL)return 1;
00270     return(((op1.mmb1!=NULL||op2.mmb1!=NULL)&&(*(op1.mmb1)!=*(op2.mmb1)))||
00271            ((op1.mmb2!=NULL||op2.mmb2!=NULL)&&(*(op1.mmb2)!=*(op2.mmb2))));
00272 }
00273 
00274 COperation COperation::operator+() const
00275 {return *this;}
00276 
00277 COperation COperation::operator-() const
00278 {if(op==Num)return -ValC;
00279     COperation resultat;
00280     if(op==Opp)resultat=*mmb2;else{resultat.op=Opp;resultat.mmb2=new COperation(*this);};
00281     return resultat;
00282 }
00283 
00284 COperation operator,(const COperation& op1,const COperation& op2)
00285 {COperation resultat;
00286     resultat.op=Juxt;resultat.mmb1=new COperation(op1);
00287     resultat.mmb2=new COperation(op2);
00288     return resultat;
00289 }
00290 
00291 COperation operator+(const COperation& op1,const COperation& op2)
00292 {
00293     if(op1.op==Num&&op2.op==Num)return op1.ValC+op2.ValC;
00294     if(op1==0.)return op2;if(op2==0.)return op1;
00295     if(op1.op==Opp)return op2-*(op1.mmb2);if(op2.op==Opp)return op1-*(op2.mmb2);
00296     COperation resultat;
00297     resultat.op=Add;resultat.mmb1=new COperation(op1);
00298     resultat.mmb2=new COperation(op2);
00299     return resultat;
00300 }
00301 
00302 COperation operator-(const COperation& op1,const COperation& op2)
00303 {
00304     if(op1.op==Num&&op2.op==Num)return op1.ValC-op2.ValC;
00305     if(op1==0.)return -op2;if(op2==0.)return op1;
00306     if(op1.op==Opp)return -(op2+*(op1.mmb2));if(op2.op==Opp)return op1+*(op2.mmb2);
00307     COperation resultat;
00308     resultat.op=Sub;resultat.mmb1=new COperation(op1);
00309     resultat.mmb2=new COperation(op2);
00310     return resultat;
00311 }
00312 
00313 COperation operator*(const COperation& op1,const COperation& op2)
00314 {
00315     if(op1.op==Num&&op2.op==Num)return op1.ValC*op2.ValC;
00316     if(op1==0.||op2==0.)return 0.;
00317     if(op1==1.)return op2;if(op2==1.)return op1;
00318     if(op1.op==Opp)return -(*(op1.mmb2)*op2);if(op2.op==Opp)return -(op1**(op2.mmb2));
00319     COperation resultat;
00320     resultat.op=Mult;resultat.mmb1=new COperation(op1);
00321     resultat.mmb2=new COperation(op2);
00322     return resultat;
00323 }
00324 
00325 COperation operator/(const COperation& op1,const COperation& op2)
00326 {if(op1.op==Num&&op2.op==Num)return (op2.ValC!=double_complex(0,0)?op1.ValC/op2.ValC:ErrVal);
00327     if(op1==0.0)return 0.;if(op2==1.)return op1;if(op2==0.)return ErrVal;
00328     if(op1.op==Opp)return -(*(op1.mmb2)/op2);if(op2.op==Opp)return -(op1/(*(op2.mmb2)));
00329     COperation resultat;
00330     resultat.op=Div;resultat.mmb1=new COperation(op1);
00331     resultat.mmb2=new COperation(op2);
00332     return resultat;
00333 }
00334 
00335 COperation operator^(const COperation& op1,const COperation& op2)
00336 {if(op1==0.)return 0.;
00337     if(op2==0.)return 1.;
00338     if(op2==1.)return op1;
00339     COperation resultat;
00340     resultat.op=Pow;resultat.mmb1=new COperation(op1);
00341     resultat.mmb2=new COperation(op2);
00342     return resultat;
00343 }
00344 
00345 COperation real(const COperation& op)
00346 {
00347     if(op.op==Num)return real(op.ValC);
00348     COperation rop;rop.op=Real;rop.mmb2=new COperation(op);return rop;
00349 }
00350 COperation imag(const COperation& op)
00351 {
00352     if(op.op==Num)return imag(op.ValC);
00353     COperation rop;rop.op=Imag;rop.mmb2=new COperation(op);return rop;
00354 }
00355 COperation conj(const COperation& op)
00356 {
00357     if(op.op==Num)return conj(op.ValC);
00358     COperation rop;rop.op=Conj;rop.mmb2=new COperation(op);return rop;
00359 }
00360 COperation arg(const COperation& op)
00361 {COperation rop;rop.op=Arg;rop.mmb2=new COperation(op);return rop;}
00362 COperation sqrt(const COperation& op)
00363 {COperation rop;rop.op=Sqrt;rop.mmb2=new COperation(op);return rop;}
00364 COperation abs(const COperation& op)
00365 {COperation rop;rop.op=Abs;rop.mmb2=new COperation(op);return rop;}
00366 COperation sin(const COperation& op)
00367 {COperation rop;rop.op=Sin;rop.mmb2=new COperation(op);return rop;}
00368 COperation cos(const COperation& op)
00369 {COperation rop;rop.op=Cos;rop.mmb2=new COperation(op);return rop;}
00370 COperation tan(const COperation& op)
00371 {COperation rop;rop.op=Tg;rop.mmb2=new COperation(op);return rop;}
00372 COperation log(const COperation& op)
00373 {COperation rop;rop.op=Ln;rop.mmb2=new COperation(op);return rop;}
00374 COperation exp(const COperation& op)
00375 {COperation rop;rop.op=Exp;rop.mmb2=new COperation(op);return rop;}
00376 COperation acos(const COperation& op)
00377 {COperation rop;rop.op=Acos;rop.mmb2=new COperation(op);return rop;}
00378 COperation asin(const COperation& op)
00379 {COperation rop;rop.op=Asin;rop.mmb2=new COperation(op);return rop;}
00380 COperation atan(const COperation& op)
00381 {COperation rop;rop.op=Atan;rop.mmb2=new COperation(op);return rop;}
00382 
00383 COperation ApplyOperator(int n,COperation**pops,COperation (*func)(const COperation&,const COperation&))
00384 {
00385     if(n<=0)return ErrVal;
00386     if(n==1)return *pops[0];
00387     if(n==2)return (*func)(*pops[0],*pops[1]);
00388     return (*func)(*pops[0],ApplyOperator(n-1,pops+1,func));
00389 }
00390 
00391 COperation CFunction::operator()(const COperation& op)
00392 {
00393     /* Code to use to replace explcitly instead of using a pointer to
00394        if(nvars!=op.NMembers()||type==-1||type==0)return ErrVal;
00395        COperation op2=*pop;int i;
00396        CVar**ppvar2=new PCVar[nvars];char s[11]="";
00397        for(i=0;i<nvars;i++){
00398        sprintf(s,";var%i;",i);
00399        ppvar2[i]=new CVar(s,NULL);
00400        op2=op2.Substitute(*ppvar[i],(COperation)*ppvar2[i]);
00401        }
00402        for(i=0;i<nvars;i++){
00403        op2=op2.Substitute(*ppvar2[i],op.NthMember(i+1));
00404        delete ppvar2[i];
00405        }
00406        delete[]ppvar2;
00407        return op2;
00408     */
00409     COperation op2;op2.op=Fun;op2.pfunc=this;op2.mmb2=new COperation(op);
00410     return op2;
00411 }
00412 
00413 //Auxiliary string functions
00414 
00415 void SupprSpaces(char*&s)//Deletes the old string
00416 {
00417     int i;
00418     for(i=0;s[i];i++)if(s[i]==' '||s[i]=='\t'||s[i]=='\n')DelStr(s,i--);
00419 }
00420 
00421 signed char IsNumeric(char c)
00422 {if(c!='0'&&c!='1'&&c!='2'&&c!='3'&&c!='4'
00423         &&c!='5'&&c!='6'&&c!='7'&&c!='8'&&c!='9'&&c!='.')return 0;
00424     return 1;
00425 }
00426 
00427 signed char IsTNumeric(char *s)
00428 {int i;for(i=0;i<(int)strlen(s);i++)if(!IsNumeric(s[i]))return 0;return 1;
00429 }
00430 
00431 int SearchCorOpenbracket(char*s,int n)  //Searchs the corresponding bracket of an opening bracket
00432 {if(n>=(int)strlen(s)-1)return -1;
00433     int i,c=1;
00434     for(i=n+1;s[i];i++){
00435         if(s[i]=='(')c++;else if(s[i]==')')c--;
00436         if(!c)return i;
00437     };
00438     return -1;
00439 }
00440 
00441 int SearchCorClosebracket(char*s,int n)  //Searchs the corresponding bracket of a closing bracket
00442 {if(n<1)return -1;
00443     int i,c=1;
00444     for(i=n-1;i>=0;i--){
00445         if(s[i]==')')c++;else if(s[i]=='(')c--;
00446         if(!c)return i;
00447     };
00448     return -1;
00449 }
00450 
00451 int SearchOperator(char*s,COperator op)
00452 {
00453     char opc;
00454     switch(op){
00455 case ErrOp:case Num:case Var:return -1;
00456     case Juxt:opc=',';break;
00457     case Add:opc='+';break;
00458     case Sub:opc='-';break;
00459     case Mult:opc='*';break;
00460     case Div:opc='/';break;
00461     case Pow:opc='^';break;
00462     case NthRoot:opc='#';break;
00463     case E10:opc='E';break;
00464     default:return -1;
00465     };
00466     int i;
00467     for(i=(int)strlen(s)-1;i>=0;i--){
00468         if(s[i]==opc&&(op!=Sub||i&&s[i-1]==')'))return i;
00469     if(s[i]==')'){i=SearchCorClosebracket(s,i);if(i==-1)return -1;};
00470     };
00471     return -1;
00472 }
00473 
00474 void SimplifyStr(char*&s) //Warning : deletes the old string
00475 {if(!strlen(s))return;
00476     char*s1=s,*s2=s+strlen(s);signed char ind=0;
00477     if(s1[0]=='('&&SearchCorOpenbracket(s1,0)==s2-s1-1){
00478         s1++;s2--;ind=1;}
00479     if(s1==s2)
00480     {
00481         delete[]s;
00482         s=new char[1]; // ISO C++ forbids initialization in array new
00483         s[0]=0;
00484         return;
00485     }
00486     if(s1[0]==' '){ind=1;while(s1[0]==' '&&s1<s2)s1++;}
00487     if(s1==s2)
00488     {
00489         delete[]s;
00490         s=new char[1]; // ISO C++ forbids initialization in array new
00491         s[0]=0;
00492         return;
00493     }
00494     if(*(s2-1)==' '){ind=1;while(s2>s1&&*(s2-1)==' ')s2--;}
00495     *s2=0;
00496     s1=CopyStr(s1);delete[]s;s=s1;
00497     if(ind)SimplifyStr(s);
00498 }
00499 
00500 int max(int a, int b){return (a>b?a:b);}
00501 
00502 int IsVar(const char*s,int n,int nvar,PCVar*ppvar)
00503 {
00504     if(n<0||n>(int)strlen(s))return 0;
00505     int i;int l=0;
00506     for(i=0;i<nvar;i++)if(CompStr(s,n,(*(ppvar+i))->name))l=max(l,strlen((*(ppvar+i))->name));
00507     return l;
00508 }
00509 
00510 int IsFunction(const char*s,int n)
00511 {
00512     if(CompStr(s,n,"sin")||CompStr(s,n,"cos")||CompStr(s,n,"exp")
00513             ||CompStr(s,n,"tan")||CompStr(s,n,"log")||CompStr(s,n,"atg")
00514             ||CompStr(s,n,"arg")||CompStr(s,n,"abs"))return 3;
00515     if(CompStr(s,n,"tg")||CompStr(s,n,"ln"))return 2;
00516     if(CompStr(s,n,"sqrt")||CompStr(s,n,"asin")||CompStr(s,n,"atan")
00517             ||CompStr(s,n,"real")||CompStr(s,n,"conj")
00518             ||CompStr(s,n,"imag")||CompStr(s,n,"acos"))return 4;
00519     if(CompStr(s,n,"arcsin")||CompStr(s,n,"arccos")||CompStr(s,n,"arctan"))return 6;
00520     if(CompStr(s,n,"arctg"))return 5;
00521     return 0;
00522 }
00523 
00524 int IsFunction(const char*s,int n,int nfunc,PCFunction*ppfunc)
00525 //Not recognized if a user-defined function is eg "sine" ie begins like
00526 //a standard function
00527 //IF PATCHED TO DO OTHERWISE, SHOULD BE PATCHED TOGETHER WITH THE
00528 //PARSER BELOW which treats standard functions before user-defined ones
00529 {
00530     int l=IsFunction(s,n);
00531     if(l)return l;
00532     int i;l=0;
00533     for(i=0;i<nfunc;i++)if(CompStr(s,n,ppfunc[i]->name))l=max(l,strlen(ppfunc[i]->name));
00534     return l;
00535 }
00536 
00537 signed char IsFunction(COperator op)
00538 {return (op==Exp||op==Abs||op==Sin||op==Cos||op==Tg||op==Ln
00539              ||op==Atan||op==Asin||op==Acos||op==Atan||op==Sqrt||op==Opp
00540              ||op==Real||op==Imag||op==Conj||op==Arg);
00541 }
00542 
00543 void IsolateVars(char*&s,int nvar,PCVar*ppvar,int nfunc,PCFunction*ppfunc)//Deletes the old string
00544 {
00545     int i,j;
00546     i=0;
00547     for(i=0;s[i];i++){
00548         if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)return;continue;};
00549         if(((j=IsVar(s,i,nvar,ppvar))>IsFunction(s,i,nfunc,ppfunc))||((CompStr(s,i,"pi")||CompStr(s,i,"PI")||CompStr(s,i,"Pi"))&&(j=2)
00550                 ||(CompStr(s,i,"i")&&(j=1)))){
00551             InsStr(s,i,'(');InsStr(s,i+j+1,')');i+=j+1;continue;};
00552         if(IsFunction(s,i,nfunc,ppfunc)){i+=IsFunction(s,i,nfunc,ppfunc)-1;if(!s[i])return;continue;};
00553     };
00554 }
00555 
00556 void IsolateNumbers(char*&s,int nvar,CVar**ppvar,int nfunc,CFunction**ppfunc)//Deletes the old string
00557 {
00558     int i,i2,ind=0,t1,t2;
00559     for(i=0;s[i];i++){
00560         if(ind&&!IsNumeric(s[i])){ind=0;InsStr(s,i2,'(');i++;InsStr(s,i,')');continue;};
00561         t1=IsVar(s,i,nvar,ppvar);t2=IsFunction(s,i,nfunc,ppfunc);
00562         if(t1||t2){i+=max(t1,t2)-1;continue;}
00563         if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)return;continue;};
00564         if(!ind&&IsNumeric(s[i])){i2=i;ind=1;};
00565     };
00566     if(ind)InsStr(s,i2,'(');i++;InsStr(s,i,')');
00567 }
00568 
00569 COperation::COperation(char*sp,int nvar,PCVar*ppvarp,int nfuncp,PCFunction*ppfuncp)
00570 {
00571     ValC=ErrVal;mmb1=NULL;mmb2=NULL;pvar=NULL;op=ErrOp;pvarval=NULL;containfuncflag=0;pfunc=NULL;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00572     int i,j,k,l;signed char flag=1;
00573     char*s=CopyStr(sp),*s1=NULL,*s2=NULL;
00574     SimplifyStr(s);if(!s[0]||!strcmp(s,"Error")){goto fin;}
00575     while(s[0]==':'||s[0]==';'){
00576         s1=CopyStr(s+1);delete[]s;s=s1;s1=NULL;
00577         SimplifyStr(s);if(!s[0]||!strcmp(s,"Error")){goto fin;}
00578     }
00579     if(IsTNumeric(s)){op=Num;ValC=atof(s);mmb1=NULL;mmb2=NULL;goto fin;};
00580     if(EqStr(s,"pi")||EqStr(s,"PI")||EqStr(s,"Pi"))
00581     {op=Num;ValC=3.141592653589793238462643383279L;mmb1=NULL;mmb2=NULL;goto fin;};
00582     if(EqStr(s,"i")||EqStr(s,"I"))
00583     {op=Num;ValC=double_complex(0,1);mmb1=NULL;mmb2=NULL;goto fin;};
00584     if(IsFunction(s,0,nfuncp,ppfuncp)<IsVar(s,0,nvar,ppvarp))
00585         for(i=0;i<nvar;i++)if(EqStr(s,(*(ppvarp+i))->name))
00586             {pvar=ppvarp[i];pvarval=pvar->pval;op=Var;mmb1=NULL;mmb2=NULL;goto fin;};
00587     for(k=0;s[k];k++){
00588         if(s[k]=='('){k=SearchCorOpenbracket(s,k);if(k==-1)break;continue;};
00589         if((l=IsFunction(s,k,nfuncp,ppfuncp))&&l>=IsVar(s,k,nvar,ppvarp)){
00590             i=k+l;while(s[i]==' ')i++;
00591             if(s[i]=='('){
00592                 j=SearchCorOpenbracket(s,i);
00593                 if(j!=-1){InsStr(s,i,';');k=j+1;}
00594             }else if(s[i]!=':'&&s[i]!=';'){InsStr(s,i,':');k=i;}
00595         }
00596     }
00597     IsolateNumbers(s,nvar,ppvarp,nfuncp,ppfuncp);
00598     if(nvar)IsolateVars(s,nvar,ppvarp,nfuncp,ppfuncp);
00599     SupprSpaces(s);
00600     i=SearchOperator(s,Juxt);
00601     if(i!=-1){char*s1="",*s2="";s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00602         op=Juxt;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00603         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00604     };
00605     i=SearchOperator(s,Add);
00606     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00607         op=Add;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00608         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00609     };
00610     i=SearchOperator(s,Sub);
00611     if(i!=-1){
00612         s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00613         op=Sub;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00614         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00615     };
00616     if(s[0]=='-'){s2=MidStr(s,1,strlen(s)-1);
00617         op=Opp;mmb1=NULL;
00618         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00619     };
00620     for(i=0;s[i];i++){
00621         if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)break;continue;};
00622         if(IsFunction(s,i,nfuncp,ppfuncp)){
00623             k=i+IsFunction(s,i,nfuncp,ppfuncp);while(s[k]==' ')k++;
00624             if(s[k]==';'){
00625                 //      s=DelStr(s,k);
00626                 j=k;while(s[j]!='(')j++;
00627                 j=SearchCorOpenbracket(s,j);
00628                 if(j!=-1){InsStr(s,j,')');InsStr(s,i,'(');i=j+2;}
00629             }else if(s[k]==':'){
00630                 //      s=DelStr(s,k);
00631                 for(j=k;s[j];j++)
00632                 if(s[j]=='('){j=SearchCorOpenbracket(s,j);break;}
00633                 if(j==-1)break;
00634                 for(j++;s[j];j++){
00635                     if(s[j]=='('){j=SearchCorOpenbracket(s,j);if(j==-1){flag=0;break;};continue;};
00636                     if(IsFunction(s,j,nfuncp,ppfuncp))break;
00637                 }
00638             if(flag==0){flag=1;break;}
00639                 while(j>i&&s[j-1]!=')')j--;if(j<=i+1)break;
00640                 InsStr(s,i,'(');InsStr(s,j+1,')');
00641                 i=j+1;
00642             }
00643         }
00644     }
00645     for(i=0;s[i]&&s[i+1];i++)if(s[i]==')'&&s[i+1]=='(')
00646             InsStr(s,++i,'*');
00647     if(s[0]=='('&&SearchCorOpenbracket(s,0)==(int)strlen(s)-1){
00648         if(CompStr(s,1,"exp")){op=Exp;s2=MidStr(s,4,strlen(s)-2);}
00649         else if(CompStr(s,1,"real")){op=Real;s2=MidStr(s,5,strlen(s)-2);}
00650         else if(CompStr(s,1,"imag")){op=Imag;s2=MidStr(s,5,strlen(s)-2);}
00651         else if(CompStr(s,1,"conj")){op=Conj;s2=MidStr(s,5,strlen(s)-2);}
00652         else if(CompStr(s,1,"arg")){op=Arg;s2=MidStr(s,4,strlen(s)-2);}
00653         else if(CompStr(s,1,"abs")){op=Abs;s2=MidStr(s,4,strlen(s)-2);}
00654         else if(CompStr(s,1,"sin")){op=Sin;s2=MidStr(s,4,strlen(s)-2);}
00655         else if(CompStr(s,1,"cos")){op=Cos;s2=MidStr(s,4,strlen(s)-2);}
00656         else if(CompStr(s,1,"tan")){op=Tg;s2=MidStr(s,4,strlen(s)-2);}
00657         else if(CompStr(s,1,"log")){op=Ln;s2=MidStr(s,4,strlen(s)-2);}
00658         else if(CompStr(s,1,"atg")){op=Atan;s2=MidStr(s,4,strlen(s)-2);}
00659         else if(CompStr(s,1,"tg")){op=Tg;s2=MidStr(s,3,strlen(s)-2);}
00660         else if(CompStr(s,1,"ln")){op=Ln;s2=MidStr(s,3,strlen(s)-2);}
00661         else if(CompStr(s,1,"asin")){op=Asin;s2=MidStr(s,5,strlen(s)-2);}
00662         else if(CompStr(s,1,"acos")){op=Acos;s2=MidStr(s,5,strlen(s)-2);}
00663         else if(CompStr(s,1,"atan")){op=Atan;s2=MidStr(s,5,strlen(s)-2);}
00664         else if(CompStr(s,1,"sqrt")){op=Sqrt;s2=MidStr(s,5,strlen(s)-2);}
00665         else if(CompStr(s,1,"arcsin")){op=Asin;s2=MidStr(s,7,strlen(s)-2);}
00666         else if(CompStr(s,1,"arccos")){op=Acos;s2=MidStr(s,7,strlen(s)-2);}
00667         else if(CompStr(s,1,"arctan")){op=Atan;s2=MidStr(s,7,strlen(s)-2);}
00668         else if(CompStr(s,1,"arctg")){op=Atan;s2=MidStr(s,6,strlen(s)-2);}
00669         else {
00670             for(i=-1,k=0,j=0;j<nfuncp;j++)if(CompStr(s,1,ppfuncp[j]->name)&&k<(int)strlen(ppfuncp[j]->name)){k=strlen(ppfuncp[j]->name);i=j;}
00671             if(i>-1){
00672                 op=Fun;s2=MidStr(s,strlen(ppfuncp[i]->name)+1,strlen(s)-2);
00673                 pfunc=ppfuncp[i];
00674             }
00675         }
00676         mmb1=NULL;mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);
00677         if(op==Fun)if(mmb2->NMembers()!=pfunc->nvars){op=ErrOp;mmb1=NULL;mmb2=NULL;goto fin;}
00678         goto fin;
00679     };
00680     i=SearchOperator(s,Mult);
00681     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00682         op=Mult;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00683         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00684     };
00685     i=SearchOperator(s,Div);
00686     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00687         op=Div;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00688         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00689     };
00690     i=SearchOperator(s,Pow);
00691     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00692         op=Pow;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00693         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00694     };
00695     i=SearchOperator(s,NthRoot);
00696     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00697         if(i==0||s[i-1]!=')')
00698         {op=Sqrt;mmb1=NULL;}else
00699         {op=NthRoot;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);};
00700         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00701     };
00702     i=SearchOperator(s,E10);
00703     if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00704         op=E10;mmb1=new COperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00705         mmb2=new COperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00706     };
00707     op=ErrOp;mmb1=NULL;mmb2=NULL;
00708 fin:
00709     BuildCode();
00710     delete[]s;if(s1!=NULL)delete[] s1;if(s2!=NULL)delete[]s2;
00711 }
00712 
00713 void COperation::Destroy()
00714 {
00715     if(mmb1!=NULL&&mmb2!=NULL&&mmb1!=mmb2){delete mmb1;delete mmb2;mmb1=NULL;mmb2=NULL;}
00716     else if(mmb1!=NULL){delete mmb1;mmb1=NULL;}else if(mmb2!=NULL){delete mmb2;mmb2=NULL;}
00717     if(pinstr!=NULL){delete[]pinstr;pinstr=NULL;}
00718     if(pvals!=NULL){
00719         if(op==ErrOp||op==Num)delete pvals[0];
00720         delete[]pvals;pvals=NULL;
00721     }
00722 if(ppile!=NULL){delete[]ppile;ppile=NULL;}
00723     if(pfuncpile!=NULL){delete[]pfuncpile;pfuncpile=NULL;}
00724 }
00725 
00726 int operator==(const CVar& var1,const CVar& var2)
00727 {return(var1.pval==var2.pval&&EqStr(var1.name,var2.name));
00728 }
00729 
00730 int operator==(const CFunction& f1,const CFunction& f2)
00731 {
00732     if(f1.type!=f2.type)return 0;
00733     if(f1.type==-1)return 1; // Nonfunction==nonfunction
00734     if(f1.type==0)return (f1.pfuncval==f2.pfuncval&&EqStr(f1.name,f2.name));
00735     if(f1.op!=f2.op)return 0;
00736     if(!EqStr(f1.name,f2.name))return 0;
00737     if(f1.nvars!=f2.nvars)return 0;
00738     int i;
00739     for(i=0;i<f1.nvars;i++)if(!(*f1.ppvar[i]==*f2.ppvar[i]))return 0;
00740     return 1;
00741 }
00742 
00743 /*
00744 double_complex COperation::Val() const // Won't work if multi-variable functions are included
00745 {
00746   double_complex v1=ErrVal,v2=ErrVal;
00747   if(mmb1!=NULL){v1=mmb1->Val();if(norm(v1)<sqrtminfloat)v1=0;else if(v1==double_complex(ErrVal)||norm(v1)>sqrtmaxfloat)return ErrVal;};
00748   if(mmb2!=NULL){v2=mmb2->Val();if(norm(v2)<sqrtminfloat)v2=0;else if(v2==double_complex(ErrVal)||norm(v2)>sqrtmaxfloat)return ErrVal;};
00749   switch(op){
00750   case Num:return ValC;
00751   case Var:return *pvarval;
00752   case Add:return v1+v2;
00753   case Sub:return v1-v2;
00754   case Opp:return -v2;
00755   case Mult:return v1*v2;
00756   case Div:if(v2!=double_complex(0))return v1/v2;else return ErrVal;
00757   case Pow:if(v1==double_complex(0))return 0;else
00758     if(norm(v2)*log(norm(v1))<DBL_MAX_EXP)return pow(v1,v2);else return ErrVal;
00759   case Sqrt:return sqrt(v2);
00760   case NthRoot:if(v1==double_complex(0)||norm(v2)*log(fabs(norm(v1)))<DBL_MIN_EXP)return ErrVal;
00761   else return pow(v2,1/v1);
00762   case E10:if(norm(v2)<300)return v1*pow(double_complex(10.),v2);else return ErrVal;
00763   case Ln:if(v2!=double_complex(0))return log(v2);else return ErrVal;
00764   case Exp:if(real(v2)<DBL_MAX_EXP)return exp(v2);else return ErrVal;
00765   case Sin:if(norm(v2)<DBL_MAX_EXP)
00766             return sin(v2);else return ErrVal;
00767   case Cos:if(norm(v2)<DBL_MAX_EXP)return cos(v2);else return ErrVal;
00768   case Tg:if(norm(v2)<DBL_MAX_EXP)
00769            return tan(v2);else return ErrVal;
00770   case Atan:if(v2==double_complex(0,1)||v2==double_complex(0,-1))return ErrVal;
00771   else return atan(v2);
00772   case Asin:return asin(v2);
00773   case Acos:return acos(v2);
00774   case Abs:return norm(v2);
00775   case Real:return real(v2);
00776   case Imag:return imag(v2);
00777   case Conj:return conj(v2);
00778   case Arg:if(v2!=double_complex(0))return arg(v2);else return ErrVal; 
00779   case Fun:return pfunc->Val(v2);
00780   default:return ErrVal;
00781   };
00782 }
00783 */
00784 
00785 signed char COperation::ContainVar(const CVar& varp) const
00786     {if(op==Var){if(EqStr(pvar->name,varp.name)&&pvar->pval==varp.pval)
00787         return 1;else return 0;};
00788     if(mmb1!=NULL&&mmb1->ContainVar(varp))return 1;
00789     if(mmb2!=NULL&&mmb2->ContainVar(varp))return 1;
00790     return 0;
00791 }
00792 
00793 signed char COperation::ContainFuncNoRec(const CFunction& func) const // No recursive test on subfunctions
00794     {if(op==Fun){if(*pfunc==func)
00795         return 1;else return 0;}
00796     if(mmb1!=NULL&&mmb1->ContainFuncNoRec(func))return 1;
00797     if(mmb2!=NULL&&mmb2->ContainFuncNoRec(func))return 1;
00798     return 0;
00799 }
00800 
00801 signed char COperation::ContainFunc(const CFunction& func) const // Recursive test on subfunctions
00802 {
00803     if(containfuncflag)return 0;
00804     if(op==Fun&&*pfunc==func)return 1;
00805     containfuncflag=1;
00806 if(op==Fun)if(pfunc->op.ContainFunc(func)){containfuncflag=0;return 1;}
00807     if(mmb1!=NULL&&mmb1->ContainFunc(func)){containfuncflag=0;return 1;}
00808     if(mmb2!=NULL&&mmb2->ContainFunc(func)){containfuncflag=0;return 1;}
00809     containfuncflag=0;return 0;
00810 }
00811 
00812 signed char COperation::HasError(const COperation*pop) const
00813 {
00814     if(op==ErrOp)return 1;
00815     if(op==Fun&&pfunc->type==1&&pfunc->op==*(pop==NULL?this:pop))return 1;
00816     if(op==Fun&&pfunc->type==1&&pfunc->op.HasError((pop==NULL?this:pop)))return 1;
00817     if(mmb1!=NULL&&mmb1->HasError((pop==NULL?this:pop)))return 1;
00818     if(mmb2!=NULL&&mmb2->HasError((pop==NULL?this:pop)))return 1;
00819     if(op==Fun&&pfunc->type==-1)return 1;
00820     return 0;
00821 }
00822 
00823 int COperation::NMembers() const //Number of members for an operation like a,b,c...
00824 {
00825     if(op==Fun)return(pfunc->type==1?pfunc->op.NMembers():pfunc->type==0?1:0);
00826     if(op!=Juxt)return 1;else if(mmb2==NULL)return 0;else return 1+mmb2->NMembers();
00827 }
00828 
00829 COperation COperation::NthMember(int n) const
00830 {
00831     PCFunction prf;
00832     if(op==Fun&&pfunc->type==1&&pfunc->op.NMembers()>1){
00833         prf=new CFunction(pfunc->op.NthMember(n),pfunc->nvars,pfunc->ppvar);
00834         char*s=new char[strlen(pfunc->name)+10];
00835         sprintf(s,"(%s_%i)",pfunc->name,n);prf->SetName(s);delete[]s;
00836         return(*prf)(*mmb2);
00837     }
00838     if(n==1){
00839         if(op!=Juxt)return *this; else if(mmb1!=NULL)return *mmb1;else return ErrVal;
00840     };
00841     if(op!=Juxt)return ErrVal;
00842     if(n>1&&mmb2!=NULL)return mmb2->NthMember(n-1);
00843     return ErrVal;
00844 }
00845 
00846 COperation COperation::Substitute(const CVar& var,const COperation& rop) const // Replaces variable var with expression rop
00847 {
00848     if(!ContainVar(var))return *this;
00849     if(op==Var)return rop;
00850     COperation r;
00851     r.op=op;r.pvar=pvar;r.pvarval=pvarval;r.ValC=ValC;r.pfunc=pfunc;
00852     if(mmb1!=NULL)r.mmb1=new COperation(mmb1->Substitute(var,rop));else r.mmb1=NULL;
00853     if(mmb2!=NULL)r.mmb2=new COperation(mmb2->Substitute(var,rop));else r.mmb2=NULL;
00854     return r;
00855 }
00856 
00857 COperation COperation::Diff(const CVar& var) const //This is d / dz
00858 {
00859     if(!ContainVar(var))return 0.0;
00860     if(op==Var)return 1.0;
00861     COperation **ppop1,op2;int i,j;
00862     switch(op){
00863     case Juxt:return(mmb1->Diff(var),mmb2->Diff(var));
00864     case Add:return(mmb1->Diff(var)+mmb2->Diff(var));
00865     case Sub:return(mmb1->Diff(var)-mmb2->Diff(var));
00866     case Opp:return(-mmb2->Diff(var));
00867     case Mult:return((*mmb1)*(mmb2->Diff(var))+(*mmb2)*(mmb1->Diff(var)));
00868     case Div:if(mmb2->ContainVar(var))return(((*mmb2)*(mmb1->Diff(var))-(*mmb1)*(mmb2->Diff(var)))/((*mmb2)^2));
00869         else return(mmb1->Diff(var)/(*mmb2));
00870     case Pow:if(mmb2->ContainVar(var))return((*this)*(log(*mmb1)*mmb2->Diff(var)+
00871                                                 (*mmb2)*mmb1->Diff(var)/(*mmb1)));else
00872         return (*mmb2)*mmb1->Diff(var)*((*mmb1)^(*mmb2-1));
00873     case Sqrt:return(mmb2->Diff(var)/(2*sqrt(*mmb2)));
00874 case NthRoot:{COperation interm=(*mmb2)^(1/(*mmb1));return interm.Diff(var);};
00875     case E10:{COperation interm=(*mmb1)*(10^(*mmb2));return interm.Diff(var);};;
00876     case Ln:return (mmb2->Diff(var)/(*mmb2));
00877     case Exp:return (mmb2->Diff(var)*(*this));
00878     case Sin:return (mmb2->Diff(var)*cos(*mmb2));
00879     case Cos:return (-mmb2->Diff(var)*sin(*mmb2));
00880     case Tg:return (mmb2->Diff(var)*(1+((*this)^2)));
00881     case Atan:return(mmb2->Diff(var)/(1+((*mmb2)^2)));
00882     case Asin:return(mmb2->Diff(var)/sqrt(1-((*mmb2)^2)));
00883     case Acos:return(-mmb2->Diff(var)/sqrt(1-((*mmb2)^2)));
00884     case Abs:return ((conj(*mmb2)*mmb2->Diff(var)+(*mmb2)*conj(mmb2->DiffConj(var)))/(2*abs(*mmb2)));
00885     case Conj:return(conj(mmb2->DiffConj(var)));
00886     case Real:return ((mmb2->Diff(var)+conj(mmb2->DiffConj(var)))/2);
00887     case Imag:return ((mmb2->Diff(var)-conj(mmb2->DiffConj(var)))/double_complex(0,2));
00888     case Arg:return (double_complex(0,-.5)*(mmb2->Diff(var)/(*mmb2)-conj(mmb2->DiffConj(var)/(*mmb2))));
00889     case Fun:if(pfunc->type==-1||pfunc->type==0)return ErrVal;
00890         if(pfunc->nvars==0)return 0.;
00891         else if(pfunc->op.NMembers()>1){
00892             j=pfunc->op.NMembers();
00893             ppop1=new COperation*[j];
00894             for(i=0;i<j;i++)ppop1[i]=new COperation(NthMember(i+1).Diff(var));
00895             op2=ApplyOperator(pfunc->nvars,ppop1,&operator,);
00896             for(i=0;i<pfunc->nvars;i++)delete ppop1[i];
00897             delete[]ppop1;
00898             return op2;
00899         }else{
00900             ppop1=new COperation*[2*pfunc->nvars];
00901             for(i=0;i<pfunc->nvars;i++){
00902                 ppop1[i]=new COperation(pfunc->op.Diff(*pfunc->ppvar[i]));
00903                 for(j=0;j<pfunc->nvars;j++)
00904                     *ppop1[i]=ppop1[i]->Substitute(*pfunc->ppvar[j],mmb2->NthMember(j+1));
00905                 *ppop1[i]=(mmb2->NthMember(i+1).Diff(var))*(*ppop1[i]);
00906             }
00907             for(i=pfunc->nvars;i<2*pfunc->nvars;i++){
00908                 ppop1[i]=new COperation(pfunc->op.DiffConj(*pfunc->ppvar[i-pfunc->nvars]));
00909                 for(j=0;j<pfunc->nvars;j++)
00910                     *ppop1[i]=ppop1[i]->Substitute(*pfunc->ppvar[j],mmb2->NthMember(j+1));
00911                 *ppop1[i]=((conj(mmb2->NthMember(i+1-pfunc->nvars))).Diff(var))*(*ppop1[i]);
00912             }
00913             op2=ApplyOperator(2*pfunc->nvars,ppop1,&::operator+);
00914             for(i=0;i<2*pfunc->nvars;i++)delete ppop1[i];
00915             delete[]ppop1;
00916             return op2;
00917             // In the obtained expression, f' will have been replaced with its expression but f will remain pointing to itself ; this could cause some trouble if changing f afterwards
00918         }
00919     default:return ErrVal;
00920     };
00921 }
00922 
00923 COperation COperation::DiffConj(const CVar& var) const // This one is d / d conj(z)
00924 {
00925     if(!ContainVar(var))return 0.0;
00926     if(op==Var)return 0.0;
00927     COperation **ppop1,op2;int i,j;
00928     switch(op){
00929     case Juxt:return(mmb1->DiffConj(var),mmb2->DiffConj(var));
00930     case Add:return(mmb1->DiffConj(var)+mmb2->DiffConj(var));
00931     case Sub:return(mmb1->DiffConj(var)-mmb2->DiffConj(var));
00932     case Opp:return(-mmb2->DiffConj(var));
00933     case Mult:return((*mmb1)*(mmb2->DiffConj(var))+(*mmb2)*(mmb1->DiffConj(var)));
00934     case Div:if(mmb2->ContainVar(var))return(((*mmb2)*(mmb1->DiffConj(var))-(*mmb1)*(mmb2->DiffConj(var)))/((*mmb2)^2));
00935         else return(mmb1->DiffConj(var)/(*mmb2));
00936     case Pow:if(mmb2->ContainVar(var))return((*this)*(log(*mmb1)*mmb2->DiffConj(var)+
00937                                                 (*mmb2)*mmb1->DiffConj(var)/(*mmb1)));else
00938         return (*mmb2)*mmb1->DiffConj(var)*((*mmb1)^(*mmb2-1));
00939     case Sqrt:return(mmb2->DiffConj(var)/(2*sqrt(*mmb2)));
00940 case NthRoot:{COperation interm=(*mmb2)^(1/(*mmb1));return interm.DiffConj(var);};
00941     case E10:{COperation interm=(*mmb1)*(10^(*mmb2));return interm.DiffConj(var);};;
00942     case Ln:return (mmb2->DiffConj(var)/(*mmb2));
00943     case Exp:return (mmb2->DiffConj(var)*(*this));
00944     case Sin:return (mmb2->DiffConj(var)*cos(*mmb2));
00945     case Cos:return (-mmb2->DiffConj(var)*sin(*mmb2));
00946     case Tg:return (mmb2->DiffConj(var)*(1+((*this)^2)));
00947     case Atan:return(mmb2->DiffConj(var)/(1+((*mmb2)^2)));
00948     case Asin:return(mmb2->DiffConj(var)/sqrt(1-((*mmb2)^2)));
00949     case Acos:return(-mmb2->DiffConj(var)/sqrt(1-((*mmb2)^2)));
00950     case Abs:return ((conj(*mmb2)*mmb2->DiffConj(var)+(*mmb2)*conj(mmb2->Diff(var)))/(2*abs(*mmb2)));
00951     case Conj:return(conj(mmb2->Diff(var)));
00952     case Real:return ((mmb2->DiffConj(var)+conj(mmb2->Diff(var)))/2);
00953     case Imag:return ((mmb2->DiffConj(var)-conj(mmb2->Diff(var)))/double_complex(0,2));
00954     case Arg:return (double_complex(0,-.5)*(mmb2->DiffConj(var)/(*mmb2)-conj(mmb2->Diff(var)/(*mmb2))));
00955     case Fun:if(pfunc->type==-1||pfunc->type==0)return ErrVal;
00956         if(pfunc->nvars==0)return 0.;
00957         else if(pfunc->op.NMembers()>1){
00958             j=pfunc->op.NMembers();
00959             ppop1=new COperation*[j];
00960             for(i=0;i<j;i++)ppop1[i]=new COperation(NthMember(i+1).DiffConj(var));
00961             op2=ApplyOperator(pfunc->nvars,ppop1,&operator,);
00962             for(i=0;i<pfunc->nvars;i++)delete ppop1[i];
00963             delete[]ppop1;
00964             return op2;
00965         }else{
00966             ppop1=new COperation*[2*pfunc->nvars];
00967             for(i=0;i<pfunc->nvars;i++){
00968                 ppop1[i]=new COperation(pfunc->op.DiffConj(*pfunc->ppvar[i]));
00969                 for(j=0;j<pfunc->nvars;j++)
00970                     *ppop1[i]=ppop1[i]->Substitute(*pfunc->ppvar[j],mmb2->NthMember(j+1));
00971                 *ppop1[i]=(conj(mmb2->NthMember(i+1).Diff(var)))*(*ppop1[i]);
00972             }
00973             for(i=pfunc->nvars;i<2*pfunc->nvars;i++){
00974                 ppop1[i]=new COperation(pfunc->op.Diff(*pfunc->ppvar[i-pfunc->nvars]));
00975                 for(j=0;j<pfunc->nvars;j++)
00976                     *ppop1[i]=ppop1[i]->Substitute(*pfunc->ppvar[j],mmb2->NthMember(j+1));
00977                 *ppop1[i]=(mmb2->NthMember(i+1-pfunc->nvars).DiffConj(var))*(*ppop1[i]);
00978             }
00979             op2=ApplyOperator(2*pfunc->nvars,ppop1,&::operator+);
00980             for(i=0;i<2*pfunc->nvars;i++)delete ppop1[i];
00981             delete[]ppop1;
00982             return op2;
00983             // In the obtained expression, f' will have been replaced with its expression but f will remain pointing to itself ; this could cause some trouble if changing f afterwards
00984         }
00985     default:return ErrVal;
00986     };
00987 }
00988 
00989 char* formatreal(double x)
00990 {
00991     char*s=new char[20];
00992     if(x==0)s[0]=0;
00993     else if(x==(double)3.141592653589793238462643383279L)sprintf(s,"pi");
00994     else sprintf(s,"%.8g",x);
00995     return s;
00996 }
00997 
00998 char* formatimag(double x)
00999 {
01000     char*s=new char[20];
01001     if(x==0)s[0]=0;
01002     else if(x==1)sprintf(s,"i");
01003     else if(x==-1)sprintf(s,"-i");
01004     else if(x==(double)3.141592653589793238462643383279L)sprintf(s,"i pi");
01005     else if(x==(double)(-3.141592653589793238462643383279L))sprintf(s,"-i pi");
01006     else sprintf(s,"%.8g i",x);
01007     return s;
01008 }
01009 
01010 char* PrettyPrint(double_complex x)
01011 {
01012     char*s=new char[30],*s1=formatreal(real(x)),*s2=formatimag(imag(x));
01013     if(!strlen(s1)&&!strlen(s2))sprintf(s,"0");
01014     else if(x==double_complex(0,1))sprintf(s,"i");
01015     else if(!strlen(s1))sprintf(s,"(%s)",s2);
01016     else if(!strlen(s2))sprintf(s,"%s",s1);
01017     else if(imag(x)>0)sprintf(s,"(%s+%s)",s1,s2);
01018     else sprintf(s,"(%s%s)",s1,s2);
01019     delete s1, delete s2;
01020     return s;
01021 }
01022 
01023 char* COperation::Expr() const
01024 {
01025     char*s=NULL,*s1=NULL,*s2=NULL;int n=10;signed char f=0,g=0;
01026     if(op==Fun)if(strlen(pfunc->name)>4)n+=strlen(pfunc->name)-4;
01027 if(mmb1!=NULL){s1=mmb1->Expr();n+=strlen(s1);f=IsFunction(mmb1->op);}
01028     if(mmb2!=NULL){s2=mmb2->Expr();n+=strlen(s2);g=IsFunction(mmb2->op);}
01029     s=new char[n];
01030     switch(op){
01031     case Num:return PrettyPrint(ValC);
01032     case Var:return CopyStr(pvar->name);
01033     case Juxt:sprintf(s,"%s , %s",s1,s2);break;
01034     case Add:
01035         f=f||(mmb1->op==Juxt);
01036         g=g||(mmb2->op==Juxt);
01037         if(f&&g)sprintf(s,"(%s)+(%s)",s1,s2);else
01038         if(f)sprintf(s,"(%s)+%s",s1,s2);else
01039         if(g)sprintf(s,"%s+(%s)",s1,s2);else
01040         sprintf(s,"%s+%s",s1,s2);
01041         break;
01042     case Sub:
01043         f=f||(mmb1->op==Juxt);
01044         g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub);
01045         if(f&&g)sprintf(s,"(%s)-(%s)",s1,s2);else
01046         if(f)sprintf(s,"(%s)-%s",s1,s2);else
01047         if(g)sprintf(s,"%s-(%s)",s1,s2);else
01048         sprintf(s,"%s-%s",s1,s2);
01049         break;
01050     case Opp:
01051         if(mmb2->op==Add||mmb2->op==Sub||mmb2->op==Juxt)sprintf(s,"-(%s)",s2);else
01052         sprintf(s,"-%s",s2);
01053         break;
01054     case Mult:
01055         f=f||(mmb1->op==Juxt||mmb1->op==Add||mmb1->op==Sub||mmb1->op==Opp);
01056         g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub||mmb2->op==Opp);
01057         if(f&&g)sprintf(s,"(%s)*(%s)",s1,s2);else
01058         if(f)sprintf(s,"(%s)*%s",s1,s2);else
01059         if(g)sprintf(s,"%s*(%s)",s1,s2);else
01060         sprintf(s,"%s*%s",s1,s2);
01061         break;
01062     case Div:
01063         f=f||(mmb1->op==Juxt||mmb1->op==Add||mmb1->op==Sub||mmb1->op==Opp||mmb1->op==Div);
01064         g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub||mmb2->op==Opp||mmb2->op==Mult||mmb2->op==Div);
01065         if(f&&g)sprintf(s,"(%s)/(%s)",s1,s2);else
01066         if(f)sprintf(s,"(%s)/%s",s1,s2);else
01067         if(g)sprintf(s,"%s/(%s)",s1,s2);else
01068         sprintf(s,"%s/%s",s1,s2);
01069         break;
01070     case Pow:
01071         f=(mmb1->op!=Num&&mmb1->op!=Var);
01072         g=(mmb2->op!=Num&&mmb2->op!=Var);
01073         if(f&&g)sprintf(s,"(%s)^(%s)",s1,s2);else
01074         if(f)sprintf(s,"(%s)^%s",s1,s2);else
01075         if(g)sprintf(s,"%s^(%s)",s1,s2);else
01076         sprintf(s,"%s^%s",s1,s2);
01077         break;
01078     case Sqrt:
01079         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01080         if(g)sprintf(s,"sqrt(%s)",s2);
01081         else sprintf(s,"sqrt %s",s2);
01082         break;
01083     case NthRoot:
01084         f=(mmb1->op!=Num&&mmb1->op!=Var);
01085         g=(mmb2->op!=Num&&mmb2->op!=Var);
01086         if(f&&g)sprintf(s,"(%s)#(%s)",s1,s2);else
01087         if(f)sprintf(s,"(%s)#%s",s1,s2);else
01088         if(g)sprintf(s,"%s#(%s)",s1,s2);else
01089         sprintf(s,"%s#%s",s1,s2);
01090         break;
01091     case E10:
01092         f=(mmb1->op!=Num&&mmb1->op!=Var);
01093         g=(mmb2->op!=Num&&mmb2->op!=Var);
01094         if(f&&g)sprintf(s,"(%s)E(%s)",s1,s2);else
01095         if(f)sprintf(s,"(%s)E%s",s1,s2);else
01096         if(g)sprintf(s,"%sE(%s)",s1,s2);else
01097         sprintf(s,"%sE%s",s1,s2);
01098         break;
01099     case Ln:
01100         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01101         if(g)sprintf(s,"log(%s)",s2);
01102         else sprintf(s,"log %s",s2);
01103         break;
01104     case Exp:
01105         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01106         if(g)sprintf(s,"exp(%s)",s2);
01107         else sprintf(s,"exp %s",s2);
01108         break;
01109     case Sin:
01110         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01111         if(g)sprintf(s,"sin(%s)",s2);
01112         else sprintf(s,"sin %s",s2);
01113         break;
01114     case Cos:
01115         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01116         if(g)sprintf(s,"cos(%s)",s2);
01117         else sprintf(s,"cos %s",s2);
01118         break;
01119     case Tg:
01120         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01121         if(g)sprintf(s,"tan(%s)",s2);
01122         else sprintf(s,"tan %s",s2);
01123         break;
01124     case Atan:
01125         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01126         if(g)sprintf(s,"atan(%s)",s2);
01127         else sprintf(s,"atan %s",s2);
01128         break;
01129     case Asin:
01130         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01131         if(g)sprintf(s,"asin(%s)",s2);
01132         else sprintf(s,"asin %s",s2);
01133         break;
01134     case Acos:
01135         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01136         if(g)sprintf(s,"acos(%s)",s2);
01137         else sprintf(s,"acos %s",s2);
01138         break;
01139     case Abs:
01140         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01141         if(g)sprintf(s,"abs(%s)",s2);
01142         else sprintf(s,"abs %s",s2);
01143         break;
01144     case Real:
01145         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01146         if(g)sprintf(s,"real(%s)",s2);
01147         else sprintf(s,"real %s",s2);
01148         break;
01149     case Imag:
01150         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01151         if(g)sprintf(s,"imag(%s)",s2);
01152         else sprintf(s,"imag %s",s2);
01153         break;
01154     case Conj:
01155         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01156         if(g)sprintf(s,"conj(%s)",s2);
01157         else sprintf(s,"conj %s",s2);
01158         break;
01159     case Arg:
01160         g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
01161         if(g)sprintf(s,"arg(%s)",s2);
01162         else sprintf(s,"arg %s",s2);
01163         break;
01164     case Fun:
01165         sprintf(s,"%s(%s)",pfunc->name,s2);
01166         break;
01167     default:return CopyStr("Error");
01168     };
01169     if(s1!=NULL)delete[] s1;if(s2!=NULL)delete[] s2;
01170     return s;
01171 }
01172 
01173 const double sqrtmaxfloat=sqrt(DBL_MAX);
01174 const double sqrtminfloat=sqrt(DBL_MIN);
01175 
01176 void Addition(double_complex*&p)
01177 {if(*p==ErrVal||norm(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01178     if(*(--p)==ErrVal||norm(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01179     *p+=(*(p+1));}
01180 void Soustraction(double_complex*&p)
01181 {if(*p==ErrVal||norm(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01182     if(*(--p)==ErrVal||norm(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01183     *p-=(*(p+1));}
01184 void Multiplication(double_complex*&p)
01185 {if(norm(*p)<sqrtminfloat){*--p=0;return;};
01186     if(*p==ErrVal||norm(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01187     if(norm(*(--p))<sqrtminfloat){*p=0;return;};
01188     if(*p==ErrVal||norm(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01189     *p*=(*(p+1));}
01190 void Division(double_complex*&p)
01191 {if(norm(*p)<sqrtminfloat||*p==ErrVal||norm(*p)>sqrtmaxfloat)
01192     {*(--p)=ErrVal;return;};
01193     if(norm(*(--p))<sqrtminfloat)*p=0;else if(*p==ErrVal||norm(*p)>sqrtmaxfloat)
01194     {*p=ErrVal;return;};
01195     *p/=(*(p+1));}
01196 void Puissance(double_complex*&p)
01197 {double_complex v2=*p--,v1=*p;
01198     if(v2==ErrVal||v1==ErrVal||norm(v2)*log(norm(v1))>DBL_MAX_EXP){*p=ErrVal;return;};
01199     *p=(v1==0.?0:pow(v1,v2));}
01200 void RacineN(double_complex*&p)
01201 {double_complex v2=*p--,v1=*p;
01202     if(v1==ErrVal||v2==ErrVal||v1==0.||norm(v2)*log(norm(v1))<DBL_MIN_EXP){*p=ErrVal;return;};
01203     *p=pow(v2,double_complex(1,0)/v1);return;}
01204 void Puiss10(double_complex*&p)
01205 {if(norm(*p)<sqrtminfloat){*(--p)=0;return;};
01206     if(*p==ErrVal||norm(*p)>DBL_MAX_10_EXP){*(--p)=ErrVal;return;};
01207     if(norm(*(--p))<sqrtminfloat)*p=0;else if(*p==ErrVal||norm(*p)>sqrtmaxfloat)
01208     {*p=ErrVal;return;};
01209     *p*=pow(double_complex(10.),*(p+1));}
01210 void NextVal(double_complex*&){}
01211 void  RFunc(double_complex*&){}
01212 void  JuxtF(double_complex*&){}
01213 void Absolu(double_complex*&p){*p=((*p==ErrVal)?ErrVal:norm(*p));}
01214 void Oppose(double_complex*&p){*p=((*p==ErrVal)?ErrVal:-*p);}
01215 void Reelle(double_complex*&p){*p=((*p==ErrVal)?ErrVal:real(*p));}
01216 void Imaginaire(double_complex*&p){*p=((*p==ErrVal)?ErrVal:imag(*p));}
01217 void Conjugue(double_complex*&p){*p=((*p==ErrVal)?ErrVal:conj(*p));}
01218 void ArcSinus(double_complex*&p)
01219 {*p=((*p==ErrVal)?ErrVal:asin(*p));}
01220 void ArcCosinus(double_complex*&p)
01221 {*p=((*p==ErrVal||*p==double_complex(0,1)||*p==double_complex(0,-1))?ErrVal:acos(*p));}
01222 void ArcTangente(double_complex*&p)
01223 {*p=((*p==ErrVal)?ErrVal:atan(*p));}
01224 void Logarithme(double_complex*&p)
01225 {*p=((*p==ErrVal||*p==0.)?ErrVal:log(*p));}
01226 void Argument(double_complex*&p)
01227 {*p=((*p==ErrVal||*p==0.)?ErrVal:arg(*p));}
01228 void Exponentielle(double_complex*&p)
01229 {*p=((*p==ErrVal||norm(*p)>DBL_MAX_EXP)?ErrVal:exp(*p));}
01230 void Sinus(double_complex*&p)
01231 {*p=((*p==ErrVal||norm(*p)>DBL_MAX_EXP)?ErrVal:sin(*p));}
01232 void Tangente(double_complex*&p)
01233 {*p=((*p==ErrVal||norm(*p)>DBL_MAX_EXP)?ErrVal:tan(*p));}
01234 void Cosinus(double_complex*&p)
01235 {*p=((*p==ErrVal||norm(*p)>DBL_MAX_EXP)?ErrVal:cos(*p));}
01236 void Racine(double_complex*&p)
01237 {*p=((*p==ErrVal||norm(*p)>sqrtmaxfloat)?ErrVal:sqrt(*p));}
01238 void FonctionError(double_complex*&p){*p=ErrVal;}
01239 inline void ApplyRFunc(PCFunction rf,double_complex*&p)
01240 {p-=rf->nvars-1;*p=rf->Val(p);}
01241 
01242 double_complex COperation::Val() const
01243 {
01244     pfoncld*p1=pinstr;double_complex**p2=pvals,*p3=ppile-1;PCFunction*p4=pfuncpile;
01245     for(;*p1!=NULL;p1++)
01246         if(*p1==&NextVal)*(++p3)=**(p2++);else
01247     if(*p1==&RFunc) ApplyRFunc(*(p4++),p3);
01248     else (**p1)(p3);
01249     return *p3;
01250 }
01251 
01252 void BCDouble(pfoncld*&pf,pfoncld*pf1,pfoncld*pf2,
01253               double_complex**&pv,double_complex**pv1,double_complex**pv2,
01254               double_complex*&pp,double_complex*pp1,double_complex*pp2,
01255               CFunction**&prf,CFunction**prf1,CFunction**prf2,
01256               pfoncld f)
01257 {
01258     pfoncld*pf3,*pf4=pf1;long n1,n2;
01259     for(n1=0;*pf4!=NULL;pf4++,n1++);for(n2=0,pf4=pf2;*pf4!=NULL;pf4++,n2++);
01260     pf=new pfoncld[n1+n2+2];
01261     for(pf3=pf,pf4=pf1;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01262     for(pf4=pf2;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01263     *pf3++=f;*pf3=NULL;//delete[]pf1,pf2;
01264     double_complex**pv3,**pv4=pv1;
01265     for(n1=0;*pv4!=NULL;pv4++,n1++);for(n2=0,pv4=pv2;*pv4!=NULL;pv4++,n2++);
01266     pv=new double_complex*[n1+n2+1];
01267     for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01268     for(pv4=pv2;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01269     *pv3=NULL;//delete[]pv1,pv2;
01270     double_complex*pp3,*pp4=pp1;
01271     for(n1=0;*pp4!=ErrVal;pp4++,n1++);for(n2=0,pp4=pp2;*pp4!=ErrVal;pp4++,n2++);
01272     pp=new double_complex[n1+n2+1];  // Really need to add and not to take max(n1,n2) in case of Juxt operator
01273     for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01274     for(pp4=pp2;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01275     *pp3=ErrVal;//delete[]pp1,pp2;
01276     PCFunction*prf3,*prf4=prf1;
01277     for(n1=0;*prf4!=NULL;prf4++,n1++);for(n2=0,prf4=prf2;*prf4!=NULL;prf4++,n2++);
01278     prf=new PCFunction[n1+n2+1];
01279     for(prf3=prf,prf4=prf1;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01280     for(prf4=prf2;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01281     *prf3=NULL;//delete[]prf1,prf2;
01282 }
01283 
01284 void BCSimple(pfoncld*&pf,pfoncld*pf1,double_complex**&pv,double_complex**pv1,
01285               double_complex*&pp,double_complex*pp1,CFunction**&prf,CFunction**prf1,pfoncld f)
01286 {
01287     pfoncld*pf3,*pf4=pf1;long n;
01288     for(n=0;*pf4!=NULL;pf4++,n++);
01289     pf=new pfoncld[n+2];
01290     for(pf4=pf1,pf3=pf;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01291     *pf3++=f;*pf3=NULL;//delete[]pf1;
01292     double_complex**pv3,**pv4=pv1;
01293     for(n=0;*pv4!=NULL;pv4++,n++);
01294     pv=new double_complex*[n+1];
01295     for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01296     *pv3=NULL;//delete[]pv1;
01297     double_complex*pp3,*pp4=pp1;
01298     for(n=0;*pp4!=ErrVal;pp4++,n++);
01299     pp=new double_complex[n+1];
01300     for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01301     *pp3=ErrVal;//delete[]pp1;
01302     CFunction**prf3,**prf4=prf1;
01303     for(n=0;*prf4!=NULL;prf4++,n++);
01304     prf=new CFunction*[n+1];
01305     for(prf3=prf,prf4=prf1;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01306     *prf3=NULL;//delete[]prf1;
01307 }
01308 
01309 void BCFun(pfoncld*&pf,pfoncld*pf1,double_complex**&pv,double_complex**pv1,
01310            double_complex*&pp,double_complex*pp1,CFunction**&prf,CFunction**prf1,PCFunction rf)
01311 {
01312     pfoncld*pf3,*pf4=pf1;long n;
01313     for(n=0;*pf4!=NULL;pf4++,n++);
01314     pf=new pfoncld[n+2];
01315     for(pf4=pf1,pf3=pf;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01316     *pf3++=&RFunc;*pf3=NULL;//delete[]pf1;
01317     double_complex**pv3,**pv4=pv1;
01318     for(n=0;*pv4!=NULL;pv4++,n++);
01319     pv=new double_complex*[n+1];
01320     for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01321     *pv3=NULL;//delete[]pv1;
01322     double_complex*pp3,*pp4=pp1;
01323     for(n=0;*pp4!=ErrVal;pp4++,n++);
01324     pp=new double_complex[n+1];
01325     for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01326     *pp3=ErrVal;//delete[]pp1;
01327     PCFunction*prf3,*prf4=prf1;
01328     for(n=0;*prf4!=NULL;prf4++,n++);
01329     prf=new PCFunction[n+2];
01330     for(prf4=prf1,prf3=prf;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01331     *prf3++=rf;*prf3=NULL;//delete[]pf1;
01332 }
01333 
01334 void COperation::BuildCode()
01335 {
01336     //  if(mmb1!=NULL)mmb1->BuildCode();if(mmb2!=NULL)mmb2->BuildCode();
01337     if(pinstr!=NULL){delete[]pinstr;pinstr=NULL;}
01338     if(pvals!=NULL){delete[]pvals;pvals=NULL;}
01339     if(ppile!=NULL){delete[]ppile;ppile=NULL;}
01340     if(pfuncpile!=NULL){delete[]pfuncpile;pfuncpile=NULL;}
01341     switch(op){
01342     case ErrOp:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01343         pvals=new double_complex*[2];pvals[0]=new double_complex(ErrVal);pvals[1]=NULL;
01344         ppile=new double_complex[2];ppile[0]=0;ppile[1]=ErrVal;
01345         pfuncpile=new CFunction*[1];pfuncpile[0]=NULL;
01346         break;
01347     case Num:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01348         pvals=new double_complex*[2];pvals[0]=new double_complex(ValC);pvals[1]=NULL;
01349         ppile=new double_complex[2];ppile[0]=0;ppile[1]=ErrVal;
01350         pfuncpile=new CFunction*[1];pfuncpile[0]=NULL;break;
01351     case Var:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01352         pvals=new double_complex*[2];pvals[0]=pvarval;pvals[1]=NULL;
01353         ppile=new double_complex[2];ppile[0]=0;ppile[1]=ErrVal;
01354         pfuncpile=new CFunction*[1];pfuncpile[0]=NULL;break;
01355     case Juxt:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01356                            pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&JuxtF);
01357 break;case Add:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01358                                 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Addition);
01359 break;case Sub:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01360                                 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Soustraction);
01361 break;case Mult:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01362                                  pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Multiplication);
01363 break;case Div:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01364                                 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Division);
01365 break;case Pow:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01366                                 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Puissance);
01367 break;case NthRoot:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01368                                     pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&RacineN);
01369 break;case E10:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01370                                 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Puiss10);
01371 break;case Opp:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01372                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Oppose);
01373 break;case Sin:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01374                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Sinus);
01375 break;case Sqrt:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01376                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Racine);
01377 break;case Ln:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01378                                ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Logarithme);
01379 break;case Exp:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01380                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Exponentielle);
01381 break;case Cos:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01382                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Cosinus);
01383 break;case Tg:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01384                                ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Tangente);
01385 break;case Atan:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01386                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&ArcTangente);
01387 break;case Asin:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01388                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&ArcSinus);
01389 break;case Acos:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01390                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&ArcCosinus);
01391 break;case Abs:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01392                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Absolu);
01393 break;case Real:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01394                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Reelle);
01395 break;case Imag:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01396                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Imaginaire);
01397 break;case Conj:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01398                                  ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Conjugue);
01399 break;case Arg:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01400                                 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Argument);
01401 break;case Fun:BCFun(pinstr,mmb2->pinstr,pvals,mmb2->pvals,ppile,
01402                              mmb2->ppile,pfuncpile,mmb2->pfuncpile,pfunc);
01403 break;default:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01404                                ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&FonctionError);
01405     }
01406 }

Generated on Sat Mar 15 22:55:57 2008 for Armagetron Advanced by  doxygen 1.5.4