Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2017-12

Numeric error in the calculation of Variance

6 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Anton Shepelev

Hello, all

May I ask you if there is any chance of fixing the error in the Math unit that I reported here:

https://bugs.freepascal.org/view.php?id=32804

and provided a patch? Here is a test case:

Program Vartest;
uses Math;
const Size = 1000000;
var dataS: array of Single;
    dataD: array of Double;
    dataE: array of Extended;
    i,n: longint;
begin
  WriteLn('Each run should return a value near unity.');
  WriteLn('Single:');
  SetLength( dataS, Size );
  for n := 1 to 4 do
  begin
    for i := 0 to Size - 1 do
    begin
      dataS[i] := 10000000 + RandG(0,1);
    end;
    WriteLn( Math.Variance( dataS ):5:3 );
  end;
  WriteLn('Double:');
  SetLength( dataD, Size );
  for n := 1 to 4 do
  begin
    for i := 0 to Size - 1 do
    begin
      dataD[i] := 1000000000000000 + RandG(0,1);
    end;
    WriteLn( Math.Variance( dataD ):5:3 );
  end;
  WriteLn('Extended:');
  SetLength( dataE, Size );
  for n := 1 to 4 do
  begin
    for i := 0 to Size - 1 do
    begin
      dataE[i] := 1000000000000000000 + RandG(0,1);
    end;
    WriteLn( Math.Variance( dataE ):5:3 );
  end;
end.
Please, do not forward replies to my e-mail.

Reply by email

Werner Pamler
to Anton Shepelev
Anton Shepelev wrote 53 lines
Hello, all May I ask you if there is any chance of fixing the error in the Math unit that I reported here: https://bugs.freepascal.org/view.php?id=32804 and provided a patch? Here is a test case: Program Vartest; uses Math; const Size = 1000000; var dataS: array of Single; dataD: array of Double; dataE: array of Extended; i,n: longint; begin WriteLn('Each run should return a value near unity.'); WriteLn('Single:'); SetLength( dataS, Size ); for n := 1 to 4 do begin for i := 0 to Size - 1 do begin dataS[i] := 10000000 + RandG(0,1); end; WriteLn( Math.Variance( dataS ):5:3 ); end; WriteLn('Double:'); SetLength( dataD, Size ); for n := 1 to 4 do begin for i := 0 to Size - 1 do begin dataD[i] := 1000000000000000 + RandG(0,1); end; WriteLn( Math.Variance( dataD ):5:3 ); end; WriteLn('Extended:'); SetLength( dataE, Size ); for n := 1 to 4 do begin for i := 0 to Size - 1 do begin dataE[i] := 1000000000000000000 + RandG(0,1); end; WriteLn( Math.Variance( dataE ):5:3 ); end; end.

Yes, the formula used is  SS-Sqr(S)/N, and this is the bad one. Explained somewhere in the Numerical Recipes, but also in Widepedia (https://en.wikipedia.org/wiki/Variance#Formulae_for_the_variance): "it is not advised for computer calculations as it suffers from catastrophic cancellation <https://en.wikipedia.org/wiki/Catastrophic_cancellation> if the two components of the equation are similar in magnitude and floating point arithmetic is used."

Reply by email

Michael Van Canneyt
to Anton Shepelev: Hello, all May I ask you if there is any chance of fixing the error in the Math unit…
Anton Shepelev wrote 8 lines
Hello, all May I ask you if there is any chance of fixing the error in the Math unit that I reported here: https://bugs.freepascal.org/view.php?id=32804 and provided a patch? Here is a test case:

I have checked and applied the patch.

I will add your example to the documentation, if I have your permission ?

Michael.

Reply by email

Anton Shepelev
to Michael Van Canneyt

Michael Van Canneyt to Anton Shepelev:

Show quoted text 8 lines
> May I ask you if there is any chance of fixing > the error in the Math unit that I reported here: > > https://bugs.freepascal.org/view.php?id=32804 > > and provided a patch? Here is a test case: I have checked and applied the patch.

Thank you.

I will add your example to the documentation, if I have your permission?

Feel free to do so. The credit is due my friend Pe- ter Karpov, who originally discovered this bug, but you need not mention our names :-)

Please, do not forward replies to my e-mail.

Reply by email