From 87307aba9e8dbca16672e6df701d9f905b9e1786 Mon Sep 17 00:00:00 2001 From: Jens-Heiner Rechtien Date: Thu, 8 Jan 2009 10:47:13 +0000 Subject: CWS-TOOLING: integrate CWS frmdlg 2008-12-18 09:13:09 +0100 oj r265667 : merge from odff05 2008-12-18 07:58:16 +0100 oj r265658 : #i94555# patch from , ODFF: Add GAMMA, CHISQDIST, CHISQINV. Make the 'cumulative' parameter of GAMMADIST optional. Adapt the domain of CHIDIST to allow negative x. Remove the constraint "degrees of freedom < 1.0E5" from CHIDIST and CHIINV. Plus a mechanism to write the now optional parameter of GAMMADIST to PODF and ODFF if omitted, for backwards compatibility. 2008-12-15 14:06:11 +0100 oj r265490 : CWS-TOOLING: rebase CWS frmdlg to trunk@264807 (milestone: DEV300:m37) 2008-12-15 13:55:28 +0100 oj r265488 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:55:07 +0100 oj r265487 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:48 +0100 oj r265486 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:36 +0100 oj r265485 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:54:24 +0100 oj r265484 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:48:11 +0100 oj r265483 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:31:12 +0100 oj r265479 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:13:58 +0100 oj r265477 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:10:09 +0100 oj r265476 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 13:05:11 +0100 oj r265475 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:47:17 +0100 oj r265467 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:46:19 +0100 oj r265466 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 10:45:47 +0100 oj r265465 : CWS-TOOLING: do not delete this file, it's needed for 'cws rebase -C' CWS: frmdlg New MWS: DEV300 New milestone: m37 2008-12-15 07:35:07 +0100 oj r265458 : add dependency to formula 2008-12-15 07:34:24 +0100 oj r265457 : add dependency to formula 2008-12-12 13:22:00 +0100 msc r265413 : #i97089# 2008-12-12 13:20:25 +0100 msc r265412 : #i97089# 2008-12-12 12:35:12 +0100 msc r265406 : #i97089# 2008-12-12 12:34:16 +0100 msc r265405 : #i97089# 2008-12-12 12:33:05 +0100 msc r265404 : #i97089# 2008-12-12 12:31:11 +0100 msc r265403 : #i97089# 2008-12-08 11:59:10 +0100 oj r264981 : insert RTL_LOG 2008-12-08 11:50:17 +0100 oj r264980 : some small changes 2008-12-05 12:57:57 +0100 oj r264902 : eof changed 2008-12-05 12:56:46 +0100 oj r264901 : eof changed 2008-12-05 12:28:47 +0100 oj r264899 : wrong var used 2008-12-05 10:08:57 +0100 oj r264890 : token order reversed 2008-12-04 13:49:22 +0100 oc r264843 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:45:27 +0100 oc r264842 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:42:54 +0100 oc r264841 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:37:41 +0100 oc r264840 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 13:34:11 +0100 oc r264839 : #i96688: Adapt autotests because of outsourced functionwizard 2008-12-04 12:35:31 +0100 oj r264835 : new help ids for struct and function tabpage 2008-12-04 12:00:35 +0100 oj r264828 : set explicit help id 2008-12-03 14:53:27 +0100 oj r264786 : #i96845# change ref button 2008-12-03 14:51:49 +0100 oj r264785 : #i96845# change ref button 2008-12-03 08:51:57 +0100 oj r264746 : convert dos to unix lineends 2008-12-03 08:50:45 +0100 oj r264745 : convert dos to unix lineends 2008-12-03 08:50:05 +0100 oj r264744 : convert dos to unix lineends 2008-12-02 12:28:33 +0100 oj r264686 : clear help text when new helpid is set 2008-12-02 12:28:02 +0100 oj r264685 : set help id for listbox category 2008-12-02 07:15:56 +0100 oj r264655 : remove define to auto generate help ids 2008-12-01 14:36:43 +0100 oj r264604 : use temp var 2008-12-01 14:18:31 +0100 oj r264601 : moved ScJumpToken to formula 2008-12-01 14:18:11 +0100 oj r264600 : moved ScJumpToken to formula 2008-12-01 14:14:35 +0100 oj r264599 : moved ScJumpToken from sc 2008-12-01 10:48:51 +0100 oj r264589 : change quickhelptext from Shrink to Select 2008-12-01 10:28:41 +0100 oj r264588 : fix opcode data, has to be Any.Void 2008-11-28 11:16:48 +0100 oj r264532 : add help ids 2008-11-28 10:16:56 +0100 oj r264529 : set help id 2008-11-28 10:16:43 +0100 oj r264528 : set help id 2008-11-26 13:55:04 +0100 oj r264381 : #94535# use of optional instead of deleting a string myself and some small changes 2008-11-26 09:53:20 +0100 oj r264346 : compile error with debug/without debug 2008-11-25 07:41:28 +0100 oj r264271 : put static into the method which make use of them 2008-11-24 08:16:07 +0100 oj r264196 : removed not needed classes for op code 2008-11-24 08:13:44 +0100 oj r264195 : removed not needed classes for op code 2008-11-21 14:05:53 +0100 oj r264135 : make GetOpCode inline 2008-11-21 12:35:27 +0100 oj r264124 : hold symbols 2008-11-20 09:27:27 +0100 oj r264028 : merged code from DEV300_m35 which got lost 2008-11-19 20:42:12 +0100 oj r264022 : more changes for formula dialog remove 2008-11-19 20:37:41 +0100 oj r264021 : removed unused var 2008-11-19 20:35:35 +0100 oj r264020 : some more changes at token 2008-11-19 10:59:47 +0100 oj r263967 : deleted 2008-11-19 10:58:24 +0100 oj r263966 : add forui and for res files 2008-11-18 15:27:36 +0100 oj r263777 : unused para removed 2008-11-18 15:23:23 +0100 oj r263775 : add insert button to add field dlg 2008-11-18 13:39:53 +0100 oj r263764 : enable the formula dialog as well for conditional print as for conditional formatting 2008-11-18 12:03:25 +0100 oj r263760 : rename isRef in IsRef 2008-11-17 11:46:16 +0100 oj r263711 : patches for function handling 2008-11-17 11:36:22 +0100 oj r263710 : add new for forui and res file 2008-11-17 09:21:12 +0100 oj r263704 : patches for some resource for libformula 2008-11-15 12:45:30 +0100 oj r263701 : changes for formula editor extraction 2008-11-07 08:23:27 +0100 oj r263416 : merge from DEV300:m35 2008-11-07 08:22:35 +0100 oj r263415 : merge from DEV300:m35 2008-11-07 08:22:16 +0100 oj r263414 : merge from DEV300:m35 2008-11-07 08:21:41 +0100 oj r263413 : merge from DEV300:m35 2008-11-07 08:21:31 +0100 oj r263412 : merge from DEV300:m35 2008-11-07 08:20:38 +0100 oj r263411 : merge from DEV300:m35 2008-11-07 08:20:00 +0100 oj r263410 : merge from DEV300:m35 2008-11-07 08:18:50 +0100 oj r263409 : merge from DEV300:m35 2008-11-07 08:18:19 +0100 oj r263408 : merge from DEV300:m35 2008-11-07 08:10:27 +0100 oj r263407 : merge from DEV300:m35 2008-10-21 07:43:46 +0200 oj r262560 : some compile errors resolved 2008-10-17 16:40:01 +0200 oj r262291 : dep for 1st target 2008-10-07 10:08:39 +0200 oj r262077 : copy 2008-10-07 09:45:31 +0200 oj r262076 : #i94535# 2008-10-07 09:44:26 +0200 oj r262075 : #i94535# new base class 2008-10-07 09:43:21 +0200 oj r262074 : moved to formula 2008-10-07 09:41:51 +0200 oj r262073 : new images 2008-10-07 09:03:01 +0200 oj r262072 : new ids for formula 2008-10-02 08:46:27 +0200 oj r262024 : #i94535# move the formula compiler to formula 2008-10-02 08:08:54 +0200 oj r262023 : #i94535# 2008-10-02 08:06:28 +0200 oj r262022 : #i94535# 2008-10-02 08:05:52 +0200 oj r262021 : #i94535# 2008-10-01 17:15:29 +0200 oj r262014 : #i94535# 2008-10-01 17:12:40 +0200 oj r262013 : new module formula 2008-10-01 17:04:55 +0200 oj r262012 : #i94535# 2008-10-01 16:49:03 +0200 oj r262010 : #i94535# 2008-10-01 16:46:59 +0200 oj r262009 : #i94535# --- sc/source/core/tool/interpr5.cxx | 2056 +++++++++++--------------------------- 1 file changed, 565 insertions(+), 1491 deletions(-) (limited to 'sc/source/core/tool/interpr5.cxx') diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 32be76431569..41ddf3dc0aa0 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -36,7 +36,7 @@ #ifndef INCLUDED_RTL_MATH_HXX #include #endif - +#include #include #include #include @@ -63,13 +63,50 @@ #include using ::std::vector; +using namespace formula; const double fInvEpsilon = 1.0E-7; // ----------------------------------------------------------------------- + struct MatrixAdd : public ::std::binary_function + { + inline double operator() (const double& lhs, const double& rhs) const + { + return ::rtl::math::approxAdd( lhs,rhs); + } + }; + struct MatrixSub : public ::std::binary_function + { + inline double operator() (const double& lhs, const double& rhs) const + { + return ::rtl::math::approxSub( lhs,rhs); + } + }; + struct MatrixMul : public ::std::binary_function + { + inline double operator() (const double& lhs, const double& rhs) const + { + return lhs * rhs; + } + }; + struct MatrixDiv : public ::std::binary_function + { + inline double operator() (const double& lhs, const double& rhs) const + { + return ScInterpreter::div( lhs,rhs); + } + }; + struct MatrixPow : public ::std::binary_function + { + inline double operator() (const double& lhs, const double& rhs) const + { + return ::pow( lhs,rhs); + } + }; double ScInterpreter::ScGetGCD(double fx, double fy) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::div" ); // By ODFF definition GCD(0,a) => a. This is also vital for the code in // ScGCD() to work correctly with a preset fy=0.0 if (fy == 0.0) @@ -91,6 +128,7 @@ double ScInterpreter::ScGetGCD(double fx, double fy) void ScInterpreter::ScGCD() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGCD" ); short nParamCount = GetByte(); if ( MustHaveParamCountMin( nParamCount, 1 ) ) { @@ -272,6 +310,7 @@ void ScInterpreter:: ScLCM() ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetNewMat" ); ScMatrix* pMat = new ScMatrix( nC, nR); pMat->SetErrorInterpreter( this); SCSIZE nCols, nRows; @@ -285,10 +324,11 @@ ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR) return pMat; } -ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const ScToken* pToken, +ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2 ) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CreateMatrixFromDoubleRef" ); ScMatrixRef pMat = NULL; if (nTab1 == nTab2 && !nGlobalError) { @@ -299,7 +339,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const ScToken* pToken, SetError(errStackOverflow); else if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken)) != pTokenMatrixMap->end())) - pMat = (*aIter).second->GetMatrix(); + pMat = static_cast((*aIter).second.get())->GetMatrix(); else { SCSIZE nMatCols = static_cast(nCol2 - nCol1 + 1); @@ -409,6 +449,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const ScToken* pToken, ScMatrixRef ScInterpreter::GetMatrix() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetMatrix" ); ScMatrixRef pMat = NULL; switch (GetRawStackType()) { @@ -438,7 +479,7 @@ ScMatrixRef ScInterpreter::GetMatrix() SCCOL nCol1, nCol2; SCROW nRow1, nRow2; SCTAB nTab1, nTab2; - const ScToken* p = sp ? pStack[sp-1] : NULL; + const ScToken* p = sp ? static_cast(pStack[sp-1]) : NULL; PopDoubleRef(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); pMat = CreateMatrixFromDoubleRef( p, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); @@ -491,6 +532,7 @@ ScMatrixRef ScInterpreter::GetMatrix() void ScInterpreter::ScMatValue() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatValue" ); if ( MustHaveParamCount( GetByte(), 3 ) ) { // 0 to count-1 @@ -511,26 +553,7 @@ void ScInterpreter::ScMatValue() else { const ScMatrix* pMat = ((ScFormulaCell*)pCell)->GetMatrix(); - if (pMat) - { - SCSIZE nCl, nRw; - pMat->GetDimensions(nCl, nRw); - if (nC < nCl && nR < nRw) - { - ScMatValType nMatValType; - const ScMatrixValue* pMatVal = pMat->Get( nC, - nR, nMatValType); - if (ScMatrix::IsNonValueType( nMatValType)) - PushString( pMatVal->GetString() ); - else - PushDouble(pMatVal->fVal); - // also handles DoubleError - } - else - PushNoValue(); - } - else - PushNoValue(); + CalculateMatrixValue(pMat,nC,nR); } } else @@ -569,26 +592,7 @@ void ScInterpreter::ScMatValue() case svMatrix: { ScMatrixRef pMat = PopMatrix(); - if (pMat) - { - SCSIZE nCl, nRw; - pMat->GetDimensions(nCl, nRw); - if (nC < nCl && nR < nRw) - { - ScMatValType nMatValType; - const ScMatrixValue* pMatVal = pMat->Get( nC, nR, - nMatValType); - if (ScMatrix::IsNonValueType( nMatValType)) - PushString( pMatVal->GetString() ); - else - PushDouble(pMatVal->fVal); - // also handles DoubleError - } - else - PushNoValue(); - } - else - PushNoValue(); + CalculateMatrixValue(pMat,nC,nR); } break; default: @@ -598,9 +602,33 @@ void ScInterpreter::ScMatValue() } } } +void ScInterpreter::CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateMatrixValue" ); + if (pMat) + { + SCSIZE nCl, nRw; + pMat->GetDimensions(nCl, nRw); + if (nC < nCl && nR < nRw) + { + ScMatValType nMatValType; + const ScMatrixValue* pMatVal = pMat->Get( nC, nR,nMatValType); + if (ScMatrix::IsNonValueType( nMatValType)) + PushString( pMatVal->GetString() ); + else + PushDouble(pMatVal->fVal); + // also handles DoubleError + } + else + PushNoValue(); + } + else + PushNoValue(); +} void ScInterpreter::ScEMat() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScEMat" ); if ( MustHaveParamCount( GetByte(), 1 ) ) { SCSIZE nDim = static_cast(::rtl::math::approxFloor(GetDouble())); @@ -622,6 +650,7 @@ void ScInterpreter::ScEMat() void ScInterpreter::MEMat(ScMatrix* mM, SCSIZE n) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MEMat" ); mM->FillDouble(0.0, 0, 0, n-1, n-1); for (SCSIZE i = 0; i < n; i++) mM->PutDouble(1.0, i, i); @@ -631,6 +660,7 @@ void ScInterpreter::MFastMult(ScMatrix* pA, ScMatrix* pB, ScMatrix* pR, SCSIZE n, SCSIZE m, SCSIZE l) // Multipliziert n x m Mat a mit m x l Mat b nach Mat r { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MFastMult" ); double sum; for (SCSIZE i = 0; i < n; i++) { @@ -800,6 +830,7 @@ static void lcl_LUP_solve( const ScMatrix* mLU, const SCSIZE n, void ScInterpreter::ScMatDet() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatDet" ); if ( MustHaveParamCount( GetByte(), 1 ) ) { ScMatrixRef pMat = GetMatrix(); @@ -846,6 +877,7 @@ void ScInterpreter::ScMatDet() void ScInterpreter::ScMatInv() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatInv" ); if ( MustHaveParamCount( GetByte(), 1 ) ) { ScMatrixRef pMat = GetMatrix(); @@ -947,6 +979,7 @@ void ScInterpreter::ScMatInv() void ScInterpreter::ScMatMult() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatMult" ); if ( MustHaveParamCount( GetByte(), 2 ) ) { ScMatrixRef pMat2 = GetMatrix(); @@ -996,6 +1029,7 @@ void ScInterpreter::ScMatMult() void ScInterpreter::ScMatTrans() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatTrans" ); if ( MustHaveParamCount( GetByte(), 1 ) ) { ScMatrixRef pMat = GetMatrix(); @@ -1035,124 +1069,8 @@ inline SCSIZE lcl_GetMinExtent( SCSIZE n1, SCSIZE n2 ) return n2; } -ScMatrixRef ScInterpreter::MatAdd(ScMatrix* pMat1, ScMatrix* pMat2) -{ - SCSIZE nC1, nC2, nMinC; - SCSIZE nR1, nR2, nMinR; - SCSIZE i, j; - pMat1->GetDimensions(nC1, nR1); - pMat2->GetDimensions(nC2, nR2); - nMinC = lcl_GetMinExtent( nC1, nC2); - nMinR = lcl_GetMinExtent( nR1, nR2); - ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); - if (xResMat) - { - ScMatrix* pResMat = xResMat; - for (i = 0; i < nMinC; i++) - { - for (j = 0; j < nMinR; j++) - { - if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) - pResMat->PutDouble( ::rtl::math::approxAdd( pMat1->GetDouble(i,j), - pMat2->GetDouble(i,j)), i, j); - else - pResMat->PutString(ScGlobal::GetRscString( - STR_NO_VALUE), i, j); - } - } - } - return xResMat; -} - -ScMatrixRef ScInterpreter::MatSub(ScMatrix* pMat1, ScMatrix* pMat2) -{ - SCSIZE nC1, nC2, nMinC; - SCSIZE nR1, nR2, nMinR; - SCSIZE i, j; - pMat1->GetDimensions(nC1, nR1); - pMat2->GetDimensions(nC2, nR2); - nMinC = lcl_GetMinExtent( nC1, nC2); - nMinR = lcl_GetMinExtent( nR1, nR2); - ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); - if (xResMat) - { - ScMatrix* pResMat = xResMat; - for (i = 0; i < nMinC; i++) - { - for (j = 0; j < nMinR; j++) - { - if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) - pResMat->PutDouble( ::rtl::math::approxSub( pMat1->GetDouble(i,j), - pMat2->GetDouble(i,j)), i, j); - else - pResMat->PutString(ScGlobal::GetRscString( - STR_NO_VALUE), i, j); - } - } - } - return xResMat; -} - -ScMatrixRef ScInterpreter::MatMul(ScMatrix* pMat1, ScMatrix* pMat2) -{ - SCSIZE nC1, nC2, nMinC; - SCSIZE nR1, nR2, nMinR; - SCSIZE i, j; - pMat1->GetDimensions(nC1, nR1); - pMat2->GetDimensions(nC2, nR2); - nMinC = lcl_GetMinExtent( nC1, nC2); - nMinR = lcl_GetMinExtent( nR1, nR2); - ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); - if (xResMat) - { - ScMatrix* pResMat = xResMat; - for (i = 0; i < nMinC; i++) - { - for (j = 0; j < nMinR; j++) - { - if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) - pResMat->PutDouble(pMat1->GetDouble(i,j) * - pMat2->GetDouble(i,j), i, j); - else - pResMat->PutString(ScGlobal::GetRscString( - STR_NO_VALUE), i, j); - } - } - } - return xResMat; -} - -ScMatrixRef ScInterpreter::MatDiv(ScMatrix* pMat1, ScMatrix* pMat2) -{ - SCSIZE nC1, nC2, nMinC; - SCSIZE nR1, nR2, nMinR; - SCSIZE i, j; - pMat1->GetDimensions(nC1, nR1); - pMat2->GetDimensions(nC2, nR2); - nMinC = lcl_GetMinExtent( nC1, nC2); - nMinR = lcl_GetMinExtent( nR1, nR2); - ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); - if (xResMat) - { - ScMatrix* pResMat = xResMat; - for (i = 0; i < nMinC; i++) - { - for (j = 0; j < nMinR; j++) - { - if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) - pResMat->PutDouble( - div( pMat1->GetDouble(i,j), pMat2->GetDouble(i,j)), - i, j); - else - pResMat->PutString(ScGlobal::GetRscString( - STR_NO_VALUE), i, j); - } - } - } - return xResMat; -} - -ScMatrixRef ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2) +template +ScMatrixRef lcl_MatrixCalculation(const _Function& _pOperation,ScMatrix* pMat1, ScMatrix* pMat2,ScInterpreter* _pIterpreter) { SCSIZE nC1, nC2, nMinC; SCSIZE nR1, nR2, nMinR; @@ -1161,7 +1079,7 @@ ScMatrixRef ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2) pMat2->GetDimensions(nC2, nR2); nMinC = lcl_GetMinExtent( nC1, nC2); nMinR = lcl_GetMinExtent( nR1, nR2); - ScMatrixRef xResMat = GetNewMat(nMinC, nMinR); + ScMatrixRef xResMat = _pIterpreter->GetNewMat(nMinC, nMinR); if (xResMat) { ScMatrix* pResMat = xResMat; @@ -1170,11 +1088,12 @@ ScMatrixRef ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2) for (j = 0; j < nMinR; j++) { if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j)) - pResMat->PutDouble(pow(pMat1->GetDouble(i,j), - pMat2->GetDouble(i,j)), i, j); + { + double d = _pOperation(pMat1->GetDouble(i,j),pMat2->GetDouble(i,j)); + pResMat->PutDouble( d, i, j); + } else - pResMat->PutString(ScGlobal::GetRscString( - STR_NO_VALUE), i, j); + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, j); } } } @@ -1183,6 +1102,7 @@ ScMatrixRef ScInterpreter::MatPow(ScMatrix* pMat1, ScMatrix* pMat2) ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2) { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::MatConcat" ); SCSIZE nC1, nC2, nMinC; SCSIZE nR1, nR2, nMinR; SCSIZE i, j; @@ -1246,6 +1166,12 @@ void lcl_GetDiffDateTimeFmtType( short& nFuncFmt, short nFmt1, short nFmt2 ) void ScInterpreter::ScAdd() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAdd" ); + CalculateAddSub(FALSE); +} +void ScInterpreter::CalculateAddSub(BOOL _bSub) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateAddSub" ); ScMatrixRef pMat1 = NULL; ScMatrixRef pMat2 = NULL; double fVal1 = 0.0, fVal2 = 0.0; @@ -1298,7 +1224,18 @@ void ScInterpreter::ScAdd() } if (pMat1 && pMat2) { - ScMatrixRef pResMat = MatAdd(pMat1, pMat2); + ScMatrixRef pResMat; + if ( _bSub ) + { + MatrixSub aSub; + pResMat = lcl_MatrixCalculation(aSub ,pMat1, pMat2,this); + } + else + { + MatrixAdd aAdd; + pResMat = lcl_MatrixCalculation(aAdd ,pMat1, pMat2,this); + } + if (!pResMat) PushNoValue(); else @@ -1307,32 +1244,51 @@ void ScInterpreter::ScAdd() else if (pMat1 || pMat2) { double fVal; + BOOL bFlag; ScMatrixRef pMat = pMat1; if (!pMat) { fVal = fVal1; pMat = pMat2; + bFlag = TRUE; // double - Matrix } else + { fVal = fVal2; + bFlag = FALSE; // Matrix - double + } SCSIZE nC, nR; pMat->GetDimensions(nC, nR); ScMatrixRef pResMat = GetNewMat(nC, nR); if (pResMat) { SCSIZE nCount = nC * nR; - for ( SCSIZE i = 0; i < nCount; i++ ) + if (bFlag || !_bSub ) { - if (pMat->IsValue(i)) - pResMat->PutDouble( ::rtl::math::approxAdd( pMat->GetDouble(i), fVal), i); - else - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); + for ( SCSIZE i = 0; i < nCount; i++ ) + { + if (pMat->IsValue(i)) + pResMat->PutDouble( _bSub ? ::rtl::math::approxSub( fVal, pMat->GetDouble(i)) : ::rtl::math::approxAdd( pMat->GetDouble(i), fVal), i); + else + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); + } // for ( SCSIZE i = 0; i < nCount; i++ ) + } // if (bFlag || !_bSub ) + else + { + for ( SCSIZE i = 0; i < nCount; i++ ) + { if (pMat->IsValue(i)) + pResMat->PutDouble( ::rtl::math::approxSub( pMat->GetDouble(i), fVal), i); + else + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); + } // for ( SCSIZE i = 0; i < nCount; i++ ) } PushMatrix(pResMat); } else PushIllegalArgument(); } + else if ( _bSub ) + PushDouble( ::rtl::math::approxSub( fVal1, fVal2 ) ); else PushDouble( ::rtl::math::approxAdd( fVal1, fVal2 ) ); if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) @@ -1350,6 +1306,7 @@ void ScInterpreter::ScAdd() void ScInterpreter::ScAmpersand() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScAmpersand" ); ScMatrixRef pMat1 = NULL; ScMatrixRef pMat2 = NULL; String sStr1, sStr2; @@ -1441,14 +1398,18 @@ void ScInterpreter::ScAmpersand() void ScInterpreter::ScSub() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSub" ); + CalculateAddSub(TRUE); +} + +void ScInterpreter::ScMul() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMul" ); ScMatrixRef pMat1 = NULL; ScMatrixRef pMat2 = NULL; double fVal1 = 0.0, fVal2 = 0.0; - short nFmt1, nFmt2; - nFmt1 = nFmt2 = NUMBERFORMAT_UNDEFINED; short nFmtCurrencyType = nCurFmtType; ULONG nFmtCurrencyIndex = nCurFmtIndex; - short nFmtPercentType = nCurFmtType; if ( GetStackType() == svMatrix ) pMat2 = GetMatrix(); else @@ -1456,18 +1417,10 @@ void ScInterpreter::ScSub() fVal2 = GetDouble(); switch ( nCurFmtType ) { - case NUMBERFORMAT_DATE : - case NUMBERFORMAT_TIME : - case NUMBERFORMAT_DATETIME : - nFmt2 = nCurFmtType; - break; case NUMBERFORMAT_CURRENCY : nFmtCurrencyType = nCurFmtType; nFmtCurrencyIndex = nCurFmtIndex; break; - case NUMBERFORMAT_PERCENT : - nFmtPercentType = NUMBERFORMAT_PERCENT; - break; } } if ( GetStackType() == svMatrix ) @@ -1477,23 +1430,16 @@ void ScInterpreter::ScSub() fVal1 = GetDouble(); switch ( nCurFmtType ) { - case NUMBERFORMAT_DATE : - case NUMBERFORMAT_TIME : - case NUMBERFORMAT_DATETIME : - nFmt1 = nCurFmtType; - break; case NUMBERFORMAT_CURRENCY : nFmtCurrencyType = nCurFmtType; nFmtCurrencyIndex = nCurFmtIndex; break; - case NUMBERFORMAT_PERCENT : - nFmtPercentType = NUMBERFORMAT_PERCENT; - break; } } if (pMat1 && pMat2) { - ScMatrixRef pResMat = MatSub(pMat1, pMat2); + MatrixMul aMul; + ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat2,this); if (!pResMat) PushNoValue(); else @@ -1502,80 +1448,55 @@ void ScInterpreter::ScSub() else if (pMat1 || pMat2) { double fVal; - BOOL bFlag; ScMatrixRef pMat = pMat1; if (!pMat) { fVal = fVal1; pMat = pMat2; - bFlag = TRUE; // double - Matrix } else - { fVal = fVal2; - bFlag = FALSE; // Matrix - double - } SCSIZE nC, nR; pMat->GetDimensions(nC, nR); ScMatrixRef pResMat = GetNewMat(nC, nR); if (pResMat) - { // mehr klammern wg. compiler macke + { SCSIZE nCount = nC * nR; - if (bFlag) - { for ( SCSIZE i = 0; i < nCount; i++ ) - { if (pMat->IsValue(i)) - pResMat->PutDouble( ::rtl::math::approxSub( fVal, pMat->GetDouble(i)), i); - else - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); - } - } - else - { for ( SCSIZE i = 0; i < nCount; i++ ) - { if (pMat->IsValue(i)) - pResMat->PutDouble( ::rtl::math::approxSub( pMat->GetDouble(i), fVal), i); - else - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); - } - } + for ( SCSIZE i = 0; i < nCount; i++ ) + if (pMat->IsValue(i)) + pResMat->PutDouble(pMat->GetDouble(i)*fVal, i); + else + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); PushMatrix(pResMat); } else PushIllegalArgument(); } else - PushDouble( ::rtl::math::approxSub( fVal1, fVal2 ) ); + PushDouble(fVal1 * fVal2); if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) { nFuncFmtType = nFmtCurrencyType; nFuncFmtIndex = nFmtCurrencyIndex; } - else - { - lcl_GetDiffDateTimeFmtType( nFuncFmtType, nFmt1, nFmt2 ); - if ( nFmtPercentType == NUMBERFORMAT_PERCENT && nFuncFmtType == NUMBERFORMAT_NUMBER ) - nFuncFmtType = NUMBERFORMAT_PERCENT; - } } -void ScInterpreter::ScMul() +void ScInterpreter::ScDiv() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDiv" ); ScMatrixRef pMat1 = NULL; ScMatrixRef pMat2 = NULL; double fVal1 = 0.0, fVal2 = 0.0; short nFmtCurrencyType = nCurFmtType; ULONG nFmtCurrencyIndex = nCurFmtIndex; + short nFmtCurrencyType2 = NUMBERFORMAT_UNDEFINED; if ( GetStackType() == svMatrix ) pMat2 = GetMatrix(); else { fVal2 = GetDouble(); - switch ( nCurFmtType ) - { - case NUMBERFORMAT_CURRENCY : - nFmtCurrencyType = nCurFmtType; - nFmtCurrencyIndex = nCurFmtIndex; - break; - } + // hier kein Currency uebernehmen, 123kg/456DM sind nicht DM + nFmtCurrencyType2 = nCurFmtType; } if ( GetStackType() == svMatrix ) pMat1 = GetMatrix(); @@ -1592,7 +1513,8 @@ void ScInterpreter::ScMul() } if (pMat1 && pMat2) { - ScMatrixRef pResMat = MatMul(pMat1, pMat2); + MatrixDiv aDiv; + ScMatrixRef pResMat = lcl_MatrixCalculation(aDiv,pMat1, pMat2,this); if (!pResMat) PushNoValue(); else @@ -1601,92 +1523,19 @@ void ScInterpreter::ScMul() else if (pMat1 || pMat2) { double fVal; + BOOL bFlag; ScMatrixRef pMat = pMat1; if (!pMat) { fVal = fVal1; pMat = pMat2; + bFlag = TRUE; // double - Matrix } else + { fVal = fVal2; - SCSIZE nC, nR; - pMat->GetDimensions(nC, nR); - ScMatrixRef pResMat = GetNewMat(nC, nR); - if (pResMat) - { - SCSIZE nCount = nC * nR; - for ( SCSIZE i = 0; i < nCount; i++ ) - if (pMat->IsValue(i)) - pResMat->PutDouble(pMat->GetDouble(i)*fVal, i); - else - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i); - PushMatrix(pResMat); - } - else - PushIllegalArgument(); - } - else - PushDouble(fVal1 * fVal2); - if ( nFmtCurrencyType == NUMBERFORMAT_CURRENCY ) - { - nFuncFmtType = nFmtCurrencyType; - nFuncFmtIndex = nFmtCurrencyIndex; - } -} - -void ScInterpreter::ScDiv() -{ - ScMatrixRef pMat1 = NULL; - ScMatrixRef pMat2 = NULL; - double fVal1 = 0.0, fVal2 = 0.0; - short nFmtCurrencyType = nCurFmtType; - ULONG nFmtCurrencyIndex = nCurFmtIndex; - short nFmtCurrencyType2 = NUMBERFORMAT_UNDEFINED; - if ( GetStackType() == svMatrix ) - pMat2 = GetMatrix(); - else - { - fVal2 = GetDouble(); - // hier kein Currency uebernehmen, 123kg/456DM sind nicht DM - nFmtCurrencyType2 = nCurFmtType; - } - if ( GetStackType() == svMatrix ) - pMat1 = GetMatrix(); - else - { - fVal1 = GetDouble(); - switch ( nCurFmtType ) - { - case NUMBERFORMAT_CURRENCY : - nFmtCurrencyType = nCurFmtType; - nFmtCurrencyIndex = nCurFmtIndex; - break; - } - } - if (pMat1 && pMat2) - { - ScMatrixRef pResMat = MatDiv(pMat1, pMat2); - if (!pResMat) - PushNoValue(); - else - PushMatrix(pResMat); - } - else if (pMat1 || pMat2) - { - double fVal; - BOOL bFlag; - ScMatrixRef pMat = pMat1; - if (!pMat) - { - fVal = fVal1; - pMat = pMat2; - bFlag = TRUE; // double - Matrix - } - else - { - fVal = fVal2; - bFlag = FALSE; // Matrix - double - } + bFlag = FALSE; // Matrix - double + } SCSIZE nC, nR; pMat->GetDimensions(nC, nR); ScMatrixRef pResMat = GetNewMat(nC, nR); @@ -1725,12 +1574,14 @@ void ScInterpreter::ScDiv() void ScInterpreter::ScPower() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPower" ); if ( MustHaveParamCount( GetByte(), 2 ) ) ScPow(); } void ScInterpreter::ScPow() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScPow" ); ScMatrixRef pMat1 = NULL; ScMatrixRef pMat2 = NULL; double fVal1 = 0.0, fVal2 = 0.0; @@ -1744,7 +1595,8 @@ void ScInterpreter::ScPow() fVal1 = GetDouble(); if (pMat1 && pMat2) { - ScMatrixRef pResMat = MatPow(pMat1, pMat2); + MatrixPow aPow; + ScMatrixRef pResMat = lcl_MatrixCalculation(aPow,pMat1, pMat2,this); if (!pResMat) PushNoValue(); else @@ -1797,6 +1649,7 @@ void ScInterpreter::ScPow() void ScInterpreter::ScSumProduct() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumProduct" ); BYTE nParamCount = GetByte(); if ( !MustHaveParamCount( nParamCount, 1, 30 ) ) return; @@ -1814,6 +1667,7 @@ void ScInterpreter::ScSumProduct() SCSIZE nR, nR1; pMat2->GetDimensions(nC, nR); pMat = pMat2; + MatrixMul aMul; for (USHORT i = 1; i < nParamCount; i++) { pMat1 = GetMatrix(); @@ -1828,7 +1682,7 @@ void ScInterpreter::ScSumProduct() PushNoValue(); return; } - ScMatrixRef pResMat = MatMul(pMat1, pMat); + ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat,this); if (!pResMat) { PushNoValue(); @@ -1849,6 +1703,12 @@ void ScInterpreter::ScSumProduct() void ScInterpreter::ScSumX2MY2() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumX2MY2" ); + CalculateSumX2MY2SumX2DY2(FALSE); +} +void ScInterpreter::CalculateSumX2MY2SumX2DY2(BOOL _bSumX2DY2) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateSumX2MY2SumX2DY2" ); if ( !MustHaveParamCount( GetByte(), 2 ) ) return; @@ -1879,50 +1739,23 @@ void ScInterpreter::ScSumX2MY2() fVal = pMat1->GetDouble(i,j); fSum += fVal * fVal; fVal = pMat2->GetDouble(i,j); - fSum -= fVal * fVal; + if ( _bSumX2DY2 ) + fSum += fVal * fVal; + else + fSum -= fVal * fVal; } PushDouble(fSum); } void ScInterpreter::ScSumX2DY2() { - if ( !MustHaveParamCount( GetByte(), 2 ) ) - return; - - ScMatrixRef pMat1 = NULL; - ScMatrixRef pMat2 = NULL; - SCSIZE i, j; - pMat2 = GetMatrix(); - pMat1 = GetMatrix(); - if (!pMat2 || !pMat1) - { - PushIllegalParameter(); - return; - } - SCSIZE nC1, nC2; - SCSIZE nR1, nR2; - pMat2->GetDimensions(nC2, nR2); - pMat1->GetDimensions(nC1, nR1); - if (nC1 != nC2 || nR1 != nR2) - { - PushNoValue(); - return; - } - double fVal, fSum = 0.0; - for (i = 0; i < nC1; i++) - for (j = 0; j < nR1; j++) - if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j)) - { - fVal = pMat1->GetDouble(i,j); - fSum += fVal * fVal; - fVal = pMat2->GetDouble(i,j); - fSum += fVal * fVal; - } - PushDouble(fSum); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumX2DY2" ); + CalculateSumX2MY2SumX2DY2(TRUE); } void ScInterpreter::ScSumXMY2() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScSumXMY2" ); if ( !MustHaveParamCount( GetByte(), 2 ) ) return; @@ -1943,12 +1776,12 @@ void ScInterpreter::ScSumXMY2() { PushNoValue(); return; - } - ScMatrixRef pResMat = MatSub(pMat1, pMat2); + } // if (nC1 != nC2 || nR1 != nR2) + MatrixSub aSub; + ScMatrixRef pResMat = lcl_MatrixCalculation(aSub,pMat1, pMat2,this); if (!pResMat) { PushNoValue(); - return; } else { @@ -1966,6 +1799,7 @@ void ScInterpreter::ScSumXMY2() void ScInterpreter::ScFrequency() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScFrequency" ); if ( !MustHaveParamCount( GetByte(), 2 ) ) return; @@ -2122,68 +1956,163 @@ BOOL ScInterpreter::RGetVariances( ScMatrix* pV, ScMatrix* pX, } return bOk; } - -void ScInterpreter::ScRGP() +// ----------------------------------------------------------------------------- +void ScInterpreter::Calculate(ScMatrixRef& pResMat,ScMatrixRef& pE,ScMatrixRef& pQ,ScMatrixRef& pV,ScMatrixRef& pMatX,BOOL bConstant,SCSIZE N,SCSIZE M,BYTE nCase) { - BYTE nParamCount = GetByte(); - if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) - return; - BOOL bConstant, bStats; - if (nParamCount == 4) - bStats = GetBool(); - else - bStats = FALSE; - if (nParamCount >= 3) - bConstant = GetBool(); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::RGetVariances" ); + // pE[0] := Sigma i=1...n (Yi) + // pE[k] := Sigma i=1...n (Xki*Yi) + // pE[M+1] := Sigma i=1...n (Yi**2) + // pQ[0,M+1]:= B + // pQ[k,M+1]:= Mk + double fSQR, fSQT, fSQE; + fSQT = pE->GetDouble(M+1) + - pE->GetDouble(0) * pE->GetDouble(0) / (double)N; + fSQR = pE->GetDouble(M+1); + SCSIZE i, j; + for (i = 0; i < M+1; i++) + fSQR -= pQ->GetDouble(i, M+1) * pE->GetDouble(i); + fSQE = fSQT-fSQR; + // r2 (Bestimmtheitsmass, 0...1) + if (fSQT == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); else - bConstant = TRUE; - ScMatrixRef pMatX; - ScMatrixRef pMatY; - if (nParamCount >= 2) - pMatX = GetMatrix(); + pResMat->PutDouble (fSQE/fSQT, 0, 2); + // ssReg (Regressions-Quadratsumme) + pResMat->PutDouble(fSQE, 0, 4); + // ssResid (Residual-Quadratsumme, Summe der Abweichungsquadrate) + pResMat->PutDouble(fSQR, 1, 4); + for (i = 2; i < 5; i++) + for (j = 2; j < M+1; j++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); + if (bConstant) + { + if (N-M-1 == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M-1); + // sey (Standardfehler des Schaetzwertes y) + pResMat->PutDouble(sqrt(fSE2), 1, 2); + // sen...se1 (Standardfehler der Koeffizienten mn...m1) + // seb (Standardfehler der Konstanten b) + if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) ) + { + for (i = 0; i < M+1; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + // F (F-Statistik) + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); + // df (Freiheitsgrad) + pResMat->PutDouble(((double)(N-M-1)), 1, 3); + } else - pMatX = NULL; - pMatY = GetMatrix(); - if (!pMatY) { - PushIllegalParameter(); - return; + if (N-M == 0) + { + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); + } + else + { + double fSE2 = fSQR/(N-M); + pResMat->PutDouble(sqrt(fSE2), 1, 2); + if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) ) + { + for (i = 0; i < M; i++) + pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); + } + else + { + for (i = 0; i < M+1; i++) + pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); + } + } + if (fSQR == 0.0) + pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); + else + pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); + pResMat->PutDouble(((double)(N-M)), 1, 3); } - BYTE nCase; // 1 = normal, 2,3 = mehrfach - SCSIZE nCX, nCY; - SCSIZE nRX, nRY; - SCSIZE M = 0, N = 0; +} + +void ScInterpreter::ScRGP() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRGP" ); + CalulateRGPRKP(FALSE); +} +bool ScInterpreter::CheckMatrix(BOOL _bLOG,BOOL _bTrendGrowth,BYTE& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY) +{ + nCX = 0; + nCY = 0; + nRX = 0; + nRY = 0; + M = 0; + N = 0; pMatY->GetDimensions(nCY, nRY); - SCSIZE nCountY = nCY * nRY; + const SCSIZE nCountY = nCY * nRY; for ( SCSIZE i = 0; i < nCountY; i++ ) + { if (!pMatY->IsValue(i)) { PushIllegalArgument(); - return; - } + return false; + } // if (!pMatY->IsValue(i)) + } // for ( SCSIZE i = 0; i < nCountY; i++ ) + if ( _bLOG ) + { + for (SCSIZE nElem = 0; nElem < nCountY; nElem++) + { + const double fVal = pMatY->GetDouble(nElem); + if (fVal <= 0.0) + { + PushIllegalArgument(); + return false; + } + else + pMatY->PutDouble(log(fVal), nElem); + } // for (nElem = 0; nElem < nCountY; nElem++) + } // if ( _bRKP ) + + if (pMatX) { pMatX->GetDimensions(nCX, nRX); - SCSIZE nCountX = nCX * nRX; + const SCSIZE nCountX = nCX * nRX; for ( SCSIZE i = 0; i < nCountX; i++ ) if (!pMatX->IsValue(i)) { PushIllegalArgument(); - return; + return false; } if (nCX == nCY && nRX == nRY) nCase = 1; // einfache Regression else if (nCY != 1 && nRY != 1) { PushIllegalArgument(); - return; + return false; } else if (nCY == 1) { if (nRX != nRY) { PushIllegalArgument(); - return; + return false; } else { @@ -2195,7 +2124,7 @@ void ScInterpreter::ScRGP() else if (nCX != nCY) { PushIllegalArgument(); - return; + return false; } else { @@ -2207,15 +2136,56 @@ void ScInterpreter::ScRGP() else { pMatX = GetNewMat(nCY, nRY); + if ( _bTrendGrowth ) + { + nCX = nCY; + nRX = nRY; + } if (!pMatX) { PushIllegalArgument(); - return; + return false; } for ( SCSIZE i = 1; i <= nCountY; i++ ) pMatX->PutDouble((double)i, i-1); nCase = 1; } + return true; +} +void ScInterpreter::CalulateRGPRKP(BOOL _bRKP) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CheckMatrix" ); + BYTE nParamCount = GetByte(); + if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) + return; + BOOL bConstant, bStats; + if (nParamCount == 4) + bStats = GetBool(); + else + bStats = FALSE; + if (nParamCount >= 3) + bConstant = GetBool(); + else + bConstant = TRUE; + ScMatrixRef pMatX; + ScMatrixRef pMatY; + if (nParamCount >= 2) + pMatX = GetMatrix(); + else + pMatX = NULL; + pMatY = GetMatrix(); + if (!pMatY) + { + PushIllegalParameter(); + return; + } // if (!pMatY) + BYTE nCase; // 1 = normal, 2,3 = mehrfach + SCSIZE nCX, nCY; + SCSIZE nRX, nRY; + SCSIZE M = 0, N = 0; + if ( !CheckMatrix(_bRKP,FALSE,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) ) + return; + ScMatrixRef pResMat; if (nCase == 1) { @@ -2264,8 +2234,8 @@ void ScInterpreter::ScRGP() b = 0.0; m = fSumXY/fSumSqrX; } - pResMat->PutDouble(m, 0, 0); - pResMat->PutDouble(b, 1, 0); + pResMat->PutDouble(_bRKP ? exp(m) : m, 0, 0); + pResMat->PutDouble(_bRKP ? exp(b) : b, 1, 0); if (bStats) { double fY = fCount*fSumSqrY-fSumY*fSumY; @@ -2296,8 +2266,8 @@ void ScInterpreter::ScRGP() pResMat->PutDouble(fSyx, 1, 4); } } - } - else + } // if (nCase == 1) + if ( nCase != 1 ) { SCSIZE i, j, k; if (!bStats) @@ -2334,7 +2304,7 @@ void ScInterpreter::ScRGP() pE->PutDouble( sumXikYk, i+1); for (j = i; j < M; j++) { - double fVal = pMatX->GetDouble(j,k); + const double fVal = pMatX->GetDouble(j,k); double sumXikXjk = pQ->GetDouble(j+1, i+1) + Xik * fVal; pQ->PutDouble( sumXikXjk, j+1, i+1); @@ -2363,7 +2333,7 @@ void ScInterpreter::ScRGP() pE->PutDouble( sumXkiYk, i+1); for (j = i; j < M; j++) { - double fVal = pMatX->GetDouble(k,j); + const double fVal = pMatX->GetDouble(k,j); double sumXkiXkj = pQ->GetDouble(j+1, i+1) + Xki * fVal; pQ->PutDouble( sumXkiXkj, j+1, i+1); @@ -2372,933 +2342,220 @@ void ScInterpreter::ScRGP() } } } - pQ->PutDouble((double)N, 0, 0); - if (bConstant) + if ( !Calculate4(_bRKP,pResMat,pQ,bConstant,N,M) ) + return; + + if (bStats) + Calculate(pResMat,pE,pQ,pV,pMatX,bConstant,N,M,nCase); + } + PushMatrix(pResMat); +} + +void ScInterpreter::ScRKP() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScRKP" ); + CalulateRGPRKP(TRUE); +} +// ----------------------------------------------------------------------------- +bool ScInterpreter::Calculate4(BOOL _bExp,ScMatrixRef& pResMat,ScMatrixRef& pQ,BOOL bConstant,SCSIZE N,SCSIZE M) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate4" ); + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + SCSIZE S, L; + for (S = 0; S < M+1; S++) { - SCSIZE S, L; - for (S = 0; S < M+1; S++) + SCSIZE i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 0; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) + PushNoValue(); + return false; + } + double fVal; + for (L = 0; L < M+2; L++) + { + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) + { + if (i != S) { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); } } } - else + } + else + { + if ( !Calculate3(M,pQ) ) + return false; + + } + for (SCSIZE i = 0; i < M+1; i++) + { + const double d = pQ->GetDouble(M-i,M+1); + pResMat->PutDouble(_bExp ? exp(d) : d, i, 0); + } // for (SCSIZE i = 0; i < M+1; i++) + return true; +} + +ScMatrixRef ScInterpreter::Calculate2(const BOOL bConstant,const SCSIZE M ,const SCSIZE N,ScMatrixRef& pMatX,ScMatrixRef& pMatY,BYTE nCase) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate2" ); + SCSIZE i, j, k; + ScMatrixRef pQ = GetNewMat(M+1, M+2); + ScMatrixRef pE = GetNewMat(M+2, 1); + pE->PutDouble(0.0, M+1); + pQ->FillDouble(0.0, 0, 0, M, M+1); + if (nCase == 2) + { + for (k = 0; k < N; k++) { - SCSIZE S, L; - for (S = 1; S < M+1; S++) + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) { - PushNoValue(); - return; - } - double fVal; - for (L = 1; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 1; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - pQ->PutDouble(0.0, 0, M+1); // Konstante b - } - } - // mn ... m1, b - for (i = 0; i < M+1; i++) - pResMat->PutDouble(pQ->GetDouble(M-i,M+1), i, 0); - if (bStats) - { - // pE[0] := Sigma i=1...n (Yi) - // pE[k] := Sigma i=1...n (Xki*Yi) - // pE[M+1] := Sigma i=1...n (Yi**2) - // pQ[0,M+1]:= B - // pQ[k,M+1]:= Mk - double fSQR, fSQT, fSQE; - fSQT = pE->GetDouble(M+1) - - pE->GetDouble(0) * pE->GetDouble(0) / (double)N; - fSQR = pE->GetDouble(M+1); - for (i = 0; i < M+1; i++) - fSQR -= pQ->GetDouble(i, M+1) * pE->GetDouble(i); - fSQE = fSQT-fSQR; - // r2 (Bestimmtheitsmass, 0...1) - if (fSQT == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); - else - pResMat->PutDouble (fSQE/fSQT, 0, 2); - // ssReg (Regressions-Quadratsumme) - pResMat->PutDouble(fSQE, 0, 4); - // ssResid (Residual-Quadratsumme, Summe der Abweichungsquadrate) - pResMat->PutDouble(fSQR, 1, 4); - for (i = 2; i < 5; i++) - for (j = 2; j < M+1; j++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); - if (bConstant) - { - if (N-M-1 == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M-1); - // sey (Standardfehler des Schaetzwertes y) - pResMat->PutDouble(sqrt(fSE2), 1, 2); - // sen...se1 (Standardfehler der Koeffizienten mn...m1) - // seb (Standardfehler der Konstanten b) - if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) ) - { - for (i = 0; i < M+1; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); - } - else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - // F (F-Statistik) - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); - // df (Freiheitsgrad) - pResMat->PutDouble(((double)(N-M-1)), 1, 3); - } - else - { - if (N-M == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M); - pResMat->PutDouble(sqrt(fSE2), 1, 2); - if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) ) - { - for (i = 0; i < M; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); - } - else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); - pResMat->PutDouble(((double)(N-M)), 1, 3); - } - } - } - PushMatrix(pResMat); -} - -void ScInterpreter::ScRKP() -{ - BYTE nParamCount = GetByte(); - if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) - return; - BOOL bConstant, bStats; - if (nParamCount == 4) - bStats = GetBool(); - else - bStats = FALSE; - if (nParamCount >= 3) - bConstant = GetBool(); - else - bConstant = TRUE; - ScMatrixRef pMatX; - ScMatrixRef pMatY; - if (nParamCount >= 2) - pMatX = GetMatrix(); - else - pMatX = NULL; - pMatY = GetMatrix(); - if (!pMatY) - { - PushIllegalParameter(); - return; - } - BYTE nCase; // 1 = normal, 2,3 = mehrfach - SCSIZE nCX, nCY; - SCSIZE nRX, nRY; - SCSIZE M = 0, N = 0; - pMatY->GetDimensions(nCY, nRY); - SCSIZE nCountY = nCY * nRY; - SCSIZE nElem; - for (nElem = 0; nElem < nCountY; nElem++) - if (!pMatY->IsValue(nElem)) - { - PushIllegalArgument(); - return; - } - for (nElem = 0; nElem < nCountY; nElem++) - { - double fVal = pMatY->GetDouble(nElem); - if (fVal <= 0.0) - { - PushIllegalArgument(); - return; - } - else - pMatY->PutDouble(log(pMatY->GetDouble(nElem)), nElem); - } - if (pMatX) - { - pMatX->GetDimensions(nCX, nRX); - SCSIZE nCountX = nCX * nRX; - for (nElem = 0; nElem < nCountX; nElem++) - if (!pMatX->IsValue(nElem)) - { - PushIllegalArgument(); - return; - } - if (nCX == nCY && nRX == nRY) - nCase = 1; // einfache Regression - else if (nCY != 1 && nRY != 1) - { - PushIllegalArgument(); - return; - } - else if (nCY == 1) - { - if (nRX != nRY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 2; // zeilenweise - N = nRY; - M = nCX; - } - } - else if (nCX != nCY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 3; // spaltenweise - N = nCY; - M = nRX; - } - } - else - { - pMatX = GetNewMat(nCY, nRY); - if (!pMatX) - { - PushIllegalArgument(); - return; - } - for ( SCSIZE i = 1; i <= nCountY; i++ ) - pMatX->PutDouble((double)i, i-1); - nCase = 1; - } - ScMatrixRef pResMat; - if (nCase == 1) - { - if (!bStats) - pResMat = GetNewMat(2,1); - else - pResMat = GetNewMat(2,5); - if (!pResMat) - { - PushIllegalArgument(); - return; - } - double fCount = 0.0; - double fSumX = 0.0; - double fSumSqrX = 0.0; - double fSumY = 0.0; - double fSumSqrY = 0.0; - double fSumXY = 0.0; - double fValX, fValY; - for (SCSIZE i = 0; i < nCY; i++) - for (SCSIZE j = 0; j < nRY; j++) - { - fValX = pMatX->GetDouble(i,j); - fValY = pMatY->GetDouble(i,j); - fSumX += fValX; - fSumSqrX += fValX * fValX; - fSumY += fValY; - fSumSqrY += fValY * fValY; - fSumXY += fValX*fValY; - fCount++; - } - if (fCount < 1.0) - PushNoValue(); - else - { - double f1 = fCount*fSumXY-fSumX*fSumY; - double fX = fCount*fSumSqrX-fSumX*fSumX; - double b, m; - if (bConstant) - { - b = fSumY/fCount - f1/fX*fSumX/fCount; - m = f1/fX; - } - else - { - b = 0.0; - m = fSumXY/fSumSqrX; - } - pResMat->PutDouble(exp(m), 0, 0); - pResMat->PutDouble(exp(b), 1, 0); - if (bStats) - { - double fY = fCount*fSumSqrY-fSumY*fSumY; - double fSyx = fSumSqrY-b*fSumY-m*fSumXY; - double fR2 = f1*f1/(fX*fY); - pResMat->PutDouble (fR2, 0, 2); - if (fCount < 3.0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); - } - else - { - pResMat->PutDouble(sqrt(fSyx*fCount/(fX*(fCount-2.0))), 0, 1); - pResMat->PutDouble(sqrt(fSyx*fSumSqrX/fX/(fCount-2.0)), 1, 1); - pResMat->PutDouble( - sqrt((fCount*fSumSqrY - fSumY*fSumY - f1*f1/fX)/ - (fCount*(fCount-2.0))), 1, 2); - if (fR2 == 1.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3 ); - else - pResMat->PutDouble(fR2*(fCount-2.0)/(1.0-fR2), 0, 3); - } - pResMat->PutDouble(((double)(nCY*nRY))-2.0, 1, 3); - pResMat->PutDouble(fY/fCount-fSyx, 0, 4); - pResMat->PutDouble(fSyx, 1, 4); - } - } - } - else - { - SCSIZE i, j, k; - if (!bStats) - pResMat = GetNewMat(M+1,1); - else - pResMat = GetNewMat(M+1,5); - if (!pResMat) - { - PushIllegalArgument(); - return; - } - ScMatrixRef pQ = GetNewMat(M+1, M+2); - ScMatrixRef pE = GetNewMat(M+2, 1); - ScMatrixRef pV = GetNewMat(M+1, 1); - pE->PutDouble(0.0, M+1); - pQ->FillDouble(0.0, 0, 0, M, M+1); - if (nCase == 2) - { - for (k = 0; k < N; k++) - { - double Yk = pMatY->GetDouble(k); - pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); - double sumYk = pQ->GetDouble(0, M+1) + Yk; - pQ->PutDouble( sumYk, 0, M+1 ); - pE->PutDouble( sumYk, 0 ); - for (i = 0; i < M; i++) - { - double Xik = pMatX->GetDouble(i,k); - double sumXik = pQ->GetDouble(0, i+1) + Xik; - pQ->PutDouble( sumXik, 0, i+1); - pQ->PutDouble( sumXik, i+1, 0); - double sumXikYk = pQ->GetDouble(i+1, M+1) + Xik * Yk; - pQ->PutDouble( sumXikYk, i+1, M+1); - pE->PutDouble( sumXikYk, i+1); - for (j = i; j < M; j++) - { - double sumXikXjk = pQ->GetDouble(j+1, i+1) + - Xik * pMatX->GetDouble(j,k); - pQ->PutDouble( sumXikXjk, j+1, i+1); - pQ->PutDouble( sumXikXjk, i+1, j+1); - } - } - } - } - else - { - for (k = 0; k < N; k++) - { - double Yk = pMatY->GetDouble(k); - pE->PutDouble( pE->GetDouble(M+1)+Yk*Yk, M+1 ); - double sumYk = pQ->GetDouble(0, M+1) + Yk; - pQ->PutDouble( sumYk, 0, M+1 ); - pE->PutDouble( sumYk, 0 ); - for (i = 0; i < M; i++) - { - double Xki = pMatX->GetDouble(k,i); - double sumXki = pQ->GetDouble(0, i+1) + Xki; - pQ->PutDouble( sumXki, 0, i+1); - pQ->PutDouble( sumXki, i+1, 0); - double sumXkiYk = pQ->GetDouble(i+1, M+1) + Xki * Yk; - pQ->PutDouble( sumXkiYk, i+1, M+1); - pE->PutDouble( sumXkiYk, i+1); - for (j = i; j < M; j++) - { - double sumXkiXkj = pQ->GetDouble(j+1, i+1) + - Xki * pMatX->GetDouble(k,j); - pQ->PutDouble( sumXkiXkj, j+1, i+1); - pQ->PutDouble( sumXkiXkj, i+1, j+1); - } - } - } - } - pQ->PutDouble((double)N, 0, 0); - if (bConstant) - { - SCSIZE S, L; - for (S = 0; S < M+1; S++) - { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 0; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - } - } - else - { - SCSIZE S, L; - for (S = 1; S < M+1; S++) - { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 1; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 1; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - pQ->PutDouble(0.0, 0, M+1); - } - } - for (i = 0; i < M+1; i++) - pResMat->PutDouble(exp(pQ->GetDouble(M-i,M+1)), i, 0); - if (bStats) - { - double fSQR, fSQT, fSQE; - fSQT = pE->GetDouble(M+1)-pE->GetDouble(0)*pE->GetDouble(0)/((double)N); - fSQR = pE->GetDouble(M+1); - for (i = 0; i < M+1; i++) - fSQR += -pQ->GetDouble(i, M+1)*pE->GetDouble(i); - fSQE = fSQT-fSQR; - if (fSQT == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 2); - else - pResMat->PutDouble (fSQE/fSQT, 0, 2); - pResMat->PutDouble(fSQE, 0, 4); - pResMat->PutDouble(fSQR, 1, 4); - for (i = 2; i < 5; i++) - for (j = 2; j < M+1; j++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), j, i); - if (bConstant) - { - if (N-M-1 == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M-1); - pResMat->PutDouble(sqrt(fSE2), 1, 2); - if ( RGetVariances( pV, pMatX, M+1, N, nCase != 2, FALSE ) ) - { - for (i = 0; i < M+1; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i, 1 ); - } - else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M-1))*fSQE/fSQR/((double)M),0, 3); - pResMat->PutDouble(((double)(N-M-1)), 1, 3); - } - else - { - if (N-M == 0) - { - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 1, 2); - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, 1); - } - else - { - double fSE2 = fSQR/(N-M); - pResMat->PutDouble(sqrt(fSE2), 1, 2); - if ( RGetVariances( pV, pMatX, M, N, nCase != 2, TRUE ) ) - { - for (i = 0; i < M; i++) - pResMat->PutDouble( sqrt(fSE2 * pV->GetDouble(i)), M-i-1, 1 ); - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), M, 1); - } - else - { - for (i = 0; i < M+1; i++) - pResMat->PutString(ScGlobal::GetRscString(STR_NV_STR), i, 1); - } - } - if (fSQR == 0.0) - pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), 0, 3); - else - pResMat->PutDouble(((double)(N-M))*fSQE/fSQR/((double)M),0, 3); - pResMat->PutDouble(((double)(N-M)), 1, 3); - } - } - } - PushMatrix(pResMat); -} - - -void ScInterpreter::ScTrend() -{ - BYTE nParamCount = GetByte(); - if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) - return; - BOOL bConstant; - if (nParamCount == 4) - bConstant = GetBool(); - else - bConstant = TRUE; - ScMatrixRef pMatX; - ScMatrixRef pMatY; - ScMatrixRef pMatNewX; - if (nParamCount >= 3) - pMatNewX = GetMatrix(); - else - pMatNewX = NULL; - if (nParamCount >= 2) - pMatX = GetMatrix(); - else - pMatX = NULL; - pMatY = GetMatrix(); - if (!pMatY) - { - PushIllegalParameter(); - return; - } - BYTE nCase; // 1 = normal, 2,3 = mehrfach - SCSIZE nCX, nCY; - SCSIZE nRX, nRY; - SCSIZE M = 0, N = 0; - pMatY->GetDimensions(nCY, nRY); - SCSIZE nCountY = nCY * nRY; - SCSIZE nElem; - for (nElem = 0; nElem < nCountY; nElem++) - if (!pMatY->IsValue(nElem)) - { - PushIllegalArgument(); - return; - } - if (pMatX) - { - pMatX->GetDimensions(nCX, nRX); - SCSIZE nCountX = nCX * nRX; - for (nElem = 0; nElem < nCountX; nElem++) - if (!pMatX->IsValue(nElem)) - { - PushIllegalArgument(); - return; - } - if (nCX == nCY && nRX == nRY) - nCase = 1; // einfache Regression - else if (nCY != 1 && nRY != 1) - { - PushIllegalArgument(); - return; - } - else if (nCY == 1) - { - if (nRX != nRY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 2; // zeilenweise - N = nRY; - M = nCX; - } - } - else if (nCX != nCY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 3; // spaltenweise - N = nCY; - M = nRX; - } - } - else - { - pMatX = GetNewMat(nCY, nRY); - nCX = nCY; - nRX = nRY; - if (!pMatX) - { - PushIllegalArgument(); - return; - } - for (nElem = 1; nElem <= nCountY; nElem++) - pMatX->PutDouble((double)nElem, nElem-1); - nCase = 1; - } - SCSIZE nCXN, nRXN; - SCSIZE nCountXN; - if (!pMatNewX) - { - nCXN = nCX; - nRXN = nRX; - nCountXN = nCXN * nRXN; - pMatNewX = pMatX; - } - else - { - pMatNewX->GetDimensions(nCXN, nRXN); - if ((nCase == 2 && nCX != nCXN) || (nCase == 3 && nRX != nRXN)) - { - PushIllegalArgument(); - return; - } - nCountXN = nCXN * nRXN; - for ( SCSIZE i = 0; i < nCountXN; i++ ) - if (!pMatNewX->IsValue(i)) - { - PushIllegalArgument(); - return; - } - } - ScMatrixRef pResMat; - if (nCase == 1) - { - double fCount = 0.0; - double fSumX = 0.0; - double fSumSqrX = 0.0; - double fSumY = 0.0; - double fSumSqrY = 0.0; - double fSumXY = 0.0; - double fValX, fValY; - SCSIZE i; - for (i = 0; i < nCY; i++) - for (SCSIZE j = 0; j < nRY; j++) - { - fValX = pMatX->GetDouble(i,j); - fValY = pMatY->GetDouble(i,j); - fSumX += fValX; - fSumSqrX += fValX * fValX; - fSumY += fValY; - fSumSqrY += fValY * fValY; - fSumXY += fValX*fValY; - fCount++; - } - if (fCount < 1.0) - { - PushNoValue(); - return; - } - else - { - double f1 = fCount*fSumXY-fSumX*fSumY; - double fX = fCount*fSumSqrX-fSumX*fSumX; - double b, m; - if (bConstant) - { - b = fSumY/fCount - f1/fX*fSumX/fCount; - m = f1/fX; - } - else - { - b = 0.0; - m = fSumXY/fSumSqrX; - } - pResMat = GetNewMat(nCXN, nRXN); - if (!pResMat) - { - PushIllegalArgument(); - return; + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); + } } - for (i = 0; i < nCountXN; i++) - pResMat->PutDouble(pMatNewX->GetDouble(i)*m+b, i); } } else { - SCSIZE i, j, k; - ScMatrixRef pQ = GetNewMat(M+1, M+2); - ScMatrixRef pE = GetNewMat(M+2, 1); - pE->PutDouble(0.0, M+1); - pQ->FillDouble(0.0, 0, 0, M, M+1); - if (nCase == 2) + for (k = 0; k < N; k++) { - for (k = 0; k < N; k++) + pE->PutDouble( + pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); + pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); + pE->PutDouble(pQ->GetDouble(0, M+1), 0); + for (i = 0; i < M; i++) { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) + pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); + pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); + pQ->PutDouble(pQ->GetDouble(i+1, M+1) + + pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); + pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); + for (j = i; j < M; j++) { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) - { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); - } + pQ->PutDouble(pQ->GetDouble(j+1, i+1) + + pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); + pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); } } } - else + } + pQ->PutDouble((double)N, 0, 0); + if (bConstant) + { + SCSIZE S, L; + for (S = 0; S < M+1; S++) { - for (k = 0; k < N; k++) + i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) - { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) - { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); - } - } + PushNoValue(); + return ScMatrixRef(); } - } - pQ->PutDouble((double)N, 0, 0); - if (bConstant) - { - SCSIZE S, L; - for (S = 0; S < M+1; S++) + double fVal; + for (L = 0; L < M+2; L++) { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 0; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); } - } - else - { - SCSIZE S, L; - for (S = 1; S < M+1; S++) + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 0; i < M+1; i++) { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 1; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 1; i < M+1; i++) + if (i != S) { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } + fVal = -pQ->GetDouble(i, S); + for (L = 0; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); } - pQ->PutDouble(0.0, 0, M+1); } } - if (nCase == 2) + } + else + { + if ( !Calculate3(M,pQ) ) + return ScMatrixRef(); + } + return pQ; +} +bool ScInterpreter::Calculate3(const SCSIZE M ,ScMatrixRef& pQ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::Calculate3" ); + SCSIZE S, L; + for (S = 1; S < M+1; S++) + { + SCSIZE i = S; + while (i < M+1 && pQ->GetDouble(i, S) == 0.0) + i++; + if (i >= M+1) { - pResMat = GetNewMat(1, nRXN); - if (!pResMat) - { - PushIllegalArgument(); - return; - } - double fVal; - for (i = 0; i < nRXN; i++) - { - fVal = pQ->GetDouble(0, M+1); - for (j = 0; j < M; j++) - fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i); - pResMat->PutDouble(fVal, i); - } + PushNoValue(); + return ScMatrixRef(); } - else + double fVal; + for (L = 1; L < M+2; L++) { - pResMat = GetNewMat(nCXN, 1); - if (!pResMat) - { - PushIllegalArgument(); - return; - } - double fVal; - for (i = 0; i < nCXN; i++) + fVal = pQ->GetDouble(S, L); + pQ->PutDouble(pQ->GetDouble(i, L), S, L); + pQ->PutDouble(fVal, i, L); + } + fVal = 1.0/pQ->GetDouble(S, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); + for (i = 1; i < M+1; i++) + { + if (i != S) { - fVal = pQ->GetDouble(0, M+1); - for (j = 0; j < M; j++) - fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j); - pResMat->PutDouble(fVal, i); + fVal = -pQ->GetDouble(i, S); + for (L = 1; L < M+2; L++) + pQ->PutDouble( + pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); } } - } - PushMatrix(pResMat); + pQ->PutDouble(0.0, 0, M+1); + } // for (S = 1; S < M+1; S++) + return true; } -void ScInterpreter::ScGrowth() +void ScInterpreter::ScTrend() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScTrend" ); + CalculateTrendGrowth(FALSE); +} +void ScInterpreter::CalculateTrendGrowth(BOOL _bGrowth) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::CalculateTrendGrowth" ); BYTE nParamCount = GetByte(); if ( !MustHaveParamCount( nParamCount, 1, 4 ) ) return; @@ -3323,89 +2580,16 @@ void ScInterpreter::ScGrowth() { PushIllegalParameter(); return; - } + } // if (!pMatY) + BYTE nCase; // 1 = normal, 2,3 = mehrfach SCSIZE nCX, nCY; SCSIZE nRX, nRY; SCSIZE M = 0, N = 0; - pMatY->GetDimensions(nCY, nRY); - SCSIZE nCountY = nCY * nRY; - SCSIZE nElem; - for (nElem = 0; nElem < nCountY; nElem++) - { - if (!pMatY->IsValue(nElem)) - { - PushIllegalArgument(); - return; - } - } - for (nElem = 0; nElem < nCountY; nElem++) - { - if (pMatY->GetDouble(nElem) <= 0.0) - { - PushIllegalArgument(); - return; - } - else - pMatY->PutDouble(log(pMatY->GetDouble(nElem)), nElem); - } - if (pMatX) - { - pMatX->GetDimensions(nCX, nRX); - SCSIZE nCountX = nCX * nRX; - for ( SCSIZE i = 0; i < nCountX; i++ ) - if (!pMatX->IsValue(i)) - { - PushIllegalArgument(); - return; - } - if (nCX == nCY && nRX == nRY) - nCase = 1; // einfache Regression - else if (nCY != 1 && nRY != 1) - { - PushIllegalArgument(); - return; - } - else if (nCY == 1) - { - if (nRX != nRY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 2; // zeilenweise - N = nRY; - M = nCX; - } - } - else if (nCX != nCY) - { - PushIllegalArgument(); - return; - } - else - { - nCase = 3; // spaltenweise - N = nCY; - M = nRX; - } - } - else - { - pMatX = GetNewMat(nCY, nRY); - nCX = nCY; - nRX = nRY; - if (!pMatX) - { - PushIllegalArgument(); - return; - } - for (SCSIZE i = 1; i <= nCountY; i++) - pMatX->PutDouble((double)i, i-1); - nCase = 1; - } + if ( !CheckMatrix(_bGrowth,TRUE,nCase,nCX,nCY,nRX,nRY,M,N,pMatX,pMatY) ) + return; + + SCSIZE nCXN, nRXN; SCSIZE nCountXN; if (!pMatNewX) @@ -3441,7 +2625,8 @@ void ScInterpreter::ScGrowth() double fSumSqrY = 0.0; double fSumXY = 0.0; double fValX, fValY; - for (SCSIZE i = 0; i < nCY; i++) + SCSIZE i; + for (i = 0; i < nCY; i++) for (SCSIZE j = 0; j < nRY; j++) { fValX = pMatX->GetDouble(i,j); @@ -3479,137 +2664,18 @@ void ScInterpreter::ScGrowth() PushIllegalArgument(); return; } - for (SCSIZE i = 0; i < nCountXN; i++) - pResMat->PutDouble(exp(pMatNewX->GetDouble(i)*m+b), i); + for (i = 0; i < nCountXN; i++) + { + const double d = pMatNewX->GetDouble(i)*m+b; + pResMat->PutDouble(_bGrowth ? exp(d) : d, i); + } } } else { - SCSIZE i, j, k; - ScMatrixRef pQ = GetNewMat(M+1, M+2); - ScMatrixRef pE = GetNewMat(M+2, 1); - pE->PutDouble(0.0, M+1); - pQ->FillDouble(0.0, 0, 0, M, M+1); - if (nCase == 2) - { - for (k = 0; k < N; k++) - { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) - { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(i,k), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(i,k)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) - { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(i,k)*pMatX->GetDouble(j,k), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); - } - } - } - } - else - { - for (k = 0; k < N; k++) - { - pE->PutDouble( - pE->GetDouble(M+1)+pMatY->GetDouble(k)*pMatY->GetDouble(k), M+1); - pQ->PutDouble(pQ->GetDouble(0, M+1) + pMatY->GetDouble(k), 0, M+1); - pE->PutDouble(pQ->GetDouble(0, M+1), 0); - for (i = 0; i < M; i++) - { - pQ->PutDouble(pQ->GetDouble(0, i+1)+pMatX->GetDouble(k,i), 0, i+1); - pQ->PutDouble(pQ->GetDouble(0, i+1), i+1, 0); - pQ->PutDouble(pQ->GetDouble(i+1, M+1) + - pMatX->GetDouble(k,i)*pMatY->GetDouble(k), i+1, M+1); - pE->PutDouble(pQ->GetDouble(i+1, M+1), i+1); - for (j = i; j < M; j++) - { - pQ->PutDouble(pQ->GetDouble(j+1, i+1) + - pMatX->GetDouble(k, i)*pMatX->GetDouble(k, j), j+1, i+1); - pQ->PutDouble(pQ->GetDouble(j+1, i+1), i+1, j+1); - } - } - } - } - pQ->PutDouble((double)N, 0, 0); - if (bConstant) - { - SCSIZE S, L; - for (S = 0; S < M+1; S++) - { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 0; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 0; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 0; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - } - } - else - { - SCSIZE S, L; - for (S = 1; S < M+1; S++) - { - i = S; - while (i < M+1 && pQ->GetDouble(i, S) == 0.0) - i++; - if (i >= M+1) - { - PushNoValue(); - return; - } - double fVal; - for (L = 1; L < M+2; L++) - { - fVal = pQ->GetDouble(S, L); - pQ->PutDouble(pQ->GetDouble(i, L), S, L); - pQ->PutDouble(fVal, i, L); - } - fVal = 1.0/pQ->GetDouble(S, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble(pQ->GetDouble(S, L)*fVal, S, L); - for (i = 1; i < M+1; i++) - { - if (i != S) - { - fVal = -pQ->GetDouble(i, S); - for (L = 1; L < M+2; L++) - pQ->PutDouble( - pQ->GetDouble(i,L)+fVal*pQ->GetDouble(S,L),i,L); - } - } - pQ->PutDouble(0.0, 0, M+1); - } - } + ScMatrixRef pQ = Calculate2(bConstant,M ,N,pMatX,pMatY,nCase); + if ( !pQ.Is() ) + return; if (nCase == 2) { pResMat = GetNewMat(1, nRXN); @@ -3619,12 +2685,12 @@ void ScInterpreter::ScGrowth() return; } double fVal; - for (i = 0; i < nRXN; i++) + for (SCSIZE i = 0; i < nRXN; i++) { fVal = pQ->GetDouble(0, M+1); - for (j = 0; j < M; j++) + for (SCSIZE j = 0; j < M; j++) fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(j, i); - pResMat->PutDouble(exp(fVal), i); + pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i); } } else @@ -3636,22 +2702,29 @@ void ScInterpreter::ScGrowth() return; } double fVal; - for (i = 0; i < nCXN; i++) + for (SCSIZE i = 0; i < nCXN; i++) { fVal = pQ->GetDouble(0, M+1); - for (j = 0; j < M; j++) + for (SCSIZE j = 0; j < M; j++) fVal += pQ->GetDouble(j+1, M+1)*pMatNewX->GetDouble(i, j); - pResMat->PutDouble(exp(fVal), i); + pResMat->PutDouble(_bGrowth ? exp(fVal) : fVal, i); } } } PushMatrix(pResMat); } +void ScInterpreter::ScGrowth() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScGrowth" ); + CalculateTrendGrowth(TRUE); +} + void ScInterpreter::ScMatRef() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScMatRef" ); // Falls Deltarefs drin sind... - Push( (ScToken&) *pCur ); + Push( (FormulaToken&)*pCur ); ScAddress aAdr; PopSingleRef( aAdr ); ScFormulaCell* pCell = (ScFormulaCell*) GetCell( aAdr ); @@ -3719,6 +2792,7 @@ void ScInterpreter::ScMatRef() void ScInterpreter::ScInfo() { + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScInfo" ); if( MustHaveParamCount( GetByte(), 1 ) ) { String aStr = GetString(); -- cgit v1.2.3