Changing the size of a matrix in MATLAB - matlab

I am given the following matrices A of size 3x1 and B of size 5x1
A = B=
1 A
2 B
3 C
D
E
I want to convert matrix C in a 15x2 matrix
C =
1 A
1 B
1 C
1 D
1 E
2 A
.
.
.
3 E
How can I make it?

Can be done with repmat
D = repmat(A',size(B,1),1);
C = [D(:),repmat(B,size(A,1),1)]

Here's a different alternative based on code for generating truth tables from Generate All Possible combinations of a Matrix in Matlab
ind = dec2base(0:power(5,2)-1,5)-47;
C = [A(ind(1:15,1) + 48, B(ind(1:15,2)];
And if you want to generalize it
m = max(size(A,1),size(B,1));
n = size(A,1)*size(B,1);
col = 2;
ind = dec2base(0:power(n,col)-1,n)-47;
ind = ind(1:n,:);
C = [A(ind(:,1) + 48, B(ind(:,2)];
The + 48 is just to convert your A matrix from a numerical matrix to a char matrix so that C can hold both number and letters. You can leave it out if A was already a char matrix.
What's useful about this technique is that by changing col, this generalizes to combing more than just 2 vectors in a similar fashion

Related

Permuting columns of a matrix in MATLAB

Say I have an n by d matrix A and I want to permute the entries of some columns. To do this, I compute permutations of 1 ... n as
idx1 = randperm(n)'
idx2 = randperm(n)'
Then I could do:
A(:,1) = A(idx1,1)
A(:,2) = A(idx2,2)
However, I dont want to do this using a for-loop, as it'll be slow. Say I have an n by d matrix A and an n by d index matrix IDX that specifies the permutations, is there a quicker equivalent of the following for-loop:
for i = 1:d
A(:,i) = A(IDX(:,i),i);
end
Using linear-indexing with the help of bsxfun -
[n,m] = size(A);
newA = A(bsxfun(#plus,IDX,[0:m-1]*n))
I guess another rather stupid way to do it is with cellfun, stupid because you have to convert it into a cell and then convert it back, but it is there anyways.
N=ones(d,1)*n; %//create a vector of d length with each element = n
M=num2cell(N); %//convert it into a cell
P=cellfun(#randperm, M,'uni',0); %//cellfun applys randperm to each cell
res = cell2mat(P); %//Convert result back into a matrix (since results are numeric).
This also allows randperm of type Char and String, but the cell2mat will not work for those cases, results are in Cell Array format instead.
for d = 5, n = 3:
>> res =
1 3 2
1 2 3
2 3 1
3 1 2
3 2 1

How to zero out the centre k by k matrix in an input matrix with odd number of columns and rows

I am trying to solve this problem:
Write a function called cancel_middle that takes A, an n-by-m
matrix, as an input where both n and m are odd numbers and k, a positive
odd integer that is smaller than both m and n (the function does not have to
check the input). The function returns the input matrix with its center k-by-k
matrix zeroed out.
Check out the following run:
>> cancel_middle(ones(5),3)
ans =
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
My code works only when k=3. How can I generalize it for all odd values of k? Here's what I have so far:
function test(n,m,k)
A = ones(n,m);
B = zeros(k);
A((end+1)/2,(end+1)/2)=B((end+1)/2,(end+1)/2);
A(((end+1)/2)-1,((end+1)/2)-1)= B(1,1);
A(((end+1)/2)-1,((end+1)/2))= B(1,2);
A(((end+1)/2)-1,((end+1)/2)+1)= B(1,3);
A(((end+1)/2),((end+1)/2)-1)= B(2,1);
A(((end+1)/2),((end+1)/2)+1)= B(2,3);
A(((end+1)/2)+1,((end+1)/2)-1)= B(3,1);
A(((end+1)/2)+1,((end+1)/2))= B(3,2);
A((end+1)/2+1,(end+1)/2+1)=B(3,3)
end
You can simplify your code. Please have a look at
Matrix Indexing in MATLAB. "one or both of the row and column subscripts can be vectors", i.e. you can define a submatrix. Then you simply need to do the indexing correct: as you have odd numbers just subtract m-k and n-k and you have the number of elements left from your old matrix A. If you divide it by 2 you get the padding on the left/right, top/bottom. And another +1/-1 because of Matlab indexing.
% Generate test data
n = 13;
m = 11;
A = reshape( 1:m*n, n, m )
k = 3;
% Do the calculations
start_row = (n-k)/2 + 1
start_col = (m-k)/2 + 1
A( start_row:start_row+k-1, start_col:start_col+k-1 ) = zeros( k )
function b = cancel_middle(a,k)
[n,m] = size(a);
start_row = (n-k)/2 + 1;
start_column = (m-k)/2 + 1;
end_row = (n-k)/2 + k;
end_column = (m-k)/2 + k;
a(start_row:end_row,start_column:end_column) = 0;
b = a;
end
I have made a function in an m file called cancel_middle and it basically converts the central k by k matrix as a zero matrix with the same dimensions i.e. k by k.
the rest of the matrix remains the same. It is a general function and you'll need to give 2 inputs i.e the matrix you want to convert and the order of submatrix, which is k.

How to multiply each row of a matrix by corresponding column of another matrix in matlab?

I have two matrices A and B. A is N-by-L matrix and B is L-by-N matrix.
A = [1 2 3;
4 5 6];
B = [ 7 8;
9 10;
11 12];
I would like to multiply the each row of the first matrix by the corresponding column of the second matrix. After the multiplication I would have a (Nx1) vector. The result would be
C = [ 1*7 + 2*9 + 3*11,
4*8 + 5*10 + 6*12];
I can perform the multiplication with a for loop, but it is not efficient for large matrices.
ASize = size(A);
for i = 1:ASize(1),
C(i) = A(i,:) * B(:,i);
end
Is there a better way to do this?
I think this should do the trick:
C = sum(A.*B', 2);
I think this will work better and is simple
C=diag(A*B);

MATLAB concatenate 2D matrix tiles

I have n2 equally sized (8x8) matrices which I want to tile into a single matrix like in the following diagram:
I know I could concatenate them column by column and then concatenate each row, but I want to know if there's a simpler method to achieve this.
There's a simpler method, you can store all your matrices in a cell array, then reshape and convert back to a matrix:
In the following example, suppose that C is your n2×1 cell array of matrices:
cell2mat(reshape(C, sqrt(numel(C)), []));
The result is a single tiled matrix A as required.
Example
a = ones(2); b = 2 * a; c = 3 * a; d = 4 * a;
C = {a, b, c, d};
A = cell2mat(reshape(C, sqrt(numel(C)), []))
The result is:
A =
1 1 3 3
1 1 3 3
2 2 4 4
2 2 4 4
Note the order of the sub-matrices: they are arranged column-wise. If you want A to be:
A =
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
then you'll have to pass the transposed version of C to reshape:
cell2mat(reshape(C', sqrt(numel(C)), []))
If you already have a for loop where you create the 8-by-8 matrices, you can do something like this:
M = 8; % Rows of each block matrix
N = 8; % Columns of each square block matrix
m = 2; % Number of blocks across
n = 2; % Number of blocks vertically
A(m*n*M,N) = 0; % Preallocate an m*n*M-by-N column of blocks
for i = 1:m*n
a = rand(M,N); % Create your data, just random here
A(1+M*(i-1):M*i,:) = a; % Insert data
end
A = reshape(A,[M*m N*n]); % Reshape to obtain block matrix
This assumes that you have a single for loop iterating over all n^2 (or m*n) cases. Also, it builds up A one column of blocks at a time. Note: if you need to build it with the blocks going across the rows first, then you'll need to change the allocation of A and how the data is inserted by swapping the indices.
Yes there is!
%Assuming your matrices are A1, A2, A3 and A4:
A = zeros(size(A1)*2);
A(1:8,1:8) = A1;
A(9:16, 1:8) = A2;
A(1:8, 9:16) = A3;
A(9:16, 9:16) = A4;

Matlab Generating a Matrix

I am trying to generate a matrix in matlab which I will use to solve a polynomial regression formula.
Here is how I am trying to generate the matrix:
I have an input vector X containing N elements and an integer d. d is the integer to know how many times we will add a new column to the matrix we are trying to generate int he following way.
N = [X^d X^{d-1} ... X^2 X O]
O is a vector of same length as X with all 1's.
Everytime d > 2 it does not work.
Can you see any errors in my code (i am new to matlab):
function [ PR ] = PolyRegress( X, Y, d )
O = ones(length(X), 1)
N = [X O]
for j = 2:d
tmp = power(X, j)
N = [tmp N]
end
%TO DO: compute PR
end
It looks like the matlab function vander already does what you want to do.
The VANDER function will only generate powers of the vector upto d = length(X)-1. For a more general solution, you can use the BSXFUN function (works with any value of d):
N = bsxfun(#power, X(:), d:-1:0)
Example:
>> X = (1:.5:2);
>> d = 5;
>> N = bsxfun(#power, X(:), d:-1:0)
N =
1 1 1 1 1 1
7.5938 5.0625 3.375 2.25 1.5 1
32 16 8 4 2 1
I'm not sure if this is the order you want, but it can be easily reversed: use 0:d instead of d:-1:0...