sig
  module Spec :
    sig
      module Eval :
        sig
          module Kernel :
            sig
              type t = Eval.Spec.Kernel.t
              type params = Eval.Spec.Kernel.params
              val create : params -> t
              val get_params : t -> params
            end
          module Inducing :
            sig
              type t = Eval.Spec.Inducing.t
              val get_n_points : t -> int
              val calc_upper : Kernel.t -> t -> Lacaml.D.mat
            end
          module Input :
            sig
              type t = Eval.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 = Eval.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 Hyper :
        sig
          type t
          val get_all :
            Eval.Kernel.t -> Eval.Inducing.t -> Eval.Inputs.t -> t array
          val get_value :
            Eval.Kernel.t -> Eval.Inducing.t -> Eval.Inputs.t -> t -> float
          val set_values :
            Eval.Kernel.t ->
            Eval.Inducing.t ->
            Eval.Inputs.t ->
            t array ->
            Lacaml.D.vec -> Eval.Kernel.t * Eval.Inducing.t * Eval.Inputs.t
        end
      module Inducing :
        sig
          type upper
          val calc_shared_upper :
            Eval.Kernel.t -> Eval.Inducing.t -> Lacaml.D.mat * upper
          val calc_deriv_upper : upper -> Hyper.t -> symm_mat_deriv
        end
      module Inputs :
        sig
          type diag
          type cross
          val calc_shared_diag :
            Eval.Kernel.t -> Eval.Inputs.t -> Lacaml.D.vec * diag
          val calc_shared_cross :
            Eval.Kernel.t ->
            inputs:Eval.Inputs.t ->
            inducing:Eval.Inducing.t -> Lacaml.D.mat * cross
          val calc_deriv_diag : diag -> Hyper.t -> diag_deriv
          val calc_deriv_cross : cross -> Hyper.t -> mat_deriv
        end
    end
  module Inducing :
    sig
      type t
      val calc :
        Eval.Spec.Kernel.t ->
        Eval.Spec.Inducing.t -> Gpr_interfaces.Sigs.Deriv.Deriv.Inducing.t
      val calc_eval :
        Gpr_interfaces.Sigs.Deriv.Deriv.Inducing.t ->
        Gpr_interfaces.Sigs.Eval.Inducing.t
    end
  module Inputs :
    sig
      type t
      val calc :
        Gpr_interfaces.Sigs.Deriv.Deriv.Inducing.t ->
        Eval.Spec.Inputs.t -> Gpr_interfaces.Sigs.Deriv.Deriv.Inputs.t
      val calc_eval :
        Gpr_interfaces.Sigs.Deriv.Deriv.Inputs.t ->
        Gpr_interfaces.Sigs.Eval.Inputs.t
    end
  module Model :
    sig
      type t
      type hyper_t
      val calc :
        Gpr_interfaces.Sigs.Deriv.Deriv.Inputs.t ->
        sigma2:float -> Gpr_interfaces.Sigs.Deriv.Deriv.Model.t
      val update_sigma2 :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.t ->
        float -> Gpr_interfaces.Sigs.Deriv.Deriv.Model.t
      val calc_eval :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.t ->
        Gpr_interfaces.Sigs.Eval.Model.t
      val calc_log_evidence_sigma2 :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.t -> float
      val prepare_hyper :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.t ->
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.hyper_t
      val calc_log_evidence :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.hyper_t ->
        Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t -> float
    end
  module Trained :
    sig
      type t
      type hyper_t
      val calc :
        Gpr_interfaces.Sigs.Deriv.Deriv.Model.t ->
        targets:Lacaml.D.vec -> Gpr_interfaces.Sigs.Deriv.Deriv.Trained.t
      val calc_eval :
        Gpr_interfaces.Sigs.Deriv.Deriv.Trained.t ->
        Gpr_interfaces.Sigs.Eval.Trained.t
      val calc_log_evidence_sigma2 :
        Gpr_interfaces.Sigs.Deriv.Deriv.Trained.t -> float
      val prepare_hyper :
        Gpr_interfaces.Sigs.Deriv.Deriv.Trained.t ->
        Gpr_interfaces.Sigs.Deriv.Deriv.Trained.hyper_t
      val calc_log_evidence :
        Gpr_interfaces.Sigs.Deriv.Deriv.Trained.hyper_t ->
        Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t -> float
    end
  module Test :
    sig
      val check_deriv_hyper :
        ?eps:float ->
        ?tol:float ->
        Eval.Spec.Kernel.t ->
        Eval.Spec.Inducing.t ->
        Eval.Spec.Inputs.t ->
        Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t -> unit
      val self_test :
        ?eps:float ->
        ?tol:float ->
        Eval.Spec.Kernel.t ->
        Eval.Spec.Inducing.t ->
        Eval.Spec.Inputs.t ->
        sigma2:float ->
        targets:Lacaml.D.vec ->
        [ `Hyper of Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t | `Sigma2 ] ->
        unit
    end
  module Optim :
    sig
      module Gsl :
        sig
          exception Optim_exception of exn
          val train :
            ?step:float ->
            ?tol:float ->
            ?epsabs:float ->
            ?report_trained_model:(iter:int ->
                                   Gpr_interfaces.Sigs.Eval.Trained.t -> unit) ->
            ?report_gradient_norm:(iter:int -> float -> unit) ->
            ?kernel:Eval.Spec.Kernel.t ->
            ?sigma2:float ->
            ?inducing:Eval.Spec.Inducing.t ->
            ?n_rand_inducing:int ->
            ?learn_sigma2:bool ->
            ?hypers:Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t array ->
            inputs:Eval.Spec.Inputs.t ->
            targets:Lacaml.D.vec ->
            unit -> Gpr_interfaces.Sigs.Eval.Trained.t
        end
      module SGD :
        sig
          type t
          val create :
            ?tau:float ->
            ?eta0:float ->
            ?step:int ->
            ?kernel:Eval.Spec.Kernel.t ->
            ?sigma2:float ->
            ?inducing:Eval.Spec.Inducing.t ->
            ?n_rand_inducing:int ->
            ?learn_sigma2:bool ->
            ?hypers:Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t array ->
            inputs:Eval.Spec.Inputs.t ->
            targets:Lacaml.D.vec ->
            unit -> Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t
          val step :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t
          val gradient_norm :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t -> float
          val get_trained :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t ->
            Gpr_interfaces.Sigs.Eval.Trained.t
          val get_eta : Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t -> float
          val get_step : Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t -> int
          val test :
            ?epsabs:float ->
            ?max_iter:int ->
            ?report:(Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t -> unit) ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SGD.t
        end
      module SMD :
        sig
          type t
          val create :
            ?eps:float ->
            ?lambda:float ->
            ?mu:float ->
            ?eta0:Lacaml.D.vec ->
            ?nu0:Lacaml.D.vec ->
            ?kernel:Eval.Spec.Kernel.t ->
            ?sigma2:float ->
            ?inducing:Eval.Spec.Inducing.t ->
            ?n_rand_inducing:int ->
            ?learn_sigma2:bool ->
            ?hypers:Gpr_interfaces.Sigs.Deriv.Deriv.Spec.Hyper.t array ->
            inputs:Eval.Spec.Inputs.t ->
            targets:Lacaml.D.vec ->
            unit -> Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t
          val step :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t
          val gradient_norm :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t -> float
          val get_trained :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t ->
            Gpr_interfaces.Sigs.Eval.Trained.t
          val get_eta :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t -> Lacaml.D.vec
          val get_nu :
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t -> Lacaml.D.vec
          val test :
            ?epsabs:float ->
            ?max_iter:int ->
            ?report:(Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t -> unit) ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t ->
            Gpr_interfaces.Sigs.Deriv.Deriv.Optim.SMD.t
        end
    end
end