Exercise 4 for the course "Parallel and distributed systems" of THMMY in AUTH university.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.7 KiB

/*
* =============================================================
* pagerank_gs_mult.c Compute the matrix vector multiplication
* for the gauss seidel iteration in an efficient manner
* (that is, by overwriting the vector x in place.)
*
* David Gleich
* Stanford University
* 28 January 2006
* =============================================================
*/
#include "mex.h"
/*
* The mex function just computes one matrix-vector product.
*/
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
int i, j, k;
int n, mrows, ncols;
/* sparse matrix */
int A_nz;
int *A_row, *A_col;
double *A_val;
double *x, *b;
double *xold;
if (nrhs != 3)
{
mexErrMsgTxt("Three inputs required.");
}
else if (nlhs > 1)
{
mexErrMsgTxt("Too many output arguments");
}
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
if (mrows != ncols ||
!mxIsSparse(prhs[0]) ||
!mxIsDouble(prhs[0]) ||
mxIsComplex(prhs[0]))
{
mexErrMsgTxt("Input must be a noncomplex square sparse matrix.");
}
/* okay, the first input passes */
n = mrows;
/* The second input must be a vector. */
if (mxGetM(prhs[1])*mxGetN(prhs[1]) != n ||
mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]))
{
mexErrMsgTxt("Invalid vector.");
}
/* The third input must be a vector. */
if (mxGetM(prhs[2])*mxGetN(prhs[2]) != n ||
mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2]))
{
mexErrMsgTxt("Invalid vector.");
}
/* Get the sparse matrix */
A_nz = mxGetNzmax(prhs[0]);
A_val = mxGetPr(prhs[0]);
A_row = mxGetIr(prhs[0]);
A_col = mxGetJc(prhs[0]);
/* Get the vector x */
x = mxGetPr(prhs[1]);
/* Get the vector b */
b = mxGetPr(prhs[2]);
/* if they request x old, then we need to copy x to xold */
if (nlhs > 0)
{
plhs[0] = mxDuplicateArray(prhs[1]);
}
/* Update x in place, this means we have to iterate over columns
* of the matrix A. */
for (i = 0; i < n; i++)
{
/* we actually compute one iteration for the
* system (I+A')x = b */
double aself = 1.0;
double xnew = b[i];
for (j = A_col[i]; j < A_col[i+1]; ++j)
{
/* add to aself only if the row = i (the column) */
aself += A_val[j]*(A_row[j] == i);
/* add to xnew only if row != i */
xnew -= A_val[j]*x[A_row[j]]*(A_row[j] != i);
}
x[i] = xnew/aself;
}
}