0

Today I ran into a problem with precision in Matlab:

Tp = a./(3600*sqrt(g)*sqrt(K).*u.*Sd*sqrt(bB))

where

a =

                  346751.503002533 

g =

                  9.81

bB =

                  2000

Sd =

      749.158805838953
      848.621203222693
       282.57250570754
      1.69002068665559
      529.068503515487

u =

     0.308500000000039
     0.291030000000031
      0.38996000000005
      0.99272999999926
     0.271120000000031

K =

 3.80976148470781e-009
 3.33620420353532e-009
 1.67593037457502e-008
 7.22952172629158e-005
 9.89028880679124e-009

Apparently, due to the calculations of variables of different dimensions, I get a problem with the computer precision:

Tp =

      48.2045906674902
      48.2045906674902
      48.2045906674902
      48.2045906674902
      48.2045906674902

Unfortunately, I do not really know how to handle this. I played around with the output format, but this is not the issue. So I assume that it really is the internal computation precision that gets me. However, if I calculte sqrt(K).*u or u.*Sd by itself I do get reasonable values. Only once I multiply all the 3 matrices together I get the same value as a result, although it should vary. I found this thread, but my case is slightly different, because I do not get arbitrary values, but they are all the same for some reason: numerical issue when computing complementary projection

I also thought that scaling all variables like so: Sd = Sd/max(Sd) might help, but since I need a farily accurate and dimensonally correct result, this would not help.

Even when using

vpa(a./(3600*sqrt(g)*sqrt(K).*u.*Sd*sqrt(bB)))

I get the same value each time, but with more digits. Why is this?

I hope you can help me. Cheers

Edit: Here is more of the code for a better grasp of my problem:

Al = 2835000000; % [m^2]
Qp = 3000000; [m^3*s^-1]
% draw 100 uniformally distributed values for s & r
s = 600 + (8000-600).*rand(100,1);
r = 600 + (15000-600).*rand(100,1);

% calculate Sd & Rd
Sd = 680./s;
Rd = 680./r;
figure
subplot(2,1,1)
hist(Sd)
subplot(2,1,2)
hist(Rd)

%% calculate my numerically
% calculate sigma
sig = Sd./Rd;

% define starting parameters for numerical solution
t = -1*ones(size(sig));
u = zeros(size(sig));
f = zeros(size(sig));

% define step
st = 0.00001;

% define break criterion
br = -0.001;

% increase u incrementally by st until t <= br
for i=1:length(sig)
    while t(i)<br
        while t(i)<-0.1
            f(i) = sig(i)*u(i)/sqrt(pi); % calculate f for convenience
            ierfc = exp(-f(i)*f(i))/sqrt(pi) - f(i)*erfc(f(i)); % calculate integral  of complementary error function
            t(i) = (u(i)/sqrt(pi))*erfc(-f(i))*(1+sig(i))-ierfc
            u(i) = u(i) + st*1000
        end
        while t(i)>=-0.1&& t(i)<br
            f(i) = sig(i)*u(i)/sqrt(pi); % calculate f for convenience
            ierfc = exp(-f(i)*f(i))/sqrt(pi) - f(i)*erfc(f(i)); % calculate integral of complementary error function
            t(i) = (u(i)/sqrt(pi))*erfc(-f(i))*(1+sig(i))-ierfc
            u(i) = u(i) + st;
        end
    end
end
figure
hist(u)


%% calculate K from Qp
K = 3/2*pi*(Qp^(2/3)*bB^(1/3))./(g^(1/3)*u.^2.*Sd.^2*Al);

%% calculate Tp
% in hours!
Tp = (3/2*sqrt(6*pi)*sqrt(Al))./(3600*sqrt(g)*sqrt(K).*u.*Sd*sqrt(bB));
Community
  • 1
  • 1
TheodorBecker
  • 249
  • 1
  • 17
  • Using vpa this way will first evaluate value inside parenthesis with double precision, so there will be no profit of using vpa(). See MATLAB's help for explanation, and info how to use symbolic numbers with vpa. Still, the differences are so small that I would rather worry about input data precision as @CST-link wrote :) – Paweł Bulwan Apr 28 '13 at 11:49

1 Answers1

3

I ran this test that uses only your vector quantities:

Sd = [                    ...
        749.158805838953  ...
        848.621203222693  ...
        282.57250570754   ...
        1.69002068665559  ...
        529.068503515487
];

u = [                     ...
        0.308500000000039 ...
        0.291030000000031 ...
        0.38996000000005  ...
        0.99272999999926  ...
        0.271120000000031 ...
];

K = [                         ...
        3.80976148470781e-009 ...
        3.33620420353532e-009 ...
        1.67593037457502e-008 ...
        7.22952172629158e-005 ...
        9.89028880679124e-009 ...
];

r = sqrt(K).*u.*Sd;
min_r = min(r);
max_r = max(r);
disp(min_r);
disp(max_r - min_r);

And I got this result:

0.0143

3.2960e-17

To me this looks like there's no real precision loss, but your vectors are rigged in such a way that they will return approximately the same values. I mean, when the value is of order of magnitude 10^−2, errors of order of magnitude 10^−17 are fairly small, near the representation precision of doubles (16 decimal digits). And the double floating point precision losses should be far less a concern compared to, for example, precision loss when converting to/from decimal representation. So the questions are: 1) are your data sources reliable and/or precise? 2) are you sure that the element-wise product of the three vectors shouldn't return a uniform-value vector?

LaterEdit

We show only the vector dependency and ignore the scalars, because they contribute to all vector components by the same factor. We'll use '~' to express proportionality between vector components. Then, according to your formulas:

Ki ~ ui−2 × Sdi−2

Tpi ~ Ki−1/2 × ui−1 × Sdi−1

By plugging the first formula into the second, one gets:

Tpi ~ (ui−2 × Sdi−2)−1/2 × ui−1 × Sdi−1

or, after some trivial algebraic manipulation:

Tpi ~ ui(−2×−1/2) × Sdi(−2×−1/2) × ui−1 × Sdi−1

Tpi ~ ui × Sdi × ui−1 × Sdi−1

Tpi ~ 1i

So, yes, your resulting vector Tp is supposed to have all the components with the same value; this is not the result of an accident or a precision limitation. This is because the way you compute either K, or Tp, or both.

  • As I am not a native speaker, could you please rephrase what you mean by rigged? They do return the exactly the same values! 0.0143 for r in your formula! Does the fact that max_r-min_r does not return zero display the fact that the values within r DO vary or is this now just a case of precision loss, wenn subracting numbers this similar? To explain my problem a little further: These values are an excerpt of a monte carlo analysis. Sd are n normally distributed values, u and K are calculated using Sd. So do I trust these values? No! I just want to run the script to see maximum changes in Tp – TheodorBecker Apr 28 '13 at 17:34
  • @TheodorBecker: "rigged" as in "specially set up" (not a native english speaker either). And, because one of the factors is random, it doesn't mean that the result is random. If *a* is random, then *b* = 1 / *a* is also random, but *ab* is not random anymore. That's why I was asking the question no. 2. Maybe you post the formulas that you use, and we see that instead of guessing it. If you cannot do this, then all I can advice is to transform your formula into a Taylor series expanded in terms of `Sd` and see the contribution of linear, quadratic etc. terms compared to the constant term. –  Apr 28 '13 at 18:22
  • @CST-Link: I added more code in my first post. Maybe this helps to clearify my issue. Maybe I did not understand your 2nd question correctly. What do you mean by uniform-value vector? Most values of my calculation, like Qp, Al, bB are given and set, some I only now with some uncertainty. Therefore, I wanted to address this with a uniform distribution (r,s) to calculate Rd, Sd, respectively and to get a sensitivity analysis for changes of Tp with r and s. – TheodorBecker Apr 28 '13 at 18:37
  • @TheodorBecker: "uniform-value vector" in my post meant "vector with the same value for all components" (nothing to do with uniform distribution for random variables.) I'm looking at your code now... be back with comments if I have something pertinent. –  Apr 28 '13 at 18:46
  • @TheodorBecker: Hi, I have edited my comment to take in account your new input. Apparently this is not a mistake of the machine or a limitation in the precision. The values are supposed to be equal. The **fluctuations** around the "true" value **are** instead due to precision limitations. –  Apr 28 '13 at 19:30
  • Very true. Don't know how to manage to miss this. Checked it again in the original paper and you are absolutely right. Unfortunately there is no other way of calculating K, so looks like I have to live with this result and won't be able to run a monte carlo analysis with r & s randomized. Thank you very much! – TheodorBecker Apr 29 '13 at 08:09
  • @TheodorBecker: Glad I could help. :-) –  Apr 29 '13 at 17:54