Browse Source

Fix serial implementation

Add extension to executable filename so git ignore can catch it
Fix matrix transpose function
master
Apostolos Fanakis 6 years ago
parent
commit
2e1c170af6
  1. 3
      .gitignore
  2. 5
      datasets/smallset
  3. 5
      serial/Makefile
  4. BIN
      serial/pagerank
  5. 4
      serial/serial_gs_pagerank.c
  6. 425
      serial/serial_gs_pagerank_functions.c
  7. 52
      serial/serial_gs_pagerank_functions.h

3
.gitignore

@ -50,3 +50,6 @@ modules.order
Module.symvers Module.symvers
Mkfile.old Mkfile.old
dkms.conf dkms.conf
#Output files
*_output

5
datasets/smallset

@ -0,0 +1,5 @@
0 0 0 0 0
1 0 1 0 0
1 1 0 1 1
0 0 0 0 1
0 0 0 1 0

5
serial/Makefile

@ -5,14 +5,15 @@ SHELL := /bin/bash
CC = gcc CC = gcc
RM = rm -f RM = rm -f
CFLAGS=-O0 -g -I. CFLAGS_DEBUG=-O0 -g -I.
CFLAGS=-O3 -I.
OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o
DEPS=serial_gs_pagerank_functions.h DEPS=serial_gs_pagerank_functions.h
# ========================================== # ==========================================
# TARGETS # TARGETS
EXECUTABLES = pagerank EXECUTABLES = pagerank.out
.PHONY: all clean .PHONY: all clean

BIN
serial/pagerank

Binary file not shown.

4
serial/serial_gs_pagerank.c

@ -14,7 +14,7 @@ int main(int argc, char **argv) {
initialize(&directedWebGraph, &transitionMatrix, &pagerankVector, &parameters); initialize(&directedWebGraph, &transitionMatrix, &pagerankVector, &parameters);
//Starts wall-clock timer // Starts wall-clock timer
gettimeofday (&startwtime, NULL); gettimeofday (&startwtime, NULL);
int iterations = pagerank(&transitionMatrix, &pagerankVector, parameters); int iterations = pagerank(&transitionMatrix, &pagerankVector, parameters);
@ -23,7 +23,7 @@ int main(int argc, char **argv) {
\nTotal iterations = %d\n", iterations); \nTotal iterations = %d\n", iterations);
} }
//Stops wall-clock timer // Stops wall-clock timer
gettimeofday (&endwtime, NULL); gettimeofday (&endwtime, NULL);
double seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6 + double seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6 +
endwtime.tv_sec - startwtime.tv_sec); endwtime.tv_sec - startwtime.tv_sec);

425
serial/serial_gs_pagerank_functions.c

@ -1,32 +1,210 @@
#include "serial_gs_pagerank_functions.h" #include "serial_gs_pagerank_functions.h"
const char *CONVERGENCE_ARGUMENT = "-c"; const char *ARGUMENT_CONVERGENCE_TOLERANCE = "-c";
const char *MAX_ITERATIONS_ARGUMENT = "-m"; const char *ARGUMENT_MAX_ITERATIONS = "-m";
const char *DAMPING_FACTOR_ARGUMENT = "-a"; const char *ARGUMENT_DAMPING_FACTOR = "-a";
const char *VERBAL_OUTPUT_ARGUMENT = "-v"; const char *ARGUMENT_VERBAL_OUTPUT = "-v";
const char *ARGUMENT_OUTPUT_HISTORY = "-h";
const char *ARGUMENT_OUTPUT_FILENAME = "-o";
const int NUMERICAL_BASE = 10; const int NUMERICAL_BASE = 10;
char *DEFAULT_OUTPUT_FILENAME = "pagerank_output";
void validUsage(char *programName) { // ==================== PAGERANK ====================
printf("%s [-c convergence] [-m max_iterations] [-a alpha] [-v] <graph_file>\
\n-c convergence\ int pagerank(double ***transitionMatrix, double **pagerankVector, Parameters parameters) {
\n\tthe convergence criterion\ int iterations = 0;
\n-m max_iterations\ double delta,
\n\tmaximum number of iterations to perform\ *vectorDifference = (double *) malloc(parameters.numberOfPages * sizeof(double)),
\n-a alpha\ *previousPagerankVector = (double *) malloc(parameters.numberOfPages * sizeof(double));
\n\tthe damping factor\
\n-v enable verbal output\ if (parameters.verbose) {
\n", programName); printf("\n----- Starting iterations -----\n");
exit(EXIT_FAILURE); }
do {
memcpy(previousPagerankVector, *pagerankVector, parameters.numberOfPages * sizeof(double));
matrixVectorMultiplication(transitionMatrix, previousPagerankVector,
pagerankVector, parameters.numberOfPages, parameters.dampingFactor);
if (parameters.history) {
savePagerankToFile(parameters.outputFilename, iterations != 0,
*pagerankVector, parameters.numberOfPages);
}
for (int i=0; i<parameters.numberOfPages; ++i) {
vectorDifference[i] = (*pagerankVector)[i] - previousPagerankVector[i];
}
delta = vectorNorm(vectorDifference, parameters.numberOfPages);
++iterations;
printf("Iteration %d: delta = %f\n", iterations, delta);
} while (delta > parameters.convergenceCriterion &&
(parameters.maxIterations == 0 || iterations < parameters.maxIterations));
if (!parameters.history) {
savePagerankToFile(parameters.outputFilename, false, *pagerankVector,
parameters.numberOfPages);
}
return iterations;
} }
int checkIncrement(int previousIndex, int maxIndex, char *programName) { // ==================== INITIALIZATION ====================
if (previousIndex == maxIndex) {
validUsage(programName); /*
exit(EXIT_FAILURE); * initialize allocates required memory for arrays, reads the web graph from the
* from the file and creates the initial transition probability distribution
* matrix.
*/
void initialize(int ***directedWebGraph, double ***transitionMatrix,
double **pagerankVector, Parameters *parameters) {
// Reads web graph from file
if ((*parameters).verbose) {
printf("----- Reading graph from file -----\n");
} }
return ++previousIndex; readGraphFromFile(directedWebGraph, parameters);
// Outputs the algorithm parameters to the console
if ((*parameters).verbose) {
printf("\n----- Running with parameters -----\
\nNumber of pages: %d", (*parameters).numberOfPages);
if (!(*parameters).maxIterations) {
printf("\nMaximum number of iterations: inf");
} else {
printf("\nMaximum number of iterations: %d", (*parameters).maxIterations);
}
printf("\nConvergence criterion: %f\
\nDamping factor: %f\
\nGraph filename: %s\n", (*parameters).convergenceCriterion,
(*parameters).dampingFactor, (*parameters).graphFilename);
}
// Allocates memory for the pagerank vector
(*pagerankVector) = (double *) malloc((*parameters).numberOfPages * sizeof(double));
double webUniformProbability = 1. / (*parameters).numberOfPages;
for (int i=0; i<(*parameters).numberOfPages; ++i) {
(*pagerankVector)[i] = webUniformProbability;
}
// Generates the initial transition matrix (matrix P).
generateNormalizedTransitionMatrix(transitionMatrix, *directedWebGraph, *parameters);
// Transposes the transition matrix (P^T).
transposeMatrix(transitionMatrix, (*parameters).numberOfPages, (*parameters).numberOfPages);
}
/*
* generateNormalizedTransitionMatrix generates the normalized transition matrix
* from the graph data (matrix P').
*/
void generateNormalizedTransitionMatrix(double ***transitionMatrix,
int **directedWebGraph, Parameters parameters) {
// Allocates memory for the transitionMatrix rows
(*transitionMatrix) = (double **) malloc(parameters.numberOfPages * sizeof(double *));
for (int i=0; i<parameters.numberOfPages; ++i) {
// Allocates memory for this row's columns
(*transitionMatrix)[i] = (double *) malloc(parameters.numberOfPages * sizeof(double));
// Calculates the outdegree of this page
int pageOutdegree = 0;
for (int j=0; j<parameters.numberOfPages; ++j) {
pageOutdegree += directedWebGraph[i][j];
}
// Populates this row of the transition matrix
if (pageOutdegree != 0) {
// Calculates the uniform probability once.
double pageUniformProbability = 1. / pageOutdegree;
for (int j=0; j<parameters.numberOfPages; ++j) {
if (directedWebGraph[i][j] == 1){
(*transitionMatrix)[i][j] = pageUniformProbability;
} else {
(*transitionMatrix)[i][j] = 0;
}
}
} else {
for (int j=0; j<parameters.numberOfPages; ++j) {
(*transitionMatrix)[i][j] = 0;
}
}
}
}
// ==================== MATH UTILS ====================
/*
* matrixVectorMultiplication calculates the product of the multiplication
* between a matrix and the a vector in a cheap way.
*/
void matrixVectorMultiplication(double ***matrix, double *vector,
double **product, int vectorSize, double dampingFactor) {
double webUniformProbability = 1. / vectorSize;
for (int i=0; i<vectorSize; ++i) {
double sum = 0;
for (int j=0; j<vectorSize; ++j) {
sum += (*matrix)[i][j] * vector[j];
}
(*product)[i] = dampingFactor * sum;
}
double normDifference = vectorNorm(vector, vectorSize) -
vectorNorm((*product), vectorSize);
for (int i=0; i<vectorSize; ++i) {
(*product)[i] += normDifference * webUniformProbability;
}
}
/*
* vectorNorm calculates the first norm of a vector.
*/
double vectorNorm(double *vector, int vectorSize) {
double norm = 0.;
for (int i=0; i<vectorSize; ++i) {
norm += fabs(vector[i]);
}
return norm;
} }
/*
* transposeMatrix transposes the matrix passed (by reference) in the arguments.
*/
void transposeMatrix(double ***matrix, int rows, int columns) {
// Transposes the matrix
// Rows become columns and vice versa
double **tempArray = (double **) malloc(columns * sizeof(double *));
for (int i=0; i<columns; ++i) {
tempArray[i] = malloc(rows * sizeof(double));
for (int j=0; j<rows; ++j) {
tempArray[i][j] = (*matrix)[j][i];
}
}
// TODO free memory
//double **pointerToFreeMemoryLater = *matrix;
*matrix = tempArray;
/*for (int i=0; i<rows; ++i) {
free(pointerToFreeMemoryLater[i]);
}
free(pointerToFreeMemoryLater);*/
}
// ==================== PROGRAM INPUT AND OUTPUT UTILS ====================
/*
* parseArguments parses the command line arguments given by the user.
*/
void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters) { void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters) {
if (argumentCount < 2 || argumentCount > 10) { if (argumentCount < 2 || argumentCount > 10) {
validUsage(argumentVector[0]); validUsage(argumentVector[0]);
@ -37,12 +215,14 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
(*parameters).convergenceCriterion = 1; (*parameters).convergenceCriterion = 1;
(*parameters).dampingFactor = 0.85; (*parameters).dampingFactor = 0.85;
(*parameters).verbose = false; (*parameters).verbose = false;
(*parameters).history = false;
(*parameters).outputFilename = DEFAULT_OUTPUT_FILENAME;
char *endPointer; char *endPointer;
int argumentIndex = 1; int argumentIndex = 1;
while (argumentIndex < argumentCount) { while (argumentIndex < argumentCount) {
if (!strcmp(argumentVector[argumentIndex], CONVERGENCE_ARGUMENT)) { if (!strcmp(argumentVector[argumentIndex], ARGUMENT_CONVERGENCE_TOLERANCE)) {
argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]); argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]);
double convergenceInput = strtod(argumentVector[argumentIndex], &endPointer); double convergenceInput = strtod(argumentVector[argumentIndex], &endPointer);
@ -51,7 +231,7 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
(*parameters).convergenceCriterion = convergenceInput; (*parameters).convergenceCriterion = convergenceInput;
} else if (!strcmp(argumentVector[argumentIndex], MAX_ITERATIONS_ARGUMENT)) { } else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_MAX_ITERATIONS)) {
argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]); argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]);
size_t iterationsInput = strtol(argumentVector[argumentIndex], &endPointer, NUMERICAL_BASE); size_t iterationsInput = strtol(argumentVector[argumentIndex], &endPointer, NUMERICAL_BASE);
@ -60,7 +240,7 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
(*parameters).maxIterations = iterationsInput; (*parameters).maxIterations = iterationsInput;
} else if (!strcmp(argumentVector[argumentIndex], DAMPING_FACTOR_ARGUMENT)) { } else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_DAMPING_FACTOR)) {
argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]); argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]);
double alphaInput = strtod(argumentVector[argumentIndex], &endPointer); double alphaInput = strtod(argumentVector[argumentIndex], &endPointer);
@ -69,8 +249,18 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
(*parameters).dampingFactor = alphaInput; (*parameters).dampingFactor = alphaInput;
} else if (!strcmp(argumentVector[argumentIndex], VERBAL_OUTPUT_ARGUMENT)) { } else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_VERBAL_OUTPUT)) {
(*parameters).verbose = true; (*parameters).verbose = true;
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_OUTPUT_HISTORY)) {
(*parameters).history = true;
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_OUTPUT_FILENAME)) {
argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]);
if (fopen(argumentVector[argumentIndex], "w") == NULL) {
printf("Invalid output filename. Reverting to default.\n");
continue;
}
(*parameters).outputFilename = argumentVector[argumentIndex];
} else if (argumentIndex == argumentCount - 1) { } else if (argumentIndex == argumentCount - 1) {
(*parameters).graphFilename = argumentVector[argumentIndex]; (*parameters).graphFilename = argumentVector[argumentIndex];
} else { } else {
@ -81,6 +271,10 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
} }
} }
/*
* readGraphFromFile loads the file supplied in the command line arguments to an
* array (directedWebGraph) that represents the graph.
*/
void readGraphFromFile(int ***directedWebGraph, Parameters *parameters) { void readGraphFromFile(int ***directedWebGraph, Parameters *parameters) {
FILE *graphFile; FILE *graphFile;
@ -103,11 +297,11 @@ void readGraphFromFile(int ***directedWebGraph, Parameters *parameters) {
} }
if ((*parameters).verbose) { if ((*parameters).verbose) {
printf("Line count of file is %d \n", numberOfLines); printf("Line count of file is %d \n", numberOfLines + 1);
} }
// Each line of the file represents one page of the graph // Each line of the file represents one page of the graph
(*parameters).numberOfPages = numberOfLines; (*parameters).numberOfPages = numberOfLines + 1;
rewind(graphFile); rewind(graphFile);
// Allocates memory and loads values into directedWebGraph (matrix A) // Allocates memory and loads values into directedWebGraph (matrix A)
@ -122,165 +316,62 @@ void readGraphFromFile(int ***directedWebGraph, Parameters *parameters) {
if (!fscanf(graphFile, "%d ", &(*directedWebGraph)[i][j])) { if (!fscanf(graphFile, "%d ", &(*directedWebGraph)[i][j])) {
break; break;
} }
//printf("directedWebGraph[%d][%d] = %d", i , j, (*directedWebGraph)[i][j]);
} }
} }
fclose(graphFile); fclose(graphFile);
} }
void generateNormalizedTransitionMatrix(double ***transitionMatrix, /*
int **directedWebGraph, Parameters parameters) { * validUsage outputs a message to the console that informs the user of the
// Allocates memory for the transitionMatrix rows * correct (valid) way to use the program.
(*transitionMatrix) = (double **) malloc(parameters.numberOfPages * sizeof(double *)); */
void validUsage(char *programName) {
for (int i=0; i<parameters.numberOfPages; ++i) { printf("%s [-c convergence_criterion] [-m max_iterations] [-a alpha] [-v] [-h] [-o output_filename] <graph_file>\
// Allocates memory for this row's columns \n-c convergence_criterion\
(*transitionMatrix)[i] = (double *) malloc(parameters.numberOfPages * sizeof(double)); \n\tthe convergence tolerance criterion\
\n-m max_iterations\
int pageOutdegree = 0; \n\tmaximum number of iterations to perform\
//Calculates the outdegree of this page \n-a alpha\
for (int j=0; j<parameters.numberOfPages; ++j) { \n\tthe damping factor\
pageOutdegree += directedWebGraph[i][j]; \n-v enable verbal output\
} \n-h enable history output to file\
for (int j=0; j<parameters.numberOfPages; ++j) { \n-o output_filename\
if (pageOutdegree == 0) { \n\tfilename and path for the output\
// Introduces random jumps from dangling nodes (P' = P + D) \n", programName);
// This makes sure that there are no pages with zero outdegree. exit(EXIT_FAILURE);
(*transitionMatrix)[i][j] = 1. / parameters.numberOfPages;
} else {
(*transitionMatrix)[i][j] = 1. / pageOutdegree;
}
}
}
}
void makeIrreducible(double ***transitionMatrix, Parameters parameters) {
// Manipulates the values of transitionMatrix to make it irreducible. A
// uniform probability (1/number_of_pages) and no personalization are used
// here.
// Introduces teleportation (P'' = cP' + (1 - c)E)
for (int i=0; i<parameters.numberOfPages; ++i) {
for (int j=0; j<parameters.numberOfPages; ++j) {
(*transitionMatrix)[i][j] =
parameters.dampingFactor *(*transitionMatrix)[i][j] +
(1 - parameters.dampingFactor) / parameters.numberOfPages;
}
}
} }
void transposeMatrix(double ***matrix, int rows, int columns) { /*
// Transposes the matrix * checkIncrement is a helper function for parseArguments function.
// Rows become columns and vice versa */
int checkIncrement(int previousIndex, int maxIndex, char *programName) {
double **tempArray = (double **) malloc(rows * sizeof(double *)); if (previousIndex == maxIndex) {
for (int i=0; i<rows; ++i) { validUsage(programName);
tempArray[i] = malloc(columns * sizeof(double)); exit(EXIT_FAILURE);
for (int j=0; j<columns; ++j) {
tempArray[i][j] = (*matrix)[j][i];
}
}
//double **pointerToFreeMemoryLater = *matrix;
matrix = &tempArray;
/*for (int i=0; i<rows; ++i) {
free(pointerToFreeMemoryLater[i]);
} }
free(pointerToFreeMemoryLater);*/ return ++previousIndex;
} }
void initialize(int ***directedWebGraph, double ***transitionMatrix, void savePagerankToFile(char *filename, bool append, double *pagerankVector,
double **pagerankVector, Parameters *parameters) { int vectorSize) {
FILE *outputFile;
if ((*parameters).verbose) { if (append) {
printf("----- Reading graph from file -----\n"); outputFile = fopen(filename, "a");
}
readGraphFromFile(directedWebGraph, parameters);
if ((*parameters).verbose) {
printf("\n----- Running with parameters -----\
\nNumber of pages: %d", (*parameters).numberOfPages);
if (!(*parameters).maxIterations) {
printf("\nMaximum number of iterations: inf");
} else { } else {
printf("\nMaximum number of iterations: %d", (*parameters).maxIterations); outputFile = fopen(filename, "w");
}
printf("\nConvergence criterion: %f\
\nDamping factor: %f\
\nGraph filename: %s\n", (*parameters).convergenceCriterion,
(*parameters).dampingFactor, (*parameters).graphFilename);
} }
// Allocates memory for the pagerank vector if (outputFile == NULL) {
(*pagerankVector) = (double *) malloc((*parameters).numberOfPages * sizeof(double)); printf("Error while opening the output file.\n");
for (int i=0; i<(*parameters).numberOfPages; ++i) { return;
(*pagerankVector)[i] = 1. / (*parameters).numberOfPages;
} }
generateNormalizedTransitionMatrix(transitionMatrix, *directedWebGraph, *parameters);
makeIrreducible(transitionMatrix, *parameters);
transposeMatrix(transitionMatrix, (*parameters).numberOfPages, (*parameters).numberOfPages);
}
double vectorFirstNorm(double *vector, int vectorSize) {
double norm = 0;
for (int i=0; i<vectorSize; ++i) { for (int i=0; i<vectorSize; ++i) {
norm += vector[i]; fprintf(outputFile, "%f ", pagerankVector[i]);
} }
fprintf(outputFile, "\n");
return norm; fclose(outputFile);
}
void nextProbabilityDistribution(double ***transitionMatrix, double *previousPagerankVector,
double **newPagerankVector, Parameters parameters) {
transposeMatrix(transitionMatrix, parameters.numberOfPages, parameters.numberOfPages);
for (int i=0; i<parameters.numberOfPages; ++i) {
double sum = 0;
for (int j=0; j<parameters.numberOfPages; ++j) {
sum += (*transitionMatrix)[i][j] * previousPagerankVector[j];
}
(*newPagerankVector)[i] = parameters.dampingFactor * sum;
}
double normDifference = vectorFirstNorm(previousPagerankVector, parameters.numberOfPages) -
vectorFirstNorm((*newPagerankVector), parameters.numberOfPages);
for (int i=0; i<parameters.numberOfPages; ++i) {
(*newPagerankVector)[i] += normDifference / parameters.numberOfPages;
}
transposeMatrix(transitionMatrix, parameters.numberOfPages, parameters.numberOfPages);
}
int pagerank(double ***transitionMatrix, double **pagerankVector, Parameters parameters) {
int iterations = 0;
double delta,
*vectorDifference = (double *) malloc(parameters.numberOfPages * sizeof(double)),
*previousPagerankVector = (double *) malloc(parameters.numberOfPages * sizeof(double));
if (parameters.verbose) {
printf("\n----- Starting iterations -----\n");
}
do {
memcpy(previousPagerankVector, *pagerankVector, parameters.numberOfPages * sizeof(double));
nextProbabilityDistribution(transitionMatrix, previousPagerankVector, pagerankVector, parameters);
for (int i=0; i<parameters.numberOfPages; ++i) {
vectorDifference[i] = (*pagerankVector)[i] - previousPagerankVector[i];
}
delta = vectorFirstNorm(vectorDifference, parameters.numberOfPages);
++iterations;
printf("Iteration %d: delta = %f\n", iterations, delta);
} while (delta > parameters.convergenceCriterion &&
(parameters.maxIterations != 0 || iterations < parameters.maxIterations));
return iterations;
} }

52
serial/serial_gs_pagerank_functions.h

@ -5,25 +5,30 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h>
/* /*
* Constant strings that store the command line options available. * Constant strings that store the command line options available.
*/ */
extern const char *CONVERGENCE_ARGUMENT; extern const char *ARGUMENT_CONVERGENCE_TOLERANCE;
extern const char *MAX_ITERATIONS_ARGUMENT; extern const char *ARGUMENT_MAX_ITERATIONS;
extern const char *DAMPING_FACTOR_ARGUMENT; extern const char *ARGUMENT_DAMPING_FACTOR;
extern const char *VERBAL_OUTPUT_ARGUMENT; extern const char *ARGUMENT_VERBAL_OUTPUT;
extern const char *ARGUMENT_OUTPUT_HISTORY;
extern const char *ARGUMENT_OUTPUT_FILENAME;
// This is the numerical base used when parsing the numerical command line // This is the numerical base used when parsing the numerical command line
// arguments. // arguments.
extern const int NUMERICAL_BASE; extern const int NUMERICAL_BASE;
// Default filename used for the output.
extern char *DEFAULT_OUTPUT_FILENAME;
// Declares a data structure to conveniently hold the algorithm's parameters // Declares a data structure to conveniently hold the algorithm's parameters.
typedef struct parameters { typedef struct parameters {
int numberOfPages, maxIterations; int numberOfPages, maxIterations;
double convergenceCriterion, dampingFactor; double convergenceCriterion, dampingFactor;
bool verbose; bool verbose, history;
char* graphFilename; char *outputFilename, *graphFilename;
} Parameters; } Parameters;
// Function validUsage outputs the correct way to use the program with command // Function validUsage outputs the correct way to use the program with command
@ -37,19 +42,21 @@ int checkIncrement(int previousIndex, int maxIndex, char *programName);
// Function parseArguments parses command line arguments. // Function parseArguments parses command line arguments.
void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters); void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters);
// Function readGraphFromFile loads the graph stored in the file provided in the // Function readGraphFromFile loads adjacency matrix, that represents the web
// command line arguments to the array directedWebGraph. // graph, stored in the file provided in the command line arguments to the array
// directedWebGraph.
void readGraphFromFile(int ***directedWebGraph, Parameters *parameters); void readGraphFromFile(int ***directedWebGraph, Parameters *parameters);
// Function generateNormalizedTransitionMatrix generates the normalized transition // Function savePagerankToFile appends or overwrites the pagerank vector
// matrix from the graph data. // "pagerankVector" to the file with the filename supplied in the arguments
void savePagerankToFile(char *filename, bool append, double *pagerankVector,
int vectorSize);
// Function generateNormalizedTransitionMatrix generates the normalized
// transition matrix from the web graph data.
void generateNormalizedTransitionMatrix(double ***transitionMatrix, void generateNormalizedTransitionMatrix(double ***transitionMatrix,
int **directedWebGraph, Parameters parameters); int **directedWebGraph, Parameters parameters);
// Function makeIrreducible introduces teleportation to the transition matrix,
// making it irreducible.
void makeIrreducible(double ***transitionMatrix, Parameters parameters);
// Function transposeMatrix transposes a matrix. // Function transposeMatrix transposes a matrix.
void transposeMatrix(double ***matrix, int rows, int columns); void transposeMatrix(double ***matrix, int rows, int columns);
@ -62,14 +69,17 @@ void initialize(
Parameters *parameters Parameters *parameters
); );
// Function vectorFirstNorm calculates the first norm of a vector. // Function vectorNorm calculates the first norm of a vector.
double vectorFirstNorm(double *vector, int vectorSize); double vectorNorm(double *vector, int vectorSize);
// Function nextProbabilityDistribution calculates the product of the transition // Function matrixVectorMultiplication calculates the product of the
// matrix and the pagerank vector. // multiplication between a matrix and the a vector.
void nextProbabilityDistribution(double ***transitionMatrix, double *previousPagerankVector, void matrixVectorMultiplication(double ***matrix, double *vector,
double **newPagerankVector, Parameters parameters); double **product, int vectorSize, double dampingFactor);
// Function pagerank iteratively calculates the pagerank of each page until
// either the convergence criterion is met or the maximum number of iterations
// is reached.
int pagerank(double ***transitionMatrix, double **pagerankVector, Parameters parameters); int pagerank(double ***transitionMatrix, double **pagerankVector, Parameters parameters);
#endif // SERIAL_GS_PAGERANK_FUNCTIONS_H #endif // SERIAL_GS_PAGERANK_FUNCTIONS_H
Loading…
Cancel
Save