00001 #include "rpn.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
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++;
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:
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++;
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:
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++;
00147 iCurrent = ++m_iEditedPos;
00148 m_pEdited[m_iEditedPos] = m_pExpression[m_nTree][m_iPosition];
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)
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)
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)
00174 #else
00175 if(r1<m_iTermNum && r1==r2)
00176 #endif
00177 { m_iEditedPos = iCurrent;
00178 m_pEdited[m_iEditedPos] = NUL;
00179 return NUL;
00180 }
00181 else if(r2==NUL)
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
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)
00193 return SUB;
00194 m_iEditedPos = iCurrent;
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)
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)
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
00218 else if(r1==NUL || r2==NUL)
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)
00232 #else
00233 if(r1<m_iTermNum && r1==r2)
00234 #endif
00235 { m_iEditedPos = iCurrent;
00236 m_pEdited[m_iEditedPos] = ONE;
00237 return ONE;
00238 }
00239
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)
00245 return DIV;
00246 m_iEditedPos = iCurrent;
00247 m_pEdited[m_iEditedPos] = ONE;
00248 return ONE;
00249 }
00250 else if(r2 == NUL)
00251 { m_iEditedPos = iCurrent;
00252 m_pEdited[m_iEditedPos] = ONE;
00253 return ONE;
00254 }
00255 #ifndef STARO
00256
00257 else if(r2 == ONE)
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)
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
00275
00276 if(r1 <= TERMINALS + OFFSET)
00277 { m_iEditedPos = iCurrent;
00278 m_pEdited[m_iEditedPos] = r1;
00279 return r1;
00280 }
00281 else
00282 return POS;
00283 break;
00284 case SQR:
00285 r1 = edit();
00286
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:
00303 return m_pExpression[m_nTree][m_iPosition];
00304 break;
00305 }
00306 }
00307
00308
00309
00310 void RPN::copy()
00311 {
00312
00313 for(int i = 0; i<TOTAL_NODES; i++)
00314 if(Nodes[i].active)
00315 m_pNodeFreq[i] = 0;
00316
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
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
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++;
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:
00386
00387 m_output += Nodes[m_pExpression[m_nTree][m_iPosition]].name;
00388 break;
00389 }
00390 }