I have some variables to find like x= [1x16 (x1,x2,x3,....x16 variables)] with condition that x1+x2+x3+....x16=1. I have also 16x16 matrix Q= [16x16 (real values)].
I need to solve the equation 'x*Q=x' as shown here. How can I solve it in Matlab or in any other language easily?
By transposition, your equation is equivalent to Q'y=1y where y:=x' (a column vector) where Q' is the transpose of Q (matlab notation...) which means that y is an eigenvector associated with eigenvalue 1 for matrix Q'. Such an eigenvector always exists for a Markov matrix. Let s be the sum of the entries of column vector y. Two cases can occur :
either s is not 0 ; then it suffices to divide all coordinates of y by s : we obtain a vector that is still an eigenvector, with a coordinate sum equal to 1.
or s=0 and there is no solution to your problem.
Here is a Matlab program that does the work for a 3 x 3 matrix :
M=[.2 .3 .5
.1 .8 .1
.4 .4 .2]
[P,D]=eig(M')
Y=P(:,3)
M'*Y - Y,% should be 0
Z=Y/sum(Y),%the sum of Z's coordinates is 1
M'*Z-Z,% should be 0
Related
I want to generate 100 different 5 by 5 random matrices using matlab in [0,1] with the following property: Assume that the required matrix is A=[a_{ij}] having the condition a_{ih}+a_{hj}-a_{ij}-0.5=0 (Matrix A is the so-called Fuzzy Preference matrix (i.e.a_{ji}=1-a_{ij} for all i,j), and also consistent). But, I am stuck to write the matlab code. Could anyone help me? Thanks!
Example of such matrix, but not consistent:
A=[.5 .5 .5 .8155 .5 .3423;...
.5 .5 .6577 .8155 .5 .3423;...
.5 .3423 .5 .88662 .75 .3423;...
.1845 .8145 .1338 .5 .25 .25;...
.5 .5 .25 .75 .5 .25;...
.6577 .6577 .6577 .75 .75 .5]
Example of 3 by 3 consistent Fuzzy Preference matrix:
B=[.5 .2 .5;...
.8 .5 .8;...
.5 .2 .5]
To solve this question we need to find solutions to a system of linear equations. The unknowns are the matrix entries, so for an NxN matrix there will be N^2 unknowns. There are N^3 equations since there is an equation for each combination of i, j, and h. This is an overdetermined system, but is consistent, it's easy to see that the constant matrix with all entries 0.5 is a solution.
The system of equations can be written in matrix form, with matrix M defined as follows:
N = 5; % size of resulting matrix
M = zeros(N^3,N^2); % ar = size of matrix A
t = 0;
for i = 1:N
for j = 1:N
for h = 1:N
t = t+1;
M(t,(i-1)*N+h) = M(t,(i-1)*N+h)+1;
M(t,(h-1)*N+j) = M(t,(h-1)*N+j)+1;
M(t,(i-1)*N+j) = M(t,(i-1)*N+j)-1;
end
end
end
The right hand side is a vector of N^3 0.5's. The rank of the matrix appears to be N^2-N+1 (I think this is because the main diagonal of the result must be filled with 0.5, so there are really only N^2-N unknowns). The rank of the augmented system is the same, so we do have an infinite number of solutions, spanning an N-1 dimensional space.
So we can find the solutions as the sum of the vector of 0.5's plus any element of the null space of the matrix.
a = 0.5*ones(N^2,1) % solution to non-homogenous equation
nullspace = null(M) % columns form a basis for the null space
So we can now generate as many solutions as we like by adding multiples of the basis vectors of the null space to a,
s = a+sum(rand(1,N-1).*nullspace,2) % always a solution
The final problem is to sample uniformly from this null space while requiring the all the entries stay within [0,1].
I think it's hard even to say what uniform sampling over this space is, but at least I can generate random elements by the following:
% first check the size of the largest element
% we can't addd/subtract more than 0.5to the homogeneous solution
for p = 1:size(nullspace,2)
mn(p) = 0.5/max(abs(nullspace(:,p)));
end
c = 0;
mat = {};
while c<5 % generate 5 matrices
% a solution is the homogeneous part 0.5*ones(N) plus
% some element of the nullspace sum(rand(1,size(n,2)).*mn.* nullspace,2)
% reshaped to be a square matrix
newM = 0.5*ones(N)+reshape(sum((2*rand(1,size(nullspace,2))-1).*mn.* nullspace,2),N,N)
% make sure the entries are all in [0,1]
if all(newM(:)>=0) && all(newM(:)<=1)
c = c+1;
mat{c} = newM;
end
end
% mat is a cell array of 5 matrices satisfying the condition
I don't have much idea about the distribution of the resulting matrices.
Assume we want to determine the coefficients of a polynomial equation that is approximating the tangent function between 0 to 1, as follow:
-A is m×n vandermonde matrix. The entries are populated using m value between 0 to 11(given as input).
-The corresponding vector b is calculated using tangent function.
-x is calculated by typing x= A\b in MATLAB.
Now, using MATLAB, the computed x are subsittued in Ax. The result is plotted and it is pretty close to tangent function. But if I use polyval function of n−1 degree (in MATLAB) to calculate b, the resulting plot is significantly different from the original b. I cannot understand the reason for such a significant difference between the results of these two methods.
Here is the code:
clear all;
format long;
m = 60;
n = 11;
t = linspace(0,1,m);
A= fliplr(vander(t));
A=A(:,1:n);
b=tan(t');
x= A\b;
y=polyval(x, t);
plot(t,y,'r')
y2= A*x
hold on;
plot(t,y2,'g.');
hold on;
plot(t,tan(t),'--b');
Any insight would be appreciated. Thank you.
After A= fliplr(vander(t)) the A matrix is equal to
1 t(1) t(1)^2 ...
1 t(2) t(2)^2 ...
...
1 t(m) t(m)^2 ...
It is not correct because polyval accepts the coefficients in descending powers. You don't need to flip the columns of A:
A= vander(t);
A= A(:,end-n+1:end);
I have this RGB matrix of a set of different pixels. (N pixels => n rows, RGB => 3 columns). I have to calculate the minimum RGB distance between any two pixels from this matrix. I tried the loop approach, but because the set is too big (let's say N=24000), it looks like it will take forever for the program to finish. Is there another approach? I read about pdist, but the RGB Euclidean distance cannot be used with it.
k=1;
for i = 1:N
for j = 1:N
if (i~=j)
dist_vect(k)=RGB_dist(U(i,1),U(j,1),U(i,2),U(j,2),U(i,3),U(j,3))
k=k+1;
end
end
end
Euclidean distance between two pixels:
So, pdist syntax would be like this: D=pdist2(U,U,#calc_distance());, where U is obtained like this:
rgbImage = imread('peppers.png');
rgb_columns = reshape(rgbImage, [], 3)
[U, m, n] = unique(rgb_columns, 'rows','stable');
But if pdist2 does the loops itself, how should I enter the parameters for my function?
function[distance]=RGB_dist(R1, R2, G1, G2, B1, B2),
where R1,G1,B1,R2,G2,B2 are the components of each pixel.
I made a new function like this:
function[distance]=RGB_dist(x,y)
distance=sqrt(sum(((x-y)*[3;4;2]).^2,2));
end
and I called it D=pdist(U,U,#RGB_dist); and I got 'Error using pdist (line 132)
The 'DISTANCE' argument must be a
string or a function.'
Testing RGB_dist new function alone, with these input set
x=[62,29,64;
63,31,62;
65,29,60;
63,29,62;
63,31,62;];
d=RGB_dist(x,x);
disp(d);
outputs only values of 0.
Contrary to what your post says, you can use the Euclidean distance as part of pdist. You have to specify it as a flag when you call pdist.
The loop you have described above can simply be computed by:
dist_vect = pdist(U, 'euclidean');
This should compute the L2 norm between each unique pair of rows. Seeing that your matrix has a RGB pixel per row, and each column represents a single channel, pdist should totally be fine for your application.
If you want to display this as a distance matrix, where row i and column j corresponds to the distance between a pixel in row i and row j of your matrix U, you can use squareform.
dist_matrix = squareform(dist_vect);
As an additional bonus, if you want to find which two pixels in your matrix share the smallest distance, you can simply do a find search on the lower triangular half of dist_matrix. The diagonals of dist_matrix are going to be all zero as any vector whose distance to itself should be 0. In addition, this matrix is symmetric and so the upper triangular half should be equal to the lower triangular half. Therefore, we can set the diagonal and the upper triangular half to Inf, then search for the minimum for those elements that are remaining. In other words:
indices_to_set = true(size(dist_matrix));
indices_to_set = triu(indices_to_set);
dist_matrix(indices_to_set) = Inf;
[v1,v2] = find(dist_matrix == min(dist_matrix(:)), 1);
v1 and v2 will thus contain the rows of U where those RGB pixels contained the smallest Euclidean distance. Note that we specify the second parameter as 1 as we want to find just one match, as what your post has stated as a requirement. If you wish to find all vectors who match the same distance, simply remove the second parameter 1.
Edit - June 25th, 2014
Seeing as how you want to weight each component of the Euclidean distance, you can define your own custom function to calculate distances between two RGB pixels. As such, instead of specifying euclidean, you can specify your own function which can calculate the distances between two vectors within your matrix by calling pdist like so:
pdist(x, #(XI,XJ) ...);
#(XI,XJ)... is an anonymous function that takes in a vector XI and a matrix XJ. For pdist you need to make sure that the custom distance function takes in XI as a 1 x N vector which is a single row of pixels. XJ is then a M x N matrix that contains multiple rows of pixels. As such, this function needs to return a M x 1 vector of distances. Therefore, we can achieve your weighted Euclidean distance as so:
weights = [3;4;2];
weuc = #(XI, XJ, W) sqrt(bsxfun(#minus, XI, XJ).^2 * W);
dist_matrix = pdist(double(U), #(XI, XJ) weuc(XI, XJ, weights));
bsxfun can handle that nicely as it will replicate XI for as many rows as we need to, and it should compute this single vector with every single element in XJ by subtracting. We thus square each of the differences, weight by weights, then take the square root and sum. Note that I didn't use sum(X,2), but I used vector algebra to compute the sum. If you recall, we are simply computing the dot product between the square distance of each component with a weight. In other words, x^{T}y where x is the square distance of each component and y are the weights for each component. You could do sum(X,2) if you like, but I find this to be more elegant and easy to read... plus it's less code!
Now that I know how you're obtaining U, the type is uint8 so you need to cast the image to double before we do anything. This should achieve your weighted Euclidean distance as we talked about.
As a check, let's put in your matrix in your example, then run it through pdist then squareform
x=[62,29,64;
63,31,62;
65,29,60;
63,29,62;
63,31,62];
weights = [3;4;2];
weuc = #(XI, XJ, W) sqrt(bsxfun(#minus,XI,XJ).^2 * W);
%// Make sure you CAST TO DOUBLE, as your image is uint8
%// We don't have to do it here as x is already a double, but
%// I would like to remind you to do so!
dist_vector = pdist(double(x), #(XI, XJ) weuc(XI, XJ, weights));
dist_matrix = squareform(dist_vector)
dist_matrix =
0 5.1962 7.6811 3.3166 5.1962
5.1962 0 6.0000 4.0000 0
7.6811 6.0000 0 4.4721 6.0000
3.3166 4.0000 4.4721 0 4.0000
5.1962 0 6.0000 4.0000 0
As you can see, the distance between pixels 1 and 2 is 5.1962. To check, sqrt(3*(63-62)^2 + 4*(31-29)^2 + 2*(64-62)^2) = sqrt(3 + 16 + 8) = sqrt(27) = 5.1962. You can do similar checks among elements within this matrix. We can tell that the distance between pixels 5 and 2 is 0 as you have made these rows of pixels the same. Also, the distance between each of themselves is also 0 (along the diagonal). Cool!
according this article
http://www.wseas.us/e-library/conferences/2012/Vouliagmeni/MMAS/MMAS-07.pdf
matrix can be approximated by one rank matrices using tensorial approximation,i know that in matlab kronecker product plays same role as tensorial product,function is kron,now let us suppose that we have following matrix
a=[2 1 3;4 3 5]
a =
2 1 3
4 3 5
SVD of this matrix is
[U E V]=svd(a)
U =
-0.4641 -0.8858
-0.8858 0.4641
E =
7.9764 0 0
0 0.6142 0
V =
-0.5606 0.1382 -0.8165
-0.3913 0.8247 0.4082
-0.7298 -0.5484 0.4082
please help me to implement algorithm with using tensorial approximation reconstructs original matrix in matlab languages,how can i apply tensorial product?like this
X=kron(U(:,1),V(:,1));
or?thanks in advance
I'm not quite sure about the Tensorial interpretation but the closest rank-1 approximation to the matrix is essentially the outer-product of the two dominant singular vectors amplified by the singular value.
In simple words, if [U E V] = svd(X), then the closest rank-1 approximation to X is the outer-product of the first singular vectors multiplied by the first singular value.
In MATLAB, you could do this as:
U(:,1)*E(1,1)*V(:,1)'
Which yields:
ans =
2.0752 1.4487 2.7017
3.9606 2.7649 5.1563
Also, mathematically speaking, the kronecker product of a row vector and a column vector is essentially their outer product. So, you could do the same thing using Kronecker products as:
(kron(U(:,1)',V(:,1))*E(1,1))'
Which yields the same answer.
I have got a problem like A*x=lambda*x, where A is of order d*d, x is of order d*c and lambda is a constant. A and lambda are known and the matrix x is unknown.
Is there any way to solve this problem in matlab?? (Like eigen values but x is a d*c matrix instead of being a vector).
If I've understood you correctly, there will not necessarily be any solutions for x. If A*x=lambda*x, then any column y of x satisfies A*y=lambda*y, so the columns of x are simply eigenvectors of A corresponding to the eigenvalue lambda, and there will only be any solutions if lambda is in fact an eigenvalue.
From the documentation:
[V,D] = eig(A) produces matrices of eigenvalues (D) and eigenvectors
(V) of matrix A, so that A*V = V*D. Matrix D is the canonical form of
A — a diagonal matrix with A's eigenvalues on the main diagonal.
Matrix V is the modal matrix — its columns are the eigenvectors of A.
You can use this to check if lambda is an eigenvalue, and find any corresponding eigenvectors.
You can transform this problem. Write x as vector by by using x(:) (has size d*c x 1). Then A can be rewritten to a d*c x d*c matrix which has c versions of A along the diagonal.
Now it's a simple eigenvalue problem.
Its actually trivial. Your requirement is that A*X = lambda*X, where X is an array. Effectively, look at what happens for a single column of X. If An array X exists, then it is true that
A*X(:,i) = lambda*X(:,i)
And this must be true for the SAME value of lambda for all columns of X. Essentially, this means that X(:,i) is an eigenvector of A, with corresponding eigenvalue lambda. More importantly, it means that EVERY column of X has the same eigenvalue as every other column.
So a trivial solution to this problem is to simply have a matrix X with identical columns, as long as that column is an eigenvector of A. If an eigenvalue has multiplicity greater than one (therefore there are multiple eigenvectors with the same eigenvalue) then the columns of X may be any linear combination of those eigenvectors.
Try it in practice. I'll pick some simple matrix A.
>> A = [2 3;3 2];
>> [V,D] = eig(A)
V =
-0.70711 0.70711
0.70711 0.70711
D =
-1 0
0 5
The second column of V is an eigenvector, with eigenvalue of 5. We can arbitrarily scale an eigenvector by any constant. So now pick the vector vec, and create a matrix with replicated columns.
>> vec = [1;1];
>> A*[vec,vec,vec]
ans =
5 5 5
5 5 5
This should surprise nobody.