Round number closest to 0 in array
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
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.
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에 대해 자세히 알아보기
참고 항목
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 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)
