Search code examples
plotfloating-pointnumerical-methods

How to plot the relationship between any error and the exact solution of a problem involving summation of real number


I am taking Numerical Methods class and we were asked this problem. The problem is as follows,

Add the real number 10^-N to itself 10^N times. Run the program for N = 1 to 12. So I've written the following C++ code

#include <iostream>
#include <cmath>        // std::pow for power of numbers
#include <iomanip>      // std::setprecision
using namespace std;

int main(){
double i, sum, Nx; // Initialize the variables

for(i = 1; i < 3; i++ ){

Nx = pow(10,i); // Here Nx is the 10^n term.

cout << "Nx: " << Nx << endl;  // Printing Nx before starting the loop

sum = 0;  // Initializing the Total sum to zero

while(Nx){
     sum = sum + pow(10,-i); // Adds every 1/10^i term to itself till 10^i becomes 0.
     Nx--;
     cout << "For i = " << i << " the sum is: " << setprecision(10) << sum << endl; // Printing the summation value
  }
 }
return 0;
}

The summation is 1.

But the second part of the question is Plot the relationship between any error and the exact solution in a meaningful way.

I get that I need a log scale to plot it. But how do I generate the error? Any help would be greatly appreciated.


Solution

  • The number dx=10^-N itself has a rounding error in its binary representation of at most one half of an ULP, or about 0.5*mu*dx where mu=2^-52 which is about 2e-16. The sum of these errors is at most 0.5*mu, thus does not influence the result.

    Let's look at the summation steps. At first the sum is small, so the rounding error will be small accordingly. With increasing sum the error of the single addition will also increase. Halfway through the summation, one encounters the average of the extremes, so look at the addition of dx=10^-N to 0.5. The addition again has a rounding error of at most one half of an ULP, but now that is relative to the result which is again around 0.5, giving an error of 0.25*mu. Taking this as the average error, the whole computation will give an error of around 10^N*0.25*mu which is about 0.5*10^(N-16). Which means that about the last N digits are "dirty". Note that the rounding errors have a somewhat random distribution in size and direction, so that they can also cancel, giving a smaller error in the end than this estimate.

    In the cases you observed, the error will be in the last 3 of 16 digits. By rounding to 10 digits, you eliminate that error in the printed numbers. There is two things you can do:

    • increase the number of digits in the output,
    • print also the difference to 1.