#pragma once 
#include <vector>
#include <cstddef>

// now we declare functions that we define in benh_funcs.cpp
double dot_basic(const std::vector<double>& x, const std::vector<double>& y);
double dot_kahan(const std::vector<double>& x, const std::vector<double>& y);
double norm_basic(const std::vector<double>& x);

void matvec_rowmajor(const std::vector<double>& A, std::size_t M, std::size_t N,
                     const std::vector<double>& x, std::vector<double>& b);

void matmul_rowmajor(const std::vector<double>& A, std::size_t M, std::size_t L,
                     const std::vector<double>& B, std::size_t N,
                     std::vector<double>& C);

void polyp_horner(const std::vector<double>& a, const std::vector<double>& x,
                  std::vector<double>& y);

struct CSR { //compressed Sparse Row
    std::size_t n;                 // number of rows
    std::vector<double> val;       // non-zero values
    std::vector<std::size_t> col;  // column indices
    std::vector<std::size_t> row_ptr; // row pointers (size n+1)
};
void jacobi_csr(const CSR& K, const std::vector<double>& f, std::vector<double>& u,
                std::size_t max_iter, double omega, double tol);
