• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/examples/iprojekt/rpn.cpp

00001 #include "rpn.h"
00002 
00003 //#define STARO // ovo treba ukljuciti ako se provjeravaju stara rjesenja (sa greskom u editiranju)
00004 
00005 // evaluiramo za sve poslove odjednom!
00006 // broj poslova je konstantan za pojedini test skup: m_iArraySize
00007 // m_iOffset je prvi posao kojega uzimamo u obzir; prethodni su vec rasporedjeni!
00008 // pIndex je polje u kojemu su do m_iOffset-a indeksi svih rasporedjenih, a iza svi ostali
00009 // dodano 10.08.: idemo od Offset do End (ne gledamo poslove iza End u polju indeksa)
00010 // dodano 06.09.: m_nTree odredjuje koje se stablo evaluira (default = 0)
00011 void RPN::evaluate_array(double dResult[])
00012 {
00013     double d1[MAX_JOBS],d2[MAX_JOBS],d3[MAX_JOBS],d4[MAX_JOBS];
00014     uint i;
00015     m_iPosition++; // pomicemo se na sljedeci simbol; pocetna vrijednost mora biti -1 !!!
00016     switch(m_pExpression[m_nTree][m_iPosition])
00017     {
00018         case ADD:
00019             evaluate_array(d1);
00020             evaluate_array(d2);
00021             for(i=m_iOffset; i<m_iEnd; i++)
00022                 dResult[pIndex[i]] = d1[pIndex[i]] + d2[pIndex[i]];
00023             break;
00024         case SUB:
00025             evaluate_array(d1);
00026             evaluate_array(d2);
00027             for(i=m_iOffset; i<m_iEnd; i++)
00028                 dResult[pIndex[i]] = d1[pIndex[i]] - d2[pIndex[i]];
00029             break;
00030         case MUL:
00031             evaluate_array(d1);
00032             evaluate_array(d2);
00033             for(i=m_iOffset; i<m_iEnd; i++)
00034                 dResult[pIndex[i]] = d1[pIndex[i]] * d2[pIndex[i]];
00035             break;
00036         case DIV:
00037             evaluate_array(d1);
00038             evaluate_array(d2);
00039             for(i=m_iOffset; i<m_iEnd; i++)
00040             {   if(fabs(d2[pIndex[i]]) < 0.000001)
00041                     dResult[pIndex[i]] = 1;
00042                 else
00043                     dResult[pIndex[i]] = d1[pIndex[i]] / d2[pIndex[i]];
00044             }
00045             break;
00046         case POS:
00047             evaluate_array(d1);
00048             for(i=m_iOffset; i<m_iEnd; i++)
00049                 if(d1[pIndex[i]] > 0)
00050                     dResult[pIndex[i]] = d1[pIndex[i]];
00051                 else
00052                     dResult[pIndex[i]] = 0;
00053             break;
00054         case SIN:
00055             evaluate_array(d1);
00056             for(i=m_iOffset; i<m_iEnd; i++)
00057                 dResult[pIndex[i]] = sin(d1[pIndex[i]]);
00058             break;
00059         case COS:
00060             evaluate_array(d1);
00061             for(i=m_iOffset; i<m_iEnd; i++)
00062                 dResult[pIndex[i]] = cos(d1[pIndex[i]]);
00063             break;
00064         case EXP:
00065             evaluate_array(d1);
00066             for(i=m_iOffset; i<m_iEnd; i++)
00067                 if(d1[pIndex[i]] < 80.)
00068                     dResult[pIndex[i]] = cos(d1[pIndex[i]]);
00069                 else
00070                     dResult[pIndex[i]] = 1;
00071             break;
00072         case LOG:
00073             evaluate_array(d1);
00074             for(i=m_iOffset; i<m_iEnd; i++)
00075                 if(fabs(d1[pIndex[i]]) > 0.000001)
00076                     dResult[pIndex[i]] = log(fabs(d1[pIndex[i]]));
00077                 else
00078                     dResult[pIndex[i]] = 1;
00079             break;
00080         case SQR:
00081             evaluate_array(d1);
00082             for(i=m_iOffset; i<m_iEnd; i++)
00083                 if(d1[pIndex[i]] < 0)
00084                     dResult[pIndex[i]] = 1;
00085                 else
00086                     dResult[pIndex[i]] = sqrt(d1[pIndex[i]]);
00087             break;
00088         case IFGT:
00089             evaluate_array(d1);
00090             evaluate_array(d2);
00091             evaluate_array(d3);
00092             evaluate_array(d4);
00093             for(i=m_iOffset; i<m_iEnd; i++)
00094                 if(d1[pIndex[i]] > d2[pIndex[i]])
00095                     dResult[pIndex[i]] = d3[pIndex[i]];
00096                 else
00097                     dResult[pIndex[i]] = d4[pIndex[i]];
00098             break;
00099         default:    // terminal
00100             memcpy(dResult, m_dTermValuesArray[m_pExpression[m_nTree][m_iPosition]], m_iArraySize*sizeof(double));
00101             break;
00102     }
00103 }
00104 
00105 
00106 double RPN::evaluate()
00107 {
00108     double d1,d2;
00109     m_iPosition++; // pomicemo se na sljedeci simbol; pocetna vrijednost mora biti -1 !!!
00110     switch(m_pExpression[m_nTree][m_iPosition])
00111     {
00112         case ADD:
00113             return evaluate() + evaluate();
00114             break;
00115         case SUB:
00116             return evaluate() - evaluate();
00117             break;
00118         case MUL:
00119             return evaluate() * evaluate();
00120             break;
00121         case DIV:
00122             d1 = evaluate();
00123             d2 = evaluate();
00124             if(fabs(d2) < 0.000001)
00125                 return 1;
00126             else
00127                 return d1/d2;
00128             break;
00129         case POS:
00130             d1 = evaluate();
00131             if(d1 > 0)
00132                 return d1;
00133             else
00134                 return 0;
00135             break;
00136         default:    // terminal
00137             return m_pTermValues[m_pExpression[m_nTree][m_iPosition]];
00138             break;
00139     }
00140 }
00141 
00142 int RPN::edit()
00143 {
00144     int r1,r2;
00145     uint iCurrent,iOp1,iOp2,i;
00146     m_iPosition++;  // pomicemo se na sljedeci simbol; pocetna vrijednost mora biti -1 !!!
00147     iCurrent = ++m_iEditedPos;  // usput pamtimo gdje smo u edited polju
00148     m_pEdited[m_iEditedPos] = m_pExpression[m_nTree][m_iPosition];  // prepisujemo tekuci simbol
00149     switch(m_pExpression[m_nTree][m_iPosition])
00150     {
00151         case ADD:
00152             r1 = edit(); iOp1 = m_iEditedPos;
00153             r2 = edit(); iOp2 = m_iEditedPos;
00154             if(r1==NUL)             // 0+A = A
00155             {   for(i=0; i<iOp2-iOp1; i++)
00156                     m_pEdited[iCurrent+i] = m_pEdited[iOp1+1+i];
00157                 m_iEditedPos = m_iEditedPos - (iOp1 - iCurrent) - 1;
00158                 return r2;
00159             }
00160             else if(r2==NUL)        // A+0 = A
00161             {   for(i=0; i<iOp1-iCurrent; i++)
00162                     m_pEdited[iCurrent+i] = m_pEdited[iCurrent+i+1];
00163                 m_iEditedPos = m_iEditedPos - (iOp2 - iOp1) - 1;
00164                 return r1;
00165             }
00166             else
00167                 return ADD;
00168             break;
00169         case SUB:
00170             r1 = edit(); iOp1 = m_iEditedPos;
00171             r2 = edit(); iOp2 = m_iEditedPos;
00172 #ifdef STARO
00173             if(r1<100 && r1==r2)    // ovo je bilo prije; krivo! 27.07.
00174 #else
00175             if(r1<m_iTermNum && r1==r2) // A-A = 0
00176 #endif
00177             {   m_iEditedPos = iCurrent;
00178                 m_pEdited[m_iEditedPos] = NUL;
00179                 return NUL;
00180             }
00181             else if(r2==NUL)        // A-0 = A
00182             {   for(i=0; i<iOp1-iCurrent; i++)
00183                     m_pEdited[iCurrent+i] = m_pEdited[iCurrent+i+1];
00184                 m_iEditedPos = m_iEditedPos - (iOp2 - iOp1) - 1;
00185                 return r1;
00186             }
00187             // prosirenje za simbolicku jednakost A-A
00188             else if(r1==r2 && (iOp1-iCurrent)==(iOp2-iOp1)) 
00189             {   for(i=0; i<iOp2-iOp1; i++)
00190                     if(m_pEdited[iCurrent+1+i] != m_pEdited[iOp1+1+i])
00191                         break;
00192                 if(i != iOp2-iOp1)  // neuspjeh...
00193                     return SUB;
00194                 m_iEditedPos = iCurrent;    // uspjeh!!
00195                 m_pEdited[m_iEditedPos] = NUL;
00196                 return NUL;
00197             }
00198             else
00199                 return SUB;
00200             break;
00201         case MUL:
00202             r1 = edit(); iOp1 = m_iEditedPos;
00203             r2 = edit(); iOp2 = m_iEditedPos;
00204             if(r1==ONE)             // 1*A = A
00205             {   for(i=0; i<iOp2-iOp1; i++)
00206                     m_pEdited[iCurrent+i] = m_pEdited[iOp1+1+i];
00207                 m_iEditedPos = m_iEditedPos - (iOp1 - iCurrent) - 1;
00208                 return r2;
00209             }
00210             else if(r2==ONE)        // A*1 = A
00211             {   for(i=0; i<iOp1-iCurrent; i++)
00212                     m_pEdited[iCurrent+i] = m_pEdited[iCurrent+i+1];
00213                 m_iEditedPos = m_iEditedPos - (iOp2 - iOp1) - 1;
00214                 return r1;
00215             }
00216 #ifndef STARO
00217             // dodano 27.07.
00218             else if(r1==NUL || r2==NUL) // A*0 = 0*A = 0
00219             {   m_iEditedPos = iCurrent;
00220                 m_pEdited[m_iEditedPos] = NUL;
00221                 return NUL;
00222             }
00223 #endif
00224             else
00225                 return MUL;
00226             break;
00227         case DIV:
00228             r1 = edit(); iOp1 = m_iEditedPos;
00229             r2 = edit(); iOp2 = m_iEditedPos;
00230 #ifdef STARO
00231             if(r1<100 && r1==r2)    // ovo je bilo prije; krivo! 27.07.
00232 #else
00233             if(r1<m_iTermNum && r1==r2) // A/A = 1
00234 #endif
00235             {   m_iEditedPos = iCurrent;
00236                 m_pEdited[m_iEditedPos] = ONE;
00237                 return ONE;
00238             }
00239             // prosirenje za simbolicku jednakost A/A
00240             else if(r1==r2 && (iOp1-iCurrent)==(iOp2-iOp1)) 
00241             {   for(i=0; i<iOp2-iOp1; i++)
00242                     if(m_pEdited[iCurrent+1+i] != m_pEdited[iOp1+1+i])
00243                         break;
00244                 if(i != iOp2-iOp1)  // neuspjeh...
00245                     return DIV;
00246                 m_iEditedPos = iCurrent;    // uspjeh!!
00247                 m_pEdited[m_iEditedPos] = ONE;
00248                 return ONE;
00249             }
00250             else if(r2 == NUL)  // A/0 = 1
00251             {   m_iEditedPos = iCurrent;
00252                 m_pEdited[m_iEditedPos] = ONE;
00253                 return ONE;
00254             }
00255 #ifndef STARO
00256             // dodano 27.07.
00257             else if(r2 == ONE)  // A/1 = A
00258             {   for(i=0; i<iOp1-iCurrent; i++)
00259                     m_pEdited[iCurrent+i] = m_pEdited[iCurrent+i+1];
00260                 m_iEditedPos = m_iEditedPos - (iOp2 - iOp1) - 1;
00261                 return r1;
00262             }
00263             else if(r1 == NUL)  // 0/A = 0
00264             {   m_iEditedPos = iCurrent;
00265                 m_pEdited[m_iEditedPos] = NUL;
00266                 return NUL;
00267             }
00268 #endif
00269             else
00270                 return DIV;
00271             break;
00272         case POS:
00273             r1 = edit();
00274             // POS(0) = 0, POS(1) = 1
00275             // a i svi ostali terminali (do T_age) su po definiciji pozitivne vrijednosti
00276             if(r1 <= TERMINALS + OFFSET)
00277             {   m_iEditedPos = iCurrent;
00278                 m_pEdited[m_iEditedPos] = r1;
00279                 return r1;
00280             }
00281             else    // ako je ispod funkcija, nista
00282                 return POS;
00283             break;
00284         case SQR:
00285             r1 = edit();
00286             // SQR(0,1) = 0,1
00287             if(r1 == NUL || r1 == ONE)
00288             {   m_iEditedPos = iCurrent;
00289                 m_pEdited[m_iEditedPos] = r1;
00290                 return r1;
00291             }
00292             else
00293                 return SQR;
00294             break;
00295         case IFGT:
00296             r1 = edit();
00297             r1 = edit();
00298             r1 = edit();
00299             r1 = edit();
00300             return IFGT;
00301             break;
00302         default:    // terminal
00303             return m_pExpression[m_nTree][m_iPosition];
00304             break;
00305     }
00306 }
00307 
00308 // kopira editirani izraz u izvorni
00309 // usput prebroji terminale!
00310 void RPN::copy()
00311 {
00312     // obrisi brojace od prosle jedinke
00313     for(int i = 0; i<TOTAL_NODES; i++)
00314         if(Nodes[i].active)
00315             m_pNodeFreq[i] = 0;
00316     // prebroji za ovoga i kumulativno
00317     for(int i = 0; i<m_iEditedPos+1; i++)
00318     {   Nodes[m_pEdited[i]].frequency++;
00319         m_pNodeFreq[m_pEdited[i]] += 1;
00320         m_pExpression[m_nTree][i] = m_pEdited[i];
00321     }
00322 }
00323 
00324 // broj terminala postavlja na nulu
00325 void RPN::ResetNodeFreq()
00326 {
00327     int i;
00328     for(i = 0; i<TERMINALS+OFFSET; i++)
00329         Nodes[i].frequency = 0;
00330     for(i = FUNC_START; i<FUNC_END; i++)
00331         Nodes[i].frequency = 0;
00332 }
00333 
00334 // ispis stabla u infix notaciji
00335 void RPN::write()
00336 {
00337     m_output = " ";
00338     m_iPosition = -1;
00339     r_write();
00340 }
00341 
00342 void RPN::r_write()
00343 {
00344     m_iPosition++; // pomicemo se na sljedeci simbol; pocetna vrijednost mora biti -1 !!!
00345     switch(m_pExpression[m_nTree][m_iPosition])
00346     {
00347         case ADD:
00348             m_output += "(";
00349             r_write();
00350             m_output += "+";
00351             r_write();
00352             m_output += ")";
00353             break;
00354         case SUB:
00355             m_output += "(";
00356             r_write();
00357             m_output += "-";
00358             r_write();
00359             m_output += ")";
00360             break;
00361         case MUL:
00362             m_output += "(";
00363             r_write();
00364             m_output += "*";
00365             r_write();
00366             m_output += ")";
00367             break;
00368         case DIV:
00369             m_output += "(";
00370             r_write();
00371             m_output += "/";
00372             r_write();
00373             m_output += ")";
00374             break;
00375         case POS:
00376             m_output += "pos(";
00377             r_write();
00378             m_output += ")";
00379             break;
00380         case SQR:
00381             m_output += "sqr(";
00382             r_write();
00383             m_output += ")";
00384             break;
00385         default:    // terminal
00386             //itoa(m_pExpression[m_nTree][m_iPosition],pom,10);
00387             m_output += Nodes[m_pExpression[m_nTree][m_iPosition]].name;
00388             break;
00389     }
00390 }

Generated on Thu Jul 10 2014 14:13:41 for ECF by  doxygen 1.7.1