Generating random weighted adjacency matrix in MATLAB - matlab

I would like to create a random adjacency matrix in MATLAB such that the total sum of weight is equal to the number of edges. Finally find the Laplacian matrix using
L = diag(sum(A)) - A
and then graph it. Is there any way to do so?
Thanks in advance.

An adjacency matrix for an undirected graph is simply a square symmetric matrix.
If you have no constraints on the degree of the nodes only on the weights than I would suggest something like
n ; % number of nodes in the graph
density = 1e-3; % a rough estimate of the amount of edges
A = sprand( n, n, density ); % generate adjacency matrix at random
% normalize weights to sum to num of edges
A = tril( A, -1 );
A = spfun( #(x) x./nnz(A), A );
% make it symmetric (for undirected graph)
A = A + A.';
I have used in this code:
sprand to generate random sparse matrix.
spfun to help normalize the edge weights.
tril to extract only half the matrix.

Related

Eigen faces using PCA

I am trying to implement Principal Component Analysis (PCA) to extract the features from the image in MATLAB. I have implemented the following code.
[Rows, Columns] = size(x); % find size of input matrix
m=mean(x); % find mean of input matrix
y=x-ones(size(x,1),1)*m; % normalise by subtracting mean
c=cov(y); % find covariance matrix
[V,D]=eig(c); % find eigenvectors (V) and eigenvalues (D) of covariance matrix
[D,idx] = sort(diag(D)); % sort eigenvalues in descending order by first diagonalising eigenvalue matrix, idx stores order to use when ordering eigenvectors
D = D(end:-1:1)';
V = V(:,idx(end:-1:1)); % put eigenvectors in order to correspond with eigenvalues
V2d=V(:,1:200); % (significant Principal Components we use, OutputSize is input variable)
prefinal=V2d'*y';
final=prefinal'; % final is normalised data projected onto eigenspace
imshow(final);
I want to know that how can I check the 1st Eigen faces,2nd Eigen faces.. etc
EDIT:
Here is the Input Image and the Eigen Image is Eigen Image
The first eigenface is the first eigenvector!
My guess, is that with your code:
eigenface1=reshape(V(:,1),rows,cols);
as, if your code is right, each eigenvector should be the same size as your input images, but unrolled. I am assuming that rows and cols are the size of the image.

Calculating the degree matrix having the sparse representation of the adjacency matrix

I am trying to calculate the laplacian matrix of a graph. I ve calculated the sparse representation of the adjacency matrix which is stored in a text file with dimension Nx3. N the size of nodes (ith-node jth node weight). I open in Matlab this file with adj = spconvert(adj);. The next step is to calculate the degree matrix of this sparse matrix in order to perform the operation L = D - adj. How is it possible to calculate the degree matrix having as an input the sparse adjacency matrix of the graph? In order to calculate the degree matrix I calculate the degree for every node:
for i=1:n % size of the node
degree(i) = length(find(adj(:,1) == i & adj(:,3) == 1));
end
However, how can I perform the subtraction of D and A?
Use the spdiags function to convert the degree vector to a sparse diagonal matrix. Then subtract the adjacency matrix from diagonal matrix to get the Laplacian. Example using your code:
adj = spconvert(adj);
for i=1:size(adj, 1)
degree(i) = CalcDegree(adj, i)
end
D = spdiags(degree, 0, size(adj, 1), size(adj, 2));
L = D - adj;
By the way, your code for calculating the node degree may be incorrect.

Matlab Vectorization of Multivariate Gaussian Basis Functions

I have the following code for calculating the result of a linear combination of Gaussian functions. What I'd really like to do is to vectorize this somehow so that it's far more performant in Matlab.
Note that y is a column vector (output), x is a matrix where each column corresponds to a data point and each row corresponds to a dimension (i.e. 2 rows = 2D), variance is a double, gaussians is a matrix where each column is a vector corresponding to the mean point of the gaussian and weights is a row vector of the weights in front of each gaussian. Note that the length of weights is 1 bigger than gaussians as weights(1) is the 0th order weight.
function [ y ] = CalcPrediction( gaussians, variance, weights, x )
basisFunctions = size(gaussians, 2);
xvalues = size(x, 2);
if length(weights) ~= basisFunctions + 1
ME = MException('TRAIN:CALC', 'The number of weights should be equal to the number of basis functions plus one');
throw(ME);
end
y = weights(1) * ones(xvalues, 1);
for xIdx = 1:xvalues
for i = 1:basisFunctions
diff = x(:, xIdx) - gaussians(:, i);
y(xIdx) = y(xIdx) + weights(i+1) * exp(-(diff')*diff/(2*variance));
end
end
end
You can see that at the moment I simply iterate over the x vectors and then the gaussians inside 2 for loops. I'm hoping that this can be improved - I've looked at meshgrid but that seems to only apply to vectors (and I have matrices)
Thanks.
Try this
diffx = bsxfun(#minus,x,permute(gaussians,[1,3,2])); % binary operation with singleton expansion
diffx2 = squeeze(sum(diffx.^2,1)); % dot product, shape is now [XVALUES,BASISFUNCTIONS]
weight_col = weights(:); % make sure weights is a column vector
y = exp(-diffx2/2/variance)*weight_col(2:end); % a column vector of length XVALUES
Note, I changed diff to diffx since diff is a builtin. I'm not sure this will improve performance as allocating arrays will offset increase by vectorization.

Random permutation matrix

Is there an easy way to simulate a random permutation matrix (say of size 1000 by 1000) in Matlab? I would like to study the eigenvalue distribution of independent sum of such matrices.
Thanks in advance!
You can generate a random permutation matrix like so:
Create a unity matrix:
A = eye( N ); %// N is the size of your matrix
For large values of N it is better to use sparse matrices:
A = speye( N ); % create sparse identity matrix
Generate a random permutation:
idx = randperm(1:N);
Use vector indexing to rearrange the rows accordingly
A = A(idx, :);
Voila!
In Matlab (used R2012a) idx = randperm(1:N) gives a warning that input should be scalar. So: idx = randperm(N); .

Ploting degree distribution for a directed network

I have a dataset for the edges and nodes I've crawled from a social networking site. How can I plot the degree distribution using the data I have in a spreadsheet? The edges are directed. I am a MATLAB beginner. Please help.
I have created the adjacency matrix adj as follows:
clear all;
disp('Processing Edge-List File');
A = xlsread('edges.csv');
dim = max(max(A));
[E_Size, junk] = size(A);
sprintf('The dataset has %d nodes and %d edges',dim, E_Size);
disp('Filling Adjanceny Matrix');
adj = sparse(A(:,1), A(:,2), ones(E_Size,1), dim, dim, E_Size);
if(adj==adj') disp('Symmetric Adjacency Matrix - Undirected Graph') ;
else disp('Assymmetric Adjacency Matrix - Directed Graph');
Then i tried surf(adj) . its giving me an empty graph . Is there a problem in the way I am creating the adjacency matrix?
I'm assuming that you want to plot something like this:
Once you have determined the in and out degree of each node, you need to store it in a matrix A such that A(i,j) represents the number of nodes with in-degree i and out-degree j.
Then you can display this information with surf(A). surf plots an interpolated 3D surface where the intensity of each element in the matrix is the Z-coordinate of the surface and the column and row indices are the X,Y values.