I'm looking for a way to get the contour of a matlab/numpy submatrix.
For example, if I have :
A=
[x,x,x,x,x,x,x]
[x,x,x,x,x,x,x]
[x,1,2,3,4,x,x]
[x,5,x,x,6,x,x]
[x,7,8,9,10,x,x]
[x,x,x,x,x,x,x]
Is there a way to get [1,2,3,4,6,10,9,8,7,5] faster (ie more readable) than slicing every edge and then concatenating them ?
EDIT :
The problem is that slicing with numpy is bothersome.
For example, let's say I have i0,i1,j0,j1 to identify the submatrix :
I wanted to do :
np._r[A[i0,j0:j1+1],A[i0:i1+1,j1],A[i1,j1:j0-1:-1],A[i1:i0-1:-1,j0]]
But [j1:j0-1:-1] does not work if j0==0, as [j1:-1:-1] returns an empty slice...
EDIT 2 :
The following slice seems to work, I'm not sure it's really good, but I have not manage to do better.
np._r[A[i0,j0:j1+1],A[i0+1:i1+1,j1],(A[i1,j0+1:j1+1])[::-1],(A[i0+1:i1+1,j0])[::-1]]
Still thanks to all those who answered, if you found a better way, do not hesitate to post.
I think this is a good solution:
contour = [A(3,2:5) A(4,5) A(5,5:-1:2) A(4,2)];
here the value of contour will be your array [1,2,3,4,5,6,7,8,9,a]
rows = [2,2,2,2,3,4,4,4,4,3]
cols = [1,2,3,4,4,4,3,2,1,1]
A[rows, cols]
Should return [1,2,3,4,5,6,7,8,9,a] in your case.
Related
I'm looking an efficient way to turn the vector:
[1,1,1,2,3,3,3,4,4,4,5,1]
into a vector of vectors such that:
[[1,2,3,12],[4],[5,6,7],[8,9,10],[11]]
In general:
newVector[i] = indexes of the initial vector that contained i
Preferably in Matlab/Octave but I'm just curious if there is an efficient way of achieving this.
I tried looking it up on google and stack but I have no idea what to call this 'operation' so nothing came up.
There is an easy way to do it using accumarray
A = [1,1,1,2,3,3,3,4,4,4,5,1]
accumarray(A',A',[],#(x){find(ismember(A,x))})
But next time, please show your own attempt in your question
Alternatively (but only if A starts from 1 and doesn't skip any numbers)
accumarray(A', (1:size(A,2))', [], #(x){sort(x)})
I have a 2D matrix ("my_input") and I would like to check if all its values are present in a given list of values (in my case, I want to accept only 0 and 1).
Is there a convenient way to do that ? Here is my "brutal" solution for now :
% exclude cases where values are not only 0 and 1
if ~all(all(ismember(my_input,[0 1])))
return;
end
% rest of the code
It's not very simple to read. Any idea ?
ASantosRibeiro made the best proposal so far (in comments) :
~all(ismember(my_input(:),[0 1]))
Although the question was stupid since I almost had the answer, I hope it will help other people in the future.
In Matlab I'm trying to find points in a 3d matrix whose coordinates are smaller than some function.
If these coordinates are equal to some functions than I can write:
A(some_function1,some_function2,some_function3)=2;
But what if I want to do something like:
A(<some_function1,<some_function2,<some_function3)=2;
This isn't working - so what is the other way of finding such points without using "for" loop? Unfortunately with "for" loop my code takes a lot of time to compute. Thank you for your help!
How about something along the lines of
A( ceil(min(some_function1,size(A,1))),...
ceil(min(some_function2,size(A,2))),...
ceil(min(some_function3,size(A,3))) );
This will cap the indicies to the end of each array dimension
You can just use regular indexing to achieve this:
A(1:floor(some_function1),1:floor(some_function2),1:floor(some_function3)) = 2;
assuming you check / ensure that floor(some_function*) is smaller than the dimensions of A
Try:
A(1:size(A,1)<some_function1, 1:size(A,2)<some_function2, 1:size(A,3)<some_function3) = 2
I hope I got your question correctly.
I need to add a new matrix to a previously existant matrix, but on his dimension coordinate.
I know this is hard to understand, so let's see it on a example:
I've a matrix like this:
480x640x3
And I want to add the following one:
480x640x6
The result has be this: (6+3 = 9)
480x640x9
As you can see it adds but on the 3rd dimension.
For concatenating along higher dimensions, use the function CAT:
newMatrix = cat(3,matrix1,matrix2);
I would say that gnovice's answer is probably the best way to go, but you could do it this way too:
matrix1(:,:,4:9) = matrix2;
Keeping simple, take a matrix of ones i.e.
U_iso = ones(72,37)
and some parameters
ThDeg = 0:5:180;
dtheta = 5*pi/180;
dphi = 5*pi/180;
Th = ThDeg*pi/180;
Now the code is
omega_iso = 0;
for i = 1:72
for j=1:37
omega_iso = omega_iso + U_iso(i,j)*sin(Th(j))*dphi*dtheta;
end
end
and
D_iso = (4 * pi)/omega_iso
This code is fine. It take a matrix with dimension 72*37. The loop is an approximation of the integral which is further divided by 4pi to get ONE value of directivity of antenna.
Now this code gives one value which will be around 1.002.
My problem is I dont need 1 value. I need a 72*37 matrix as my answer where the above integral approximation is implemented on each cell of the 72 * 37 matrix. and thus the Directviity 'D' also results in a matrix of same size with each cell giving the same value.
So all we have to do is instead of getting 1 value, we need value at each cell.
Can anyone please help.
You talk about creating a result that is a function essentially of the elements of U. However, in no place is that code dependent on the elements of U. Look carefully at what you have written. While you do use the variable U_iso, never is any element of U employed anywhere in that code as you have written it.
So while you talk about defining this for a matrix U, that definition is meaningless. So far, it appears that a call to repmat at the very end would create a matrix of the desired size, and clearly that is not what you are looking for.
Perhaps you tried to make the problem simple for ease of explanation. But what you did was to over-simplify, not leaving us with something that even made any sense. Please explain your problem more clearly and show code that is consistent with your explanation, for a better answer than I can provide so far.
(Note: One option MIGHT be to use arrayfun. Or the answer to this question might be more trivial, using simple vectorized operations. I cannot know at this point.)
EDIT:
Your question is still unanswerable. This loop creates a single scalar result, essentially summing over the entire array. You don't say what you mean for the integral to be computed for each element of U_iso, since you are already summing over the entire array. Please learn to be accurate in your questions, otherwise we are just guessing as to what you mean.
My best guess at the moment is that you might wish to compute a cumulative integral, in two dimensions. cumtrapz can help you there, IF that is your goal. But I'm not sure it is your goal, since your explanation is so incomplete.
You say that you wish to get the same value in each cell of the result. If that is what you wish, then a call to repmat at the end will do what you wish.