Search code examples
matlabwolfram-mathematicatransitionadjacency-matrixpagerank

How do I reproduce this mathematica code for calculating the transition matrix of pagerank on matlab?


So the formula that needs to be implemented is:

P = ((1 - delta)/n) + ((delta)*(A)ij / (Sigma(k=1 to n)(A)ik))

where delta = 0.85
n = 8
and A = the adjacency matrix for web pages being surfed

The mathematica code for it is:

    A = {{1, 1, 1, 0, 0, 1, 0, 1}, {0, 0, 1, 0, 0, 1, 0, 1}, {1, 1, 0, 1, 
        0, 1, 1, 0}, {0, 1, 1, 0, 1, 0, 1, 0}, {1, 1, 1, 1, 0, 1, 1, 
        1}, {1, 1, 1, 0, 0, 1, 1, 0}, {1, 0, 1, 0, 1, 0, 1, 0}, {0, 0, 0, 
        0, 1, 0, 0, 1}};

       n = 8;

       \[Delta] = 0.85;

       P = Transpose[Table[(1 - \[Delta])/n + (\[Delta]*A[[i, j]])/(Sum[A[[i, k]], {k, 1, n}]), {i, 1, n}, {j, 1, n}]];

Everything else is just plugging in numbers. Now the main problem I seem to have is getting the A[[i,j]]/Sum[A[i,k]] to work on matlab.

On matlab: when I input A[[i,j]] as A, and sum[A[i,k]] as either (sum(A,2))' or sum(A,1), the P that gets output on matlab becomes a column vector rather than an 8 x 8 matrix.

What am I missing?


Solution

  • There are many ways of doing it. I'll show you one way of using native vectorized MATLAB code, so no need for for-loops or arrayfun or anything like that.

    A = [1, 1, 1, 0, 0, 1, 0, 1; 0, 0, 1, 0, 0, 1, 0, 1; 1, 1, 0, 1, 0, 1, 1, 0; 0, 1, 1, 0, 1, 0, 1, 0; 1, 1, 1, 1, 0, 1, 1, 1; 1, 1, 1, 0, 0, 1, 1, 0; 1, 0, 1, 0, 1, 0, 1, 0; 0, 0, 0, 0, 1, 0, 0, 1];
    n = size(A, 1);
    delta = 0.85; 
    
    % First, sum up all columns in each row
    rowSums = sum(A,2); 
    
    % Then replicate them because the entries in each row of the vector are valid for every column in that specific row. So replicate them so that the output-matrix matches the size of A so we can work element-wise division later
    rowSums2 = repmat(rowSums, 1, n);
    
    % Use vectorized code, ./ will yield element-wise division as A and rowSums2 are of the same size now
    P = (1 - delta)/n + delta*A ./ rowSums2
    

    I hope I got the desired output right.