This question already has answers here:
Construct a matrix from a set of coordinates
(5 answers)
Closed 6 years ago.
For example, I have a matrix like A=[1,2,3,4;5,6,7,8;9,10,11,12]. And two array x=[1,1,3,2] and y = [2,4,3,1], which represent X- and Y-coordinate.
And I want to get 4 elements in the matrix [A(1,2);A(1,4);A(3,3);A(2,1)]. I use this code: result = diag(A(x,y)); Although I get what I want, but if I deal with a large matrix, such code runs too slow for me. Dose someone have a better way?
thanks!
Probably not the faster ones, but following are some approaches to this:
A = [1 2 3 4;
5 6 7 8;
9 10 11 12];
x = [1 1 3 2];
y = [2 4 3 1];
%Approach-1 (Yours approach)
diagonal = diag(A(x,y))
%Approach-2
A1=A(x,y); LowUp=A1(tril(triu(A1))~=0)
%Approach-3
EYE= A1((eye(4,4).*A1)~=0)
%Approach-4
findeye=A1(find(eye(size(A1))))
%Approach-5
subind=A(sub2ind(size(A),x,y)).'
%Approach-6
for i=1:4
loop(i)=A(x(i),y(i));
end
loop=loop.'
You need sub2ind
A = [1,2,3,4;
5,6,7,8;
9,10,11,12];
x = [1,1,3,2];
y = [2,4,3,1];
id = sub2ind(size(A),x,y)
id =
4 10 9 2
A(id)
ans =
2 4 11 5
Related
This question already has answers here:
MATLAB: Duplicate each element of a vector? [closed]
(1 answer)
Element-wise Matrix Replication in MATLAB
(1 answer)
Element-wise array replication in Matlab
(7 answers)
Closed 5 years ago.
I have a vector that has N=1263 entries:
temp=[14, 0.5, ..., 12]
I want to make a vector which repeats entry 1, i.e. 14, 42 times, then entry 2, i.e. 0.5, 42 times and similarly all through the vector. It should produce a vector with size 53046x1.
The following code does the work for a simple case:
F = [1 4 9];
R = [repmat(F(1),[3,1]); repmat(F(2),[3,1]); repmat(F(3),[3,1])]
R = [1 1 1 4 4 4 9 9 9]
but it is cumbersome when N becomes large. Is there a faster way around this?
This is exactly what repelem (introduced in R2015a) is for. For your actual problem, you would use:
R = repelem(temp.',42); %This will repeat each entry of 'temp' 42 times
For the given example,
F = [1 4 9];
R = repelem(F.',3); %This will repeat each entry of 'F' 3 times
You can also do it with this:
R = ones(42,1)*temp;
R = R(:);
Kind of an unusual way of doing this but it works
https://www.mathworks.com/help/matlab/ref/kron.html
All you need to do is include your matrix as well as a ones matrix of the length of the repetition.
R = kron(F(:),ones(42,1));
R = reshape(repmat(F, 42, 1), [], 1);
This question already has answers here:
Element-wise array replication in Matlab
(7 answers)
Closed 6 years ago.
I would appreaciate a lot if you help. I am beginner in programming. I am using Matlab. So, I have an array which is 431x1 type - double; there i have numbers 1 to 6; for ex: 1 4 5 3 2 6 6 3 3 5 4 1 ...; what I want to do is I need to make a new array where I would have each element repeat for 11 times; for ex: a(1:11)=1; a(12:22)=4; a(23:33)=5; or to illustrate differently : a=[1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4...];
I tried doing it in a loop but had some problems, which way could you suggest, do you know any function I could take advantage of?
First of all, it would help if you could format your code is separate blocks to make your question easier to read...
Let's say you had an array of length Nx1 as:
x = [1 2 3 4 5 ...]';
You could construct a loop and concatenate as:
for i = 1 : length(x)
for i = 1: length(x)
y(1 + (i - 1) * 11 : 1 + i * 11) = x(i); % Copy to a moving block
end
y(end) = []; % Delete the superfluous one at the end
You could also look at functions like repmat in the MATLAB help for replicating arrays.
Try this (NRepis how many times you want it repeated):
x = [1, 2, 3, 4, 5];
NRep = 5;
y = reshape(repmat(x,[NRep,1]),[1,length(x)*NRep])
Since it's a little cumbersome to write that out, I also particularly enjoy to use this "hack":
x = [1, 2, 3, 4, 5];
NRep = 5;
y = kron(x, ones(1,NRep));
Hope that helps!
P.S.: This is designed for row vectors only. Though if you need column vectors it's easy to modify.
edit: Of course, if you're post-R2015a you can just use y=repelem(x,NRep). I tend to forget about those because I work on older Matlabs (and sometimes it's not such a bad idea to be a bit backward compatible). Thanks to #rahnema1 for reminding me.
This question already has answers here:
A similar function to R's rep in Matlab [duplicate]
(4 answers)
Closed 7 years ago.
A = [1 4 5 2 1 2]
How could I concisely replicate each element n times whilst maintaining the overall order e.g. if n = 3, the desired result would be:
[1 1 1 4 4 4 5 5 5 2 2 2 1 1 1 2 2 2]
For Matlab R2015a or higher use repelem
n = 3;
u = repelem(A,n)
For older versions use bsxfun
n = 3;
u = bsxfun(#mtimes ,A(:).',ones(n,1))
u = u(:)
You could do the following:
reshape(repmat(a',[3 1]),[],1)
I'm trying to create a script to solve my problem, but I got stuck in one place.
So I have imported .txt file with 4x1 sized matrix (simplified to give an example in my case it might be 1209x1 matrix) which contains some coordinate X. And it's look like this:
0
1
2
3
That's coordinates for one period, and I need to get one column for different number of periods N . Each period is the same and lenght=L
So you can do it manually by this script, for example for N=3 periods:
X=[X; X+L; X+2*L];
so for example if L=3
then i will get
0
1
2
3
3
4
5
6
6
7
8
9
it works well but it's not efficient in case if I need to work with number of periods let's say N=1000 or if I need to change their number quickly. Any solution to parameterize this operation so I can just put number for N and get X for N periods?
Thanks and Regards
I don't have MATLAB on this machine so I can't test, but the most straightforward implementation would be something like:
n = 1000;
L = 3;
nvalues = length(X); % Assuming X is your initial vector
newx = zeros(n*nvalues, 1); % Preallocate new array
for ii = 0:(n-1)
startidx = (nvalues*ii) + 1;
endidx = nvalues*(ii+1);
newx(startidx:endidx) = X + ii*L
end
You can use bsxfun to create X, X+L, X+2*L, ... and then reshape it to a vector
>> F=bsxfun(#plus, X, (0:(N-1))*L)
F =
0 3 6
1 4 7
2 5 8
3 6 9
>> X=F(:)
X =
0
1
2
3
3
4
5
6
6
7
8
9
or in a more concise form:
>> X=reshape(bsxfun(#plus, X, (0:(N-1))*L), [], 1)
X =
0
1
2
3
3
4
5
6
6
7
8
9
This question already has an answer here:
MATLAB: Duplicate each element of a vector? [closed]
(1 answer)
Closed 8 years ago.
It's hard to explain so I will show an example of what I would like to do:
x = [1 2 3 4 5]
I would like the outcome to be:
x = [1 1 2 2 3 3 4 4 5 5]
Preferably without the use of a for loop, but either method would be appreciative.
Thanks.
You can also use the Kronecker tensor product (kron function) which is pretty neat:
x = kron(x,ones(1,2))
x =
1 1 2 2 3 3 4 4 5 5
If you want it sorted as you have here, you could do:
y = sort([x x]);
alternatively if the order matters:
y = reshape([x;x],[1,2*length(x)])