Setting a lower bound on the values of an array ( can it be done without a for loop?)
35 ビュー (過去 30 日間)
古いコメントを表示
I have a matrix the values of it are very small, some are so small that they appear as NaN. Is there an efficient way to go through the matrix and whenever a value is so small that its NaN It changes to the smallest number matlab can hold? Moreover, what is the smallest number matlab can hold?
EDIT : Yes I was wrong in what I wrote the values are very small i.e close to zero, so matlab is just calling them zero. I dont want any values to be zero because I want to divide by them later. I wanted to bound the values of my matrix away from zero.
0 件のコメント
採用された回答
John D'Errico
2021 年 10 月 12 日
編集済み: John D'Errico
2021 年 10 月 12 日
Since the question is morphing along, I'll add a second answer to the current question.
You cannot tell MATLAB to automatically never allow a matrix element to become as small as zero.
You CAN test to see if an element has become smaller than some desired value, and then replace it. For example...
format long g
X = [1e-100, 1e-20, 1e-3, 1 10]
X =
1e-100 1e-20 0.001 1 10
minX = 1e-10;
X(X < minX) = minX
X =
1e-10 1e-10 0.001 1 10
The above is trivial to do, thus testing to see if an element is smaller than what I would like, and replacing it with some minimum value.
I could also have just used the max function, thus I might have written:
X = max(X,minX);
0 件のコメント
その他の回答 (1 件)
John D'Errico
2021 年 10 月 12 日
編集済み: John D'Errico
2021 年 10 月 12 日
I'm sorry, but you are simply wrong. When a number is TOO small, it does not turn into a NaN. It turns into either zero, or -inf. Which it is depends on whether you are talking about how near a number is to -infinity or to zero.
For example...
format long g
X = 1;
Y = 1/2;
while X ~= Y
X = Y;
Y = Y/2;
end
[X,Y]
So I kept on dividing by 2, stopping only when an underflow happened, and both values are now zero. Are they EXACTLY zero?
[X,Y] == 0
So yes. They are EXACTLY zero.
There are many computations that will produce a NaN. NaNs are created where a result is indeterminate. For example, there is no way to consistently define the value 0/0 in an intelligent way using limits. So we say that 0/0 is indeterminate.
0/0
SImilarly, we cannot define the ratio of two infinities as anything valid. Nor can we dinfine the difference of two infinities. So we have
inf/inf
inf - inf
You would also guess that things like sin(inf) have no value we could assign. This is because sin(X) is a periodic function, so as we take a limit, we get nothing meaningful.
sin(inf)
But it is NEVER true that a number will be so small as to become NaN.
Could you have a situation where a ratio approaches zero, and then at some point suddenly creates a NaN? Well yes. But this is not because the number was getting too small. For example...
% What is the limit of X/X^2 as X --> inf?
syms X
limit(X/X^2,X,inf)
MATLAB is smart enough to know this limit to be zero. But now try this:
for n = 1:50:1000
X = 10^n;
disp([n,X/X^2])
end
So the ratio becomes smaller and smaller. Eventually, it becomes 0. And then, suddenly, we get a NaN. WHAT HAPPENED? I thought I just said this cannot happen?
In fact, I was correct. What happened was at the point where X overflowed to inf, then X^2 is also inf. Now MATLAB computes inf/inf, and returns a NaN. The problem was NOT that the ratio was too small, but that the numerator AND the denominator were BOTH infinities. And what did I say inf/inf will produce? Correct: NaN.
Similarly, when numbers approach -infinity, they do not suddeny become NaN. Instead, they become -inf at the point of overflow for a double. But never NaN.
Whatever is producing NaNs, this we cannot guess, since you tell us too little information.
You do ask two other questions. Technically, the smallest number representable in MATLAB is realmin/2^52.
realmin
realmin/2^52
realmin/2^53
Below the level of realmin, we wander into the realm of what are called denormalized numbers. And we can go down a little ways until we get to realmin/2^52. Beyond that we just underflow to 0.
Can you search for NaNs, and then replace them with some small number? Of course. But you cannot tell MATLAB to do this automtically with all arrays, as a matter of normal operation.
X = [1 2 NaN inf]
X(isnan(X)) = realmin
The display format shows that third element as 0.000, but it is truly just realmin.
2 件のコメント
Steven Lord
2023 年 1 月 31 日
Technically, the smallest number representable in MATLAB is realmin/2^52.
Technically, that's the smallest positive number. The smallest finite number is -realmax and the smallest number is -Inf.
Another way to write realmin/2^52 is eps(0). This makes sense as eps(0) is the distance from 0 to the next largest number and so 0 + eps(0) is that next largest number.
format longg
x = realmin/2^52
y = eps(0)
z = -realmax
w = -Inf
You can see they (x and y) have the same bit pattern.
format hex
[x; y; z; w]
Checking who's smallest:
w < z % true
z < y % true
x == y % also true
参考
カテゴリ
Help Center および File Exchange で Numeric Types についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!