Round number closest to 0 in array
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
I have an array with numbers which are all really small (-9e-07 upto 2e+06). I want to round the values in each column of a 4D array,F, which are the closest to zero, to zero.
採用された回答
Birdman
2017 年 12 月 25 日
[~,idx]=min(abs(a))
a(idx)=0
12 件のコメント
mathman
2017 年 12 月 25 日
I just want to clarify; is the first line there to identify the minimum values of an array 'a' whilst ignoring the sign of each. And the second line replaces the identified elements in the array with 0?
Birdman
2017 年 12 月 25 日
The answer to both question is: Yes. Because at first, you wanted to identify the closest element to zero, which means I have to check the absolute values of the elements. Secondly, I just replaced the value with 0.
mathman
2017 年 12 月 25 日
Thanks for clarifying that. It works perfectly if I first index the array I want to apply it to, if I don't index it however, it doesn't produce the output I'm looking for. I've posted the complete code below if you can make sense of it.
Array 'F', which is a 4D array is where I want to apply the code you've given. If I do: F1 = F(2,2,1,:); then it works as I would like it to. Otherwise it doesn't change any elements of the array 'F'. Sorry if that is unclear, I can try my best to clarify.
%Define grid points for pressure to be calculated at, step size of 0.001m =
%1mm. Choose value of 0.01m = 10mm.
x_g = (0:0.001:x );
y_g = (0:0.001:y);
z_g = (0:0.001:z);
%Define time vector. Pressure will be calculated at every time step.
%Time step: 1e-08s = 10ns
%End time: 1e-06s = 1microsecond
t = (0:10^-8:t2*10^-6);
%Create 4D grid
[X_G, Y_G, Z_G, T_G] = ndgrid(x_g,y_g,z_g,t);
%Obtain values for distances between source and grid points in meters
r = (sqrt(((X_G-xs).^2) +((Y_G-ys).^2)+((Z_G-zs).^2)));
%Populate arrays for speed of cound and initial pressure with size equal
%to T_G to allow matrices to be manipulated
C_G = repmat(c, size(T_G));
p0_G = repmat(p0, size(T_G));
%Determine arrival time (r/c)
G = r ./ C_G;
%Determine values of function within delta function (t-r/c)
F = T_G - G;
[~,idx] = min(abs(F));
F(idx) = 0;
Image Analyst
2017 年 12 月 25 日
編集済み: Image Analyst
2017 年 12 月 25 日
It should work because idx is a linear index, so it doesn't matter what the dimension of the array is. It could be 4-D or any dimension. You shouldn't need to create the F1 variable.
However, in a loop, or if you do it a second time, the min will be zero and the code will just set the zero to zero, not the smallest non-zero number. If you want the smallest non-zero number, first replace zeros with inf before running the code, then set them back to zero afterwards.
Also, we can't run your code because we don't have values for x, y, and z.
mathman
2017 年 12 月 25 日
Yeah that's what I thought, I'm not sure why it isn't working. The input variables are:
x = 0.01
y = 0.01
z = 0.01
t2 = 3
xs = 0
ys = 0
zs = 0
c = 1500
p0 = 1
Specifically, the element at F(2,2,1,95) should be set to 0. Which it does if I index F as above. If I run min(abs(F)) on it's own it gives me the smallest values in each column which is perfect, its just not replacing those values with 0. It's replacing some values in the first column of the 1st page with 0 and seemingly nothing else.
Image Analyst
2017 年 12 月 25 日
birdman wrote the code assuming a vector. For a multi-dimensional array you need to use (:) to turn it into a vector:
[minValue, linearIndexOfMinValue] = min(abs(F(:)));
Unfortunately though, the code still needs to be modified like I said to find the value closest to zero but not zero. As is, with your parameters, the closest index is 1 where F = 0 at that point, so it will just set 0 equal to 0. Can you do this modification?
Ah I see. Do you mean setting the zeros to Inf before indexing and then reverting them?
Assuming that is what you meant, I've done that but it still doesn't seem to work. I've altered the code you posted to be
[minValue, linearIndexOfMinValue] = min(abs(F(:,:,:,:)));
I think that should find the values and positions of the smallest values in each position within F. But again, when replacing them with 0 it just changes the first 5 values of F(:,1,1,1);.
On reading the original question again, I might've been unclear with exactly what I want. I want the values closest to 0 in each column within the 4D array F.
mathman
2017 年 12 月 25 日
I've tried to do it like this:
Z = zeros(size(F));
[~, idx] = min(abs(F(:,:,:,:)));
F(idx) = Z;
But it gives me an error on the final line saying 'In an assignment A(:) = B, the number of elements in A and B must be the same.'
The number of elements in F and Z are the same so I'm not sure what the problem there is.
Image Analyst
2017 年 12 月 25 日
Help us understand what a "column" means in this 4-D array. For example are these RGB images and the 4th dimension is the frame (i.e. time) dimension? And WHY do you want to do this quirky thing?
mathman
2017 年 12 月 25 日
The 4th dimension is time. The other 3 are just points in space. So, a column in this context is just the y-axis and the rows are x-axis and 'pages' are z-axis.
Each element in F is an output of the formula: T-(r/c) where T is the time at each point, r is the distance from a source (in this case:(0,0,0)) and c is the speed of sound.
The formula T-(r/c) is 'contained within' a delta distribution, so it needs to set the output of that to 1 when T = r/c (in other words; when it's 0). The problem is that it never reaches exactly 0 at any point, it just gets super small at some points. Hence the reason I want to find the smallest values and set them to 0.
After that I'll make a logical array,H, to set any values of 0 to 1 and anything else to 0.
Using this logical array ,H, I can then calculate my final array using the delta distribution.
I've tried to explain it as best I can, hopefully it's clear.
I think I understand what's going on now.
So when I do [~, idx] = min(abs(F(:,:,:,:)));
It lists the element positions of each column which is the lowest. Then when I do F(idx) = 0; it replaces the elements identified in 'idx' with 0. But with multi-dimensional array indexing, the elements of F are listed in a column. So idx identifies elements ranging from 1-5. Therefore, when it tries to replace the elements it's just doing elements 1-5 from the WHOLE array expressed as a column. Rather than EACH individual column! I think I've got what the issue is now, I'm not sure how I would solve it yet.
その他の回答 (0 件)
カテゴリ
ヘルプ センター および File Exchange で Common Operations についてさらに検索
参考
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
