diff --git a/serial/Makefile b/serial/Makefile index a6ed4bc..9c4e0e6 100644 --- a/serial/Makefile +++ b/serial/Makefile @@ -5,10 +5,10 @@ SHELL := /bin/bash CC = gcc RM = rm -f -CFLAGS_DEBUG=-O0 -g -I. -CFLAGS=-O3 -I. -OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o sparse_matrix.o -DEPS=serial_gs_pagerank_functions.h sparse_matrix.h +CFLAGS_DEBUG=-O0 -ggdb3 -Wall -I. +CFLAGS=-O3 -Wall -I. +OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o coo_sparse_matrix.o lil_sparse_matrix.o +DEPS=serial_gs_pagerank_functions.h coo_sparse_matrix.h lil_sparse_matrix.h # ========================================== # TARGETS diff --git a/serial/coo_sparse_matrix.c b/serial/coo_sparse_matrix.c new file mode 100644 index 0000000..42fc7f1 --- /dev/null +++ b/serial/coo_sparse_matrix.c @@ -0,0 +1,117 @@ +#include "coo_sparse_matrix.h" + +CooSparseMatrix initCooSparseMatrix() { + CooSparseMatrix sparseMatrix; + sparseMatrix.size = 0; + sparseMatrix.elements = NULL; + return sparseMatrix; +} + +void allocMemoryForElements (CooSparseMatrix *sparseMatrix, int elements) { + sparseMatrix->elements = (CooSparseMatrixElement **) malloc( + elements * sizeof(CooSparseMatrixElement *)); +} + +void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column) { + // Creates the new element + CooSparseMatrixElement *newElement = (CooSparseMatrixElement *) malloc( + sizeof(CooSparseMatrixElement)); + newElement->value = value; + newElement->rowIndex = row; + newElement->columnIndex = column; + + sparseMatrix->elements[sparseMatrix->size] = newElement; + sparseMatrix->size = sparseMatrix->size + 1; +} + +void zeroOutRow(CooSparseMatrix *sparseMatrix, int row) { + for (int i=0; isize; ++i) { + CooSparseMatrixElement *element = sparseMatrix->elements[i]; + if (element->rowIndex == row) { + element->value = 0; + } + } +} +void zeroOutColumn(CooSparseMatrix *sparseMatrix, int column) { + for (int i=0; isize; ++i) { + CooSparseMatrixElement *element = sparseMatrix->elements[i]; + if (element->columnIndex == column) { + element->value = 0; + } + } +} + +int *getRowIndexes(CooSparseMatrix sparseMatrix, int row, int *rowSize) { + *rowSize = 0; + for (int i=0; irowIndex == row) { + ++(*rowSize); + } + } + + if (!(*rowSize)) { + return NULL; + } + + int *indexes = (int *) malloc((*rowSize) * sizeof(int)); + int rowElementIndex = 0; + for (int i=0; irowIndex == row) { + indexes[rowElementIndex] = i; + ++rowElementIndex; + } + } + + return indexes; +} + +void transposeSparseMatrix(CooSparseMatrix *sparseMatrix) { + for (int i=0; isize; ++i) { + CooSparseMatrixElement *element = sparseMatrix->elements[i]; + int tempRow = element->rowIndex; + element->rowIndex = element->columnIndex; + element->columnIndex = tempRow; + } +} + +void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix, + double *vector, double **product, int vectorSize) { + // Initializes the elements of the product vector to zero + for (int i=0; irowIndex, column = element->columnIndex; + + if (row >= vectorSize) { + printf("Error at sparseMatrixVectorMultiplication. Matrix has more rows than vector!\n"); + printf("row = %d\n", row); + exit(EXIT_FAILURE); + } + + (*product)[row] = (*product)[row] + element->value * vector[column]; + } +} + +void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix) { + for (int i=0; isize; ++i) { + free(sparseMatrix->elements[i]); + } + free(sparseMatrix->elements); +} + +void printCooSparseMatrix(CooSparseMatrix sparseMatrix) { + if (sparseMatrix.size == 0) { + return; + } + + CooSparseMatrixElement *element; + for (int i=0; irowIndex, element->columnIndex, + element->value); + } +} \ No newline at end of file diff --git a/serial/coo_sparse_matrix.h b/serial/coo_sparse_matrix.h new file mode 100644 index 0000000..66f538b --- /dev/null +++ b/serial/coo_sparse_matrix.h @@ -0,0 +1,31 @@ +#ifndef COO_SPARSE_MATRIX_H /* Include guard */ +#define COO_SPARSE_MATRIX_H + +#include +#include +#include +#include + +typedef struct cooSparseMatrixElement { + double value; + int rowIndex, columnIndex; +} CooSparseMatrixElement; + +typedef struct cooSparseMatrix { + int size; + CooSparseMatrixElement **elements; +} CooSparseMatrix; + +CooSparseMatrix initCooSparseMatrix(); +void allocMemoryForElements (CooSparseMatrix *sparseMatrix, int elements); +void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column); +void zeroOutRow(CooSparseMatrix *sparseMatrix, int row); +void zeroOutColumn(CooSparseMatrix *sparseMatrix, int column); +int *getRowIndexes(CooSparseMatrix sparseMatrix, int row, int *rowSize); +void transposeSparseMatrix(CooSparseMatrix *sparseMatrix); +void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix, double *vector, + double **product, int vectorSize); +void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix); +void printCooSparseMatrix(CooSparseMatrix sparseMatrix); + +#endif // COO_SPARSE_MATRIX_H \ No newline at end of file diff --git a/serial/lil_sparse_matrix.c b/serial/lil_sparse_matrix.c new file mode 100644 index 0000000..61777ea --- /dev/null +++ b/serial/lil_sparse_matrix.c @@ -0,0 +1,76 @@ +#include "lil_sparse_matrix.h" + +LilSparseMatrix createLilSparseMatrix() { + LilSparseMatrix sparseMatrix; + sparseMatrix.elements = 0; + sparseMatrix.firstElement = NULL; + sparseMatrix.lastElement = NULL; + return sparseMatrix; +} + +void apendElement(LilSparseMatrix *sparseMatrix, double value, int row, int column) { + // Creates the new element + LilSparseMatrixElement *newElement = (LilSparseMatrixElement *) malloc(sizeof(LilSparseMatrixElement)); + newElement->value = value; + newElement->rowIndex = row; + newElement->columnIndex = column; + newElement->nextElement = NULL; + + if (sparseMatrix->firstElement == NULL) { + // Sparse matrix is empty, this is the first element + sparseMatrix->firstElement = newElement; + sparseMatrix->lastElement = newElement; + } else { + //Gets last element of the matrix + LilSparseMatrixElement *lastElement = sparseMatrix->lastElement; + + lastElement->nextElement = newElement; + sparseMatrix->lastElement = newElement; + } + + sparseMatrix->elements = sparseMatrix->elements + 1; +} + +void lilSparseMatrixVectorMultiplication(LilSparseMatrix sparseMatrix, + double *vector, double **product, int vectorSize) { + // Initializes the elements of the product vector to zero + for (int i=0; irowIndex, column = element->columnIndex; + + if (row >= vectorSize) { + printf("Error at sparseMatrixVectorMultiplication. Matrix has more rows than vector!\n"); + printf("row = %d\n", row); + exit(EXIT_FAILURE); + } + + (*product)[row] = (*product)[row] + element->value * vector[column]; + element = element->nextElement; + } +} + +void destroyLilSparseMatrix(LilSparseMatrix *sparseMatrix) { + LilSparseMatrixElement *currentElement = sparseMatrix->firstElement; + while (currentElement != NULL) { + LilSparseMatrixElement *toDelete = currentElement; + currentElement = currentElement->nextElement; + free(toDelete); + } +} + +void printLilSparseMatrix(LilSparseMatrix sparseMatrix) { + if (sparseMatrix.elements == 0) { + return; + } + + LilSparseMatrixElement *currentElement = sparseMatrix.firstElement; + for (int i=0; irowIndex, + currentElement->columnIndex, currentElement->value); + currentElement = currentElement->nextElement; + } +} \ No newline at end of file diff --git a/serial/lil_sparse_matrix.h b/serial/lil_sparse_matrix.h new file mode 100644 index 0000000..599cdae --- /dev/null +++ b/serial/lil_sparse_matrix.h @@ -0,0 +1,29 @@ +#ifndef LIL_SPARSE_MATRIX_H /* Include guard */ +#define LIL_SPARSE_MATRIX_H + +#include +#include +#include +#include + +typedef struct lilSparseMatrixElement { + double value; + int rowIndex, columnIndex; + struct lilSparseMatrixElement *nextElement; +} LilSparseMatrixElement; + +typedef struct lilSparseMatrix { + int elements; + LilSparseMatrixElement *firstElement; + LilSparseMatrixElement *lastElement; +} LilSparseMatrix; + +LilSparseMatrix createLilSparseMatrix(); +void apendElement(LilSparseMatrix *sparseMatrix, double value, int row, + int column); +void lilSparseMatrixVectorMultiplication(LilSparseMatrix sparseMatrix, + double *vector, double **product, int vectorSize); +void destroyLilSparseMatrix(LilSparseMatrix *sparseMatrix); +void printLilSparseMatrix(LilSparseMatrix sparseMatrix); + +#endif // LIL_SPARSE_MATRIX_H \ No newline at end of file diff --git a/serial/serial_gs_pagerank.c b/serial/serial_gs_pagerank.c index fdb7031..9a4cf6f 100644 --- a/serial/serial_gs_pagerank.c +++ b/serial/serial_gs_pagerank.c @@ -1,19 +1,17 @@ #include #include "serial_gs_pagerank_functions.h" -#include "sparse_matrix.h" +//#include "coo_sparse_matrix.h" struct timeval startwtime, endwtime; double seq_time; int main(int argc, char **argv) { - SparseMatrix transitionMatrix; + CooSparseMatrix transitionMatrix = initCooSparseMatrix(); double *pagerankVector; bool convergenceStatus; Parameters parameters; - transitionMatrix = createSparseMatrix(); - parseArguments(argc, argv, ¶meters); initialize(&transitionMatrix, &pagerankVector, ¶meters); @@ -40,4 +38,7 @@ int main(int argc, char **argv) { endwtime.tv_sec - startwtime.tv_sec); printf("%s wall clock time = %f\n","Pagerank (Gauss-Seidel method), serial implementation", seq_time); + + free(pagerankVector); + destroyCooSparseMatrix(&transitionMatrix); } diff --git a/serial/serial_gs_pagerank_functions.c b/serial/serial_gs_pagerank_functions.c index d3ec921..b8b9e9e 100644 --- a/serial/serial_gs_pagerank_functions.c +++ b/serial/serial_gs_pagerank_functions.c @@ -1,5 +1,9 @@ +/* ===== INCLUDES ===== */ + #include "serial_gs_pagerank_functions.h" +/* ===== CONSTANTS ===== */ + const char *ARGUMENT_CONVERGENCE_TOLERANCE = "-c"; const char *ARGUMENT_MAX_ITERATIONS = "-m"; const char *ARGUMENT_DAMPING_FACTOR = "-a"; @@ -11,24 +15,43 @@ const int NUMERICAL_BASE = 10; char *DEFAULT_OUTPUT_FILENAME = "pagerank_output"; const int FILE_READ_BUFFER_SIZE = 4096; -// ==================== PAGERANK ==================== +const int CONVERGENCE_CHECK_ITERATION_PERIOD = 3; +const int SPARSITY_INCREASE_ITERATION_PERIOD = 9; -int pagerank(SparseMatrix *transitionMatrix, double **pagerankVector, +/* ===== FUNCTIONS ===== */ + +int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector, bool *convergenceStatus, Parameters parameters) { - int iterations = 0; - double delta, - *vectorDifference = (double *) malloc(parameters.numberOfPages * sizeof(double)), - *previousPagerankVector = (double *) malloc(parameters.numberOfPages * sizeof(double)), - *convergedPagerankVector = (double *) malloc(parameters.numberOfPages * sizeof(double)), - *linksFromConvergedPagesPagerankVector = (double *) malloc(parameters.numberOfPages * sizeof(double)); - SparseMatrix linksFromConvergedPages = createSparseMatrix(); - bool *converganceMatrix = (bool *) malloc(parameters.numberOfPages * sizeof(bool)); - *convergenceStatus = false; - - for (int i=0; ivalue, i, j); - } + for (int i=0; ielements[rowIndexes[j]]; + // Checks for links from converged pages to non converged + int pageLinksTo = element->columnIndex; + if (convergenceMatrix[pageLinksTo] == false){ + // Link exists, adds element to the vector + apendElement(&linksFromConvergedPages, + element->value, i, pageLinksTo); } - deleteElement(transitionMatrix, i, j); - deleteElement(transitionMatrix, j, i); } - sparseMatrixVectorMultiplication(linksFromConvergedPages, *pagerankVector, - &linksFromConvergedPagesPagerankVector, parameters.numberOfPages); + // Increases sparsity of the transition matrix by + // deleting elements that correspond to converged pages + zeroOutRow(transitionMatrix, i); + zeroOutColumn(transitionMatrix, i); + + // Builds the new linksFromConvergedPagesPagerankVector + lilSparseMatrixVectorMultiplication(linksFromConvergedPages, + *pagerankVector, &linksFromConvergedPagesPagerankVector, + numberOfPages); } } + free(newlyConvergedPages); } ++iterations; + // Outputs information about this iteration if (iterations%2) { printf(ANSI_COLOR_BLUE "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, iterations, delta); } else { printf(ANSI_COLOR_CYAN "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, iterations, delta); } - } while (!*convergenceStatus && - (parameters.maxIterations == 0 || iterations < parameters.maxIterations)); + } while (!*convergenceStatus && (parameters.maxIterations == 0 || + iterations < parameters.maxIterations)); if (!parameters.history) { + // Outputs last pagerank vector to file savePagerankToFile(parameters.outputFilename, false, *pagerankVector, - parameters.numberOfPages); + numberOfPages); } + // Frees memory + free(pagerankDifference); + free(previousPagerankVector); + free(convergedPagerankVector); + free(linksFromConvergedPagesPagerankVector); + free(convergenceMatrix); + destroyLilSparseMatrix(&linksFromConvergedPages); + return iterations; } -// ==================== INITIALIZATION ==================== - /* * 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(SparseMatrix *transitionMatrix, +void initialize(CooSparseMatrix *transitionMatrix, double **pagerankVector, Parameters *parameters) { // Reads web graph from file @@ -148,14 +205,17 @@ void initialize(SparseMatrix *transitionMatrix, // ==================== MATH UTILS ==================== /* - * matrixVectorMultiplication calculates the product of the multiplication + * calculateNextPagerank calculates the product of the multiplication * between a matrix and the a vector in a cheap way. */ -void matrixVectorMultiplication(SparseMatrix *transitionMatrix, double *previousPagerankVector, - double **pagerankVector, int vectorSize, double dampingFactor) { +void calculateNextPagerank(CooSparseMatrix *transitionMatrix, + double *previousPagerankVector, double **pagerankVector, + double *linksFromConvergedPagesPagerankVector, + double *convergedPagerankVector, int vectorSize, double dampingFactor) { + // Calculates the web uniform probability once. double webUniformProbability = 1. / vectorSize; - sparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector, + cooSparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector, pagerankVector, vectorSize); for (int i=0; i maxPageIndex) { maxPageIndex = fileFrom; } - apendElement(transitionMatrix, 1, fileFrom, fileTo); + if (fileTo > maxPageIndex) { + maxPageIndex = fileTo; + } + addElement(transitionMatrix, 1, fileFrom, fileTo); } + printf("\n"); if ((*parameters).verbose) { printf("Max page index found is: %d\n", maxPageIndex); @@ -359,41 +417,26 @@ void generateNormalizedTransitionMatrixFromFile(SparseMatrix *transitionMatrix, // Calculates the outdegree of each page and assigns the uniform probability // of transition to the elements of the corresponding row - int currentRow = transitionMatrix->firstElement->rowIndex; - SparseMatrixElement *startElement = transitionMatrix->firstElement; - while(true) { - int pageOutdegree = 1; - SparseMatrixElement *currentElement = startElement->nextElement; - - // Calculates current page's outdegree - while (currentElement != NULL) { - if (currentElement->rowIndex == currentRow) { - ++pageOutdegree; - currentElement = currentElement->nextElement; - } else { - break; - } - } - - // Assigns the value 1/outdegree to current page's columns - currentElement = startElement; - double pageUniformProbability = 1. / pageOutdegree; - for (int i=0; irowIndex == currentRow) { - currentElement->value = pageUniformProbability; - currentElement = currentElement->nextElement; - } else { - break; + int currentRow = transitionMatrix->elements[0]->rowIndex, pageOutdegree = 1; + for (int i=1; isize; ++i) { + CooSparseMatrixElement *currentElement = transitionMatrix->elements[i]; + if (currentElement->rowIndex == currentRow) { + ++pageOutdegree; + } else { + double pageUniformProbability = 1. / pageOutdegree; + for (int j=i-pageOutdegree; jelements[j]->value = pageUniformProbability; } - } - // Reached the last element; - if (currentElement == NULL) { - break; + currentRow = currentElement->rowIndex; + pageOutdegree = 1; } + } - startElement = currentElement; - currentRow = startElement->rowIndex; + // Does the last row + double pageUniformProbability = 1. / pageOutdegree; + for (int j=transitionMatrix->size-pageOutdegree; jsize; ++j) { + transitionMatrix->elements[j]->value = pageUniformProbability; } fclose(graphFile); diff --git a/serial/serial_gs_pagerank_functions.h b/serial/serial_gs_pagerank_functions.h index 9e5267c..40ed518 100644 --- a/serial/serial_gs_pagerank_functions.h +++ b/serial/serial_gs_pagerank_functions.h @@ -1,14 +1,20 @@ #ifndef SERIAL_GS_PAGERANK_FUNCTIONS_H /* Include guard */ #define SERIAL_GS_PAGERANK_FUNCTIONS_H +/* ===== INCLUDES ===== */ + #include #include #include #include #include -#include "sparse_matrix.h" +#include "coo_sparse_matrix.h" +#include "lil_sparse_matrix.h" + +/* ===== DEFINITIONS ===== */ +//Colors used for better console output formating. #define ANSI_COLOR_RED "\x1B[31m" #define ANSI_COLOR_GREEN "\x1B[32m" #define ANSI_COLOR_YELLOW "\x1B[33m" @@ -16,25 +22,25 @@ #define ANSI_COLOR_CYAN "\x1B[36m" #define ANSI_COLOR_RESET "\x1B[0m" -/* - * Constant strings that store the command line options available. -*/ +/* ===== CONSTANTS DEFINITION ===== */ + +// Constant strings that store the command line options available. extern const char *ARGUMENT_CONVERGENCE_TOLERANCE; extern const char *ARGUMENT_MAX_ITERATIONS; extern const char *ARGUMENT_DAMPING_FACTOR; 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 -// arguments. +// The numerical base used when parsing numerical command line arguments. extern const int NUMERICAL_BASE; // Default filename used for the output. extern char *DEFAULT_OUTPUT_FILENAME; +// The size of the buffer used for reading the graph input file. +extern const int FILE_READ_BUFFER_SIZE; -extern const int MAX_PAGE_LINKS_TEXT_SIZE; +/* ===== STRUCTURES ===== */ -// Declares a data structure to conveniently hold the algorithm's parameters. +// A data structure to conveniently hold the algorithm's parameters. typedef struct parameters { int numberOfPages, maxIterations; double convergenceCriterion, dampingFactor; @@ -42,8 +48,7 @@ typedef struct parameters { char *outputFilename, *graphFilename; } Parameters; -//extern typedef SparseMatrixElement; -//extern typedef SparseMatrix; +/* ===== FUNCTION DEFINITIONS ===== */ // Function validUsage outputs the correct way to use the program with command // line arguments. @@ -54,39 +59,41 @@ void validUsage(char *programName); int checkIncrement(int previousIndex, int maxIndex, char *programName); // 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 adjacency matrix, that represents the web -// graph, stored in the file provided in the command line arguments to the array -// directedWebGraph. -void generateNormalizedTransitionMatrixFromFile(SparseMatrix *transitionMatrix, Parameters *parameters); +// Function generateNormalizedTransitionMatrixFromFile reads through the entries +// of the file specified in the arguments (parameters->graphFilename), using +// them to populate the sparse array (transitionMatrix). The entries of the file +// represent the edges of the web transition graph. The entries are then +// modified to become the rows of the transition matrix. +void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatrix, + Parameters *parameters); // Function savePagerankToFile appends or overwrites the pagerank vector -// "pagerankVector" to the file with the filename supplied in the arguments +// "pagerankVector" to the file with the filename supplied in the arguments. void savePagerankToFile(char *filename, bool append, double *pagerankVector, int vectorSize); -// Function initialize allocates required memory for arrays, reads the dataset -// from the file and creates the transition probability distribution matrix. -void initialize( - SparseMatrix *transitionMatrix, /*This is matrix A (transition probability distribution matrix)*/ - double **pagerankVector, /*This is the resulting pagerank vector*/ - Parameters *parameters - ); +// Function initialize allocates memory for the pagerank vector, reads the +// dataset from the file and creates the transition probability distribution +// matrix. +void initialize(CooSparseMatrix *transitionMatrix, double **pagerankVector, + Parameters *parameters); // Function vectorNorm calculates the first norm of a vector. double vectorNorm(double *vector, int vectorSize); -// Function matrixVectorMultiplication calculates the product of the -// multiplication between a matrix and the a vector. -void matrixVectorMultiplication(SparseMatrix *transitionMatrix, - double *previousPagerankVector, double **pagerankVector, int vectorSize, - double dampingFactor); +// Function calculateNextPagerank calculates the next pagerank vector. +void calculateNextPagerank(CooSparseMatrix *transitionMatrix, + double *previousPagerankVector, double **pagerankVector, + double *linksFromConvergedPagesPagerankVector, + double *convergedPagerankVector, 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(SparseMatrix *transitionMatrix, double **pagerankVector, +int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector, bool *convergenceStatus, Parameters parameters); #endif // SERIAL_GS_PAGERANK_FUNCTIONS_H \ No newline at end of file diff --git a/serial/sparse_matrix.c b/serial/sparse_matrix.c deleted file mode 100644 index 2df1b0d..0000000 --- a/serial/sparse_matrix.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "sparse_matrix.h" - -SparseMatrix createSparseMatrix() { - SparseMatrix sparseMatrix; - sparseMatrix.elements = 0; - sparseMatrix.firstElement = NULL; - sparseMatrix.lastElement = NULL; - return sparseMatrix; -} - -void apendElement(SparseMatrix *sparseMatrix, double value, int row, int column) { - // Creates the new element - SparseMatrixElement *newElement = (SparseMatrixElement *) malloc(sizeof(SparseMatrixElement)); - newElement->value = value; - newElement->rowIndex = row; - newElement->columnIndex = column; - newElement->nextElement = NULL; - - if (sparseMatrix->firstElement == NULL) { - // Sparse matrix is empty, this is the first element - sparseMatrix->firstElement = newElement; - sparseMatrix->lastElement = newElement; - } else { - //Gets last element of the matrix - SparseMatrixElement *lastElement = sparseMatrix->lastElement; - - lastElement->nextElement = newElement; - sparseMatrix->lastElement = newElement; - } - - sparseMatrix->elements = sparseMatrix->elements + 1; -} - -bool deleteElement(SparseMatrix *sparseMatrix, int row, int column) { - if (sparseMatrix->elements == 0) { - // Matrix is empty, nothing can be deleted - return false; - } else if (sparseMatrix->elements == 1) { - // Matrix has one element. Deletes it. - free(sparseMatrix->firstElement); - sparseMatrix->firstElement = NULL; - sparseMatrix->lastElement = NULL; - sparseMatrix->elements = sparseMatrix->elements - 1; - return true; - } - - SparseMatrixElement *currentElement = sparseMatrix->firstElement; - - if (currentElement->rowIndex == row && currentElement->columnIndex == column) { - sparseMatrix->firstElement = currentElement->nextElement; - free(currentElement); - sparseMatrix->elements = sparseMatrix->elements - 1; - return true; - } - - // Matrix has multiple elements. Finds the first element that has the coordinates - // (row,column) and deletes it. - for (int i=0; ielements - 1; ++i) { - SparseMatrixElement *nextElement = currentElement->nextElement; - if (nextElement->rowIndex == row && nextElement->columnIndex == column) { - currentElement->nextElement = nextElement->nextElement; - if (currentElement->nextElement == NULL) { - sparseMatrix->lastElement = currentElement; - } - free(nextElement); - sparseMatrix->elements = sparseMatrix->elements - 1; - return true; - } else { - currentElement = currentElement->nextElement; - } - } -} - -SparseMatrixElement *getElement(SparseMatrix sparseMatrix, int row, int column) { - SparseMatrixElement *currentElement = sparseMatrix.firstElement; - do { - if (currentElement->rowIndex == row && currentElement->columnIndex == column) { - return currentElement; - } - currentElement = currentElement->nextElement; - } while (currentElement != NULL); - - return NULL; -} - -void transposeSparseMatrix(SparseMatrix *sparseMatrix) { - SparseMatrixElement *currentElement = sparseMatrix->firstElement; - for (int i=0; ielements; ++i) { - int temp = currentElement->rowIndex; - currentElement->rowIndex = currentElement->columnIndex; - currentElement->columnIndex = temp; - - currentElement = currentElement->nextElement; - } -} - -void sparseMatrixVectorMultiplication(SparseMatrix sparseMatrix, - double *vector, double **product, int vectorSize) { - // Initializes the elements of the product vector to zero - for (int i=0; irowIndex, column = element->columnIndex; - - if (row >= vectorSize) { - printf("Error at sparseMatrixVectorMultiplication. Matrix has more rows than vector!\n"); - printf("row = %d\n", row); - exit(EXIT_FAILURE); - } - - (*product)[row] = (*product)[row] + element->value * vector[column]; - element = element->nextElement; - } -} - -void printSparseMatrix(SparseMatrix sparseMatrix) { - if (sparseMatrix.elements == 0) { - return; - } - - SparseMatrixElement *currentElement = sparseMatrix.firstElement; - for (int i=0; irowIndex, - currentElement->columnIndex, currentElement->value); - currentElement = currentElement->nextElement; - } -} \ No newline at end of file diff --git a/serial/sparse_matrix.h b/serial/sparse_matrix.h deleted file mode 100644 index 7a977d2..0000000 --- a/serial/sparse_matrix.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef SPARSE_MATRIX_H /* Include guard */ -#define SPARSE_MATRIX_H - -#include -#include -#include -#include - -typedef struct sparseMatrixElement { - double value; - int rowIndex, columnIndex; - struct sparseMatrixElement *nextElement; -} SparseMatrixElement; - -typedef struct sparseMatrix { - int elements; - SparseMatrixElement *firstElement; - SparseMatrixElement *lastElement; -} SparseMatrix; - -SparseMatrix createSparseMatrix(); -void apendElement(SparseMatrix *sparseMatrix, double value, int row, int column); -bool deleteElement(SparseMatrix *sparseMatrix, int row, int column); -SparseMatrixElement *getElement(SparseMatrix sparseMatrix, int row, int column); -void transposeSparseMatrix(SparseMatrix *sparseMatrix); -void sparseMatrixVectorMultiplication(SparseMatrix sparseMatrix, double *vector, - double **product, int vectorSize); -void printSparseMatrix(SparseMatrix sparseMatrix); - -#endif // SPARSE_MATRIX_H \ No newline at end of file