00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00030 
00031 
00032 
00033 
00034 
00035 #ifdef __GNUG__
00036 #pragma implementation "Monomial.h"
00037 #endif
00038 
00039 
00040 #include "mc/mcprec.h"
00041 #ifdef __BORLANDC__
00042     #pragma hdrstop
00043 #endif
00044 
00045 #ifndef mcPRECOMP
00046  #include "mc/MathUtils.h"
00047  #include "mc/Monomial.h"
00048  #include "mc/Number.h"
00049  #include "mc/Fraction.h"
00050  #include "mc/Bracket.h"
00051  #include "mc/Text.h"
00052  #include "mc/Symbol.h"
00053  #include "mc/AddSubOp.h" 
00054  #include "mc/MultDivOp.h" 
00055  #include "mc/Function.h"
00056  #include "mc/Radical.h"
00057 #endif
00058 
00059 
00060 mcIMPLEMENT_MAIN_CLASS(mcMonomial, mcElementArray);
00061 
00062 
00063 
00064 
00065 int mcMonomialHelpers::sgui_nSpaceBetween = 1;
00066 
00067 mcMonomial *mcMonomialHelpers::smath_pOne = NULL;
00068 mcMonomial *mcMonomialHelpers::smath_pZero = NULL;
00069 
00070 bool mcMonomialHelpers::sgui_bEmptyBoxReplacing = TRUE;
00071 bool mcMonomialHelpers::sgui_bFunctionScanEnabled = TRUE;
00072 bool mcMonomialHelpers::sgui_bTransformDivInFractions = TRUE;
00073 bool mcMonomialHelpers::sio_bAutoConvertDivOpToFractions = TRUE;
00074 
00075 
00076 
00077 mcMonomial mcEmptyMonomial(NULL);
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 bool isMonomialOkay(const mcElement &p)
00087 {
00088  if (p.data_GetType() == mcET_POLYNOMIAL)
00089   return FALSE;
00090  return TRUE;
00091 }
00092 
00093 mcMonomial::mcMonomial(const mcFraction &towrap)
00094 { data_SetRefData(new mcMonomialHelpers); data_AddElements(&towrap, 1); }
00095 mcMonomial::mcMonomial(const mcSymbol &towrap)
00096 { data_SetRefData(new mcMonomialHelpers); data_AddElements(&towrap, 1); }
00097 mcMonomial::mcMonomial(const mcNumber &towrap)
00098 { data_SetRefData(new mcMonomialHelpers); data_AddElements(&towrap, 1); }
00099 mcMonomial::mcMonomial(const mcBracket &towrap)
00100 { data_SetRefData(new mcMonomialHelpers); data_AddElements(&towrap, 1); }
00101 mcMonomial::mcMonomial(const mcRadical &towrap)
00102 { data_SetRefData(new mcMonomialHelpers); data_AddElements(&towrap, 1); }
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 #ifdef __MCDEBUG__
00112 
00113 void mcMonomialHelpers::data_Check() const
00114 {
00115  
00116  mcASSERT(data_GetCount() == 0 || (!data_isOp(0) && !data_isOp(data_GetCount()-1)), 
00117   wxT("The expression must always start and end with a non-operator element"));
00118 
00119  
00120  mcASSERT(data_ScanArray(isMonomialOkay, TRUE), 
00121   wxT("Found a mcPolynomial nested in a mcMonomial"));
00122 
00123  
00124  mcElementArrayHelpers::data_Check();
00125 }
00126 
00127 #endif  // __MCDEBUG__
00128 
00129 void mcMonomialHelpers::data_Repair()
00130 {
00131  if (data_isArrayEmpty())
00132   return;
00133 
00134  
00135  if (data_isOp(0)) {
00136   data_Delete(0);
00137   data_MoveElemLeft(0);
00138  }
00139 
00140  
00141  if (data_isOp(data_GetCount()-1))
00142   data_DeleteLast(1);
00143 
00144  
00145  for (int i=0; i < data_GetCount(); i++) {
00146 
00147   if (i < data_GetCount()-1 && 
00148    !data_Get(i).data_isAllowedBefore(data_Get(i+1).data_GetType())) {
00149 
00150    if (data_isOp(i)) {
00151 
00152     
00153     
00154     data_Delete(i);
00155     data_MoveElemLeft(i);
00156 
00157     
00158     i--;
00159     
00160    } else {
00161     
00162     
00163     
00164     
00165     data_MoveElemRight(i+1);
00166     data_AddNewOp(mcET_MULTOP, i+1);
00167    }
00168   }
00169 
00170   if (i > 0 &&
00171    !data_Get(i).data_isAllowedAfter(data_Get(i-1).data_GetType())) {
00172 
00173    
00174    
00175    
00176    
00177    data_MoveElemRight(i);
00178    data_AddNewOp(mcET_MULTOP, i);
00179   }
00180  }
00181 
00182  
00183  data_Check();
00184 }
00185 
00186 void mcMonomialHelpers::data_TransformDivOp()
00187 {
00188  mcLOG(wxT("mcMonomialHelpers::data_TransformDivOp [%s]"), mcTXTTHIS);
00189 
00190  
00191  int begin = -1;
00192  for (int i=0; i < data_GetCount(); i++) {
00193 
00194   if (!data_isOp(i) && begin == -1)
00195    begin = i;
00196   if (data_Get(i).data_GetType() != mcET_DIVOP)
00197    continue;
00198 
00199   
00200   mcFraction f;
00201   mcPolynomial &num = f.data_GetNum();
00202   mcPolynomial &den = f.data_GetDen();
00203 
00204   
00205   num.data_AddNewMonomialContaining(data_GetArray(begin), i-begin, -1, TRUE);
00206 
00207   
00208   
00209   
00210   
00211   
00212   
00213   
00214   int end = i+1;
00215   int j = i+1;
00216   while (j < data_GetCount()) {
00217 
00218    if (data_Get(j).data_GetType() == mcET_MULTOP) {
00219 
00220     
00221     
00222     
00223     
00224     end = j-1;
00225     break;
00226 
00227    } else if (data_Get(j).data_GetType() != mcET_DIVOP) {
00228 
00229     if (!data_isOp(j-1)) {
00230      end = j-1;
00231      break;
00232     }   
00233    }
00234 
00235    
00236    j++;
00237   }
00238 
00239   
00240   mcMonomial tmp; 
00241 
00242   
00243   for (j=i+1; j <= end; j++) {
00244 
00245    
00246    
00247    if (!data_isOp(j)) 
00248     tmp.data_AddElements(data_GetArray(j), 1);
00249   }
00250 
00251   den.data_AddNewMonomial(tmp, -1, TRUE);
00252 
00253   
00254   
00255   for (j=begin; j < end; j++) {
00256    data_Delete(begin);
00257    data_MoveElemLeft(begin);
00258   }
00259   
00260   data_AddElements((mcElement *)(&f), 1, begin, TRUE);
00261 
00262   
00263   i = begin++;
00264   begin = -1;
00265   tmp.data_DeleteAll();
00266 
00267   mcLOG(wxT("mcMonomialHelpers::data_TransformDivOp [%s]"), mcTXTTHIS);
00268  }
00269 }
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 int mcMonomialHelpers::gui_Draw(wxDC &dc, int x, int y, long flags, const wxPoint &pt, int cl) const
00279 {
00280  mcGUILOG(wxT("mcMonomialHelpers::gui_Draw"));
00281 
00282  
00283  if (this->gui_isSelected()) {
00284 
00285   
00286   
00287   
00288   
00289   int w, n;
00290   if (flags & mcDRW_ALLOW_TOTAL_SELECTION) {
00291 
00292    
00293    n = mcElementArrayHelpers::gui_ExDraw(dc, x, y, flags, pt, cl);
00294 
00295    
00296    
00297    if ((w=gui_DrawSelection(dc, x, y, flags, pt, cl)) != mcDRW_NOACTIVEELEM)
00298     n = w;
00299 
00300    return n;
00301   }
00302  } 
00303 
00304  
00305  
00306  
00307  
00308  
00309  return mcElementArrayHelpers::gui_ExDraw(dc, x, y, flags, pt, cl, 0, -1, TRUE);
00310 }
00311 
00312 void mcMonomialHelpers::gui_CheckCursorPos() const
00313 {
00314  if (data_GetCount() > 0) {
00315 
00316   
00317   mcASSERT(!data_isOp(mgui_nCursorPos), wxT("Cursor cannot be placed on an operator"));
00318  }
00319 }
00320 
00321 int mcMonomialHelpers::gui_AddNewElement(mcElementType type, const mcKey &key, int pos)
00322 {
00323  if (pos == -1) pos = data_GetCount();
00324 
00325  
00326  int idx = mcElementArrayHelpers::gui_AddNewElement(type, key, pos);
00327 
00328  
00329  if (mcOperatorHelpers::data_isOp(type)) {
00330   if (pos == data_GetCount()-1 || data_isOp(pos+1)) {
00331 
00332    
00333    
00334    
00335    data_MoveElemRight(pos+1);
00336    mcElementArrayHelpers::gui_AddNewEmptyBox(pos+1);
00337 
00338   } else if (pos > 0 && data_isOp(pos-1)) {
00339 
00340    
00341    
00342    data_MoveElemRight(pos);
00343    mcElementArrayHelpers::gui_AddNewEmptyBox(pos);
00344   }
00345   pos++;
00346  }
00347 
00348  
00349  if (sgui_bTransformDivInFractions && type == mcET_DIVOP) {
00350 
00351   
00352   
00353   
00354   mcFraction p;
00355 
00356   
00357   
00358   
00359 
00360   
00361   mcMonomial num(this);
00362   num.data_DeleteLast(num.data_GetCount()-idx);
00363   p.data_AddElements(TRUE, &num, 1, -1, TRUE);
00364   p.data_GetNum().data_Check();
00365 
00366   
00367   mcMonomial den(this);
00368   den.data_DeleteFirst(idx+1);
00369   p.data_AddElements(FALSE, &den, 1, -1, TRUE);
00370   p.gui_SetCursorOnDen();
00371   p.data_GetDen().data_Check();
00372 
00373   
00374   data_DeleteAll();
00375   data_AddElements(&p, 1, -1, TRUE);
00376   data_Check();
00377 
00378   pos = 0;
00379  }
00380 
00381  
00382  gui_RecalcSize();
00383  return pos;
00384 }
00385 
00386 mcInputRes mcMonomialHelpers::gui_BackInput(const mcKey &key, mcElement *pnewelem, int n)
00387 {
00388  int rightidx;
00389  bool b1, b2;
00390 
00391  
00392  switch (n) {
00393  case mcIR_OKAY:
00394   break;
00395 
00396  case mcIR_DIRECT_DELETE:
00397 
00398   
00399   
00400   if (data_GetCount() == 1) {
00401 
00402    
00403    
00404    
00405    return mcIR_DELETE_THIS;
00406   }
00407 
00408   
00409   
00410 
00411  case mcIR_DELETE_THIS:
00412   
00413   
00414   data_Delete(mgui_nCursorPos);
00415   
00416   
00417   
00418   
00419   
00420   
00421   if (data_GetCount() == 1) {
00422 
00423    if (sgui_bEmptyBoxReplacing) {
00424 
00425     
00426     
00427     
00428     
00429     data_AddNewEmptyBox(0);
00430     return mcIR_OKAY;
00431 
00432    } else {
00433 
00434     
00435     
00436     return mcIR_DELETE_THIS;
00437    }
00438   }
00439 
00440   
00441   
00442   if (sgui_bEmptyBoxReplacing && n != mcIR_DIRECT_DELETE) {
00443    
00444    
00445    b1 = (mgui_nCursorPos > 0 && data_isOp(mgui_nCursorPos-1));
00446    b2 = (mgui_nCursorPos < data_GetCount()-1 && 
00447     data_isOp(mgui_nCursorPos+1));
00448    
00449    
00450    b1 |= (mgui_nCursorPos == 0);
00451    b2 |= (mgui_nCursorPos == data_GetCount()-1);
00452    
00453    if (b1 && b2) {
00454 
00455     
00456     data_AddNewEmptyBox(mgui_nCursorPos);
00457     return mcIR_OKAY;
00458    }
00459   }
00460 
00461   
00462   
00463   if (mcMathCore::Get()->m_pCancelKey->MatchKey(key)) {
00464    
00465    
00466    
00467    
00468    
00469    
00470    gui_DeleteNextOp();
00471    
00472    
00473    
00474    
00475    
00476    
00477    gui_DeletePreviousOp();
00478 
00479   } else if (mcMathCore::Get()->m_pDeleteKey->MatchKey(key)) {
00480    
00481    
00482    
00483    
00484    
00485    
00486    gui_DeleteNextOp();
00487 
00488    
00489    
00490    
00491    
00492    
00493    gui_DeletePreviousOp();
00494   }
00495 
00496   
00497   
00498   data_MoveElemLeft(mgui_nCursorPos);
00499 
00500   
00501   
00502   
00503   
00504   if (mgui_nCursorPos > 0) {
00505 
00506    mgui_nCursorPos--;
00507    if (mcMathCore::Get()->m_pCancelKey->MatchKey(key))
00508     data_Get(mgui_nCursorPos).gui_SetCursorPos(mcCP_BEGIN);
00509    else if (mcMathCore::Get()->m_pDeleteKey->MatchKey(key))
00510     data_Get(mgui_nCursorPos).gui_SetCursorPos(mcCP_END);
00511 
00512   } else {
00513 
00514    
00515    
00516    
00517    
00518    
00519    
00520    gui_SetCursorPos(mcCP_BEGIN);
00521   }
00522 
00523   
00524   rightidx = mgui_nCursorPos+1;  
00525 
00526   
00527   
00528   
00529   
00530   
00531   
00532   if (rightidx > 0 && rightidx < data_GetCount()) {
00533 
00534    
00535    bool b = FALSE;
00536    if (!data_Get(rightidx-1).data_isAllowedBefore(
00537     data_Get(rightidx).data_GetType())) {
00538 
00539     
00540     b = data_Get(rightidx-1).gui_MergeWith(data_Get(rightidx));
00541     if (b) {
00542 
00543      
00544      
00545      data_MoveElemLeft(rightidx);
00546 
00547      
00548     }
00549    }
00550 
00551    
00552    
00553    if (!b) {
00554 
00555     data_Repair(); 
00556    }
00557   }
00558 
00559   
00560   break;
00561   
00562 
00563  case mcIR_DELETE_PREVIOUS:
00564   
00565   
00566   if (mgui_nCursorPos == 0) {
00567    
00568    
00569    
00570    mcASSERT(data_GetCount() > 0, wxT("If we received an mcIR_data_Delete_PREVIOUS code, ")
00571     wxT("there must still be some element which sent it !!!"));
00572    
00573    
00574    
00575    return mcIR_DELETE_PREVIOUS;
00576    
00577   } else {
00578    
00579    if (!data_isOp(mgui_nCursorPos-1)) {
00580     
00581     
00582     gui_MoveCursorLeft();
00583     mcKey tmp = mcMathCore::Get()->m_pDeleteKey->GetEvent();
00584     gui_Input(tmp, NULL);
00585     
00586    } else {
00587 
00588     if (mgui_nCursorPos > 1 && 
00589      !data_Get(mgui_nCursorPos-2).data_isAllowedBefore(
00590        data_Get(mgui_nCursorPos).data_GetType())) {
00591 
00592      
00593      mcMathCore::Get()->SyntaxError(wxT("Cannot data_Delete this operator..."));
00594      break;
00595     }
00596     
00597     
00598     data_Delete(mgui_nCursorPos-1);
00599     data_MoveElemLeft(mgui_nCursorPos-1);
00600     
00601     
00602     if (mgui_nCursorPos > 1)
00603      mgui_nCursorPos -= 2;
00604     else
00605      mgui_nCursorPos--;
00606 
00607     
00608     data_Repair();
00609    }
00610   }
00611   break;
00612 
00613 
00614  case mcIR_DELETE_NEXT:
00615 
00616   
00617   if (mgui_nCursorPos == data_GetCount()-1) {
00618    
00619    
00620    
00621    mcASSERT(data_GetCount() > 0, wxT("If we received an mcIR_data_Delete_NEXT code, ")
00622     wxT("there must still be some element which sent it !!!"));
00623    
00624    
00625    
00626    return mcIR_DELETE_NEXT;
00627    
00628   } else {
00629    
00630    if (!data_isOp(mgui_nCursorPos+1)) {
00631     
00632     gui_MoveCursorRight();
00633     mcKey tmp = mcMathCore::Get()->m_pCancelKey->GetEvent();
00634     gui_Input(tmp, NULL);
00635 
00636     
00637     gui_MoveCursorLeft();
00638     
00639    } else {
00640 
00641     if (mgui_nCursorPos < data_GetCount()-2 && 
00642      !data_Get(mgui_nCursorPos).data_isAllowedBefore(
00643       data_Get(mgui_nCursorPos+2).data_GetType())) {
00644 
00645      
00646      mcMathCore::Get()->SyntaxError(wxT("Cannot data_Delete this operator..."));
00647      break;
00648     }
00649 
00650     
00651     data_Delete(mgui_nCursorPos+1);
00652     data_MoveElemLeft(mgui_nCursorPos+1);
00653 
00654     
00655     data_Repair();
00656     
00657     
00658    }
00659   }
00660   break;
00661   
00662   
00663  case mcIR_REPLACE_THIS:
00664   gui_Replace(pnewelem);
00665   break;
00666 
00667  case mcIR_DISTRIBUTE:
00668 
00669   
00670   return mcIR_DISTRIBUTE;  
00671   
00672  default:
00673   mcASSERT(0, wxT("Unhandled return flag"));
00674  }
00675  
00676  
00677  return mcIR_OKAY;
00678 }
00679 
00680 void mcMonomialHelpers::gui_DoSplit(mcElementType type, const mcKey &key)
00681 {
00682  mcElement ptmp = mcEmptyElement;
00683  mcKey splitkey(key);
00684 
00685  
00686  
00687  
00688  
00689  
00690  
00691  
00692  
00693  
00694  
00695  
00696  
00697  
00698  mcASSERT(!data_Get(mgui_nCursorPos).gui_Split(&ptmp), 
00699   wxT("Such case (the first half asked to data_Delete itself) is not handled yet"));
00700  
00701  
00702  mcASSERT(ptmp != mcEmptyElement, wxT("Tried to split an element which does not support splitting"));
00703  
00704  
00705  data_MoveElemRight(mgui_nCursorPos+1);
00706  data_Set(mgui_nCursorPos+1, ptmp);
00707  
00708  
00709  data_MoveElemRight(mgui_nCursorPos+1);
00710  
00711  
00712  
00713  mgui_nCursorPos = gui_AddNewElement(type, key, mgui_nCursorPos+1);
00714 }
00715 
00716 bool mcMonomialHelpers::gui_Split(mcElement *p)
00717 {
00718  
00719  
00720  
00721  
00722  
00723  mcMonomial pnew;
00724 
00725  
00726  mcElement ptmp;
00727  bool b = data_Get(mgui_nCursorPos).gui_Split(&ptmp);
00728 
00729  
00730  if (b) {
00731   data_Delete(mgui_nCursorPos);
00732   data_MoveElemLeft(mgui_nCursorPos);
00733  }
00734  
00735  
00736  if (ptmp != mcEmptyElement) 
00737   pnew.data_AddElements(&ptmp, 1);
00738 
00739  if (mgui_nCursorPos < data_GetCount()-1) {
00740 
00741   
00742   pnew.data_AddElements(data_GetArray(mgui_nCursorPos+1),
00743         data_GetCount()-mgui_nCursorPos-1);  
00744 
00745   
00746   data_DetachLastElem(data_GetCount()-mgui_nCursorPos-1);
00747  }
00748 
00749  
00750  data_Repair();
00751  pnew.data_Repair();
00752 
00753  
00754  this->mgui_nCursorPos = data_GetCount()-1;
00755  data_Get(mgui_nCursorPos).gui_SetCursorPos(mcCP_END);
00756 
00757  pnew.hlp()->mgui_nCursorPos = 0;
00758  pnew.data_Get(pnew.hlp()->mgui_nCursorPos).gui_SetCursorPos(mcCP_BEGIN);
00759 
00760  
00761  gui_RecalcSize();
00762  *p = pnew;
00763 
00764  return TRUE;
00765 }
00766 
00767 bool mcMonomialHelpers::gui_MergeWith(const mcElement &p)
00768 {
00769  if (p.data_GetType() != mcET_MONOMIAL)
00770   return FALSE;
00771 
00772  mcMonomial m(p);
00773 
00774  
00775  if (data_GetLast().gui_isSplittable() &&
00776   m.data_Get(0).gui_isSplittable() &&
00777   data_GetLast().data_isAllowedBefore(
00778   m.data_GetLast().data_GetType())) {
00779 
00780   
00781   bool okay = data_GetLast().gui_MergeWith(m.data_Get(0));
00782 
00783   if (okay) {
00784 
00785    
00786    m.data_Delete(0);
00787    m.data_MoveElemLeft(0);
00788    if (!m.data_isArrayEmpty() && m.data_isOp(0)) {
00789     m.data_Delete(0);
00790     m.data_MoveElemLeft(0);
00791    }
00792   }
00793  }
00794 
00795  
00796  
00797  data_Merge(m);
00798  data_Repair();
00799 
00800  
00801  gui_RecalcSize();
00802 
00803  
00804  return TRUE;
00805 }
00806 
00807 mcInputRes mcMonomialHelpers::gui_Input(const mcKey &ev, mcElement *newelem)
00808 {
00809  mcInputRes n = mcElementArrayHelpers::gui_Input(ev, newelem);
00810 
00811  
00812  
00813  if (sgui_bFunctionScanEnabled)
00814   gui_ScanArrayForFunctions();
00815 
00816  return n;
00817 }
00818 
00819 void mcMonomialHelpers::gui_ScanArrayForFunctions()
00820 {
00821  
00822  
00823  int f, i;
00824  for (int n=0; n < data_GetCount(); n++) {
00825   if (data_Get(n).data_GetType() == mcET_SYMBOL) {
00826    
00827    
00828    for (i=n; i < data_GetCount(); i++)
00829     if (data_Get(i).data_GetType() != mcET_SYMBOL)
00830      break;
00831     
00832    
00833    
00834    f=mcFunction::data_GetFunctionType(data_GetArray(n), i-n);
00835    if (f != mcFUNCTION_TYPE_NOTFOUND)
00836     gui_ReplaceSymbolsWithFunction(n, f);
00837   }
00838  }
00839 }
00840 
00841 void mcMonomialHelpers::gui_ReplaceSymbolsWithFunction(int idx, int fnc)
00842 {
00843  
00844  
00845  mcFunction pnew;
00846  data_AddElements((mcElement *)(&pnew), 1, idx, TRUE);
00847  
00848  
00849  pnew.gui_Setup(fnc);
00850  mgui_nCursorPos = idx++;
00851     
00852  
00853  int max = (int)(pnew.data_GetName().Len()-1);
00854  for (int i=0; i < max; i++) {
00855   data_Delete(idx);
00856   data_MoveElemLeft(idx);
00857  }
00858  
00859  gui_RecalcSize();
00860 }
00861 
00862 void mcMonomialHelpers::gui_Replace(mcElement *pnewelem)
00863 { 
00864  
00865  
00866  mcASSERT(pnewelem != NULL && data_isValidElem(*pnewelem), 
00867   wxT("Cannot replace the focused element with an invalid pointer"));
00868  
00869  
00870  if (!data_isElementAllowed((*pnewelem).data_GetType())) {
00871   
00872   
00873   mcMathCore::Get()->SyntaxError(wxT("Cannot create such an element !!!"));
00874   
00875  }
00876  
00877  
00878  if ((*pnewelem).data_GetType() == mcET_ADDOP || 
00879   (*pnewelem).data_GetType() == mcET_SUBOP) {
00880   
00881   mcASSERT(0, wxT("A monomial cannot contain a mcAddOp or a mcSubOp"));
00882  }
00883  
00884  
00885  if ((*pnewelem).data_GetType() == mcET_MULTOP || 
00886   (*pnewelem).data_GetType() == mcET_DIVOP) {
00887   
00888   
00889   data_AddNewEmptyBox(mgui_nCursorPos);  
00890   data_AddElements(pnewelem, 1, mgui_nCursorPos+1, TRUE);
00891   data_AddNewEmptyBox(mgui_nCursorPos+2);
00892   mgui_nCursorPos += 2;
00893   
00894  } else {
00895   
00896   
00897   data_AddElements(pnewelem, 1, mgui_nCursorPos, TRUE);
00898   (*pnewelem) = NULL;
00899  }
00900 }
00901 
00902 mcInsertRes mcMonomialHelpers::gui_Insert(const mcElement &toinsert, mcElement *)
00903 {
00904  mcCursorPos cp(data_Get(mgui_nCursorPos).gui_GetCursorPos());
00905  mcElement replacement;
00906 
00907 
00908   
00909   mcInsertRes r = data_Get(mgui_nCursorPos).gui_Insert(toinsert, &replacement);
00910 
00911   switch (r) {
00912   case mcINSR_OKAY:
00913    return mcINSR_OKAY;
00914 
00915   case mcINSR_REPLACE_THIS:
00916    gui_Replace(&replacement);
00917    break;
00918   }
00919 
00920 
00921  return mcINSR_OKAY;
00922 
00923 
00924 
00925 
00926 
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 }
00940 
00941 mcInsertRes mcMonomialHelpers::gui_Insert(const mcElement *arr, int n)
00942 {
00943 
00944 
00945 
00946 
00947 
00948 
00949 
00950 
00951 
00952 
00953 
00954 
00955 
00956 
00957 
00958 
00959 
00960  return mcINSR_OKAY;
00961 }
00962 
00963 
00964 
00965 
00966 
00967 
00968 
00969 
00970 
00971 
00972 wxXml2Node mcMonomialHelpers::io_GetMathML(bool bGetPresentation) const
00973 {
00974  if (data_GetCount() == 1) {
00975   
00976   return data_Get(0).io_GetMathML(bGetPresentation);
00977  }
00978 
00979  
00980  wxXml2Node maintag(wxXML_ELEMENT_NODE, wxXml2EmptyDoc, wxT("mrow")); 
00981 
00982  
00983  for (int i=0, max=data_GetCount(); i < max; i++) {
00984 
00985   
00986   wxXml2Node tmp(data_Get(i).io_GetMathML(bGetPresentation));
00987   maintag.AddChild(tmp);
00988   
00989   
00990   
00991   if (i < max-1 && !data_isOp(i) && !data_isOp(i+1)) {
00992 
00993    wxXml2Node mult(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("mo"), wxT("⁢"));
00994    maintag.AddChild(mult);
00995   }
00996  }
00997 
00998  return maintag;
00999 }
01000 
01001 bool mcMonomialHelpers::io_ImportPresentationMathML(wxXml2Node tag, wxString &err)
01002 {
01003  mcASSERT(tag.GetName() == wxT("mrow") ||
01004    tag.GetName() == wxT("mo"), wxT("Error in mcMonomialHelpers::io_isBeginTag"));
01005  
01006  wxXml2Node p = tag.GetChildren();
01007  mcElementType n;
01008 
01009  
01010  data_DeleteAll();
01011 
01012  
01013  
01014  
01015  if (tag.GetName() == wxT("mo") || (tag.GetName() == wxT("mrow") && p.GetName() == wxT("mo"))) {
01016 
01017   
01018   wxXml2Node mo = (tag.GetName() == wxT("mo")) ? tag : p;
01019   n = mcElementHelpers::io_isTagBeginTag(mo);
01020   mcASSERT(n == mcET_ADDOP || n == mcET_SUBOP,
01021    wxT("The given node should be, or contain (as first child), a + or -"));
01022 
01023   
01024   data_DeleteAll();
01025   mcElement pnew = mcElementHelpers::data_NewElem(n);
01026   if (!pnew.io_ImportPresentationMathML(mo, err))
01027    return FALSE;
01028   data_AddElements(&pnew, 1);
01029 
01030   
01031   
01032   
01033   p = p.GetNext();
01034  }
01035 
01036  if (tag.GetName() == wxT("mrow")) {
01037 
01038   
01039   
01040   
01041 
01042 
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050   
01051   if (data_GetCount() != 1 ||
01052    (data_Get(0).data_GetType() != mcET_ADDOP && 
01053    data_Get(0).data_GetType() != mcET_SUBOP)) {
01054 
01055    data_DeleteAll();  
01056 
01057    
01058    mcEmptyBox first;
01059    data_AddElements(&first, 1);
01060   }
01061 
01062   
01063   while (p != wxXml2EmptyNode) {
01064 
01065    
01066    n = mcElementHelpers::io_isTagBeginTag(p);
01067    if (n != FALSE) {
01068 
01069     mcElement pnew = mcElementHelpers::data_NewElem(n);
01070     if (!pnew.io_ImportPresentationMathML(p, err))
01071      return FALSE;
01072     data_AddElements(&pnew, 1);
01073    }
01074 
01075    p = p.GetNext();
01076   }
01077  }
01078 
01079  
01080  io_PostProcessChildren();
01081 
01082  return TRUE;
01083 }
01084 
01085 bool mcMonomialHelpers::io_ImportInlinedExpr(const wxString &todecode, int *c, wxString &pErr)
01086 {
01087  wxString token(todecode);
01088  mcElementType n;
01089  int count;
01090 
01091  
01092  data_DeleteAll();
01093 
01094  while (!token.IsEmpty()) {
01095   
01096   
01097   
01098   n = mcFunctionHelpers::io_isFunctionBeginChar(token) ? mcET_FUNCTION : mcET_INVALID;
01099   
01100   
01101   if (n == mcET_INVALID)
01102    n = mcRadicalHelpers::io_isRadicalBeginChar(token) ? mcET_RADICAL : mcET_INVALID;
01103 
01104   
01105   if (n == mcET_INVALID)
01106    n = mcElementHelpers::io_isCharBeginChar(token.GetChar(0));
01107   
01108   
01109   if (n == mcET_ADDOP || n == mcET_SUBOP)
01110    break;  
01111 
01112   if (n != mcET_INVALID) {
01113    
01114    mcElement pnew = mcElementHelpers::data_NewElem(n);   
01115    
01116    
01117    
01118    if (!pnew.io_ImportInlinedExpr(token, &count, pErr))
01119     return FALSE;
01120    
01121    
01122    data_AddElements(&pnew, 1);
01123    
01124 
01125    
01126    token = token.Right(token.Len()-count);
01127    
01128   } else {
01129    
01130    pErr = wxT("Could not recognize the first element ")
01131     wxT("encoded in this token: ") + token;
01132    return FALSE;
01133   }
01134  }
01135  
01136  
01137  
01138  if (c) *c = todecode.Len()-token.Len();
01139 
01140  
01141  
01142  data_Repair();
01143 
01144  
01145  io_PostProcessChildren();
01146 
01147  mcIOLOG(wxT("mcMonomialHelpers::io_ImportInlinedExpr - we've imported [%s]"), mcTXTTHIS);
01148 
01149  return TRUE;
01150 }
01151 
01152 void mcMonomialHelpers::io_PostProcess()
01153 {
01154  
01155  
01156  
01157  
01158  
01159  
01160  
01161  
01162  
01163  
01164  
01165  if (mcMonomialHelpers::sio_bAutoConvertDivOpToFractions)
01166   data_TransformDivOp();
01167 }
01168 
01169 
01170 
01171 
01172 
01174 
01175 
01176 
01177 
01178 
01179 
01180 
01181 
01182 
01183 
01184 
01185 
01186 
01187 
01188 
01189 
01190 
01191 
01192 
01193 
01194 
01195 
01196 
01197 
01198 
01199 
01200 
01201 
01202 
01203 
01204 
01205 
01206 
01207 
01208 
01209 int mcMonomialHelpers::math_MathToDataIdx(int mathindex) const
01210 { 
01211  if (mathindex < 0 || mathindex >= math_GetCount()) {
01212 
01213   mcMATHLOG(wxT("mcMonomialHelpers::math_MathToDataIdx [%s] - ")
01214    wxT("invalid conversion required"), mcTXTTHIS);
01215   return -1;  
01216  }
01217  
01218  return data_GetNonOpElemIndex(mathindex); 
01219 }
01220  
01221 int mcMonomialHelpers::math_DataToMathIdx(int dataindex) const
01222 {
01223  data_CheckIndex(dataindex);
01224 
01225  int elements=0;
01226  for (int n=0; n < dataindex; n++)
01227   if (!data_isOp(n))
01228    elements++;
01229 
01230  return elements;
01231 }
01232 
01233 mcBasicOpRes mcMonomialHelpers::math_RaiseTo(const mcPolynomial &p)
01234 {
01235  mcMATHLOG(wxT("mcMonomialHelpers::math_RaiseTo [%s] - raising %d elements to [%s]"),
01236         mcTXTTHIS, math_GetCount(), mcTXT(p));
01237 
01238  
01239  for (int i=0,max=math_GetCount(); i < max; i++) {
01240 
01241   mcBasicOpRes r = math_Get(i).math_RaiseTo(p);
01242 
01243   switch (r) {
01244   case mcBOR_REMOVE_OPERAND:
01245    continue;
01246 
01247   case mcBOR_INVALID:
01248   default:
01249    mcASSERT(0, wxT("invalid raise !"));
01250   }
01251  }
01252 
01253  return mcBOR_REMOVE_OPERAND;
01254 }
01255 
01256 mcExpSimRes mcMonomialHelpers::math_HandleExpSimFlag(mcExpSimRes r, mcElement *newelem, int i)
01257 {
01258  
01259  
01260  
01261  
01262  if (r == mcESR_REPLACE_THIS && 
01263   (*newelem).data_GetType() == mcET_POLYNOMIAL) {
01264 
01265   
01266   
01267   
01268 
01269   
01270   
01271   
01272 
01273   
01274   
01275   return mcESR_REPLACE_THIS;
01276  }
01277 
01278  
01279  if (r == mcESR_DISTRIBUTE)
01280   return mcESR_DISTRIBUTE;
01281  if (r == mcESR_CHANGE_SIGN)
01282   return mcESR_CHANGE_SIGN;
01283 
01284  return mcElementArrayHelpers::math_HandleExpSimFlag(r, newelem, i);
01285 }
01286 
01287 void mcMonomialHelpers::math_Abs()
01288 {
01289  
01290  
01291  mcNumber oldcoeff(math_GetCoeff());
01292  oldcoeff.math_Abs();
01293 
01294  math_SetCoeff(oldcoeff);
01295 }
01296 
01297 mcExpSimRes mcMonomialHelpers::math_Reorder()
01298 { 
01299  
01300  mcASSERT(data_GetNumOfElemType(mcET_DIVOP) == 0, 
01301   wxT("This function cannot work with mcDivOp scattered in the array"));
01302  
01303  
01304  math_RemoveAllOp();
01305 
01306  
01307  int n = math_ReorderElements(data_GetArray(), data_GetCount());
01308 
01309  
01310  data_Repair();
01311  
01312  return (n == 0 ? mcESR_DONE : mcESR_NOTFINISHED);
01313 }
01314 
01315 int mcMonomialHelpers::math_GetOrderPos() const
01316 {
01317  mcMATHLOG(wxT("mcMonomialHelpers::math_GetOrderPos - retrieving order position for [%s]"), mcTXTTHIS);
01318 
01319  mcIntegerValue unk = math_GetMaxDegreeForSymbolArray(&mcSymbol::arrUnknowns);
01320  if (unk != *mcIntegerValue::pNAN)
01321   return -(int)(unk.GetInt()*10000);  
01322 
01323  
01324  
01325  mcIntegerValue par = math_GetMaxDegreeForSymbolArray(&mcSymbol::arrParameters);
01326  if (par == *mcIntegerValue::pNAN) par = 0;
01327  mcIntegerValue con = math_GetMaxDegreeForSymbolArray(&mcSymbol::arrConstants);
01328  if (con == *mcIntegerValue::pNAN) con = 0;
01329 
01330  
01331  par *= 1;
01332  con /= 2;
01333 
01334  
01335  return -(int)(par.GetInt()+con.GetInt());
01336 }
01337 
01338 mcIntegerValue mcMonomialHelpers::math_GetMaxDegreeFor(const mcSymbolProperties *p) const
01339 { 
01340  mcMATHLOG(wxT("mcMonomialHelpers::math_GetMaxDegreeFor [%s]"), mcTXTTHIS);
01341  mcSymbol s(p->data_GetSafeLinkedSym());
01342  mcIntegerValue res = 0;
01343 
01344  
01345  for (int i=0,max=math_GetCountOf(s); i < max; i++) {
01346   
01347   mcSymbol sym(math_Find(i, s));
01348   mcASSERT(sym.data_isLinkedWith(p), wxT("The math_Find() function did not work"));
01349   
01350   
01351   const mcPolynomial exp = sym.math_GetConstExp();
01352   mcMATHLOG(wxT("mcMonomialHelpers::math_GetMaxDegreeFor - symbol [%s] have [%s] as exp"), 
01353      mcTXT(sym), mcTXT(exp));
01354   mcIntegerValue tmp = 0;
01355   
01356   
01357   if (exp != mcEmptyElement) 
01358    tmp = mcIntegerValue(exp.math_GetWrappedNumber());
01359   
01360   
01361   if (!tmp.isValid())
01362    return tmp;
01363   
01364   res = res.GetMax(tmp);
01365   mcMATHLOG(wxT("mcMonomialHelpers::math_GetMaxDegreeFor - currently it's [%s]"), 
01366    res.GetStr().c_str());
01367  }
01368  
01369  
01370  return res;
01371 }
01372 
01373 mcIntegerValue mcMonomialHelpers::math_GetMaxDegreeForSymbolArray(const mcSymbolArray *p) const
01374 {
01375  mcIntegerValue res = 0;
01376  for (int i=0; i < p->data_GetCount(); i++) {
01377 
01378   
01379   mcIntegerValue tmp = math_GetMaxDegreeFor(p->data_GetSymbol(i));
01380   if (tmp == *mcIntegerValue::pNAN)
01381    return *mcIntegerValue::pNAN;
01382 
01383   
01384   res += tmp;
01385  }
01386 
01387  return res;
01388 }
01389 
01390 
01391 
01392 
01393 
01394 
01395 
01396 mcPolynomial mcMonomialHelpers::math_GetPolynomialWrapper() const
01397 {
01398  
01399  mcPolynomial res;
01400  mcElement copy(this);
01401  copy.data_MakePrivateCopy();
01402 
01403  
01404  res.data_AddElements(©, 1);
01405 
01406  
01407  return res;
01408 }
01409 
01410 mcArrayEntry mcMonomialHelpers::math_WrapMonomial(const mcMonomial &mon)
01411 {
01412  mcASSERT(0, wxT("bad use of this function !"));
01413 
01414  
01415  data_DeepCopy(mon.hlp());
01416 
01417  
01418  return mcArrayEntry(this, -1);
01419 }
01420 
01421 mcArrayEntry mcMonomialHelpers::math_WrapSimple(const mcElement &p)
01422 {
01423  mcASSERT(p.data_GetType() != mcET_MONOMIAL &&
01424    p.data_GetType() != mcET_POLYNOMIAL, wxT("cannot nest arrays !!"));
01425 
01426  int idx = data_AddElements(&p, 1);
01427  return mcArrayEntry(this, idx);
01428 }
01429 
01430 void mcMonomialHelpers::math_PrepareForComparison(mcElementArray &p) const
01431 {
01432  
01433 
01434  
01435  
01436  
01437  p.math_MaxSimplify(mcEXPSIM_NOFLAGS);
01438 
01439  
01440  
01441  if (p.data_GetType() == mcET_MONOMIAL)
01442   mcMonomial(p).math_RemoveAllOp();
01443 }
01444 
01445 mcExpSimRes mcMonomialHelpers::math_BeginSimSteps()
01446 {
01447  
01448  data_Repair();
01449 
01450  
01451  math_TransformDivOp();
01452 
01453  
01454  return mcESR_DONE;
01455 }
01456 
01457 void mcMonomialHelpers::math_EndSimSteps()
01458 {
01459  
01460  data_Repair();
01461 }
01462 
01463 
01464 
01465 
01466 
01467 
01468 
01469 
01470 bool mcMonomialHelpers::math_CanBeAddedWith(const mcElement &p) const
01471 {
01472  const mcMonomial &m = (mcMonomial &)p;
01473 
01474  
01475  
01476  if (p.data_GetType() == mcET_MONOMIAL) {
01477  
01478   if (math_GetCount() == 1 &&
01479    m.math_GetCount() == 1) {
01480 
01481    
01482    
01483    bool res = data_Get(0).math_CanBeAddedWith(m.math_Get(0));
01484 
01485    
01486    
01487    
01488    
01489    
01490    
01491    
01492    
01493    
01494    
01495    
01496    
01497    if (res) return TRUE;
01498   }
01499 
01500   
01501   
01502   if (math_isSimilarTo(m))
01503    return TRUE;
01504  }
01505 
01506  return FALSE;
01507 }
01508 
01509 mcBasicOpRes mcMonomialHelpers::math_Add(const mcElement &p, mcElement *pp, bool add)
01510 {
01511  const mcMonomial &m = (const mcMonomial &)p;
01512  mcASSERT(p.data_GetType() == mcET_MONOMIAL, wxT("Cannot add non-monomials"));
01513 
01514  
01515  
01516  math_RemoveAllOp();
01517 
01518  
01519  
01520 
01521  
01522  
01523  
01524  if (math_GetCount() == 1 && m.math_GetCount() == 1) {
01525 
01526   mcElement operand = m.math_Get(0);
01527   
01528   
01529   
01530   
01531   if (math_Get(0).math_CanBeAddedWith(operand)) {
01532    
01533    
01534    
01535    
01536    mcMATHLOG(wxT("mcMonomialHelpers::math_Add - %s [%s] and [%s]"), 
01537     (add ? wxT("adding") : wxT("subtracting")), mcTXT(math_Get(0)), mcTXT(operand));
01538    return math_Get(0).math_Add(operand, NULL, add);
01539   }
01540  }
01541 
01542  
01543  
01544  
01545  mcASSERT(math_isSimilarTo(m), wxT("math_CanBeAddedWith() is buggy"));
01546  
01547 
01548  
01549  mcRealValue thiscoeff = math_GetCoeff();  
01550  mcRealValue mcoeff = m.math_GetCoeff();
01551  mcMATHLOG(wxT("mcMonomialHelpers::math_Add - the two coeff to %s are: [%s] and [%s]"), 
01552   (add ? wxT("ADD") : wxT("SUBTRACT")), mcTXTV(thiscoeff), mcTXTV(mcoeff));
01553  
01554  if (add)
01555   thiscoeff += mcoeff;
01556  else
01557   thiscoeff -= mcoeff;
01558 
01559  mcMATHLOG(wxT("mcMonomialHelpers::math_Add - the result is [%s]"), mcTXTV(thiscoeff)); 
01560  math_SetCoeff(mcNumber(thiscoeff));
01561  
01562  
01563  data_Repair();
01564 
01565  
01566  return mcBOR_REMOVE_OPERAND;
01567 }
01568 
01569 mcBasicOpRes mcMonomialHelpers::math_MultiplyBy(const mcElement &e, mcElement *pp)
01570 {
01571  mcASSERT(e.data_GetType() == mcET_MONOMIAL, 
01572   wxT("Only monomials can be used here; use math_MultiplyBySimple() instead"));
01573 
01574  mcMonomial &m = (mcMonomial &)e;
01575  
01576  mcElement num(mcEmptyElement);
01577  if ((num=data_GetWrapped(mcET_NUMBER)) != mcEmptyElement &&
01578   mcNumber(num).data_Get() == 1.0) {  
01579 
01580   
01581   
01582   data_DeleteAll();
01583   data_Merge(m);
01584 
01585  } else {
01586  
01587   
01588   data_Merge(m);
01589  }
01590 
01591  
01592  data_Repair();
01593 
01594  
01595  return mcBOR_REMOVE_OPERAND;
01596 }
01597 
01598 mcBasicOpRes mcMonomialHelpers::math_DivideBy(const mcElement &e, mcElement *pp)
01599 {
01600  mcASSERT(e.data_GetType() == mcET_MONOMIAL, 
01601   wxT("Only monomials can be used here; use math_DivideBySimple() instead"));
01602 
01603  
01604  mcPolynomial &den = math_EmbedInFraction(FALSE).data_GetFraction().data_GetDen();
01605 
01606  
01607  mcMonomial towrap(e);
01608  den.data_DeleteAll();
01609  den.math_WrapMonomial(towrap);
01610  
01611  
01612  return mcBOR_REMOVE_OPERAND;
01613 }
01614 
01615 
01616 
01617 
01618 
01619 
01620 
01621 
01622 
01623 
01624 bool mcMonomialHelpers::math_isSimilarTo(const mcMonomial &m) const
01625 {
01626  
01627  mcMonomial m1(this);
01628  mcMonomial m2(m);
01629  
01630  
01631  m1.math_RemoveCoeff();
01632  m2.math_RemoveCoeff();
01633 
01634  
01635  mcMATHLOG(wxT("mcMonomialHelpers::math_isSimilarTo - are [%s] and [%s] similar ?"),
01636             mcTXT(m1), mcTXT(m2));
01637  bool res = m1.math_Compare(m2, mcFIND_NOFLAGS);
01638  mcMATHLOG(wxT("mcMonomialHelpers::math_isSimilarTo - %s"),
01639     (res == TRUE ? wxT("yes they are") : wxT("no they aren't")));
01640 
01641  
01642  
01643  
01644 
01645  return res;
01646 }
01647 
01648 void mcMonomialHelpers::math_TransformDivOp()
01649 {
01650  
01651  for (int i=0; i < data_GetCount()-1; i++) {
01652 
01653   
01654   if (data_Get(i).data_GetType() == mcET_DIVOP) {
01655 
01656    
01657    mcElement replacement = NULL;
01658    data_Get(i+1).math_MakeReciprocal(&replacement);
01659 
01660    if (replacement != mcEmptyElement) {
01661 
01662     
01663     data_AddElements(&replacement, 1, i+1, TRUE);
01664    }
01665 
01666    
01667    data_AddNewOp(mcET_MULTOP, i);
01668   }
01669  }
01670 }
01671 
01672 void mcMonomialHelpers::math_RemoveAllOp()
01673 {
01674  
01675  math_TransformDivOp();
01676 
01677  
01678  for (int i=0; i < data_GetCount(); i++) {
01679 
01680   if (data_isOp(i)) {  
01681 
01682    data_Delete(i);
01683    data_MoveElemLeft(i);
01684   }
01685  }
01686 }
01687 
01688 void mcMonomialHelpers::math_RemoveCoeff()
01689 {
01690  for (int i=0; i < math_GetCount(); i++) {
01691 
01692 #ifdef EXTENDED_COEFF
01693   if (!data_Get(i).math_ContainsUnknowns(NULL))
01694    if (!Remove(i, TRUE))
01695     i--;  
01696 #else
01697   
01698   if (math_Get(i).data_GetType() == mcET_NUMBER) {
01699 
01700    
01701    
01702    
01703    if (!math_Remove(i, TRUE))
01704     i--;  
01705   }
01706 #endif
01707  }
01708 }
01709 
01710 mcMonomial mcMonomialHelpers::math_DetachNonCommonFactors(const mcMonomial &m)
01711 {
01712  
01713  
01714  mcMonomial res;
01715 
01716  
01717  for (int i=0; i < data_GetCount(); i++) {
01718   
01719   mcElementType t = data_Get(i).data_GetType();
01720   int n = -1;
01721   
01722   
01723   
01724   
01725   for (int j=0; j < m.math_GetCount(); j++)
01726    if (t == m.math_Get(j).data_GetType())
01727     if (data_Get(i).math_Compare(m.math_Get(j), TRUE))
01728      n = j;
01729   
01730   if (n == -1) {
01731    
01732    
01733    res.data_AddElements(data_GetArray(i), 1, -1, TRUE);
01734    
01735    
01736    data_Delete(i);
01737    data_MoveElemLeft(i);
01738    i--;
01739   }
01740  }
01741 
01742  return res;
01743 }
01744 
01745 void mcMonomialHelpers::math_SimplifyCoeff()
01746 {
01747  mcMATHLOG(wxT("mcMonomialHelpers::math_SimplifyCoeff [%s] - process starting"), mcTXTTHIS);
01748 
01749  
01750  mcNumber num = *mcNumberHelpers::smath_pOne;
01751 
01752  
01753  mcNumber den = *mcNumberHelpers::smath_pOne;
01754 
01755  for (int i=0, max=data_GetNumOfElemType(mcET_NUMBER); i < max; i++) {
01756 
01757   int n = data_GetElemIndexOfType(i, mcET_NUMBER);
01758 
01759   
01760   
01761   mcElementType t = mcET_MULTOP;
01762   
01763   
01764   
01765   if (n >= 0) {
01766    if (n > 0 && data_isOp(n-1))
01767     t = data_Get(n-1).data_GetType();
01768    
01769    
01770    
01771    if (t == mcET_MULTOP)
01772     num.math_SimpleMultiplyBy(data_Get(n));
01773    else if (t == mcET_DIVOP)
01774     den.math_SimpleMultiplyBy(data_Get(n));  
01775   }
01776  }
01777 
01778  
01779  math_ApplyOpSimple(mcET_DIVOP, num, den);
01780 
01781  
01782  
01783  math_SetCoeff(num);
01784  mcMATHLOG(wxT("mcMonomialHelpers::math_SimplifyCoeff [%s] - coeff simplified"), mcTXTTHIS);
01785 }
01786 
01787 
01788 mcRealValue mcMonomialHelpers::math_GetCoeff() const
01789 {
01790 #ifdef EXTENDED_COEFF
01791 
01792  mcMonomial &coeff = (mcMonomial &)mcNewMonomial();
01793 
01794  
01795  for (int i=0, max=data_GetCount(); i < max; i++) {
01796 
01797   mcElement p = data_Get(i);
01798   if (!p->math_ContainsUnknowns(NULL))
01799    coeff->data_AddElements(&p, 1, -1);
01800  }
01801 
01802  if (coeff->data_GetCount() > 0)
01803   return coeff;
01804  return *mcNumberHelpers::smath_pOne;
01805 
01806 #else
01807 
01808  int n = data_GetNumOfElemType(mcET_NUMBER);
01809  mcMonomial touse(this);
01810 
01811  if (n > 1) {
01812   mcMonomial copy(this);
01813 
01814   
01815   
01816   copy.math_SimplifyCoeff();
01817 
01818   
01819   touse.data_Ref(copy);
01820   
01821   
01822 #ifdef __MCDEBUG__
01823   n = touse.data_GetNumOfElemType(mcET_NUMBER);
01824 #else
01825   n = 1;
01826 #endif
01827  }
01828 
01829  mcASSERT(n <= 1, wxT("Something wrong in math_SimplifyCoeff"));
01830  
01831  
01832  if (n > 0)
01833   return mcNumber(touse.data_GetElemOfType(0, mcET_NUMBER)).data_Get();
01834  
01835  
01836  return mcRealValue(1);
01837 
01838 #endif
01839 }
01840 
01841 void mcMonomialHelpers::math_SetCoeff(const mcNumber &coeff)
01842 {
01843  mcNumber n(coeff);
01844 
01845  
01846  math_RemoveCoeff();
01847 
01848  
01849  
01850 
01851 
01852 
01853 
01854 
01855 
01856 
01857 
01858  
01859  
01860  
01861  bool overwrite = FALSE;
01862  if (data_GetCount() > 0 && data_Get(0).data_GetType() == mcET_NUMBER)
01863   overwrite = TRUE;
01864 
01865  
01866  data_AddElements((mcElement *)(&n), 1, 0, overwrite);
01867 }
01868 
01869 void mcMonomialHelpers::math_ChangeCoeffSign()
01870 { 
01871  
01872  math_SetCoeff(mcNumber(math_GetCoeff().ChangeSign())); 
01873 }
01874 
01875 
01876 
01877 
01878 
01879 
01880 
01881 
01882 
01883 mcMonomial mcMonomialHelpers::math_GetLCM(const mcElement &p) const
01884 {
01885  mcMATHLOG(wxT("mcMonomialHelpers::math_GetLCM - computing lcm between [%s] and [%s]"), 
01886     mcTXTTHIS, mcTXT(p));
01887 
01888  mcMonomial arr(p);
01889  mcMonomial res(this);
01890 
01891  if (arr.math_GetCount() == 1 && math_GetCount() == 1) {
01892 
01893   mcElement a(arr.math_Get(0));
01894   mcElement b(math_Get(0));
01895 
01896   
01897   
01898   if (!a.math_Compare(b, TRUE)) {
01899 
01900    res.math_SimpleMultiplyBy(a);
01901   }
01902 
01903  } else {
01904 
01905   for (int j=0,max=arr.math_GetCount(); j < max; j++) {
01906 
01907    mcElement tofind(arr.math_Get(j));
01908    mcMATHLOG(wxT("mcMonomialHelpers::math_GetLCM - now processing [%s]"), mcTXT(tofind));
01909    
01910    
01911    int idx=res.math_GetIndexOf(0, tofind);
01912    
01913    if (idx > -1) {
01914 
01915     
01916     
01917     mcElement &tmp = res.math_Get(idx);   
01918     mcMonomial mon(tmp.math_GetLCM(tofind));
01919    
01920     
01921     
01922     res.math_Remove(idx);
01923     res.math_SimpleMultiplyBy(mon);
01924 
01925     
01926     
01927     mcASSERT(res.math_GetIndexOf(1, tofind) == -1, 
01928      wxT("Cannot be present more than a factor of 'tofind'..."));
01929 
01930    } else {
01931 
01932     
01933     
01934     res.math_SimpleMultiplyBy(tofind);
01935    }
01936 
01937    mcMATHLOG(wxT("mcMonomialHelpers::math_GetLCM - final lcm now is [%s]"), mcTXT(res));
01938   }
01939  }
01940 
01941  mcMATHLOG(wxT("mcMonomialHelpers::math_GetLCM - lcm is [%s]"), mcTXT(res));
01942  return res;
01943 }
01944 
01945 mcMonomial mcMonomialHelpers::math_GetGCD(const mcElement &p) const
01946 {
01947  mcMATHLOG(wxT("mcMonomialHelpers::math_GetGCD - computing gcd between [%s] and [%s]"), 
01948     mcTXTTHIS, mcTXT(p));
01949 
01950  
01951  
01952  mcMonomial arr2(p);
01953  mcMonomial res;
01954 
01955  
01956  
01957  
01958 
01959  if (arr2.math_GetCount() == 1 && math_GetCount() == 1) {
01960 
01961   mcElement a(arr2.math_Get(0));
01962   mcElement b(math_Get(0));
01963 
01964   if (a.data_GetType() != b.data_GetType())
01965    return *mcMonomialHelpers::smath_pOne;
01966 
01967   
01968   return a.math_GetGCD(b);
01969 
01970  } else {
01971   
01972   res.math_ResetToOne();
01973   for (int i=0; i < math_GetCount(); i++) {
01974    for (int j=0; j < arr2.math_GetCount(); j++) {
01975     
01976     
01977     
01978     
01979     
01980     
01981     
01982     
01983     
01984     
01985     
01986     
01987     
01988     
01989     
01990     
01991     mcElement tmp(math_Get(i).hlp()->math_GetGCD(arr2.math_Get(j)));
01992     if (!mcMonomial(tmp).math_isWrappingOnly(1.0))
01993      res.math_SimpleMultiplyBy(tmp);
01994 
01995     mcMATHLOG(wxT("mcMonomialHelpers::math_GetGCD - gcd currently is [%s]"), 
01996       mcTXT(res));
01997    }
01998   }
01999  }
02000 
02001  mcMATHLOG(wxT("mcMonomialHelpers::math_GetGCD - final gcd is [%s]"), mcTXT(res));
02002  return res;
02003 }
02004 
02005 
02006