/*
 * Helpfull functions for SpMV multiplication
 * 
 * Author: Petros Anastasiadis(panastas@cslab.ece.ntua.gr) 
 */
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "dmv.h"

void dmv_serial(double **a, const double *x, double *y,
                size_t n, size_t m)
{
    size_t  i, j;
	double yi;
    for (i = 0; i < n; ++i) {
        yi = 0.0 ;
        for (j = 0; j < m; ++j) {
            yi += a[i][j]*x[j];
        }
        y[i] = yi;
    }
}

void dmv_omp(double **a, const double *x, double *y,
                size_t n, size_t m)
{
    size_t  i, j;
	#pragma omp parallel for private(i,j) shared(n,m,a,y) schedule(dynamic)
    for (i = 0; i < n; ++i) {
        register double    _yi = 0;
        for (j = 0; j < m; ++j) {
            _yi += a[i][j]*x[j];
        }
        y[i] = _yi;
    }
}


void dmv_csr(int * csrPtr, int *csrCol, double * csrVal, double *x, double *ys, int n)
{
	int  i, j;
	for (i = 0; i < n; ++i) {
        	double yi = 0;
        	for (j = csrPtr[i]; j < csrPtr[i + 1]; j++) yi += csrVal[j] * x[csrCol[j]];
        	ys[i] = yi;
    	}
}

int vec_equals(const double *v1, const double *v2, size_t n, double eps)
{
	size_t  i,k=0;
    	for (i = 0; i < n; ++i) {
		if (fabs(v1[i] - v2[i]) > eps) k++;	
    	}
	return k;
}




void vec_print(const double *v, size_t n)
{
    size_t  i;
    for (i = 0; i < n; ++i)
        printf("%f\n", v[i]);
}
