pagerank implementation
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.pdf
|
||||
out/
|
||||
data/
|
51
Makefile
Normal file
51
Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
# --------------------------------------------------
|
||||
# Configuration
|
||||
# --------------------------------------------------
|
||||
CC := gcc
|
||||
CFLAGS := -Wall -fopenmp -O3
|
||||
SRCDIR := src
|
||||
OBJDIR := out
|
||||
DATAPATH := data/web-Google/web-Google.mtx
|
||||
|
||||
#
|
||||
SRCS := $(wildcard $(SRCDIR)/*.c)
|
||||
OBJS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
|
||||
|
||||
# --------------------------------------------------
|
||||
# Phony targets
|
||||
# --------------------------------------------------
|
||||
.PHONY: all sparse clean
|
||||
|
||||
all: sparse
|
||||
|
||||
sparse: $(OBJDIR)/sparse | $(OBJDIR)
|
||||
@echo "→ Running sparse"
|
||||
./$(OBJDIR)/sparse
|
||||
|
||||
# --------------------------------------------------
|
||||
# Link
|
||||
# --------------------------------------------------
|
||||
$(OBJDIR)/sparse: $(OBJS) $(DATAPATH) | $(OBJDIR)
|
||||
@echo "→ Copying input data"
|
||||
cp $(DATAPATH) $(OBJDIR)/input.rb
|
||||
@echo "→ Linking $@"
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Compile
|
||||
# --------------------------------------------------
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
|
||||
@echo "→ Compiling $<"
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# --------------------------------------------------
|
||||
# Check if output directory exists
|
||||
# --------------------------------------------------
|
||||
$(OBJDIR):
|
||||
mkdir -p $(OBJDIR)
|
||||
|
||||
# --------------------------------------------------
|
||||
# Clean
|
||||
# --------------------------------------------------
|
||||
clean:
|
||||
rm -rf $(OBJDIR)/*
|
34
src/main.c
Normal file
34
src/main.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "matrix_operation.h"
|
||||
#include "sparse_matrix.h"
|
||||
#include "read_from_rb.h"
|
||||
#include "power_algorithm.h"
|
||||
#include "time_helper.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
void test_pagerank(const char *path) {
|
||||
struct timeval tvstart, tv;
|
||||
gettimeofday(&tvstart, NULL);
|
||||
|
||||
SparseMatrix *matrix = read_sparse_matrix_from_mtx(path);
|
||||
convert_to_stochastic(matrix);
|
||||
// Time 2
|
||||
gettimeofday(&tv, NULL);
|
||||
print_time_diff("read matrix", &tvstart, &tv);
|
||||
double *result = malloc(matrix->num_nodes * sizeof(double));
|
||||
if (result == NULL) {
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
result = pagerank(matrix, 1e-10, 0.35);
|
||||
// Time 3
|
||||
gettimeofday(&tv, NULL);
|
||||
print_time_diff("finish", &tvstart, &tv);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_pagerank("./out/input.rb");
|
||||
|
||||
return 0;
|
||||
}
|
68
src/matrix_operation.c
Normal file
68
src/matrix_operation.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include "matrix_operation.h"
|
||||
#include "vector.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void multiply_vector_matrix(const double *vector, const SparseMatrix *matrix, double *result) {
|
||||
init_vector(result, matrix->num_nodes, 0.0);
|
||||
for (int i = 0; i < matrix->num_arcs; ++i) {
|
||||
int origin = matrix->arcs[i].origin;
|
||||
int dest = matrix->arcs[i].dest;
|
||||
result[dest] += vector[origin] * matrix->arcs[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void multiply_vector_matrix_parallel(const double *vector, const SparseMatrix *matrix, double *result) {
|
||||
int num_nodes = matrix->num_nodes;
|
||||
int num_arcs = matrix->num_arcs;
|
||||
init_vector(result, num_nodes, 0.0);
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
double *local_result = (double *)calloc(num_nodes, sizeof(double));
|
||||
|
||||
// parallelize for loop
|
||||
#pragma omp for
|
||||
for (int i = 0; i < num_arcs; ++i) {
|
||||
int origin = matrix->arcs[i].origin;
|
||||
int dest = matrix->arcs[i].dest;
|
||||
local_result[dest] += vector[origin] * matrix->arcs[i].value;
|
||||
}
|
||||
|
||||
// merge results
|
||||
for (int j = 0; j < num_nodes; ++j) {
|
||||
double val = local_result[j];
|
||||
if (val != 0.0) {
|
||||
#pragma omp atomic
|
||||
result[j] += val;
|
||||
}
|
||||
}
|
||||
|
||||
free(local_result);
|
||||
}
|
||||
}
|
||||
|
||||
void convert_to_stochastic(SparseMatrix *matrix) {
|
||||
double *non_zero = (double *)calloc(matrix->num_nodes, sizeof(double));
|
||||
if (!non_zero) {
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// count non zero values
|
||||
for (int i = 0; i < matrix->num_arcs; i++) {
|
||||
non_zero[matrix->arcs[i].dest] += matrix->arcs[i].value;
|
||||
}
|
||||
|
||||
// normalize values
|
||||
for (int i = 0; i < matrix->num_arcs; i++) {
|
||||
int dest = matrix->arcs[i].dest;
|
||||
double old_value = matrix->arcs[i].value;
|
||||
matrix->arcs[i].value = old_value / (double)non_zero[dest];
|
||||
}
|
||||
|
||||
free(non_zero);
|
||||
}
|
||||
|
9
src/matrix_operation.h
Normal file
9
src/matrix_operation.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef MATRIX_OPERATION_H
|
||||
#define MATRIX_OPERATION_H
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void multiply_vector_matrix(const double *vector, const SparseMatrix *matrix, double *result);
|
||||
void multiply_vector_matrix_parallel(const double *vector, const SparseMatrix *matrix, double *result);
|
||||
void convert_to_stochastic(SparseMatrix *matrix);
|
||||
|
||||
#endif
|
21
src/matrix_print.c
Normal file
21
src/matrix_print.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void print_vector(double *vector, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
printf("%lf ", vector[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_sparse_matrix(const SparseMatrix *matrix) {
|
||||
if (matrix) {
|
||||
printf("%d %d %d\n", matrix->num_nodes, matrix->num_nodes, matrix->num_arcs);
|
||||
for (int i = 0; i < matrix->num_arcs; ++i) {
|
||||
printf("%d ", matrix->arcs[i].origin + 1);
|
||||
printf("%d ", matrix->arcs[i].dest + 1);
|
||||
printf("%.10f ", matrix->arcs[i].value);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
8
src/matrix_print.h
Normal file
8
src/matrix_print.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef MATRIX_PRINT_H
|
||||
#define MATRIX_PRINT_H
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void print_vector(double *vector, int size);
|
||||
void print_sparse_matrix(const SparseMatrix *matrix);
|
||||
|
||||
#endif
|
78
src/power_algorithm.c
Normal file
78
src/power_algorithm.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sparse_matrix.h"
|
||||
#include "matrix_operation.h"
|
||||
#include "vector.h"
|
||||
|
||||
double* power_algorithm_step(const SparseMatrix *matrix, const double *pi) {
|
||||
double* result = malloc(matrix->num_nodes*sizeof(double));
|
||||
multiply_vector_matrix_parallel(pi, matrix, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
double* power_algorithm(const SparseMatrix *matrix, double epsilon) {
|
||||
int N = matrix->num_nodes;
|
||||
int vecsize = N*sizeof(double);
|
||||
double* pi = malloc(vecsize);
|
||||
double* pi2 = malloc(vecsize);
|
||||
init_vector(pi, N, 1.0/(double)N);
|
||||
pi2 = power_algorithm_step(matrix, pi);
|
||||
while (diff_norm_vector(pi, pi2, N)>epsilon) {
|
||||
printf("step\n");
|
||||
memcpy(pi, pi2, vecsize);
|
||||
pi2 = power_algorithm_step(matrix, pi);
|
||||
}
|
||||
return pi2;
|
||||
}
|
||||
|
||||
double* pagerank(const SparseMatrix *matrix, double epsilon, double alpha) {
|
||||
int N = matrix->num_nodes;
|
||||
size_t vec_size = N * sizeof(double);
|
||||
|
||||
double* pi = malloc(vec_size);
|
||||
double* pi_new = malloc(vec_size);
|
||||
double* f = malloc(vec_size);
|
||||
double right_const = (1.0 - alpha) / N;
|
||||
|
||||
init_vector(pi, N, 1.0 / N);
|
||||
|
||||
generate_f(matrix, f);
|
||||
|
||||
double diff;
|
||||
int iter = 0;
|
||||
|
||||
do {
|
||||
// 1. pi * M
|
||||
double* temp = power_algorithm_step(matrix, pi);
|
||||
|
||||
// 2. alpha/N * (pi * f)
|
||||
double right_var = (alpha/(double)N) * vec_product(pi, f, N);
|
||||
|
||||
// 3. alpha*(pi*M) + (right_const+alpha/N * (pi * f))*e
|
||||
for (int i = 0; i < N; i++) {
|
||||
pi_new[i] = alpha * temp[i] + right_const + right_var;
|
||||
}
|
||||
|
||||
// 4. Normalize
|
||||
normalize_vector(pi_new, N);
|
||||
|
||||
// 5. Calculate convergence
|
||||
diff = diff_norm_vector(pi, pi_new, N);
|
||||
|
||||
// 6. Update for next iteration
|
||||
free(pi);
|
||||
pi = pi_new;
|
||||
pi_new = malloc(vec_size);
|
||||
|
||||
if ((++iter)%1 == 0) {
|
||||
printf("Iteration %d: diff = %.16f\n", iter, diff);
|
||||
}
|
||||
free(temp);
|
||||
} while (diff > epsilon);
|
||||
|
||||
free(pi_new);
|
||||
free(f);
|
||||
return pi;
|
||||
}
|
||||
|
8
src/power_algorithm.h
Normal file
8
src/power_algorithm.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef POWER_ALGORITHM_H
|
||||
#define POWER_ALGORITHM_H
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
double* power_algorithm(const SparseMatrix *matrix, double epsilon);
|
||||
double* pagerank(const SparseMatrix *matrix, double epsilon, double alpha);
|
||||
|
||||
#endif
|
71
src/read_from_mtx.c
Normal file
71
src/read_from_mtx.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
int read_dims_ignore_comment(SparseMatrix *matrix, FILE *file) {
|
||||
char buffer[1024];
|
||||
int read_dims = 0;
|
||||
while (fgets(buffer, sizeof(buffer), file) != NULL) {
|
||||
char *line = buffer;
|
||||
if (*line == '%' || *line == '\n' || *line == '\0') {
|
||||
continue;
|
||||
} else {
|
||||
if (sscanf(line, "%d %d", &matrix->num_nodes, &matrix->num_arcs) != 2) {
|
||||
return 1;
|
||||
}
|
||||
read_dims = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (!read_dims);
|
||||
}
|
||||
|
||||
void parse_arcs(SparseMatrix *matrix, FILE *file) {
|
||||
for (int i = 0; i < matrix->num_arcs; ++i) {
|
||||
char line[256];
|
||||
if (fgets(line, sizeof(line), file) == NULL) {
|
||||
fprintf(stderr, "Failed to read arc %d\n", i);
|
||||
exit(5);
|
||||
}
|
||||
char *ptr = line;
|
||||
int origin, dest;
|
||||
double value = 1.0;
|
||||
if (sscanf(ptr, "%d %d %lf", &origin, &dest, &value) < 2) {
|
||||
fprintf(stderr, "Failed to read arc %d\n", i);
|
||||
exit(5);
|
||||
} else {
|
||||
matrix->arcs[i].origin = origin;
|
||||
matrix->arcs[i].dest = dest;
|
||||
matrix->arcs[i].value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SparseMatrix* read_sparse_matrix_from_mtx(const char *filename) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Failed to read file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SparseMatrix *matrix = (SparseMatrix*)malloc(sizeof(SparseMatrix));
|
||||
if (!matrix) {
|
||||
fprintf(stderr, "Failed to allocate memory for matrix\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
if (read_dims_ignore_comment(matrix, file)) {
|
||||
fprintf(stderr, "Failed to read matrix dimensions\n");
|
||||
}
|
||||
|
||||
matrix->arcs = (Arc*)malloc(matrix->num_arcs * sizeof(Arc));
|
||||
if (!matrix->arcs) {
|
||||
fprintf(stderr, "Failed to allocate memory for arcs\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
parse_arcs(matrix, file);
|
||||
|
||||
fclose(file);
|
||||
return matrix;
|
||||
}
|
7
src/read_from_mtx.h
Normal file
7
src/read_from_mtx.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef MATRIX_READ_MTX_H
|
||||
#define MATRIX_READ_MTX_H
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
SparseMatrix* read_sparse_matrix_from_mtx(const char *filename);
|
||||
|
||||
#endif
|
105
src/read_from_rb.c
Normal file
105
src/read_from_rb.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "read_from_rb.h"
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
SparseMatrix* read_sparse_matrix_from_rb(const char *filename) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Failed to open file %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SparseMatrix *matrix = (SparseMatrix*)malloc(sizeof(SparseMatrix));
|
||||
if (!matrix) {
|
||||
fprintf(stderr, "Failed to allocate memory for matrix\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
fgets(buffer, sizeof(buffer), file);
|
||||
fgets(buffer, sizeof(buffer), file);
|
||||
|
||||
fgets(buffer, sizeof(buffer), file);
|
||||
char type[4];
|
||||
int rows, cols, nonzero;
|
||||
if (sscanf(buffer, "%3s %d %d %d", type, &rows, &cols, &nonzero) != 4) {
|
||||
fprintf(stderr, "Failed to read matrix metadata\n");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
matrix->num_nodes = rows;
|
||||
matrix->num_arcs = nonzero;
|
||||
matrix->arcs = (Arc*)malloc(nonzero * sizeof(Arc));
|
||||
if (!matrix->arcs) {
|
||||
fprintf(stderr, "Failed to allocate memory for arcs\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
fgets(buffer, sizeof(buffer), file);
|
||||
|
||||
int *col_ptr = (int*)malloc((cols + 1) * sizeof(int));
|
||||
int ptr_index = 0;
|
||||
while (ptr_index < cols + 1) {
|
||||
if (fgets(buffer, sizeof(buffer), file) == NULL) {
|
||||
fprintf(stderr, "Unexpected end of file while reading column pointers\n");
|
||||
exit(5);
|
||||
}
|
||||
char *ptr = buffer;
|
||||
int num_read;
|
||||
while (sscanf(ptr, "%d%n", &col_ptr[ptr_index], &num_read) == 1) {
|
||||
ptr += num_read;
|
||||
ptr_index++;
|
||||
}
|
||||
}
|
||||
|
||||
int *row_ind = (int*)malloc(nonzero * sizeof(int));
|
||||
int row_index = 0;
|
||||
while (row_index < nonzero) {
|
||||
if (fgets(buffer, sizeof(buffer), file) == NULL) {
|
||||
fprintf(stderr, "Unexpected end of file while reading row indices\n");
|
||||
exit(6);
|
||||
}
|
||||
char *ptr = buffer;
|
||||
int num_read;
|
||||
while (sscanf(ptr, "%d%n", &row_ind[row_index], &num_read) == 1) {
|
||||
ptr += num_read;
|
||||
row_index++;
|
||||
}
|
||||
}
|
||||
|
||||
double *values = (double*)malloc(nonzero * sizeof(double));
|
||||
int val_index = 0;
|
||||
while (val_index < nonzero) {
|
||||
if (fgets(buffer, sizeof(buffer), file) == NULL) {
|
||||
fprintf(stderr, "Unexpected end of file while reading values\n");
|
||||
exit(7);
|
||||
}
|
||||
char *ptr = buffer;
|
||||
int num_read;
|
||||
double val;
|
||||
while (sscanf(ptr, "%lf%n", &val, &num_read) == 1) {
|
||||
values[val_index] = val;
|
||||
ptr += num_read;
|
||||
val_index++;
|
||||
}
|
||||
}
|
||||
|
||||
int arc_idx = 0;
|
||||
for (int j = 0; j < cols; j++) {
|
||||
int start = col_ptr[j] - 1;
|
||||
int end = col_ptr[j + 1] - 1;
|
||||
for (int k = start; k < end; k++) {
|
||||
matrix->arcs[arc_idx].origin = j;
|
||||
matrix->arcs[arc_idx].dest = row_ind[k] - 1;
|
||||
matrix->arcs[arc_idx].value = values[k];
|
||||
arc_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
free(col_ptr);
|
||||
free(row_ind);
|
||||
free(values);
|
||||
fclose(file);
|
||||
return matrix;
|
||||
}
|
8
src/read_from_rb.h
Normal file
8
src/read_from_rb.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef RB_READER_H
|
||||
#define RB_READER_H
|
||||
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
SparseMatrix* read_sparse_matrix_from_rb(const char *filename);
|
||||
|
||||
#endif
|
11
src/sparse_matrix.c
Normal file
11
src/sparse_matrix.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "sparse_matrix.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void free_sparse_matrix(SparseMatrix *matrix) {
|
||||
if (matrix) {
|
||||
free(matrix->arcs);
|
||||
free(matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
21
src/sparse_matrix.h
Normal file
21
src/sparse_matrix.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef SPARSE_MATRIX_H
|
||||
#define SPARSE_MATRIX_H
|
||||
|
||||
typedef struct {
|
||||
int origin;
|
||||
int dest;
|
||||
double value;
|
||||
} Arc;
|
||||
|
||||
typedef struct {
|
||||
int num_nodes;
|
||||
int num_arcs;
|
||||
Arc *arcs;
|
||||
} SparseMatrix;
|
||||
|
||||
void free_sparse_matrix(SparseMatrix *matrix);
|
||||
void print_sparse_matrix(const SparseMatrix *matrix);
|
||||
SparseMatrix* read_sparse_matrix_from_mtx(const char *filename);
|
||||
void multiply_vector_matrix(const double *vector, const SparseMatrix *matrix, double *result);
|
||||
|
||||
#endif
|
12
src/time_helper.c
Normal file
12
src/time_helper.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void print_time_diff(const char* label, struct timeval* start, struct timeval* end) {
|
||||
long seconds = end->tv_sec - start->tv_sec;
|
||||
long microseconds = end->tv_usec - start->tv_usec;
|
||||
if (microseconds < 0) {
|
||||
seconds -= 1;
|
||||
microseconds += 1000000;
|
||||
}
|
||||
printf("%s: %ld.%ld seconds\n", label, seconds, microseconds);
|
||||
}
|
6
src/time_helper.h
Normal file
6
src/time_helper.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef TIME_HELPER_H
|
||||
#define TIME_HELPER_H
|
||||
|
||||
void print_time_diff(const char* label, struct timeval* start, struct timeval* end);
|
||||
|
||||
#endif
|
43
src/vector.c
Normal file
43
src/vector.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <math.h>
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void init_vector(double *vector, int size, double value) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
vector[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
double diff_norm_vector(double *vector1, double *vector2, int size) {
|
||||
double res = 0.0;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
res += fabs(vector1[i] - vector2[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_f(const SparseMatrix *matrix, double *res) {
|
||||
int N = matrix->num_nodes;
|
||||
init_vector(res, N, 0);
|
||||
int num_arcs = matrix->num_arcs;
|
||||
for (int i = 0; i < num_arcs; ++i) {
|
||||
res[matrix->arcs[i].dest] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
double vec_product(const double* v1, const double* v2, int N) {
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
sum += v1[i] * v2[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void normalize_vector(double* v, int N) {
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < N; i++) {
|
||||
sum += v[i];
|
||||
}
|
||||
for (int i = 0; i < N; i++) {
|
||||
v[i] /= sum;
|
||||
}
|
||||
}
|
11
src/vector.h
Normal file
11
src/vector.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef VECTOR_H
|
||||
#define VECTOR_H
|
||||
#include "sparse_matrix.h"
|
||||
|
||||
void init_vector(double *vector, int size, double value);
|
||||
double diff_norm_vector(double *vector1, double *vector2, int size);
|
||||
void generate_f(const SparseMatrix *matrix, double *res);
|
||||
void normalize_vector(double* v, int N);
|
||||
double vec_product(const double* v1, const double* v2, int N);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user