سؤال

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));
هل كانت مفيدة؟

المحلول

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top