Stack copies of elements of a vector [duplicate] - arrays

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);

Related

What does Array(True/False Array) does in MATLAB? [duplicate]

This question already has an answer here:
Linear indexing, logical indexing, and all that
(1 answer)
Closed 1 year ago.
I am trying to understand what happens in MATLAB for this certain line of code
good_mintratio=handles.mintratio(handles.good)
handles.good is an array with size (48x60) where all the elements are 1. handles.mintratio is also an array with size (48x60) where it contains floats.
I ran the following simple code to understand what it exactly does but I am not quite sure what is really happening.
For this piece of code,
A = [1,2,3; 4,5,6];
B = [1,1,1; 1,1,1];
C=A(B);
This returns C = [1,1,1;1,1,1]
It seems like C is like B but contains the elements of A where the elements of B is the indexes for A.
A = [1,2,3; 4,5,6];
B = [2,1,1; 1,5,1];
C=A(B);
Like, this will make C = [4,1,1;1,3,1]
But
good_mintratio=handles.mintratio(handles.good)
this forms a colmun with size (2880,1). It seems like all the elements got combined in to a single colmun but not sure why the size changed. Also, if handles.good has some 0's (which means false in MATLAB, right?), would that change the result?
When you use indexing by arrays (As in C = A(B);) there are 2 options:
The array B is based on non logical numbers (Double usually): The output is based on the linear indexing of the array A.
The array B is based on logical elements: The output is a vector of the elements where true was in B.
For example:
clear();
mA = reshape(1:9, 3, 3);
mB = randi([1, 9], 3, 3);
mC = logical(randi([0, 1], 3, 3));
mA(mB)
mA(mC)
Then the output:
ans =
5 9 5
9 8 9
8 7 4
ans =
2
5
8

matlab making repetitions of data from one array into another array [duplicate]

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.

Matlab ,How to get elements in a matrix using two arrays [duplicate]

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

Vectorizing the subtraction of multiple vectors from one individual vector

I am trying to vectorize, or make the following code more efficient:
[Y,k] = min(abs(dxcp-X));
X = dxcp(k);
The objective of the code is to compare a value X to an array of accepted values for x (dxcp) and assign X to the closest value in the array dxcp. For example:
X is equal to 9 and the dxcp array is: [ 1, 2, 3, 6, 10, 20]. The second line would change X to be equal to 10.
I am trying to change my script so that X can be inputted as an array of numbers and was wondering what would be the most efficient way to go about making the above code work for this case. Of course I could use:
for i = 1:numel(X)
[Y,k] = min(abs(dxcp-X(i)));
X(i) = dxcp(k);
end
But I have the feeling that there must be a way to accomplish this more efficiently. Cheers, nzbru.
You need to use bsxfun to extend your case to a vector case.
Code
dxcp = [1 2 3 6 10 20];
X = [2 5 9 18]
abs_diff_vals = abs(bsxfun(#minus,dxcp,X')); %%//'
[~,k] = min(abs_diff_vals,[],2);
X = dxcp(k)
Output
X =
2 5 9 18
X =
2 6 10 20

How would I go about this task- Matlab [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to store value generated from nested for loop in an array, in Matlab?
I have an array of digits. e.g. x = [4,9,8]. I use find(x) to obtain [1,2,3], then find(x)+length(x) to obtain [4,5,6].
I want this(in this case, adding 3 to the array, to make a sequence of 1,2,3 4,5,6 7,8,9...) to go on n number of times, so I require a loop.
Now with the array x, I want to add [4,9,8] to [1,2,3] , which gives [5,11,11].
I have [1,2,3]...[10,11,12]...[n,n+1,n+2] from find(x)+length(x) looped, I want to add elements in x to the elements in corresponding positions, in the array that is going up in three.
So, for example, [4,5,6] 5 is in position 2. x=[4,9,8]. 9 is in position 2 within x. Therefore, I want to add 9 to 5. I want to do this for each element (in this case, each of the three elements). I would add 9 to 11, and 9 to 11 as both numbers are in position '2' in their respective arrays.
I was thinking of using a nested for loop, to take care of the find(x)+length(x). I am just unsure of how to make the 'location additions' happen.
I would then like to store the results of the additions in a separate array.
Thanks in advance for your time and help!
So, we start with
x = [4,9,8]
Let's add [1, 2, 3]
x + [1, 2, 3]
ans =
5 11 11
A more flexible way
x + (1 : length(x))
ans =
5 11 11
If you do not want to start at 1 but at b (say, we add [5, 6, 7] to x):
b = 5;
x + b + (0 : length(x) - 1)
ans =
9 15 15
I think this should get you going and you can add your loop now.
Warning: You have a very strange way of using find(). Just to make sure: find(x) returns the indices of the non-zero entries in x. If all elements of the vector x are non-zero, you have the equality
find(x) == 1 : length(x)
If any element in x is zero, you run into problems, when adding it to find(x):
x = [4, 9, 0, 8];
find(x)
ans =
1 2 4
x + find(x)
Error using +
Matrix dimensions must agree.

Resources