How to create a criss cross diagonal matrix - matlab

How to create a matrix like this
A = [a 0 0 0 0 b;
0 a 0 0 b 0;
0 0 a b 0 0;
0 0 b a 0 0;
0 b 0 0 a 0;
b 0 0 0 0 a]

Perhaps something like this
N = 6; % Size of matrix
a = 1; % Example value
b = 2; % Example value
A = a*eye(N) + b*fliplr(eye(N));
A =
1 0 0 0 0 2
0 1 0 0 2 0
0 0 1 2 0 0
0 0 2 1 0 0
0 2 0 0 1 0
2 0 0 0 0 1

Related

How do I plot the the rows of a matrix as points on a graph?

I am trying to plot a truss bridge with the lines of the bridge showing which forces are present with different colors showing compression and tension. The lines of the bridge are connected by nodes. I based the line width off of the magnitude of the force divided by 1000.
A = [-0.5 1 0 0 0 0 0 0 0 0.5 0 0 0 0 0;
-sqrt(3)/2 0 0 0 0 0 0 0 0 -sqrt(3)/2 0 0 0 0 0;
0 -1 1 0 0 0 0 0 0 0 -0.5 0.5 0 0 0;
0 0 0 0 0 0 0 0 0 0 -sqrt(3)/2 -sqrt(3)/2 0 0 0;
0 0 -1 1 0 0 0 0 0 0 0 0 -0.5 0.5 0;
0 0 0 0 0 0 0 0 0 0 0 0 -sqrt(3)/2 -sqrt(3)/2 0;
0 0 0 -1 0.5 0 0 0 0 0 0 0 0 0 -0.5;
0 0 0 0 -sqrt(3)/2 0 0 0 0 0 0 0 0 0 -sqrt(3)/2;
0 0 0 0 -0.5 -1 0 0 0 0 0 0 0 0 -0.5;
0 0 0 0 0 1 -1 0 0 0 0 0 0 -0.5 0.5;
0 0 0 0 0 0 0 0 0 0 0 0 0 sqrt(3)/2 sqrt(3)/2;
0 0 0 0 0 0 1 -1 0 0 0 -0.5 0.5 0 0;
0 0 0 0 0 0 0 0 0 0 0 sqrt(3)/2 sqrt(3)/2 0 0;
0 0 0 0 0 0 0 1 -1 -0.5 0.5 0 0 0 0;
0 0 0 0 0 0 0 0 0 sqrt(3)/2 sqrt(3)/2 0 0 0 0];
w7 = 800;
w8 = 900;
w9 = 13000;
W = [0; 0; 0; 0; 0; 0; 0; 0; 0; 0; w7; 0; w8; 0; w9];
x = A\W;
nodes = [0 0;
0.5 sqrt(3)/2;
1.5 sqrt(3)/2;
2.5 sqrt(3)/2;
3.5 sqrt(3)/2;
4 0;
3 0;
2 0;
1 0];
beams = [1 2;
2 3;
3 4;
4 5;
5 6;
6 7;
7 8;
8 9;
1 9;
2 9;
3 9;
3 8;
4 8;
4 7;
5 7];
clf; % clear the figure window
set(gcf,'position',[20 50 600 250],'paperpositionmode','auto')
hold on
% Code to plot goes here!
axis equal; % make aspect ratio 1:1
axis([-.5 4.5 -.5 1.5]);
for jj = 1:15
if x(jj,1) > 0
plot(nodes(beams(jj,1:2),1),nodes(beams(jj,1:2),2),'-g','LineWidth',abs(x(jj,1))/1000);
else
plot(nodes(beams(jj,1:2),1),nodes(beams(jj,1:2),2),'-r','LineWidth',abs(x(jj,1))/1000);
end
end
plot(nodes(1:9,1:2),'.k','MarkerSize',80);
print(gcf,'-dpng','truss_bridge_beams.png');
I got the lines to be plotted the way I wanted, but I want to plot the nodes as dots at the row vectors I specified in the nodes matrix. However, when I tried to do that, the dots were scattered across the graph. Can someone help me fix this?
It’s because plot(Y) plots columns of Y against the row index instead of against each other.
plot(nodes(1:9,1), nodes(1:9,2))
should fix the problem.

How do I create random matrix where each column is all zeroes except for one random row?

I want to create a matrix of size m-by-n where all elements in a column are 0 except one element which is 1. That one element must be at a random position.
eg.
[0 1 0 0 0
0 0 1 0 0
1 0 0 1 0
0 0 0 0 0
0 0 0 0 1]
To add some variety, here's another approach:
m = 4;
n = 5;
[~, result] = sort(rand(m,n));
result = double(result==1);
This gives, for example,
result =
0 0 0 0 1
0 1 0 0 0
1 0 0 1 0
0 0 1 0 0
You can also use rand and max to do the job:
m=4;
n=5;
R=rand(m,n);
result = bsxfun(#eq, R, max(R,[],1))
On my machine it gave:
1 1 0 0 0
0 0 0 0 0
0 0 1 0 1
0 0 0 1 0
How it works: Generating a random matrix, R, and then setting to 1 the entry corresponding to the maximal element at each column. No need for sorting.
Regarding the original answer of Divakar, since it uses randperm it is restricted to square matrix only, and it will only produce random permutation matrices.
One possible way to correct his solution is to use randi instead of randperm:
result = bsxfun( #eq, (1:m)', randi(m, 1, n ) )
May give this output:
1 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0 1 0 1 1
As for the answer of bla, using accumarry can save the use of zeros and sub2ind:
m=5; n=10;
R=randi(m,n,1);
A = accumarray( {R, (1:n)' }, 1, [m n] )
May give this output:
0 0 0 0 1 0 0 1 0 0
0 1 0 0 0 0 1 0 1 0
1 0 0 1 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0
Another idea I have is to create the identity matrix of size m x m, then use randi with a range from 1 up to m to create a vector of n elements long. After, you'd use this vector to access the columns of the identity matrix to complete the random matrix you desire:
m = 5; n = 5; %// Given your example
M = eye(m);
out = M(:,randi(m, n, 1));
Here's one possible run of the above code:
out =
1 0 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 0 0 0
0 1 1 0 1
here's an example using randi:
m=5; n=10;
A=zeros(m,n);
R=randi(m,n,1);
A(sub2ind(size(A),R',1:n))=1
A =
0 0 0 0 0 0 0 1 0 1
0 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
1 0 0 0 0 0 1 0 1 0
You can use sparse with randi for a one-liner, like so -
full(sparse(randi(m,1,n),1:n,1,m,n))
Sample run -
>> m = 5; n = 6;
>> full(sparse(randi(m,1,n),1:n,1,m,n))
ans =
0 1 0 0 0 1
0 0 1 1 0 0
0 0 0 0 0 0
1 0 0 0 1 0
0 0 0 0 0 0

Interpolation inside a matrix. Matlab

I have a matrix looks like:
0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0
It is 11x5 matrix.
I want to interpolate between the values vertically for each column.
Any help ?
Thanks.
M =[0 0 0 0 0
1 0 0 0 0
0 2 0 0 0
0 0 2 0 0
0 0 0 1 0
1 0 0 0 1
0 4 0 0 0
0 0 3 0 0
6 0 0 4 0
0 3 0 0 2
0 0 5 0 0];
xi = 1:size(M,1)
for colIdx = 1:size(M,2)
col = M(:,colIdx);
x = xi(~~col); %// Note that ~~col is a logical vector of elements that are not equal to zero. i.e. it's the same as col ~= 0
y = col(~~col);
M(:,colIdx) = interp1(x,y,xi);
end
then if you want the outer points to be 0 add this line after the loop:
M(isnan(M)) = 0;

matlab: how to create matrix by shift vector

I have row and column in matlab:
a = [1 0 3 ... a_k]; - row 1xk
b = [1;0;3; ... b_k]; - column kx1
I want to create new matrix's (A and B) mxn, that can be populate by shift row and column:
A = [1 0 3 0 0 0 0 ... 0;
0 1 0 3 0 0 0 ... 0;
0 0 1 0 3 0 0 ... 0;
...
0 0 0 0 0 0 ... 1 0 3 ]
B= [1 0 0 0 0 0 0 ... 0;
0 1 0 0 0 0 0 ... 0;
3 0 1 0 0 0 0 ... 0;
0 3 0 1 0 0 0 ... 0;
0 0 3 0 1 0 0 ... 0;
...
0 0 0 0 0 0 0 ... 3]
How can I do it?
Is this what you want?
>> a = [1 0 3];
>> m = 5; %// number of rows
>> A = convmtx(a,m)
A =
1 0 3 0 0 0 0
0 1 0 3 0 0 0
0 0 1 0 3 0 0
0 0 0 1 0 3 0
0 0 0 0 1 0 3
>> b = [1;0;3];
>> m = 4; %// number of columns
>> B = convmtx(b,m)
B =
1 0 0 0
0 1 0 0
3 0 1 0
0 3 0 1
0 0 3 0
0 0 0 3
You can do this in a slightly tricky way by using a combination of indexing and bsxfun. First we want to create an index matrix that represents the shift that we're trying to. It should look like this (at least for A):
1 2 3 4 ... k
k 1 2 3 ... k-1
etc
To create this, we can use bsxfun as follows:
index = mod(bsxfun(#plus,1:k,-(1:(k-2))'),k)+1;
We can then create the matrix A by using this as an index matrix for a:
A = a(index);
The matrix B is the same, just transposed:
B = b(index)';

MATLAB one liner for batch assignment in 2D matrix?

Say I have a matrix
A = zeros(5, 5);
Instead of looping with a for loop, I wish to batch-modify some of the elements. For example, I wish to change elements marked by pts_to_modify to 1, where
pts_to_modify=[[2 3]; [3 2]];
So I wish A to become
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
However, when I do
A(pts_to_modify(:, 1), pts_to_modify(:, 2)) = 1,
I get
A =
0 0 0 0 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
How can I do it correctly?
You can use sub2ind:
>> ind = sub2ind(size(A), pts_to_modify(1,:), pts_to_modify(2,:))
ind =
12 8
>> A(ind) = 1
A =
0 0 0 0 0
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
sub2ind
linear indexing