Finding the Associated Eigenvector in Matlab - matlab

For this problem, I think I got most of code correct. However, the correct eigenvector contains the negative values of what I have.
The instructions:
My code:
clear all; close all;
M = [0 1/4 1/4 0 0 0 0 0 0 0;
1/2 0 1/4 1/4 1/6 0 0 0 0 0;
1/2 1/4 0 0 1/6 1/4 0 0 0 0;
0 1/4 0 0 1/6 0 1/2 1/4 0 0;
0 1/4 1/4 1/4 0 1/4 0 1/4 1/4 0;
0 0 1/4 0 1/6 0 0 0 1/4 1/2;
0 0 0 1/4 0 0 0 1/4 0 0;
0 0 0 1/4 1/6 0 1/2 0 1/4 0;
0 0 0 0 1/6 1/4 0 1/4 0 1/2;
0 0 0 0 0 1/4 0 0 1/4 0];
[Y, Z] = eig(M) % pull the first column of T
A8 = Y(:,1) % P
M*A8 % check
save ('A8.dat', 'A8', '-ascii')
I use,
[Y, Z] = eig(M)
to find the associated eigenvalue of 1 in Z with its associated eigenvector from Y. This yields P (or A8) to be:
0.1667
0.3333
0.3333
0.3333
0.5000
0.3333
0.1667
0.3333
0.3333
0.1667
And when I multiply M by P, I get P, which checks out. Apparently the proper values should be negative values of what I got. Can someone clarify?

This behaviour is correct. To understand the reason, we need to look at the definition of eigenvectors (source: wikipedia):
An eigenvector or characteristic vector of a square matrix A is a non-zero vector v that, when multiplied with A, yields a scalar multiple of itself. [...] That is: Av = nv.
where v is the eigenvector and n is the corresponding eigenvalue.
As these are linear operations, A*(kv)=n*(kv) for any non-zero, scalar k. That means, an eigenvector multiplied by a factor k will be another eigenvector to the corresponding eigenvalue.
Matlab outputs normalized eigenvectors, i.e. their length (norm(A8)) equals 1. But still, both the positive and the negative version are eigenvectors of M. You can verify this by creating the negative version of your result and multiplying it with P, which will again give you the negative version of your result.

Related

How does a smaller surface squares in matlab

I want to make the grid of the smaller mesh, some idea of how it is done?
That is to say something like that the path in the x-axis and y are 0.25 in 0.25,
x = (0: 0.25: 7);
y = (0: 0.25: 7);
I've the following matrix. This matrix modeling the dynamic of a population (projection matrix)
L2=[0 0 0 0 127 4 80;
0.6747 0.7370 0 0 0 0 0;
0 0.0486 0.6610 0 0 0 0;
0 0 0.0147 0.6907 0 0 0;
0 0 0 0.0518 0 0 0;
0 0 0 0 0.8091 0 0;
0 0 0 0 0 0.8091 0.8089];
With this code, I find the eingenvectors rigth and left of L2. Likewise I find the sensivity and elasticity matrix.
A=L2;
[W,lambdas]=eig(A);
V=conj(inv(W));
lambdas=diag(lambdas);
[lambdas,I]=sort(lambdas);
lambdas=flipud(lambdas);
lambda1=lambdas(1);
I=flipud(I);
W=W(:,I);
V=V(I,:);
w=W(:,1);
w=w/sum(w);
v=real(V(1,:))';
v=v/v(1);
% matrix of sensitivity
senmat=v*w';
% matrix of elasticity
emat=senmat.*A/max(eig(A));
Then, I make a surface of sensivity matrix.
surf(senmat)
This is the result:
I need to make the squares (grid) of the surface smaller.
any ideas?
best regards!
YOu can use interp2 if you have (x,y) which are defined for senmat. Read about interp2. If you want only senmat to refine use imresize.
A = imresize(senmat,[100,100]) ;
surf(A)

Vector to matrix with row sum 1

I have a logical 1-by-n vector with sum m. Now, I need to convert it into a matrix m-by-n in a way that the row sum is equal 1.
vector (1-by-8) with sum 4
[0 1 0 0 1 0 1 1]
matrix (4-by-8) with row sum 1
[0 1 0 0 0 0 0 0;
0 0 0 0 1 0 0 0;
0 0 0 0 0 0 1 0;
0 0 0 0 0 0 0 1]
Is there a mathematically efficient way without calculating the sum, creating a empty matrix, loop through the vector and adding the 1s row by row?
I think that in that case, given your input, you don't even need to calculate the sum.
You can define an identity matrix of size n, then use your input vector to sample the required rows out of it:
I = eye(n);
y = I(x, :) ; % Output Matrix. x is the input vector
Here's another method, using sparse:
matrix = full(sparse(1:m, find(vector), 1, m, n));

Proof of eigenvector and eigenvalues Matlab

I am finding the eigenvector and eigenvalues of a matrix, then I need to prove that Ax= λx where λ is the eigenvalue. Here is my code:
A = [1 1 -1;1 0 -2; 0 0 -1]
[evecs,evals]=eig(A)
for i = 1:3
A*evecs(:,i)== evals(i,i)*evecs(:,i)
end
Here is my output:
A =
1 1 -1
1 0 -2
0 0 -1
evecs =
0.8507 -0.5257 -0.3015
0.5257 0.8507 0.9045
0 0 0.3015
evals =
1.6180 0 0
0 -0.6180 0
0 0 -1.0000
ans =
0
0
1
ans =
0
1
1
ans =
0
0
1
Why are the ans not all equal to 1 as it should (in order to prove Ax= λx)
The calculations of your eigen solver are performed using finite precision floating point arithmetic. The true eigen values and eigen vectors are not even exactly representable in finite floating point data types.
Check for equality against a small tolerance to allow for this. That is check that Ax - λx is small in absolute value.
Required reading is What Every Computer Scientist Should Know About Floating-Point Arithmetic.

index exceeding matrix dimentions

I was trying to get this low order recursive function in matlab. i want to calculate the probability of status of a site at next time step, given that I have the initial probability of that being a status.
P= Probability
x= status(0,1)
Dij= probability to pick a site
P(Status of Site(i) being x at next time step)= Summation[P(Status of Site(i) being x at previous time step)*Dij]
and this is what I have done! but my index always exceeds matrix dimensions! I need help with this.
clear all;
clc;
%function [t,i]= CopyingInfluenceModel
%%Define constants
%% generate some random weights vectori.e. the transition matrix=C
% C=[0 (1,2) 0 (1,4) 0 0 0;
% (2,1) 0 (2,3) 0 0 0 0;
% 0 (3,2) 0 (3,4) 0 0 0;
% (1,4) 0 (4,3) 0 (4,5) 0 0;
% 0 0 0 (5,4) 0 (5,6) (5,7);
% 0 0 0 0 (6,5) 0 (6,7);
% 0 0 0 0 (7,5) (7,6) 0];
%copying probabilities=branch weights
onetwo=0.47;
twothree=0.47;
threefour=0.47;
onefour=0.47;
fourfive=0.023;
fivesix=0.47;
fiveseven=0.47;
sixseven=0.47;
selfweight1=0.06;
selfweight2=0.037;
% SourceNodes - a list of Nodes that are forced to be kept in one side of the cut.
% WeightedGraph - symetric matrix of edge weights. Wi,j is the edge
% connecting Nodes i,j use Wi,j=0 or Wi,j == inf to indicate unconnected Nodes
WeightedGraph=[0 onetwo 0 onefour 0 0 0;
onetwo 0 twothree 0 0 0 0;
0 twothree 0 threefour 0 0 0;
onefour 0 threefour 0 fourfive 0 0;
0 0 0 fourfive 0 fivesix fiveseven;
0 0 0 0 fivesix 0 sixseven;
0 0 0 0 fiveseven sixseven 0];
Dij=sparse(WeightedGraph);
% Initializing the variables
t=[];
i=[];
%assigining the initial conditions
t(1)=0;
p(1)= 0.003; %% initial probability of status
%set index no i to 1(initial condition for i=1)
i=1;
%repeating calculating new probabilities
%% If the probability is zero, terminate while loop
while p(i)>=0
%calculate at the next time step for given index no
t(i+1)= t(i);
%calculate the status_probability at given time t=(i+1)
[p(i+1)]=[p(i)]+sum([p(i)]*[Dij(i)]);
[NextStatus(i)]= [p(i+1)]
%index i increases by 1 to calculate next probability
i=i+1;
end
Stack Trace is:
%%??? Index exceeds matrix dimensions.
%%Error in ==> CopyingInfluenceModel at 54
%%[p(i+1)]=[p(i)]+sum([p(i)]*[Dij(i)]);
The problem is Dij not p. Dij has a fixed length so when i exceeds that the program throws an error.
Added:
I can't really see your logic in the code, but I have a strong feeling that you are calculating something wrong. Dij is a 7 x 7 matrix but you treat it as a vector by calling Dij(i). If you are trying to multiply something by a row or column, you need the Dij(i,:) or Dij(:, i) notation.
The logic as you posted it doesn't work, essentially, p(i+i) isn't defined yet. There are a few ways to do it, depending on if you want to keep p or not. I'll post a method that keeps p around, but some work could be done to make the code more efficient.
p=[p;p(i)+sum(p(i)*Dij(i))];
NextStatus(i)= p(i+1)

Creating an m by n matrix of 0s and 1s from m-sized vector of column indexes

I have a m-dimensional vector of integers ranging from 1 to n. These integers are column indexes for m × n matrix.
I want to create a m × n matrix of 0s and 1s, where in m-th row there's a 1 in the column that is specified by m-th value in my vector.
Example:
% my vector (3-dimensional, values from 1 to 4):
v = [4;
1;
2];
% corresponding 3 × 4 matrix
M = [0 0 0 1;
1 0 0 0;
0 1 0 0];
Is this possible without a for-loop?
Of course, that's why they invented sparse matrices:
>> M = sparse(1:length(v),v,ones(length(v),1))
M =
(2,1) 1
(3,2) 1
(1,4) 1
which you can convert to a full matrix if you want with full:
>> full(M)
ans =
0 0 0 1
1 0 0 0
0 1 0 0
Or without sparse matrix:
>> M = zeros(max(v),length(v));
>> M(v'+[0:size(M,2)-1]*size(M,1)) = 1;
>> M = M'
M =
0 0 0 1
1 0 0 0
0 1 0 0
Transposition is used because in matlab arrays are addressed by columns
In Octave, at least as of 3.6.3, you can do this easily using broadcasting:
M = v==1:4