(* gsl-ocaml - OCaml interface to GSL                       *)
(* Copyright (©) 2002-2012 - Olivier Andrieu                *)
(* Distributed under the terms of the GPL version 3         *)

let () = Error.init ()

type t

external _alloc : int -> t = "ml_gsl_cheb_alloc"
external _free : t -> unit = "ml_gsl_cheb_free"

let make n =
  let cs = _alloc n in
  Gc.finalise _free cs;
  cs

external order : t -> int = "ml_gsl_cheb_order"
external coefs : t -> float array = "ml_gsl_cheb_coefs"

external init : t -> Fun.gsl_fun -> a:float -> b:float -> unit
  = "ml_gsl_cheb_init"

external _eval : t -> float -> float = "ml_gsl_cheb_eval"
external _eval_err : t -> float -> Fun.result = "ml_gsl_cheb_eval_err"
external _eval_n : t -> int -> float -> float = "ml_gsl_cheb_eval_n"

external _eval_n_err : t -> int -> float -> Fun.result
  = "ml_gsl_cheb_eval_n_err"

let eval cs ?order x =
  match order with None -> _eval cs x | Some o -> _eval_n cs o x

let eval_err cs ?order x =
  match order with None -> _eval_err cs x | Some o -> _eval_n_err cs o x

external calc_deriv : t -> t -> unit = "ml_gsl_cheb_calc_deriv"
external calc_integ : t -> t -> unit = "ml_gsl_cheb_calc_integ"

let deriv cs =
  let d = make (order cs) in
  calc_deriv d cs;
  d

let integ cs =
  let d = make (order cs) in
  calc_integ d cs;
  d
