00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <math.h>
00024
00025 #include <string.h>
00026 #include <stdio.h>
00027 #include <ctype.h>
00028 #include <errno.h>
00029 #include "moremath.h"
00030 #include "equ.h"
00031 #include "parser.h"
00032 #include "func.h"
00033 #include "functext.h"
00034 #include "errors.h"
00035
00036
00037 Equation::Equation() : TTree()
00038 {
00039 Radians = true;
00040 EquationText = new char[1];
00041 EquationText[0] = 0;
00042 Variables.setAutoDelete(1);
00043 }
00044
00045
00046 Equation::~Equation()
00047 {
00048 delete [] EquationText;
00049 Variables.clear();
00050 }
00051
00052
00053 double
00054 Equation::Evaluate()
00055 {
00056 Node *TreePos;
00057 variable *Variable;
00058 TreePos=Root;
00059 errno = 0;
00060
00061 Reset(0);
00062 try {
00063 while (Root->Brackets==0) {
00064 while (TreePos->Child_One!=NULL) {
00065 if ((TreePos->Child_One)->Brackets==1) break;
00066 TreePos=TreePos->Child_One;
00067 };
00068 switch (TreePos->Type) {
00069 case MTK_NUMBER :
00070 (TreePos->CurrentValue)=(TreePos->Value).Number;
00071 (TreePos->Brackets)=1;
00072 break;
00073 case MTK_VARIABLE :
00074 Variable=Variables.at( TreePos->Value.WhichVar - 1);
00075 if (Variable==NULL) {
00076 throw ERR_VARIABLES;
00077 };
00078 TreePos->CurrentValue = Variable->Value;
00079 TreePos->Brackets = 1;
00080 break;
00081 case MTK_PI_SYM :
00082 TreePos->CurrentValue = 3.14159265358979323846;
00083 TreePos->Brackets = 1;
00084 break;
00085 default :
00086 break;
00087 };
00088 TreePos = TreePos->Parent;
00089 if (TreePos==NULL) break;
00090 if (TreePos->Child_Two==NULL) {
00091 EvalNode(TreePos);
00092 }
00093 else {
00094 if (TreePos->Child_Two->Brackets==0) {
00095 TreePos=TreePos->Child_Two;
00096 }
00097 else {
00098 EvalNode(TreePos);
00099 };
00100 };
00101 };
00102 }
00103 catch(...) {
00104 Reset(2);
00105 throw;
00106 }
00107 return (Root->CurrentValue);
00108 }
00109
00110
00111 void
00112 Equation::EvalNode(Node *TreePos)
00113 {
00114 if (errno) {
00115 switch (errno) {
00116 case EDIVZERO :
00117 errno=EZERO;
00118 throw ERR_DIV_ZERO;
00119 case ERANGE :
00120 errno=EZERO;
00121 throw ERANGE;
00122 case EINEXACT :
00123 errno=EZERO;
00124 throw ERR_INEXACT;
00125 };
00126 };
00127
00128 if ( TreePos->evalfn ) {
00129 if ( Radians || (TreePos->Type < MTK_SIN) || ( TreePos->Type > MTK_ARCTAN) ) {
00130 TreePos->CurrentValue = (*(TreePos->evalfn))((TreePos->Child_One)->CurrentValue);
00131 }
00132 else {
00133 if ( TreePos->Type <= MTK_COT )
00134 TreePos->CurrentValue = (*(TreePos->evalfn))((TreePos->Child_One)->CurrentValue*DEGTORAD);
00135 else
00136 TreePos->CurrentValue = (*(TreePos->evalfn))((TreePos->Child_One)->CurrentValue)/DEGTORAD;
00137 }
00138 }
00139 else {
00140 switch (TreePos->Type) {
00141 case MTK_ADD :
00142 TreePos->CurrentValue=((TreePos->Child_One)->CurrentValue)
00143 + ((TreePos->Child_Two)->CurrentValue);
00144 break;
00145 case MTK_SUBTRACT :
00146 TreePos->CurrentValue=((TreePos->Child_One)->CurrentValue)
00147 - ((TreePos->Child_Two)->CurrentValue);
00148 break;
00149 case MTK_MULTIPLY :
00150 TreePos->CurrentValue=((TreePos->Child_One)->CurrentValue)
00151 * ((TreePos->Child_Two)->CurrentValue);
00152 break;
00153 case MTK_DIVIDE :
00154 if (TreePos->Child_Two->CurrentValue == 0) {
00155 throw ERR_DIV_ZERO;
00156 };
00157 TreePos->CurrentValue= TreePos->Child_One->CurrentValue
00158 / TreePos->Child_Two->CurrentValue;
00159 break;
00160 case MTK_POWER :
00161 TreePos->CurrentValue=pow(TreePos->Child_One->CurrentValue
00162 ,TreePos->Child_Two->CurrentValue);
00163 break;
00164 case MTK_COMBINATION :
00165 TreePos->CurrentValue=combination(TreePos->Child_One->CurrentValue
00166 ,TreePos->Child_Two->CurrentValue);
00167 break;
00168 case MTK_PERMUTATION :
00169 TreePos->CurrentValue=permutation(TreePos->Child_One->CurrentValue
00170 ,TreePos->Child_Two->CurrentValue);
00171 break;
00172 case MTK_BESSJ :
00173 TreePos->CurrentValue=ansi_jn( (int)(TreePos->Child_One->CurrentValue) , TreePos->Child_Two->CurrentValue );
00174 break;
00175 default :
00176 throw ERR_FUNCTION;
00177 }
00178 }
00179 switch (errno) {
00180 case EDOM :
00181 errno=EZERO;
00182 throw ERR_DOM;
00183 case ERANGE :
00184 errno=EZERO;
00185 throw ERR_RANGE;
00186 };
00187 TreePos->Brackets=1;
00188 }
00189
00190
00191 char *
00192 Equation::VarText(int num)
00193 {
00194 variable *temp;
00195 temp = Variables.at(num - 1);
00196 if (temp)
00197 return temp->Name;
00198 else
00199 return "";
00200 }
00201
00202
00203 double
00204 Equation::VarValue(int num)
00205 {
00206 variable *temp;
00207
00208 char memnan[8];
00209 memset(memnan, 0, 8);
00210 memnan[6] = (char) 0xF8;
00211 memnan[7] = (char) 0x7F;
00212 double *mynan = (double *)(memnan);
00213
00214 temp = Variables.at(num - 1);
00215 if (temp)
00216 return temp->Value;
00217 else
00218 return *mynan;
00219 }
00220
00221
00222 void
00223 Equation::Differentiate(Equation *Differential, int Var, Parser *parser)
00224 {
00225 variable *PointerFrom, *PointerTo;
00226 DiffVar=Var;
00227 delete (Differential->Root);
00228 DiffFromNode(Root,&(Differential->Root));
00229 if (Differential->Root!=NULL) (Differential->Root)->Parent=NULL;
00230 PointerFrom = Variables.first();
00231 while ( PointerFrom != NULL ) {
00232 PointerTo = new variable;
00233 PointerTo->Value = PointerFrom->Value;
00234 Differential->Variables.append(PointerTo);
00235 strcpy(PointerTo->Name,PointerFrom->Name);
00236 PointerFrom = Variables.next();
00237 };
00238 parser->TreeToText(Differential);
00239 }
00240
00241
00242 void
00243 Equation::DiffFromNode(Node *Start, Node **Hook)
00244 {
00245 Node *Temp;
00246
00247 switch (Start->Type)
00248 {
00249 case MTK_ADD : case MTK_SUBTRACT :
00250 *Hook=new Node;
00251 InitNode((*Hook),Start->Type);
00252 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00253 ((*Hook)->Child_One)->Parent=(*Hook);
00254 DiffFromNode(Start->Child_Two,&((*Hook)->Child_Two));
00255 ((*Hook)->Child_Two)->Parent=(*Hook);
00256 break;
00257 case MTK_MULTIPLY :
00258 *Hook=new Node;
00259 InitNode((*Hook),MTK_ADD);
00260 AddBelowOne(*Hook,MTK_MULTIPLY);
00261 ((*Hook)->Child_One)->Child_One=new Node;
00262 Copy(Start->Child_One,((*Hook)->Child_One)->Child_One);
00263 (((*Hook)->Child_One)->Child_One)->Parent=(*Hook)->Child_One;
00264 DiffFromNode(Start->Child_Two,&(((*Hook)->Child_One)->Child_Two));
00265 (((*Hook)->Child_One)->Child_Two)->Parent=(*Hook)->Child_One;
00266 AddBelowTwo(*Hook,MTK_MULTIPLY);
00267 ((*Hook)->Child_Two)->Child_One=new Node;
00268 Copy(Start->Child_Two,((*Hook)->Child_Two)->Child_One);
00269 (((*Hook)->Child_Two)->Child_One)->Parent=(*Hook)->Child_Two;
00270 DiffFromNode(Start->Child_One,&(((*Hook)->Child_Two)->Child_Two));
00271 (((*Hook)->Child_Two)->Child_Two)->Parent=(*Hook)->Child_Two;
00272 break;
00273 case MTK_DIVIDE :
00274 *Hook=new Node;
00275 InitNode((*Hook),MTK_SUBTRACT);
00276 AddBelowOne(*Hook,MTK_DIVIDE);
00277 ((*Hook)->Child_One)->Child_Two=new Node;
00278 Copy(Start->Child_Two,((*Hook)->Child_One)->Child_Two);
00279 (((*Hook)->Child_One)->Child_Two)->Parent=(*Hook)->Child_One;
00280 DiffFromNode(Start->Child_One,&(((*Hook)->Child_One)->Child_One));
00281 (((*Hook)->Child_One)->Child_One)->Parent=(*Hook)->Child_One;
00282 AddBelowTwo(*Hook,MTK_DIVIDE);
00283 AddBelowOne((*Hook)->Child_Two,MTK_MULTIPLY);
00284 AddBelowTwo((*Hook)->Child_Two,MTK_POWER);
00285 (((*Hook)->Child_Two)->Child_One)->Child_One=new Node;
00286 Copy(Start->Child_One,(((*Hook)->Child_Two)->Child_One)->Child_One);
00287 ((((*Hook)->Child_Two)->Child_One)->Child_One)->Parent=((*Hook)->Child_Two)->Child_One;
00288 DiffFromNode(Start->Child_Two,&((((*Hook)->Child_Two)->Child_One)->Child_Two));
00289 ((((*Hook)->Child_Two)->Child_One)->Child_Two)->Parent=((*Hook)->Child_Two)->Child_One;
00290 (((*Hook)->Child_Two)->Child_Two)->Child_One=new Node;
00291 Copy(Start->Child_Two,(((*Hook)->Child_Two)->Child_Two)->Child_One);
00292 ((((*Hook)->Child_Two)->Child_Two)->Child_One)->Parent=((*Hook)->Child_Two)->Child_Two;
00293 AddBelowTwo(((*Hook)->Child_Two)->Child_Two,MTK_NUMBER,2);
00294 break;
00295 case MTK_POWER :
00296 *Hook = new Node;
00297 InitNode(*Hook, MTK_ADD);
00298 AddBelowOne(*Hook,MTK_MULTIPLY);
00299 AddBelowOne((*Hook)->Child_One,MTK_MULTIPLY);
00300 AddBelowTwo(*Hook,MTK_MULTIPLY);
00301 AddBelowOne((*Hook)->Child_Two,MTK_MULTIPLY);
00302
00303 (*Hook)->Child_One->Child_One->Child_One = new Node;
00304 (*Hook)->Child_One->Child_One->Child_One->Parent =
00305 (*Hook)->Child_One->Child_One;
00306 Copy(Start, (*Hook)->Child_One->Child_One->Child_One );
00307 AddBelowTwo((*Hook)->Child_One->Child_One, MTK_LN);
00308 (*Hook)->Child_One->Child_One->Child_Two->Child_One = new Node;
00309 (*Hook)->Child_One->Child_One->Child_Two->Child_One->Parent =
00310 (*Hook)->Child_One->Child_One->Child_Two;
00311 Copy(Start->Child_One, (*Hook)->Child_One->Child_One->Child_Two->Child_One);
00312 DiffFromNode(Start->Child_Two,&((*Hook)->Child_One->Child_Two));
00313 (*Hook)->Child_One->Child_Two->Parent
00314 = (*Hook)->Child_One;
00315
00316 (*Hook)->Child_Two->Child_One->Child_One = new Node;
00317 (*Hook)->Child_Two->Child_One->Child_One->Parent =
00318 (*Hook)->Child_Two->Child_One;
00319 Copy(Start, (*Hook)->Child_Two->Child_One->Child_One );
00320 Temp = new Node;
00321 InitNode(Temp, MTK_SUBTRACT);
00322 Temp->Parent = (*Hook)->Child_Two->Child_One->Child_One;
00323 Temp->Child_One = (*Hook)->Child_Two->Child_One->Child_One->Child_Two;
00324 Temp->Parent->Child_Two = Temp;
00325 Temp->Child_One->Parent = Temp;
00326 AddBelowTwo(Temp, MTK_NUMBER, 1);
00327 (*Hook)->Child_Two->Child_One->Child_Two = new Node;
00328 (*Hook)->Child_Two->Child_One->Child_Two->Parent =
00329 (*Hook)->Child_Two->Child_One;
00330 Copy(Start->Child_Two, (*Hook)->Child_Two->Child_One->Child_Two);
00331 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two->Child_Two));
00332 (*Hook)->Child_Two->Child_Two->Parent = (*Hook)->Child_Two;
00333 break;
00334 case MTK_SIN :
00335 *Hook=new Node;
00336 InitNode((*Hook),MTK_MULTIPLY);
00337 AddBelowOne(*Hook,MTK_COS);
00338 ((*Hook)->Child_One)->Child_One=new Node;
00339 Copy(Start->Child_One,((*Hook)->Child_One)->Child_One);
00340 (((*Hook)->Child_One)->Child_One)->Parent=(*Hook)->Child_One;
00341 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00342 ((*Hook)->Child_Two)->Parent=(*Hook);
00343 break;
00344 case MTK_COS :
00345 (*Hook)=new Node;
00346 InitNode((*Hook),MTK_MULTIPLY);
00347 AddBelowOne((*Hook),MTK_MULTIPLY);
00348 AddBelowOne((*Hook)->Child_One,MTK_NUMBER,-1);
00349 AddBelowTwo((*Hook)->Child_One,MTK_SIN);
00350 (((*Hook)->Child_One)->Child_Two)->Child_One=new Node;
00351 Copy(Start->Child_One,(((*Hook)->Child_One)->Child_Two)->Child_One);
00352 ((((*Hook)->Child_One)->Child_Two)->Child_One)->Parent=((*Hook)->Child_One)->Child_Two;
00353 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00354 ((*Hook)->Child_Two)->Parent=(*Hook);
00355 break;
00356 case MTK_TAN :
00357 (*Hook)=new Node;
00358 InitNode((*Hook),MTK_MULTIPLY);
00359 AddBelowOne((*Hook),MTK_POWER);
00360 AddBelowOne((*Hook)->Child_One,MTK_SEC);
00361 AddBelowTwo((*Hook)->Child_One,MTK_NUMBER,2);
00362 (((*Hook)->Child_One)->Child_One)->Child_One=new Node;
00363 Copy(Start->Child_One,(((*Hook)->Child_One)->Child_One)->Child_One);
00364 ((((*Hook)->Child_One)->Child_One)->Child_One)->Parent=((*Hook)->Child_One)->Child_One;
00365 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00366 ((*Hook)->Child_Two)->Parent=(*Hook);
00367 break;
00368 case MTK_SEC :
00369 *Hook=new Node;
00370 InitNode((*Hook),MTK_MULTIPLY);
00371 AddBelowOne(*Hook,MTK_MULTIPLY);
00372 Temp = (*Hook)->Child_One;
00373 AddBelowOne(Temp,MTK_SEC);
00374 Temp->Child_One->Child_One=new Node;
00375 Copy(Start->Child_One,Temp->Child_One->Child_One);
00376 Temp->Child_One->Child_One->Parent=Temp->Child_One;
00377 AddBelowTwo(Temp,MTK_TAN);
00378 Temp->Child_Two->Child_One=new Node;
00379 Copy(Start->Child_One,Temp->Child_Two->Child_One);
00380 Temp->Child_Two->Child_One->Parent=Temp->Child_Two;
00381 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00382 ((*Hook)->Child_Two)->Parent=(*Hook);
00383 break;
00384 case MTK_COSEC :
00385 *Hook=new Node;
00386 InitNode((*Hook),MTK_MULTIPLY);
00387 AddBelowOne(*Hook,MTK_MULTIPLY);
00388 Temp = (*Hook)->Child_One;
00389 AddBelowOne(Temp,MTK_MULTIPLY);
00390 Temp = Temp->Child_One;
00391 AddBelowOne(Temp,MTK_NUMBER,-1);
00392 AddBelowTwo(Temp,MTK_COSEC);
00393 Temp->Child_Two->Child_One=new Node;
00394 Copy(Start->Child_One,Temp->Child_Two->Child_One);
00395 Temp->Child_Two->Child_One->Parent=Temp->Child_Two;
00396 Temp = Temp->Parent;
00397 AddBelowTwo(Temp,MTK_COT);
00398 Temp->Child_Two->Child_One=new Node;
00399 Copy(Start->Child_One,Temp->Child_Two->Child_One);
00400 Temp->Child_Two->Child_One->Parent=Temp->Child_Two;
00401 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00402 ((*Hook)->Child_Two)->Parent=(*Hook);
00403 break;
00404 case MTK_COT :
00405 (*Hook)=new Node;
00406 InitNode((*Hook),MTK_MULTIPLY);
00407 AddBelowOne(*Hook,MTK_MULTIPLY);
00408 Temp = (*Hook)->Child_One;
00409 AddBelowOne(Temp,MTK_NUMBER,-1);
00410 AddBelowTwo(Temp,MTK_POWER);
00411 Temp = Temp->Child_Two;
00412 AddBelowOne(Temp,MTK_COSEC);
00413 AddBelowTwo(Temp,MTK_NUMBER,2);
00414 Temp->Child_One->Child_One=new Node;
00415 Copy(Start->Child_One,Temp->Child_One->Child_One);
00416 Temp->Child_One->Child_One->Parent=Temp->Child_One;
00417 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00418 ((*Hook)->Child_Two)->Parent=(*Hook);
00419 break;
00420 case MTK_ARCSIN :
00421 (*Hook)=new Node;
00422 InitNode((*Hook),MTK_DIVIDE);
00423 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00424 ((*Hook)->Child_One)->Parent=(*Hook);
00425 AddBelowTwo((*Hook),MTK_POWER);
00426 AddBelowOne((*Hook)->Child_Two,MTK_SUBTRACT);
00427 AddBelowOne(((*Hook)->Child_Two)->Child_One,MTK_NUMBER,1);
00428 AddBelowTwo(((*Hook)->Child_Two)->Child_One,MTK_POWER);
00429 ((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One=new Node;
00430 Copy(Start->Child_One,((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One);
00431 (((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One)->Parent
00432 =(((*Hook)->Child_Two)->Child_One)->Child_Two;
00433 AddBelowTwo((((*Hook)->Child_Two)->Child_One)->Child_Two,MTK_NUMBER,2);
00434 AddBelowTwo((*Hook)->Child_Two,MTK_NUMBER,0.5);
00435 break;
00436 case MTK_ARCCOS :
00437 (*Hook)=new Node;
00438 InitNode((*Hook),MTK_DIVIDE);
00439 AddBelowOne((*Hook),MTK_MULTIPLY);
00440 AddBelowOne((*Hook)->Child_One,MTK_NUMBER,-1);
00441 DiffFromNode(Start->Child_One,&(((*Hook)->Child_One)->Child_Two));
00442 (((*Hook)->Child_One)->Child_Two)->Parent=(*Hook)->Child_One;
00443 AddBelowTwo((*Hook),MTK_POWER);
00444 AddBelowOne((*Hook)->Child_Two,MTK_SUBTRACT);
00445 AddBelowOne(((*Hook)->Child_Two)->Child_One,MTK_NUMBER,1);
00446 AddBelowTwo(((*Hook)->Child_Two)->Child_One,MTK_POWER);
00447 ((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One=new Node;
00448 Copy(Start->Child_One,((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One);
00449 (((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One)->Parent
00450 =(((*Hook)->Child_Two)->Child_One)->Child_Two;
00451 AddBelowTwo((((*Hook)->Child_Two)->Child_One)->Child_Two,MTK_NUMBER,2);
00452 AddBelowTwo((*Hook)->Child_Two,MTK_NUMBER,0.5);
00453 break;
00454 case MTK_ARCTAN :
00455 (*Hook)=new Node;
00456 InitNode((*Hook),MTK_DIVIDE);
00457 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00458 ((*Hook)->Child_One)->Parent=(*Hook);
00459 AddBelowTwo((*Hook),MTK_ADD);
00460 AddBelowOne((*Hook)->Child_Two,MTK_NUMBER,1);
00461 AddBelowTwo((*Hook)->Child_Two,MTK_POWER);
00462 (((*Hook)->Child_Two)->Child_Two)->Child_One=new Node;
00463 Copy(Start->Child_One,(((*Hook)->Child_Two)->Child_Two)->Child_One);
00464 ((((*Hook)->Child_Two)->Child_Two)->Child_One)->Parent
00465 =((*Hook)->Child_Two)->Child_Two;
00466 AddBelowTwo(((*Hook)->Child_Two)->Child_Two,MTK_NUMBER,2);
00467 break;
00468 case MTK_SINH :
00469 (*Hook)=new Node;
00470 InitNode((*Hook),MTK_MULTIPLY);
00471 AddBelowOne((*Hook),MTK_COSH);
00472 ((*Hook)->Child_One)->Child_One=new Node;
00473 Copy(Start->Child_One,((*Hook)->Child_One)->Child_One);
00474 (((*Hook)->Child_One)->Child_One)->Parent=(*Hook)->Child_One;
00475 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00476 ((*Hook)->Child_Two)->Parent=(*Hook);
00477 break;
00478 case MTK_COSH :
00479 (*Hook)=new Node;
00480 InitNode((*Hook),MTK_MULTIPLY);
00481 AddBelowOne((*Hook),MTK_SINH);
00482 ((*Hook)->Child_One)->Child_One=new Node;
00483 Copy(Start->Child_One,((*Hook)->Child_One)->Child_One);
00484 (((*Hook)->Child_One)->Child_One)->Parent=(*Hook)->Child_One;
00485 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00486 ((*Hook)->Child_Two)->Parent=(*Hook);
00487 break;
00488 case MTK_TANH :
00489 (*Hook)=new Node;
00490 InitNode((*Hook),MTK_DIVIDE);
00491 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00492 ((*Hook)->Child_One)->Parent=(*Hook);
00493 AddBelowTwo((*Hook),MTK_POWER);
00494 AddBelowOne((*Hook)->Child_Two,MTK_COSH);
00495 AddBelowTwo((*Hook)->Child_Two,MTK_NUMBER,2);
00496 (((*Hook)->Child_Two)->Child_One)->Child_One=new Node;
00497 Copy(Start->Child_One,(((*Hook)->Child_Two)->Child_One)->Child_One);
00498 ((((*Hook)->Child_Two)->Child_One)->Child_One)->Parent=((*Hook)->Child_Two)->Child_One;
00499 break;
00500 case MTK_ARSINH :
00501 (*Hook)=new Node;
00502 InitNode(*Hook, MTK_DIVIDE);
00503 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00504 ((*Hook)->Child_One)->Parent=(*Hook);
00505 AddBelowTwo((*Hook),MTK_POWER);
00506 AddBelowOne((*Hook)->Child_Two,MTK_ADD);
00507 AddBelowOne(((*Hook)->Child_Two)->Child_One,MTK_NUMBER,1);
00508 AddBelowTwo(((*Hook)->Child_Two)->Child_One,MTK_POWER);
00509 ((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One=new Node;
00510 Copy(Start->Child_One,((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One);
00511 (((((*Hook)->Child_Two)->Child_One)->Child_Two)->Child_One)->Parent
00512 =(((*Hook)->Child_Two)->Child_One)->Child_Two;
00513 AddBelowTwo((((*Hook)->Child_Two)->Child_One)->Child_Two,MTK_NUMBER,2);
00514 AddBelowTwo((*Hook)->Child_Two,MTK_NUMBER,0.5);
00515 break;
00516 case MTK_ARCOSH :
00517 (*Hook)=new Node;
00518 InitNode(*Hook, MTK_DIVIDE);
00519 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00520 ((*Hook)->Child_One)->Parent=(*Hook);
00521 AddBelowTwo((*Hook),MTK_POWER);
00522 AddBelowOne((*Hook)->Child_Two,MTK_SUBTRACT);
00523 AddBelowTwo(((*Hook)->Child_Two)->Child_One,MTK_NUMBER,1);
00524 AddBelowOne(((*Hook)->Child_Two)->Child_One,MTK_POWER);
00525 ((((*Hook)->Child_Two)->Child_One)->Child_One)->Child_One=new Node;
00526 Copy(Start->Child_One,((((*Hook)->Child_Two)->Child_One)->Child_One)->Child_One);
00527 (((((*Hook)->Child_Two)->Child_One)->Child_One)->Child_One)->Parent
00528 =(((*Hook)->Child_Two)->Child_One)->Child_One;
00529 AddBelowTwo((((*Hook)->Child_Two)->Child_One)->Child_One,MTK_NUMBER,2);
00530 AddBelowTwo((*Hook)->Child_Two,MTK_NUMBER,0.5);
00531 break;
00532 case MTK_ARTANH :
00533 (*Hook)=new Node;
00534 InitNode(*Hook, MTK_DIVIDE);
00535 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00536 ((*Hook)->Child_One)->Parent=(*Hook);
00537 AddBelowTwo((*Hook),MTK_SUBTRACT);
00538 AddBelowOne((*Hook)->Child_Two,MTK_NUMBER,1);
00539 AddBelowTwo((*Hook)->Child_Two,MTK_POWER);
00540 (((*Hook)->Child_Two)->Child_Two)->Child_One=new Node;
00541 Copy(Start->Child_One,(((*Hook)->Child_Two)->Child_Two)->Child_One);
00542 ((((*Hook)->Child_Two)->Child_Two)->Child_One)->Parent
00543 =((*Hook)->Child_Two)->Child_Two;
00544 AddBelowTwo(((*Hook)->Child_Two)->Child_Two,MTK_NUMBER,2);
00545 break;
00546 case MTK_LN :
00547 (*Hook)=new Node;
00548 InitNode(*Hook, MTK_DIVIDE);
00549 (*Hook)->Child_Two=new Node;
00550 Copy(Start->Child_One,(*Hook)->Child_Two);
00551 ((*Hook)->Child_Two)->Parent=(*Hook);
00552 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00553 ((*Hook)->Child_One)->Parent=(*Hook);
00554 break;
00555 case MTK_LOG :
00556 (*Hook)=new Node;
00557 InitNode(*Hook, MTK_DIVIDE);
00558 AddBelowTwo(*Hook,MTK_MULTIPLY);
00559 AddBelowTwo((*Hook)->Child_Two,MTK_LN);
00560 AddBelowOne(((*Hook)->Child_Two)->Child_Two,MTK_NUMBER,10);
00561 ((*Hook)->Child_Two)->Child_One=new Node;
00562 Copy(Start->Child_One,((*Hook)->Child_Two)->Child_One);
00563 (((*Hook)->Child_Two)->Child_One)->Parent=(*Hook)->Child_Two;
00564 DiffFromNode(Start->Child_One,&((*Hook)->Child_One));
00565 ((*Hook)->Child_One)->Parent=*Hook;
00566 break;
00567 case MTK_EXP :
00568 (*Hook)=new Node;
00569 InitNode(*Hook, MTK_MULTIPLY);
00570 (*Hook)->Child_One=new Node;
00571 Copy(Start,(*Hook)->Child_One);
00572 ((*Hook)->Child_One)->Parent=(*Hook);
00573 DiffFromNode(Start->Child_One,&((*Hook)->Child_Two));
00574 ((*Hook)->Child_Two)->Parent=(*Hook);
00575 break;
00576 case MTK_NUMBER : case MTK_PI_SYM :
00577 (*Hook)=new Node;
00578 InitNode(*Hook, MTK_NUMBER);
00579 (*Hook)->Value.Number = 0;
00580 (*Hook)->Child_One=NULL;
00581 (*Hook)->Child_Two=NULL;
00582 break;
00583 case MTK_VARIABLE :
00584 (*Hook)=new Node;
00585 InitNode(*Hook, MTK_NUMBER);
00586 (*Hook)->Child_One=NULL;
00587 (*Hook)->Child_Two=NULL;
00588 if ((Start->Value).WhichVar==DiffVar)
00589 {
00590 ((*Hook)->Value).Number=1;
00591 }
00592 else
00593 {
00594 ((*Hook)->Value).Number=0;
00595 };
00596 break;
00597 default :
00598 throw ERR_DIFF;
00599
00600
00601
00602
00603
00604 };
00605
00606 }
00607
00608
00609 double
00610 Equation::NumInt( range Range, int var_num )
00611 {
00612 variable *var;
00613 double n,Ans;
00614 int i;
00615
00616 var = Variables.at( var_num - 1 );
00617
00618 if (!var) throw ERR_VARIABLES;
00619
00620 n = floor( ( Range.To - Range.From ) / ( Range.Step * 2 ) );
00621 if ( n==0 ) n=1;
00622 Range.Step = ( Range.To - Range.From ) / ( n * 2 );
00623 var->Value = Range.From;
00624 Ans = Evaluate();
00625 for ( i=1 ; i<n ; i++ ) {
00626 var->Value = Range.From + ( 2*i-1 ) * Range.Step;
00627 Ans = Ans + 4 * Evaluate();
00628 var->Value = var->Value + Range.Step;
00629 Ans = Ans + 2 * Evaluate();
00630 };
00631 var->Value = var->Value + Range.Step;
00632 Ans = Ans + 4 * Evaluate();
00633 var->Value = Range.To;
00634 Ans = Ans + Evaluate();
00635 Ans = Ans * Range.Step / 3;
00636 return Ans;
00637 }
00638
00639
00640 double
00641 Equation::FindRoot( range Range, int var_num )
00642 {
00643 double Mid,Below,Above,AboveVal,BelowVal,MidVal,dx;
00644 variable *var;
00645 int i;
00646
00647 Below = Range.From;
00648 Above = Range.To;
00649 var = Variables.at( var_num - 1 );
00650 var->Value = Below;
00651 BelowVal = Evaluate();
00652 if ( fabs(BelowVal) < Range.Accuracy ) return Below;
00653 var->Value = Above;
00654 AboveVal = Evaluate();
00655 if ( fabs(AboveVal) < Range.Accuracy ) return Above;
00656
00657
00658 if ( AboveVal*BelowVal > 0 ) {
00659 dx = (Range.To - Range.From)/50;
00660 Below = Range.From;
00661 Above = Below + dx;
00662 for (i=0;i<50;i++) {
00663 var->Value = Below;
00664 BelowVal = Evaluate();
00665 var->Value = Above;
00666 AboveVal = Evaluate();
00667 if ( AboveVal*BelowVal < 0 ) break;
00668 Below += dx;
00669 Above += dx;
00670 }
00671
00672
00673 if ( AboveVal*BelowVal > 0 ) {
00674 Below = Range.From;
00675 Above = Range.To;
00676 var->Value = Below;
00677 BelowVal = Evaluate();
00678 var->Value = Above;
00679 AboveVal = Evaluate();
00680 for (i=0; i<50;i++) {
00681 if ( AboveVal*BelowVal < 0 ) break;
00682 if ( fabs(BelowVal) < fabs(AboveVal) ) {
00683 Below += 1.6*(Below-Above);
00684 var->Value = Below;
00685 BelowVal = Evaluate();
00686 }
00687 else {
00688 Above += 1.6*(Above-Below);
00689 var->Value = Above;
00690 AboveVal = Evaluate();
00691 }
00692 }
00693
00694 if ( AboveVal*BelowVal > 0 ) {
00695 throw ERR_NO_ROOT;
00696 }
00697 }
00698 }
00699
00700 do {
00701 Mid = ( Above + Below ) / 2;
00702 var->Value = Mid;
00703 MidVal = Evaluate();
00704 if ( MidVal*BelowVal < 0 ) {
00705 Above = Mid;
00706 AboveVal = MidVal;
00707 }
00708 else {
00709 Below = Mid;
00710 BelowVal = MidVal;
00711 };
00712 }
00713 while ( fabs(MidVal) > Range.Accuracy );
00714 return Mid;
00715 }
00716
00717
00718 double
00719 Equation::RK4( range Range, int var_num1, int var_num2 )
00720 {
00721 variable *var1=NULL;
00722 variable *var2=NULL;
00723 double n,x,ans,hh;
00724 double k1,k2,k3,k4;
00725 int i;
00726 if (var_num1) var1 = Variables.at( var_num1 - 1 );
00727 if (var_num2) var2 = Variables.at( var_num2 - 1 );
00728
00729 hh = Range.Step/2;
00730 n = floor( (Range.To-Range.From) / Range.Step );
00731 if ( n==0 ) n=1;
00732 n = fabs( n );
00733 Range.Step = (Range.To-Range.From) / n;
00734 x = Range.From;
00735 ans = Range.Accuracy;
00736 for ( i=1; i <= (int) n; i++ ) {
00737 if ( var1 ) var1->Value = x;
00738 if ( var2 ) var2->Value = ans;
00739 k1 = Range.Step * Evaluate();
00740 if ( var1 ) var1->Value = x + hh;
00741 if ( var2 ) var2->Value = ans + k1 / 2;
00742 k2 = Range.Step * Evaluate();
00743 if ( var2 ) var2->Value = ans + k2 / 2;
00744 k3 = Range.Step * Evaluate();
00745 if ( var1 ) var1->Value = x + Range.Step;
00746 if ( var2 ) var2->Value = ans + k3;
00747 k4 = Range.Step * Evaluate();
00748 ans = ans + ( k1 / 2 + k2 + k3 + k4 / 2 ) / 3;
00749 x = x + Range.Step;
00750 };
00751 return ans;
00752 }
00753
00754
00755 void
00756 Equation::PowerSeries(Equation *Series, int var, int n, Parser *parser )
00757 {
00758 Equation *Differential=NULL;
00759 Equation *Temp=NULL;
00760 variable *PointerFrom;
00761 variable *PointerTo;
00762 variable *AboutVar=NULL;
00763 int i;
00764 double AboutValue;
00765
00766 AboutVar = Variables.at( var - 1 );
00767 if (!AboutVar) {
00768 throw ERR_VARIABLES;
00769 }
00770
00771 AboutValue = AboutVar->Value;
00772
00773
00774 PointerFrom = Variables.first();
00775 while ( PointerFrom != NULL ) {
00776 PointerTo = new variable;
00777 PointerTo->Value = PointerFrom->Value;
00778 Series->Variables.append(PointerTo);
00779 strcpy(PointerTo->Name,PointerFrom->Name);
00780 PointerFrom = Variables.next();
00781 };
00782
00783 Series->Radians = Radians;
00784 if (Series->Root) {
00785 delete Series->Root;
00786 Series->Root = NULL;
00787 }
00788 Series->AddPowerSeriesTerm(var, Root, 0, AboutValue,parser);
00789 Temp = this;
00790
00791 for (i=1;i<n;i++) {
00792 DiffVar=var;
00793 Differential = new Equation();
00794 delete (Differential->Root);
00795 Differential->Root = NULL;
00796 DiffFromNode(Temp->Root,&(Differential->Root));
00797 if (Differential->Root!=NULL) Differential->Root->Parent=NULL;
00798 PointerFrom = Variables.first();
00799 while ( PointerFrom != NULL ) {
00800 PointerTo = new variable;
00801 PointerTo->Value = PointerFrom->Value;
00802 Differential->Variables.append(PointerTo);
00803 strcpy(PointerTo->Name,PointerFrom->Name);
00804 PointerFrom = Variables.next();
00805 };
00806 parser->TidyUpEqn(Differential);
00807 Series->AddPowerSeriesTerm(var, Differential->Root, i, AboutValue, parser);
00808 if ( Temp != this ) delete Temp;
00809 Temp = Differential;
00810 }
00811 if ( Temp != this ) delete Temp;
00812 parser->TreeToText(Series);
00813 }
00814
00815
00816 void
00817 Equation::AddPowerSeriesTerm(int var, Node *coeff, double power, double about, Parser *parser)
00818 {
00819 Node *temp;
00820 Node *temp_root;
00821 NumVar tmpnum;
00822
00823 if (Root != NULL) {
00824 temp = new Node;
00825 temp->Parent = NULL;
00826 temp->Child_One = Root;
00827 Root->Parent = temp;
00828 InitNode(temp,MTK_ADD);
00829 Root = temp;
00830
00831 temp->Child_Two = new Node;
00832 temp->Child_Two->Parent = temp;
00833 temp = temp->Child_Two;
00834 }
00835 else {
00836 temp = new Node;
00837 Root = temp;
00838 temp->Parent = NULL;
00839 }
00840
00841 InitNode(temp,MTK_MULTIPLY);
00842 temp->Child_One = new Node;
00843 temp->Child_One->Parent = temp;
00844 temp = temp->Child_One;
00845 InitNode(temp,MTK_DIVIDE);
00846
00847 temp_root = new Node;
00848 temp->Child_One = temp_root;
00849 temp_root->Parent = temp;
00850 Copy(coeff,temp_root);
00851
00852 temp->Child_Two = new Node;
00853 temp->Child_Two->Parent = temp;
00854 tmpnum.Number = factorial(power);
00855 InitNode(temp->Child_Two,MTK_NUMBER,tmpnum);
00856 temp->Child_Two->Child_One = NULL;
00857 temp->Child_Two->Child_Two = NULL;
00858 temp = temp->Parent;
00859
00860 temp->Child_Two = new Node;
00861 temp->Child_Two->Parent = temp;
00862 temp = temp->Child_Two;
00863 InitNode(temp,MTK_POWER);
00864
00865 temp->Child_One = new Node;
00866 temp->Child_One->Parent = temp;
00867 temp = temp->Child_One;
00868 InitNode(temp,MTK_SUBTRACT);
00869
00870 temp->Child_One = new Node;
00871 temp->Child_One->Parent = temp;
00872 temp = temp->Child_One;
00873 tmpnum.WhichVar = var;
00874 InitNode(temp,MTK_VARIABLE,tmpnum);
00875 temp->Child_One = NULL;
00876 temp->Child_Two = NULL;
00877 temp = temp->Parent;
00878
00879 temp->Child_Two = new Node;
00880 temp->Child_Two->Parent = temp;
00881 temp = temp->Child_Two;
00882 tmpnum.Number = about;
00883 InitNode(temp,MTK_NUMBER,tmpnum);
00884 temp->Child_One = NULL;
00885 temp->Child_Two = NULL;
00886
00887 temp = temp->Parent->Parent;
00888 temp->Child_Two = new Node;
00889 temp->Child_Two->Parent = temp;
00890 temp = temp->Child_Two;
00891 tmpnum.Number = power;
00892 InitNode(temp,MTK_NUMBER,tmpnum);
00893 temp->Child_One = NULL;
00894 temp->Child_Two = NULL;
00895
00896 temp = temp_root;
00897 Reset(0,temp_root);
00898 parser->TidyUpEqn(this);
00899 Reset(0);
00900 while (temp_root->Brackets==0) {
00901 while (temp->Child_One!=NULL) {
00902 if (temp->Child_One->Brackets==1) break;
00903 temp=temp->Child_One;
00904 };
00905 if (temp->Type == MTK_VARIABLE) {
00906 if (temp->Value.WhichVar == var) {
00907 temp->Type = MTK_NUMBER;
00908 temp->evalfn = func_details[MTK_NUMBER].func_ptr;
00909 temp->Value.Number = Variables.at(var - 1)->Value;
00910 }
00911 }
00912 temp->Brackets=1;
00913 temp=temp->Parent;
00914 if (temp==NULL) break;
00915 if (temp->Child_Two != NULL) {
00916 if ((temp->Child_Two)->Brackets==0) {
00917 temp=temp->Child_Two;
00918 }
00919 else {
00920 temp->Brackets = 1;
00921 }
00922 }
00923 else {
00924 temp->Brackets = 1;
00925 };
00926 };
00927 Reset(2);
00928 Reset(0);
00929 }