functor (Spec : Interfaces.Specs.Eval->
  sig
    module Spec :
      sig
        module Kernel :
          sig
            type t = Spec.Kernel.t
            type params = Spec.Kernel.params
            val create : params -> t
            val get_params : t -> params
          end
        module Inducing :
          sig
            type t = Spec.Inducing.t
            val get_n_points : t -> int
            val calc_upper : Kernel.t -> t -> Lacaml.D.mat
          end
        module Input :
          sig
            type t = Spec.Input.t
            val eval : Kernel.t -> t -> Inducing.t -> Lacaml.D.vec
            val weighted_eval :
              Kernel.t -> t -> Inducing.t -> coeffs:Lacaml.D.vec -> float
            val eval_one : Kernel.t -> t -> float
          end
        module Inputs :
          sig
            type t = Spec.Inputs.t
            val create : Input.t array -> t
            val get_n_points : t -> int
            val choose_subset : t -> Gpr_utils.Int_vec.t -> t
            val create_inducing : Kernel.t -> t -> Inducing.t
            val create_default_kernel_params :
              t -> n_inducing:int -> Kernel.params
            val calc_upper : Kernel.t -> t -> Lacaml.D.mat
            val calc_diag : Kernel.t -> t -> Lacaml.D.vec
            val calc_cross :
              Kernel.t -> inputs:t -> inducing:Inducing.t -> Lacaml.D.mat
            val weighted_eval :
              Kernel.t ->
              inputs:t ->
              inducing:Inducing.t -> coeffs:Lacaml.D.vec -> Lacaml.D.vec
          end
      end
    module Inducing :
      sig
        type t
        val choose_n_first_inputs :
          Spec.Kernel.t -> Spec.Inputs.t -> n_inducing:int -> Spec.Inducing.t
        val choose_n_random_inputs :
          ?rnd_state:Core.Std.Random.State.t ->
          Spec.Kernel.t -> Spec.Inputs.t -> n_inducing:int -> Spec.Inducing.t
        val calc : Spec.Kernel.t -> Spec.Inducing.t -> t
        val get_points : t -> Spec.Inducing.t
      end
    module Input : sig type t val calc : Inducing.t -> Spec.Input.t -> t end
    module Inputs :
      sig
        type t
        val create_default_kernel :
          Spec.Inputs.t -> n_inducing:int -> Spec.Kernel.t
        val calc : Spec.Inputs.t -> Inducing.t -> t
        val get_points : t -> Spec.Inputs.t
      end
    module Model :
      sig
        type t
        type co_variance_coeffs
        val calc : Inputs.t -> sigma2:float -> t
        val update_sigma2 : t -> float -> t
        val calc_log_evidence : t -> float
        val calc_co_variance_coeffs : t -> co_variance_coeffs
        val get_kernel : t -> Spec.Kernel.t
        val get_sigma2 : t -> float
        val get_inputs : t -> Inputs.t
        val get_inducing : t -> Inducing.t
      end
    module Trained :
      sig
        type t
        val calc : Model.t -> targets:Lacaml.D.vec -> t
        val calc_mean_coeffs : t -> Lacaml.D.vec
        val calc_log_evidence : t -> float
        val get_model : t -> Model.t
        val get_targets : t -> Lacaml.D.vec
      end
    module Stats :
      sig
        type t = {
          n_samples : int;
          target_variance : float;
          sse : float;
          mse : float;
          rmse : float;
          smse : float;
          msll : float;
          mad : float;
          maxad : float;
        }
        val calc_n_samples : Trained.t -> int
        val calc_target_variance : Trained.t -> float
        val calc_sse : Trained.t -> float
        val calc_mse : Trained.t -> float
        val calc_rmse : Trained.t -> float
        val calc_smse : Trained.t -> float
        val calc_msll : Trained.t -> float
        val calc_mad : Trained.t -> float
        val calc_maxad : Trained.t -> float
        val calc : Trained.t -> t
      end
    module Mean_predictor :
      sig
        type t
        val calc : Spec.Inducing.t -> coeffs:Lacaml.D.vec -> t
        val calc_trained : Trained.t -> t
        val get_inducing : t -> Spec.Inducing.t
        val get_coeffs : t -> Lacaml.D.vec
      end
    module Mean :
      sig
        type t
        val calc : Mean_predictor.t -> Input.t -> t
        val get : t -> float
      end
    module Means :
      sig
        type t
        val calc : Mean_predictor.t -> Inputs.t -> t
        val get : t -> Lacaml.D.vec
      end
    module Co_variance_predictor :
      sig
        type t
        val calc :
          Spec.Kernel.t -> Spec.Inducing.t -> Model.co_variance_coeffs -> t
        val calc_model : Model.t -> t
      end
    module Variance :
      sig
        type t
        val calc : Co_variance_predictor.t -> sigma2:float -> Input.t -> t
        val get : ?predictive:bool -> t -> float
      end
    module Variances :
      sig
        type t
        val calc_model_inputs : Model.t -> t
        val calc : Co_variance_predictor.t -> sigma2:float -> Inputs.t -> t
        val get : ?predictive:bool -> t -> Lacaml.D.vec
      end
    module Covariances :
      sig
        type t
        val calc_model_inputs : Model.t -> t
        val calc : Co_variance_predictor.t -> sigma2:float -> Inputs.t -> t
        val get : ?predictive:bool -> t -> Lacaml.D.mat
        val get_variances : t -> Variances.t
      end
    module Sampler :
      sig
        type t
        val calc : ?predictive:bool -> Mean.t -> Variance.t -> t
        val sample : ?rng:Gsl.Rng.t -> t -> float
        val samples : ?rng:Gsl.Rng.t -> t -> n:int -> Lacaml.D.vec
      end
    module Cov_sampler :
      sig
        type t
        val calc : ?predictive:bool -> Means.t -> Covariances.t -> t
        val sample : ?rng:Gsl.Rng.t -> t -> Lacaml.D.vec
        val samples : ?rng:Gsl.Rng.t -> t -> n:int -> Lacaml.D.mat
      end
  end