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 #ifndef POLYNOMIAL_H
00034 #define POLYNOMIAL_H
00035
00036
00037 #ifdef __GNUG__
00038 #pragma interface "Polynomial.h"
00039 #endif
00040
00041
00042 #include "mc/ElementArray.h"
00043 #include "mc/Monomial.h"
00044
00045
00046
00047 class mcMonomialHelpers;
00048 class mcMonomial;
00049 class mcRadical;
00050
00051 mcDEFINE_HELPER_CLASSES(mcPolynomial)
00052 extern mcPolynomial mcEmptyPolynomial;
00053
00054
00055
00059 #define mcMAKEPOL_IDX(midx, eidx) (((midx) << 16) | (eidx))
00060
00061
00070 class mcPolynomialHelpers : public mcElementArrayHelpers
00071 {
00072 mcDEFINE_REFERENCE_DATA(mcPolynomial, mcET_POLYNOMIAL);
00073
00074 #ifdef mcENABLE_GUI
00075 public:
00076
00079 static int sgui_nSpaceBetween;
00080
00082 int gui_GetSpaceBetweenRatio() const
00083 { return sgui_nSpaceBetween/(gui_GetExpDepth()+1); }
00084
00087 bool mgui_bRemoveParenthesis;
00088 bool mgui_bMoveCursorAtBracketBegin;
00089
00090 mcElement mgui_pBracketToReplace;
00091 bool mgui_bRemoveLeftParenthesis;
00092
00093 #endif
00094
00095
00096 #ifdef mcENABLE_MATH
00097 public:
00098
00100 static mcPolynomial *smath_pOne;
00101
00103 static mcPolynomial *smath_pEmpty;
00104
00105 #endif
00106
00107
00108
00109 public:
00110
00111 mcPolynomialHelpers() { data_Init(); }
00112 virtual ~mcPolynomialHelpers() {}
00113
00114 protected:
00115
00116 void gui_Init() {
00117 mgui_bRemoveParenthesis = FALSE;
00118 mgui_bMoveCursorAtBracketBegin = FALSE;
00119 mgui_bRemoveLeftParenthesis = FALSE;
00120 mcElementArrayHelpers::gui_Init();
00121 }
00122
00123
00124
00125
00126 #ifdef mcENABLE_DATA
00127 protected:
00128
00129 int data_GetIdxFromEntry(const mcArrayEntry *p) const
00130 { return p->mdata_idx & ~(0xFFFF<<16); }
00131 int data_GetMonomialIdxFromEntry(const mcArrayEntry *p) const
00132 { return (p->mdata_idx >> 16); }
00133
00134 mcElement &data_GetRefFromEntry(const mcArrayEntry *p)
00135 {
00136 int midx = data_GetMonomialIdxFromEntry(p), eidx = data_GetIdxFromEntry(p);
00137 if (eidx != -1) {
00138 mcASSERT(data_Get(eidx).data_GetType() == mcET_MONOMIAL, wxT("idx is not valid"));
00139 return ((mcMonomial &)data_Get(midx)).data_Get(eidx);
00140 }
00141
00142 return data_Get(midx);
00143 }
00144
00145 public:
00146
00147 int math_GetIdxFromEntry(const mcArrayEntry *p) const
00148 { return math_DataToMathIdx(data_GetIdxFromEntry(p)); }
00149 int math_GetMonomialIdxFromEntry(const mcArrayEntry *p) const
00150 { return math_DataToMathIdx(data_GetMonomialIdxFromEntry(p)); }
00151
00152
00153 public:
00154 #ifdef __MCDEBUG__
00155
00159 void data_Check() const;
00160 #endif
00161
00162 void data_DeepCopy(const mcElementHelpers *e) {
00163 const mcPolynomialHelpers *p = (const mcPolynomialHelpers *)e;
00164 mgui_bMoveCursorAtBracketBegin = p->mgui_bMoveCursorAtBracketBegin;
00165 mgui_bRemoveLeftParenthesis = p->mgui_bRemoveLeftParenthesis;
00166 mgui_bRemoveParenthesis = p->mgui_bRemoveParenthesis;
00167 mcElementArrayHelpers::data_DeepCopy(e);
00168 }
00169
00170
00171
00172
00176
00184 int data_AddNewMonomialContaining(mcElement *contents, int count = 1,
00185 int pos = -1, bool bOverwrite = FALSE);
00186
00191 int data_AddNewMonomialContaining(mcElement &monomialinit,
00192 int pos, bool bOverwrite = FALSE)
00193 { return data_AddNewMonomialContaining(&monomialinit, 1, pos, bOverwrite); }
00194
00198 int data_AddNewMonomial(const mcMonomial &toinsert, int pos = -1,
00199 bool bOverwrite = FALSE)
00200 { return data_AddElements((mcElement*)(&toinsert), 1, pos, bOverwrite); }
00201
00203 void data_AddNewEmptyBox(int pos)
00204 { data_AddNewEmptyMonomial(pos); }
00205
00208 int data_AddNewEmptyMonomial(int pos = -1);
00209
00213 mcElement &data_AddNewWrappedElement(mcElementType t,
00214 bool bOverwrite = FALSE, int pos = -1);
00215
00221 int data_FindMonomialContaining(int occ, const mcElement &elem) const;
00222
00227 void data_DetachAndShiftMonomial(int n);
00228
00229 virtual bool data_isWrappingOnly(mcElementType t) const;
00230 virtual const mcElement &data_GetWrapped(mcElementType t) const;
00231
00233
00234
00235
00239
00246 bool data_CreateFirstOp();
00247
00251 void data_DeleteFirstOp();
00252
00264 bool data_ReplaceParentheses(bool bMoveAtBracketEnd);
00265 bool data_ReplaceParentheses(int, int, int, int, bool);
00266
00271 void data_ReplaceAllParentheses();
00272
00274
00275 #endif // mcENABLE_DATA
00276
00277
00278
00279 #ifdef mcENABLE_GUI
00280 public:
00281
00285
00290 bool gui_isBeginKey(const mcKey &) const { return FALSE; }
00291
00299 int gui_ExDraw(wxDC &dc, int x, int y, long flags, const wxPoint &pt, int cl) const;
00300
00308 void gui_ExOnSelect(wxDC &dc, wxRect &rc, int cl);
00309
00313 mcInputRes gui_BackInput(const mcKey &key, mcElement *pnewelem, int n);
00314
00318 mcInputRes gui_Input(const mcKey &key, mcElement *pnewelem);
00319
00320 mcInsertRes gui_Insert(const mcElement &toinsert, mcElement *);
00321
00322
00323 void gui_DoSplit(mcElementType type, const mcKey &ev);
00324 void gui_SetCursorPos(const mcCursorPos &code);
00325
00326 void gui_OnSelect(wxDC &dc, wxRect &rc) {
00327
00328 gui_ExOnSelect(dc, rc, -1);
00329 }
00330
00331 int gui_Draw(wxDC &dc, int x, int y, long flags, const wxPoint &pt) const {
00332
00333 return gui_ExDraw(dc, x, y, flags, pt, -1);
00334 }
00335
00337
00338
00339
00343
00345 bool gui_isArrEndKey(const mcKey &) const { return FALSE; }
00346
00351 bool gui_isArrayEmpty();
00352
00355 void gui_CheckCursorPos() const;
00356
00360 void gui_OnNewParenthesis(bool leftpar) {
00361 mgui_bRemoveParenthesis = TRUE;
00362 mgui_bMoveCursorAtBracketBegin = leftpar;
00363 }
00364
00365 void gui_SetBracketToReplace(const mcBracket &p, bool leftpar) {
00366 mgui_pBracketToReplace = (const mcElement &)p;
00367 mgui_bRemoveLeftParenthesis = leftpar;
00368 }
00369
00373 void gui_ReplaceBracket(const mcBracket &, bool left);
00374
00375
00376 int gui_AddNewElement(mcElementType type, const mcKey &key, int pos = -1);
00377
00378 void gui_AddNewEmptyMonomial(int pos = -1);
00379
00381
00382 #endif // mcENABLE_GUI
00383
00384
00385
00386
00387 #ifdef mcENABLE_MATH
00388 protected:
00389
00397 mcExpSimRes math_Reorder();
00398
00403 void math_DistributeBracket(int mdataidx, int bridx);
00404
00406 virtual void math_EndSimSteps() { }
00407
00409 virtual void math_EndExpSteps() { }
00410
00412 mcExpSimRes math_SimplifySolveOp(long flags);
00413
00414
00415 public:
00416
00420
00427 virtual int math_GetCount() const
00428 { return data_GetNumOfElemType(mcET_MONOMIAL); }
00429
00431 const mcMonomial &math_Get(int n) const
00432 { return (const mcMonomial &)(data_GetElemOfType(n, mcET_MONOMIAL)); }
00433 mcMonomial &math_Get(int n)
00434 { return (mcMonomial &)data_GetElemOfType(n, mcET_MONOMIAL); }
00435
00436
00437
00438
00439 virtual bool math_isWrappingOnly(mcElementType t) const;
00440 virtual const mcElement &math_GetWrapped(mcElementType t) const;
00441
00446 int math_FindMonomialContaining(const mcElement &elem, int occ = 0, int *n = NULL) const;
00447
00451 const mcMonomial &math_GetMonomialContaining(const mcElement &elem,
00452 int occ = 0, int *n = NULL) const;
00453
00459 mcMonomial math_GetCoeffOf(int mathidx, const mcElement *toremove, int ntoremove) const;
00460
00464 mcMonomial math_GetCoeffOf(const mcSymbolProperties *sym, const mcPolynomial &exp, int occ = 0) const;
00465
00469 mcMonomial math_GetCoeffOf(const mcSymbolProperties *sym, const mcRealValue &exp, int occ = 0) const;
00470
00471
00472
00473
00477
00478
00481 bool math_isFactorized() const { return math_GetCount() == 1; }
00482
00486 bool math_isFirstMonomialNegative() const
00487 { if (data_isArrayEmpty()) return FALSE; else return (math_GetSign(0)==-1); }
00488
00489
00491 void math_Factorize(int *n, int count);
00492
00493 void math_FactoreOut(int *n, int count, bool bForceUseless);
00494 void math_FactoreOutAll(bool bForceUseless)
00495 { math_FactoreOut(NULL, -1, bForceUseless); }
00496
00497 void math_FactoreOut(const mcSymbolProperties *unk, const mcPolynomial &pol, bool bForceUseless);
00498 void math_FactoreOutFreeOf(const mcSymbolProperties *unk, const mcPolynomial &pol, bool bForceUseless);
00499
00500 void math_FactoreOut(const mcSymbolArray *arr);
00501 void math_FactoreOutUnknowns();
00502 void math_FactoreOutParameters();
00503 void math_FactoreOutConstants();
00504
00505
00506 mcArrayEntry math_EmbedInBracket(int *n, int count);
00507
00511 mcArrayEntry math_GetIndexOf(int occ, const mcMonomial &tofind, bool positivesign) const;
00512
00514
00515 mcExpSimRes math_HandleExpSimFlag(mcExpSimRes r, mcElement *pnew, int i);
00516
00518
00519
00520
00524
00526 int math_DataToMathIdx(int dataindex) const;
00527
00529 int math_MathToDataIdx(int mathindex) const;
00530
00531 mcElementType math_GetNeutralOpType() const { return mcET_ADDOP; }
00532 double math_GetNeutralValue() const { return 0.0; }
00533
00534 mcPolynomial math_GetPolynomialWrapper() const;
00535 mcArrayEntry math_WrapMonomial(const mcMonomial &);
00536 mcArrayEntry math_WrapSimple(const mcElement &);
00537 mcElementArray math_CreateWrapperFor(const mcElement &p) const;
00538
00539
00540
00544 mcIntegerValue math_GetMaxDegreeFor(const mcSymbolProperties *) const;
00545
00547
00548
00549
00553
00555 int math_GetSign(int n) const;
00556
00560 const mcNumber &math_GetNumSign(const mcMonomial &m, int occ = 0) const;
00561
00563 void math_SetSign(int n, int sgn);
00564
00567 void math_ChangeSign(int n) { math_SetSign(n, -math_GetSign(n)); }
00568
00570 void math_ChangeAllSigns();
00571
00574 void math_SyncCoeffWithSigns();
00575
00578 void math_PackSign(mcMonomial &m, int occ = 0) const;
00579
00582 bool math_DeleteFirstOp();
00583
00585
00586
00587
00591
00592 int math_GetSelCount() const
00593 { return gui_GetSelElemCountOfType(mcET_MONOMIAL); }
00594
00595 int math_GetSelIndex(int n) const
00596 { return gui_GetSelElemIndexOfType(n, mcET_MONOMIAL); }
00597
00598 const mcMonomial &math_GetSel(int n) const
00599 { return (const mcMonomial &)gui_GetSelElemOfType(n, mcET_MONOMIAL); }
00600
00601 mcMonomial &math_GetSel(int n)
00602 { return (mcMonomial &)gui_GetSelElemOfType(n, mcET_MONOMIAL); }
00603
00604 void math_DeleteSelection();
00605
00607
00608
00609
00613
00614 mcBasicOpRes math_Add(const mcElement &, mcElement *p, bool add);
00615 mcBasicOpRes math_Subtract(const mcElement &, mcElement *p);
00616 mcBasicOpRes math_MultiplyBy(const mcElement &, mcElement *p);
00617 mcBasicOpRes math_DivideBy(const mcElement &, mcElement *p);
00618
00619 mcMonomial math_GetLCM(const mcElement &p) const;
00620 mcMonomial math_GetGCD(const mcElement &p) const;
00621
00622 mcMonomial math_GetGCDFor(int *n, int count) const;
00623
00624 mcExpSimRes math_Simplify(long flags, mcElement *newelem);
00625 mcExpSimRes math_Simplify(long flags)
00626 { return math_Simplify(flags, NULL); }
00627
00628 mcIntegerValue math_RaiseGetCoeff(int *indexes, int m);
00629 bool math_CanBeRaisedTo(const mcPolynomial &) const;
00630
00631 void math_RaiseTo(const mcRealValue &n);
00632 mcBasicOpRes math_RaiseTo(const mcPolynomial &);
00633
00637 virtual int math_GetOrderPos() const { return -1; }
00638
00640 #endif // mcENABLE_MATH
00641
00642
00643
00644 #ifdef mcENABLE_IO
00645 public:
00646
00647 wxXml2Node io_GetMathML(bool bGetPresentation) const;
00648 wxString io_GetInlinedExpr() const;
00649
00650 bool io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr);
00651 bool io_ImportInlinedExpr(const wxString &todecode, int *, wxString &pErr, int mlimit);
00652 bool io_ImportInlinedExpr(const wxString &todecode, int *p, wxString &pErr)
00653 { return io_ImportInlinedExpr(todecode, p, pErr, -1); }
00654
00655 #endif // mcENABLE_IO
00656 };
00657
00658
00659
00663 class mcPolynomial : public mcElementArray
00664 {
00665 mcDEFINE_MAIN_CLASS(Polynomial, mcElementArray);
00666
00667 public:
00668
00669
00670 mcPolynomial(const mcMonomial &towrap)
00671 { data_SetRefData(new mcPolynomialHelpers); data_AddElements(&towrap, 1); }
00672
00673
00674 mcPolynomial(const mcSymbol &towrap)
00675 { data_SetRefData(new mcPolynomialHelpers); data_AddNewMonomialContaining((mcElement *)&towrap, 1); }
00676 mcPolynomial(const mcNumber &towrap)
00677 { data_SetRefData(new mcPolynomialHelpers); data_AddNewMonomialContaining((mcElement *)&towrap, 1); }
00678 mcPolynomial(const mcSymbolProperties *towrap)
00679 { data_SetRefData(new mcPolynomialHelpers); math_WrapSymbol(towrap); }
00680 mcPolynomial(const mcRealValue &towrap)
00681 { data_SetRefData(new mcPolynomialHelpers); math_WrapNumber(towrap); }
00682
00683 mcPolynomial(const mcRadical &towrap)
00684 { data_SetRefData(new mcPolynomialHelpers); data_AddNewMonomialContaining((mcElement *)&towrap, 1); }
00685 mcPolynomial(const mcBracket &towrap)
00686 { data_SetRefData(new mcPolynomialHelpers); data_AddNewMonomialContaining((mcElement *)&towrap, 1); }
00687 mcPolynomial(const mcFraction &towrap)
00688 { data_SetRefData(new mcPolynomialHelpers); data_AddNewMonomialContaining((mcElement *)&towrap, 1); }
00689
00690
00691
00692 mcPolynomial &operator-()
00693 { this->math_ChangeAllSigns(); return *this; }
00694
00695
00696 #ifdef mcENABLE_DATA
00697 public:
00698
00699 bool data_isValidContainerFor(mcElementType t) const
00700 { return t == mcET_POLYNOMIAL; }
00701
00702 mcWRAPPER bool data_CreateFirstOp()
00703 { return hlp()->data_CreateFirstOp(); }
00704 mcWRAPPER void data_DeleteFirstOp()
00705 { hlp()->data_DeleteFirstOp(); }
00706
00707 mcWRAPPER int data_AddNewMonomialContaining(mcElement *contents,
00708 int n = 1, int pos = -1, bool bOverwrite = FALSE)
00709 { return hlp()->data_AddNewMonomialContaining(contents, n, pos, bOverwrite); }
00710
00711 mcWRAPPER int data_AddNewMonomialContaining(mcElement &monomialinit,
00712 int pos = -1, bool bOverwrite = TRUE)
00713 { return hlp()->data_AddNewMonomialContaining(monomialinit, pos, bOverwrite); }
00714
00715 mcWRAPPER int data_AddNewMonomial(const mcMonomial &toinsert,
00716 int pos = -1, bool bOverwrite = FALSE)
00717 { return hlp()->data_AddNewMonomial(toinsert, pos, bOverwrite); }
00718
00719 mcWRAPPER int data_AddNewEmptyMonomial(int pos = -1)
00720 { return hlp()->data_AddNewEmptyMonomial(pos); }
00721
00722
00723
00724
00725
00726 #endif
00727
00728
00729 #ifdef mcENABLE_GUI
00730 public:
00731
00732 mcWRAPPER void gui_AddNewEmptyMonomial(int pos = -1)
00733 { hlp()->gui_AddNewEmptyMonomial(pos); }
00734
00735 mcWRAPPER int gui_ExDraw(wxDC &dc, int x, int y, long flags, const wxPoint &pt, int cl) const
00736 { return hlp()->gui_ExDraw(dc, x, y, flags, pt, cl); }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 #endif
00772
00773
00774 mcWRAPPER const mcMonomial &math_Get(int n) const
00775 { return hlp()->math_Get(n); }
00776 mcWRAPPER mcMonomial &math_Get(int n)
00777 { return hlp()->math_Get(n); }
00778
00779
00780 mcWRAPPER int math_FindMonomialContaining(const mcElement &elem, int occ = 0, int *n = NULL) const
00781 { return hlp()->math_FindMonomialContaining(elem, occ, n); }
00782 mcWRAPPER const mcMonomial &math_GetMonomialContaining(const mcElement &elem, int occ = 0, int *n = NULL) const
00783 { return hlp()->math_GetMonomialContaining(elem, occ, n); }
00784 mcWRAPPER mcMonomial math_GetCoeffOf(int mathidx, const mcElement *toremove, int ntoremove) const
00785 { return hlp()->math_GetCoeffOf(mathidx, toremove, ntoremove); }
00786 mcWRAPPER mcMonomial math_GetCoeffOf(const mcSymbolProperties *sym, const mcPolynomial &exp, int occ = 0) const
00787 { return hlp()->math_GetCoeffOf(sym, exp, occ); }
00788 mcWRAPPER mcMonomial math_GetCoeffOf(const mcSymbolProperties *sym, const mcRealValue &exp, int occ = 0) const
00789 { return hlp()->math_GetCoeffOf(sym, exp, occ); }
00790
00791
00792 mcWRAPPER bool math_isFactorized() const
00793 { return hlp()->math_isFactorized(); }
00794 mcWRAPPER bool math_isFirstMonomialNegative() const
00795 { return hlp()->math_isFirstMonomialNegative(); }
00796 mcWRAPPER mcMonomial math_GetFactors() const
00797 { return ((mcElementArrayHelpers*)hlp())->math_GetFactors(); }
00798
00799 mcWRAPPER void math_Factorize(int *n, int count)
00800 { hlp()->math_Factorize(n, count); }
00801 mcWRAPPER void math_FactoreOut(int *n, int count, bool bForceUseless)
00802 { hlp()->math_FactoreOut(n, count, bForceUseless); }
00803 mcWRAPPER void math_FactoreOutAll(bool bForceUseless)
00804 { hlp()->math_FactoreOutAll(bForceUseless); }
00805
00806
00807 mcWRAPPER void math_FactoreOut(const mcSymbolProperties *unk, const mcPolynomial &pol, bool bForceUseless)
00808 { hlp()->math_FactoreOut(unk, pol, bForceUseless); }
00809 mcWRAPPER void math_FactoreOutFreeOf(const mcSymbolProperties *unk, const mcPolynomial &pol, bool bForceUseless)
00810 { hlp()->math_FactoreOutFreeOf(unk, pol, bForceUseless); }
00811
00812 mcWRAPPER void math_FactoreOut(const mcSymbolArray *arr)
00813 { hlp()->math_FactoreOut(arr); }
00814 mcWRAPPER void math_FactoreOutUnknowns()
00815 { hlp()->math_FactoreOutUnknowns(); }
00816 mcWRAPPER void math_FactoreOutParameters()
00817 { hlp()->math_FactoreOutParameters(); }
00818 mcWRAPPER void math_FactoreOutConstants()
00819 { hlp()->math_FactoreOutConstants(); }
00820
00821
00822 mcWRAPPER mcIntegerValue math_GetMaxDegreeFor(const mcSymbolProperties *s) const
00823 { return hlp()->math_GetMaxDegreeFor(s); }
00824
00825
00826 mcWRAPPER int math_GetSign(int n) const
00827 { return hlp()->math_GetSign(n); }
00828 mcWRAPPER const mcNumber &math_GetNumSign(const mcMonomial &m, int occ = 0) const
00829 { return hlp()->math_GetNumSign(m, occ); }
00830
00831 mcWRAPPER void math_SetSign(int n, int sgn)
00832 { hlp()->math_SetSign(n, sgn); }
00833 mcWRAPPER void math_ChangeSign(int n)
00834 { hlp()->math_ChangeSign(n); }
00835 mcWRAPPER void math_ChangeAllSigns()
00836 { hlp()->math_ChangeAllSigns(); }
00837 mcWRAPPER void math_PackSign(mcMonomial &m, int occ = 0) const
00838 { hlp()->math_PackSign(m, occ); }
00839 mcWRAPPER bool math_DeleteFirstOp()
00840 { return hlp()->math_DeleteFirstOp(); }
00841
00842 mcWRAPPER bool math_CanBeRaisedTo(const mcPolynomial &n)
00843 { return hlp()->math_CanBeRaisedTo(n); }
00844
00845 mcWRAPPER mcArrayEntry math_GetIndexOf(int occ, const mcMonomial &tofind, bool b) const
00846 { return hlp()->math_GetIndexOf(occ, tofind, b); }
00847
00848 mcWRAPPER int math_GetMonomialIdxFromEntry(const mcArrayEntry &p) const
00849 { return hlp()->math_GetMonomialIdxFromEntry(&p); }
00850 mcWRAPPER int math_GetIdxFromEntry(const mcArrayEntry &p) const
00851 { return hlp()->math_GetIdxFromEntry(&p); }
00852 };
00853
00854
00855 #endif // POLYNOMIAL_H
00856