Insert zeros into vector [duplicate] - arrays

This question already has answers here:
Inserting variable number of zeros between non-zero elements in a vector in MATLAB
(3 answers)
Closed 7 years ago.
How do I insert 3 zeros in vector a:
a = [1 2 3 4 5 6 7 8 9]
such that vector v is obtained:
v = [1 2 3 0 0 0 4 5 6 0 0 0 7 8 9]
it should be automated such that it can be implemented in a vector with length n.

assuming v does not exist and numel(a) is a multiple of n:
a = 1:9;
n = 3;
v(bsxfun(#plus, (1:n)', 0:2*n:(numel(a)-n)*2)) = a

Related

MATLAB: Remove specific elements from array

Question 1: I have a 1x15 array, comprising of positive integers and negative integers. I wish to implement a MATLAB code which keeps all positive integers and skips the cells with negative contents.
I have tried the following:
X = [1 2 3 4 5 -10 1 -5 4 6 8 9 2 4 -2];
[r c] = size(X);
for i=1:r
for j=1:c
if X(i,j)<0
X(i,j)=X(i,j+1)
end
end
end
The output should be:
X_new = [1 2 3 4 5 1 4 6 8 9 2 4]
How do I do this?
Question 2:
X = [1 2 3 4 5 -10 1 -5 4 6 8 9 2 4 -2]
Y = [5 3 8 9 4 5 6 7 4 7 9 5 2 1 4]
From Question 1,
X_new = [1 2 3 4 5 1 4 6 8 9 2 4]
I need to delete the corresponding values in Y so that:
Y_new = [5 3 8 9 4 6 4 7 9 5 2 1]
How do I perform this?
In MATLAB, manipulating arrays and matrices can be done much easier than for-loop solutions,
in your task, can do find and delete negative value in the array, simply, as follows:
Idx_neg = X < 0; % finding X indices corresponding to negative elements
X ( Idx_neg ) = []; % removing elements using [] operator
Y ( Idx_neg ) = []; % removing corresponding elements in Y array

Equalize to zero a different element of a matrix for each row without loop

I have an IxS matrix called numerateur and I would like to set one element per row to zero. However, the column to which this element belongs changes for each row. I can do it with a loop but would like to use a more efficient method.
You can find my loop below:
choice is an Ix1 vector containing, for each row, the column number of the element I want to set to zero in numerateur.
for i = 1:I
rank1 = choice(i);
numerateur(i,rank1) = 0;
end
You need to convert the column indices to linear indices:
ind = (1:size(numerateur,1)) + (choice(:).'-1)*size(numerateur,1);
numerateur(ind) = 0;
Example:
>> numerateur = randi(9,5,7)
numerateur =
8 7 8 3 2 8 4
7 8 6 3 6 1 3
8 9 5 5 5 9 5
4 4 2 7 4 9 9
1 6 7 3 8 7 9
>> choice = [2; 3; 6; 5; 1];
>> ind = (1:size(numerateur,1)) + (choice(:).'-1)*size(numerateur,1);
>> numerateur(ind) = 0;
>> numerateur
numerateur =
8 0 8 3 2 8 4
7 8 0 3 6 1 3
8 9 5 5 5 0 5
4 4 2 7 0 9 9
0 6 7 3 8 7 9
Use implicit expansion to find logical indices:
numerateur(choice == 1:size(numerator,2)) = 0;
Alternatively you can use sparse matrix to generate logical indices:
numerateur(sparse(1:I,choice,true,I,S)) = 0;

"Logical Indexing with a Smaller Array" in matlab [duplicate]

This question already has an answer here:
Linear indexing, logical indexing, and all that
(1 answer)
Closed 7 years ago.
The matlab help page for matrix indexing says:
Logical Indexing with a Smaller Array
In most cases, the logical indexing array should have the same number
of elements as the array being indexed into, but this is not a
requirement. The indexing array may have smaller (but not larger)
dimensions:
A = [1 2 3;4 5 6;7 8 9]
A =
1 2 3
4 5 6
7 8 9
B = logical([0 1 0; 1 0 1])
B =
0 1 0
1 0 1
isequal(numel(A), numel(B))
ans =
0
A(B)
ans =
4
7
8
What kind of crazy rule is matlab using here?
To understand this behavior, it's necessary to understand how matrices are stored in memory. Matlab stores matrices using column major layout. This means the 2d matrix:
A = 1 2 3
4 5 6
7 8 9
is stored in memory as one dimensional array going down the columns of A:
A = { array = [1 4 7 2 5 8 3 6 9]
n_rows = 3
n_cols = 3 }
The matrix B:
B = 0 1 0
1 0 1
is stored in memory as:
B = { array = [0 1 1 0 0 1]
n_rows = 2
n_cols = 3 }
Let's put the underlying representations next to eachother:
A.array = [1 4 7 2 5 8 3 6 9]
B.array = [0 1 1 0 0 1]
Using logical indexing, A(B) gives you [4, 7, 8] If you think a bit deeper, what's causing the unintuitive result is the combination of: (1) Matlab uses column major layout and (2) the number of columns in A and B are different.
Note: I'm using pseudo code here. A.array isn't valid code etc...
Bonus:
You can see what happens when the reshape command is called. The underlying data array doesn't change, just the n_rows and n_cols associated with the data array.

Replicating each element n times while maintaining original order [duplicate]

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)

Matlab- moving numbers to new row if condition is met

I have a variable like this that is all one row:
1 2 3 4 5 6 7 8 9 2 4 5 6 5
I want to write a for loop that will find where a number is less than the previous one and put the rest of the numbers in a new row, like this
1 2 3 4 5 6 7 8 9
2 4 5 6
5
I have tried this:
test = [1 2 3 4 5 6 7 8 9 2 4 5 6 5];
m = zeros(size(test));
for i=1:numel(test)-1;
for rows=1:size(m,1)
if test(i) > test(i+1);
m(i+1, rows+1) = test(i+1:end)
end % for rows
end % for
But it's clearly not right and just hangs.
Let x be your data vector. What you want can be done quite simply as follows:
ind = [find(diff(x)<0) numel(x)]; %// find ends of increasing subsequences
ind(2:end) = diff(ind); %// compute lengths of those subsequences
y = mat2cell(x, 1, ind); %// split data vector according to those lenghts
This produces the desired result in cell array y. A cell array is used so that each "row" can have a different number of columns.
Example:
x = [1 2 3 4 5 6 7 8 9 2 4 5 6 5];
gives
y{1} =
1 2 3 4 5 6 7 8 9
y{2} =
2 4 5 6
y{3} =
5
If you are looking for a numeric array output, you would need to fill the "gaps" with something and filling with zeros seem like a good option as you seem to be doing in your code as well.
So, here's a bsxfun based approach to achieve the same -
test = [1 2 3 4 5 6 7 8 9 2 4 5 6 5] %// Input
idx = [find(diff(test)<0) numel(test)] %// positions of row shifts
lens = [idx(1) diff(idx)] %// lengths of each row in the proposed output
m = zeros(max(lens),numel(lens)) %// setup output matrix
m(bsxfun(#le,[1:max(lens)]',lens)) = test; %//'# put values from input array
m = m.' %//'# Output that is a transposed version after putting the values
Output -
m =
1 2 3 4 5 6 7 8 9
2 4 5 6 0 0 0 0 0
5 0 0 0 0 0 0 0 0

Resources