Hello,
I had a look at the source in interpr3.cxx and have made the proposed
changes for the COVAR function. Although I'm a very beginner I think,
that I'm able to change some of the other such functions too.
The changes need to calculate the mean in a first loop and than
calculating the other results in a second loop. My question is, whether
you want, that the functions are changed in that way. If yes, I would be
glad, to do that job.
For COVAR it looks like this (based on OOF680_m18):
--- interpr3original.cxx 2006-07-21 13:34:30.000000000 +0200
+++ interpr3Version1Covar.cxx 2007-07-04 23:00:28.656250000 +0200
@@ -3656,13 +3656,18 @@
SetIllegalParameter();
return;
}
+ //#issue 78250
+ //(sum((X-MeanX)(Y-MeanY)))/N equals (SumXY)/N-MeanX*MeanY
mathematically,
+ // but the latter produces wrong results if the absolute values are
high,
+ // for example above 10^7
double fCount = 0.0;
double fSumX = 0.0;
double fSumY = 0.0;
- double fSumXY = 0.0;
+ double fSumDeltaXDeltaY = 0.0; // sum of (ValX-MeanX)*(ValY-MeanY)
double fValX, fValY;
+ double fMeanX, fMeanY;
for (SCSIZE i = 0; i < nC1; i++)
- for (SCSIZE j = 0; j < nR1; j++)
+ for (SCSIZE j = 0; j < nR1; j++)
{
if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
{
@@ -3670,14 +3675,27 @@
fValY = pMat2->GetDouble(i,j);
fSumX += fValX;
fSumY += fValY;
- fSumXY += fValX*fValY;
fCount++;
}
}
if (fCount < 1.0)
SetNoValue();
else
- PushDouble( (fSumXY-fSumX*fSumY/fCount)/fCount);
+ {
+ fMeanX = fSumX/fCount;
+ fMeanY = fSumY/fCount;
+ for (SCSIZE i = 0; i < nC1; i++)
+ for (SCSIZE j = 0; j < nR1; j++)
+ {
+ if (!pMat1->IsString(i,j) && !pMat2->IsString(i,j))
+ {
+ fValX = pMat1->GetDouble(i,j);
+ fValY = pMat2->GetDouble(i,j);
+ fSumDeltaXDeltaY
+=(fValX-fMeanX)*(fValY-fMeanY);
+ }
+ }
+ PushDouble( fSumDeltaXDeltaY/fCount);
+ }
}
kind regards
Regina
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]