#ifndef COEFFS_HPP
#define COEFFS_HPP

#include <cassert>
#include "config.hpp"
#include "rationnal.hpp"
#include "flint/fmpz.h"
#include "flint/fmpq.h"
#include "flint/fmpz_poly.h"


//**********************
//* Coefficients C_m,n *
//**********************

//! Maximal coefficinet index
static const size_t max_ind_coeffs=max_len/2+2;

//! Number of coefficients
static const size_t num_coeffs=((max_ind_coeffs+1)*(max_ind_coeffs+2))/2;

//! Array of coefficients
extern Reel coeffs[num_coeffs];
extern fmpz_poly_t coeffs_poly[num_coeffs];
extern fmpz_t coeffs_den;

//! Return the indice of coefficient C_{i,j}
size_t pos(size_t i,size_t j);

//! Return an approximation of coefficient C_{i,j}
Reel get_coeff(size_t i,size_t j);

//! Return polynom of coefficient C_{i,j}
void set_poly_coeff(size_t i,size_t j,fmpz_poly_t p);

//! Compute all the coefficients
void compute_coeffs();

//! Represent an analytic coefficient
struct CoeffAnalytic{
  //! The coefficient is a-4b/pi
  fmpq_t a,b;
};

//********************
//* Inline functions *
//********************

inline size_t
pos(size_t i,size_t j){
  return (j*(j+1))/2+i;
}

inline Reel
get_coeff(size_t i,size_t j){
  return i<j?coeffs[pos(i,j)]:coeffs[pos(j,i)];
}

inline void
set_poly_coeff(size_t i,size_t j,fmpz_poly_t p){
  size_t ind=i<j?pos(i,j):pos(j,i);
  fmpz_poly_set(p,coeffs_poly[ind]);
}
#endif
