sig
  module type Kernel =
    sig
      type t
      type params
      val create :
        Interfaces.Specs.Kernel.params -> Interfaces.Specs.Kernel.t
      val get_params :
        Interfaces.Specs.Kernel.t -> Interfaces.Specs.Kernel.params
    end
  module type Eval =
    sig
      module Kernel : Kernel
      module Inducing :
        sig
          type t
          val get_n_points : Interfaces.Specs.Eval.Inducing.t -> int
          val calc_upper :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Inducing.t -> Lacaml.D.mat
        end
      module Input :
        sig
          type t
          val eval :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Input.t ->
            Interfaces.Specs.Eval.Inducing.t -> Lacaml.D.vec
          val weighted_eval :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Input.t ->
            Interfaces.Specs.Eval.Inducing.t -> coeffs:Lacaml.D.vec -> float
          val eval_one :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Input.t -> float
        end
      module Inputs :
        sig
          type t
          val create :
            Interfaces.Specs.Eval.Input.t array ->
            Interfaces.Specs.Eval.Inputs.t
          val get_n_points : Interfaces.Specs.Eval.Inputs.t -> int
          val choose_subset :
            Interfaces.Specs.Eval.Inputs.t ->
            Gpr_utils.Int_vec.t -> Interfaces.Specs.Eval.Inputs.t
          val create_inducing :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Eval.Inducing.t
          val create_default_kernel_params :
            Interfaces.Specs.Eval.Inputs.t ->
            n_inducing:int -> Interfaces.Specs.Kernel.params
          val calc_upper :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Inputs.t -> Lacaml.D.mat
          val calc_diag :
            Interfaces.Specs.Kernel.t ->
            Interfaces.Specs.Eval.Inputs.t -> Lacaml.D.vec
          val calc_cross :
            Interfaces.Specs.Kernel.t ->
            inputs:Interfaces.Specs.Eval.Inputs.t ->
            inducing:Interfaces.Specs.Eval.Inducing.t -> Lacaml.D.mat
          val weighted_eval :
            Interfaces.Specs.Kernel.t ->
            inputs:Interfaces.Specs.Eval.Inputs.t ->
            inducing:Interfaces.Specs.Eval.Inducing.t ->
            coeffs:Lacaml.D.vec -> Lacaml.D.vec
        end
    end
  module type Deriv =
    sig
      module Eval : Eval
      module Hyper :
        sig
          type t
          val get_all :
            Eval.Kernel.t ->
            Interfaces.Specs.Eval.Inducing.t ->
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Deriv.Hyper.t array
          val get_value :
            Eval.Kernel.t ->
            Interfaces.Specs.Eval.Inducing.t ->
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Deriv.Hyper.t -> float
          val set_values :
            Eval.Kernel.t ->
            Interfaces.Specs.Eval.Inducing.t ->
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Deriv.Hyper.t array ->
            Lacaml.D.vec ->
            Eval.Kernel.t * Interfaces.Specs.Eval.Inducing.t *
            Interfaces.Specs.Eval.Inputs.t
        end
      module Inducing :
        sig
          type upper
          val calc_shared_upper :
            Eval.Kernel.t ->
            Interfaces.Specs.Eval.Inducing.t ->
            Lacaml.D.mat * Interfaces.Specs.Deriv.Inducing.upper
          val calc_deriv_upper :
            Interfaces.Specs.Deriv.Inducing.upper ->
            Interfaces.Specs.Deriv.Hyper.t -> Interfaces.symm_mat_deriv
        end
      module Inputs :
        sig
          type diag
          type cross
          val calc_shared_diag :
            Eval.Kernel.t ->
            Interfaces.Specs.Eval.Inputs.t ->
            Lacaml.D.vec * Interfaces.Specs.Deriv.Inputs.diag
          val calc_shared_cross :
            Eval.Kernel.t ->
            inputs:Interfaces.Specs.Eval.Inputs.t ->
            inducing:Interfaces.Specs.Eval.Inducing.t ->
            Lacaml.D.mat * Interfaces.Specs.Deriv.Inputs.cross
          val calc_deriv_diag :
            Interfaces.Specs.Deriv.Inputs.diag ->
            Interfaces.Specs.Deriv.Hyper.t -> Interfaces.diag_deriv
          val calc_deriv_cross :
            Interfaces.Specs.Deriv.Inputs.cross ->
            Interfaces.Specs.Deriv.Hyper.t -> Interfaces.mat_deriv
        end
    end
  module type Optimizer =
    sig
      module Eval : Eval
      module Var : sig type t end
      module Input :
        sig
          val get_vars :
            Interfaces.Specs.Eval.Input.t ->
            Interfaces.Specs.Optimizer.Var.t array
          val get_value :
            Interfaces.Specs.Eval.Input.t ->
            Interfaces.Specs.Optimizer.Var.t -> float
          val set_values :
            Interfaces.Specs.Eval.Input.t ->
            Interfaces.Specs.Optimizer.Var.t array ->
            Lacaml.D.vec -> Interfaces.Specs.Eval.Input.t
        end
      module Inputs :
        sig
          val get_vars :
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Optimizer.Var.t array
          val get_value :
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Optimizer.Var.t -> float
          val set_values :
            Interfaces.Specs.Eval.Inputs.t ->
            Interfaces.Specs.Optimizer.Var.t array ->
            Lacaml.D.vec -> Interfaces.Specs.Eval.Inputs.t
        end
    end
end