Value of variable in matlab - matlab

How can i use this recipe for delete row of matrix?
A= [1 2 3 4;5 6 7 8;9 0 1 2;3 4 5 6]
for delete row:
B = A(2,:) = []
I need to delete row and putting up to B.

This is a way for delete row of A without change A:
A = [1 2 3 4;5 6 7 8;9 0 1 2;3 4 5 6]
B = A;
B(2,:) = [];
Result: B = [1 2 3 4;9 0 1 2;3 4 5 6]

Related

union of two matrices with their common attribute added together in matlab

I have two structure and I'd like to have union of two matrices while the third row is added according to the common first two rows, the result is order-insensitive with respect to the first tow rows and duplicate values are avoided. i.e.
% struct1
row1 = [1 1 1 2 4 3];
col1 = [1 2 3 1 2 4];
att1 = [2 3 4 6 2 5];
% struct2
row2 = [2 2 1 3 3];
col2 = [1 2 3 1 4];
att2 = [1 0 1 1 5];
% result
resultRow = [1 1 1 2 2 3]
resultCol = [1 2 3 2 4 4]
resultAtt = [2 10 6 0 2 10]
I have the previously asked the intersection of two structure but it seems accumarray works for rows not matrices. Any help is appreciated.
Based on the solution to intersection part of this question, I think we can proceed as follows:
% struct1
row1 = [1 1 1 2 4 3];
col1 = [1 2 3 1 2 4];
att1 = [2 3 4 6 2 5];
% struct2
row2 = [2 2 1 3 3];
col2 = [1 2 3 1 4];
att2 = [1 0 1 1 5];
% sort in 2nd dimension to get row-column indexes insensitive for order
idx1 = sort([row1(:) col1(:)],2);
idx2 = sort([row2(:) col2(:)],2);
%find union
[idx,~,bins] = unique([idx1;idx2],'rows','stable');
att = accumarray(bins,[att1,att2]);
ResultUnion= [idx att]';
disp(ResultUnion)
and you get
ResultUnion =
1 1 1 2 3 2
1 2 3 4 4 2
2 10 6 2 10 0

Replace one element of a column in another

Let A and B be column vectors:
A = (1:6).'; %'// [1;2;3;4;5;6]
B = (7:12).'; %'// [7;8;9;10;11;12]
How do I construct a matrix such that one element of A is replaced each time by an element from B to get C as:
C = [...
7 1 1 1 1 1
2 8 2 2 2 2
3 3 9 3 3 3
4 4 4 10 4 4
5 5 5 5 11 5
6 6 6 6 6 12];
If C is to be indexed as index = [1 1 1 2 2 3 3]', how is it possible to produce
c1 = [...
1 7 1 1
1 2 8 2
1 3 3 9];
c2 = [...
2 10 4
2 5 11];
c3 = [3 6]; %// either this
c3 = [3 12]; %// or this
Problem #1:
C = bsxfun(#plus,A.',-diag(A)+diag(B));
gives:
7 2 3 4 5 6
1 8 3 4 5 6
1 2 9 4 5 6
1 2 3 10 5 6
1 2 3 4 11 6
1 2 3 4 5 12
Problem #2:
As far as I understand, you want to extract blocks out of the previously found C matrix, in the following fashion:
Where c1, c2, c3 are the green, red and blue blocks, repectively; and "missing" elements are replaced with NaN (in the initial version of your question).
index = [1 1 1 2 2 3 3]; %// Block definition
[blkSz,~] = histcounts(index,numel(unique(index))); %// Conversion...
paddedC = padarray(C,numel(index)-numel(diag(C))*[1 1],NaN,'post');
blocks = mat2cell(paddedC,blkSz,blkSz);
This results in a cell-array blocks with the following contents:
blocks =
[3x3 double] [3x2 double] [3x2 double]
[2x3 double] [2x2 double] [2x2 double]
[2x3 double] [2x2 double] [2x2 double]
Where for example blocks{1,1} is:
ans =
7 2 3
1 8 3
1 2 9
Then you can pad the array using the index of the loop, to get the c cell, like so:
c = cell(numel(blkSz),1); %// Preallocation
for ind1 = 1:numel(blkSz)
c{ind1} = padarray(blocks{ind1,ind1},1,ind1,'pre');
end
Note that c1 is found in c{1} etc.
Addition:
In the case when you don't want c1...c3 to be (possibly) padded with NaNs, the best way in my opinion would be trimming the index vector to the length of A or B ("length(C)"). This ensures you won't access blocks outside your square matrix. For example:
newIdx = index(1:numel(A));
Then just use newIdx instead of index in the rest of the code.

break a matrix to sub-matrices with equal 2nd column without using for loop

I have a matrix, L, with two columns. I want to find its sub-matrices have equal values on their 2nd column. I want to do that using MATLAB without any for loop.
example:
L=[1 2;3 2;4 6;5 3;7 3;1 3;2 7;9 7]
then the sub-matrices are:
[1 2;3 2] , [4 6] , [5 3;7 3;1 3] and [2 7;9 7]
You can use a combination of arrayfun + unique to get that -
[~,~,labels] = unique(L(:,2),'stable')
idx = arrayfun(#(x) L(labels==x,:),1:max(labels),'Uniform',0)
Display output -
>> celldisp(idx)
idx{1} =
1 2
3 2
idx{2} =
4 6
idx{3} =
5 3
7 3
1 3
idx{4} =
2 7
9 7
You can use accumarray directly or with a sorted array, depending on you want the order of the rows to be stable, or the order of the submatricxes to be stable.
Say you want the rows to be stable:
>> [L2s,inds] = sort(L(:,2));
>> M = accumarray(L2s,inds,[],#(v){L(v,:)});
>> M(cellfun(#isempty,M)) = []; % remove empty cells
>> celldisp(M)
M{1} =
1 2
3 2
M{2} =
5 3
7 3
1 3
M{3} =
4 6
M{4} =
2 7
9 7

Ismember by row in MATLAB

I'm trying to figure out a matrix-oriented way to perform the ismember function by row in MATLAB. That is, if I have matrices
[1 2 3 4 5 6]
[7 8 9 10 11 12]
And I put in
[3 4 5]
[10 11 12]
Into some ismember-ish function, I'd like it to return
[0 0 1 1 1 0]
[0 0 0 1 1 1]
Other than looping over each row of the matrix in a for loop, is there a way to do this?
Assuming that your data are available as matrices A and B
A = [
1 2 3 4 5 6
7 8 9 10 11 12
];
B = [
3 4 5
10 11 12];
you can convert them to cells and then use cellfun
cellA = mat2cell(A, ones(1, size(A,1)), size(A,2));
cellB = mat2cell(B, ones(1, size(B,1)), size(B,2));
membership = cell2mat(cellfun(#ismember, cellA, cellB, 'UniformOutput', false));
This returns
membership =
0 0 1 1 1 0
0 0 0 1 1 1
A = [5 3 4 2]; B = [2 4 4 4 6 8];
[Lia1,Locb1] = ismember(A,B)
Lia1 =
1 1 1 1 0 0
Locb1 =
4 3 3 3 0 0

How do I convert a 2X2 matrix to 4X4 matrix in MATLAB?

I need some help in converting a 2X2 matrix to a 4X4 matrix in the following manner:
A = [2 6;
8 4]
should become:
B = [2 2 6 6;
2 2 6 6;
8 8 4 4;
8 8 4 4]
How would I do this?
In newer versions of MATLAB (R2015a and later) the easiest way to do this is using the repelem function:
B = repelem(A, 2, 2);
For older versions, a short alternative to the other (largely) indexing-based solutions is to use the functions kron and ones:
>> A = [2 6; 8 4];
>> B = kron(A, ones(2))
B =
2 2 6 6
2 2 6 6
8 8 4 4
8 8 4 4
Can be done even easier than Jason's solution:
B = A([1 1 2 2], :); % replicate the rows
B = B(:, [1 1 2 2]); % replicate the columns
Here's one more solution:
A = [2 6; 8 4];
B = A( ceil( 0.5:0.5:end ), ceil( 0.5:0.5:end ) );
which uses indexing to do everything and doesn't rely on the size or shape of A.
This works:
A = [2 6; 8 4];
[X,Y] = meshgrid(1:2);
[XI,YI] = meshgrid(0.5:0.5:2);
B = interp2(X,Y,A,XI,YI,'nearest');
This is just two-dimensional nearest-neighbor interpolation of A(x,y) from x,y ∈ {1,2} to x,y ∈ {0.5, 1, 1.5, 2}.
Edit: Springboarding off of Jason S and Martijn's solutions, I think this is probably the shortest and clearest solution:
A = [2 6; 8 4];
B = A([1 1 2 2], [1 1 2 2]);
A = [2 6; 8 4];
% arbitrary 2x2 input matrix
B = repmat(A,2,2);
% replicates rows & columns but not in the way you want
B = B([1 3 2 4], :);
% swaps rows 2 and 3
B = B(:, [1 3 2 4]);
% swaps columns 2 and 3, and you're done!
Here's a method based on simple indexing that works for an arbitrary matrix. We want each element to be expanded to an MxN submatrix:
A(repmat(1:end,[M 1]),repmat(1:end,[N 1]))
Example:
>> A=reshape(1:6,[2,3])
A =
1 3 5
2 4 6
>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))
ans =
1 1 1 1 3 3 3 3 5 5 5 5
1 1 1 1 3 3 3 3 5 5 5 5
1 1 1 1 3 3 3 3 5 5 5 5
2 2 2 2 4 4 4 4 6 6 6 6
2 2 2 2 4 4 4 4 6 6 6 6
2 2 2 2 4 4 4 4 6 6 6 6
To see how the method works, let's take a closer look at the indexing. We start with a simple row vector of consecutive numbers
>> m=3; 1:m
ans =
1 2 3
Next, we extend it to a matrix, by repeating it M times in the first dimension
>> M=4; I=repmat(1:m,[M 1])
I =
1 2 3
1 2 3
1 2 3
1 2 3
If we use a matrix to index an array, then the matrix elements are used consecutively in the standard Matlab order:
>> I(:)
ans =
1
1
1
1
2
2
2
2
3
3
3
3
Finally, when indexing an array, the 'end' keyword evaluates to the size of the array in the corresponding dimension. As a result, in the example the following are equivalent:
>> A(repmat(1:end,[3 1]),repmat(1:end,[4 1]))
>> A(repmat(1:2,[3 1]),repmat(1:3,[4 1]))
>> A(repmat([1 2],[3 1]),repmat([1 2 3],[4 1]))
>> A([1 2;1 2;1 2],[1 2 3;1 2 3;1 2 3;1 2 3])
>> A([1 1 1 2 2 2],[1 1 1 1 2 2 2 2 3 3 3 3])
There is a Reshape() function that allows you to do this...
For example:
reshape(array, [64, 16])
And you can find a great video tutorial here
Cheers