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