sig
  module Eval :
    sig
      module Spec :
        sig
          module Kernel :
            sig
              type t = Spec.Eval.Kernel.t
              type params = Spec.Eval.Kernel.params
              val create : params -> t
              val get_params : t -> params
            end
          module Inducing :
            sig
              type t = Spec.Eval.Inducing.t
              val get_n_points : t -> int
              val calc_upper : Kernel.t -> t -> Lacaml.D.mat
            end
          module Input :
            sig
              type t = Spec.Eval.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.Eval.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 = FITC.Eval.Inducing.t
          val choose_n_first_inputs :
            FITC.Eval.Spec.Kernel.t ->
            FITC.Eval.Spec.Inputs.t ->
            n_inducing:int -> FITC.Eval.Spec.Inducing.t
          val choose_n_random_inputs :
            ?rnd_state:Core.Std.Random.State.t ->
            FITC.Eval.Spec.Kernel.t ->
            FITC.Eval.Spec.Inputs.t ->
            n_inducing:int -> FITC.Eval.Spec.Inducing.t
          val calc :
            FITC.Eval.Spec.Kernel.t -> FITC.Eval.Spec.Inducing.t -> t
          val get_points : t -> FITC.Eval.Spec.Inducing.t
        end
      module Input :
        sig
          type t = FITC.Eval.Input.t
          val calc : FITC.Eval.Inducing.t -> FITC.Eval.Spec.Input.t -> t
        end
      module Inputs :
        sig
          type t = FITC.Eval.Inputs.t
          val create_default_kernel :
            FITC.Eval.Spec.Inputs.t ->
            n_inducing:int -> FITC.Eval.Spec.Kernel.t
          val calc : FITC.Eval.Spec.Inputs.t -> FITC.Eval.Inducing.t -> t
          val get_points : t -> FITC.Eval.Spec.Inputs.t
        end
      module Model :
        sig
          type t = Variational_FITC.Eval.Model.t
          type co_variance_coeffs =
              Variational_FITC.Eval.Model.co_variance_coeffs
          val calc : Variational_FITC.Eval.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 -> Variational_FITC.Eval.Spec.Kernel.t
          val get_sigma2 : t -> float
          val get_inputs : t -> Variational_FITC.Eval.Inputs.t
          val get_inducing : t -> Variational_FITC.Eval.Inducing.t
        end
      module Trained :
        sig
          type t = Variational_FITC.Eval.Trained.t
          val calc :
            Variational_FITC.Eval.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 -> Variational_FITC.Eval.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 = Variational_FITC.Eval.Mean_predictor.t
          val calc :
            Variational_FITC.Eval.Spec.Inducing.t -> coeffs:Lacaml.D.vec -> t
          val calc_trained : Variational_FITC.Eval.Trained.t -> t
          val get_inducing : t -> Variational_FITC.Eval.Spec.Inducing.t
          val get_coeffs : t -> Lacaml.D.vec
        end
      module Mean :
        sig
          type t = Variational_FITC.Eval.Mean.t
          val calc :
            Variational_FITC.Eval.Mean_predictor.t ->
            Variational_FITC.Eval.Input.t -> t
          val get : t -> float
        end
      module Means :
        sig
          type t = Variational_FITC.Eval.Means.t
          val calc :
            Variational_FITC.Eval.Mean_predictor.t ->
            Variational_FITC.Eval.Inputs.t -> t
          val get : t -> Lacaml.D.vec
        end
      module Co_variance_predictor :
        sig
          type t = Variational_FITC.Eval.Co_variance_predictor.t
          val calc :
            Variational_FITC.Eval.Spec.Kernel.t ->
            Variational_FITC.Eval.Spec.Inducing.t ->
            Variational_FITC.Eval.Model.co_variance_coeffs -> t
          val calc_model : Variational_FITC.Eval.Model.t -> t
        end
      module Variance :
        sig
          type t = Variational_FITC.Eval.Variance.t
          val calc :
            Variational_FITC.Eval.Co_variance_predictor.t ->
            sigma2:float -> Variational_FITC.Eval.Input.t -> t
          val get : ?predictive:bool -> t -> float
        end
      module Variances :
        sig
          type t = Variational_FITC.Eval.Variances.t
          val calc_model_inputs : Variational_FITC.Eval.Model.t -> t
          val calc :
            Variational_FITC.Eval.Co_variance_predictor.t ->
            sigma2:float -> Variational_FITC.Eval.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 = Variational_FITC.Eval.Sampler.t
          val calc :
            ?predictive:bool ->
            Variational_FITC.Eval.Mean.t ->
            Variational_FITC.Eval.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
  module Deriv :
    sig
      module Spec :
        sig
          module Eval :
            sig
              module Kernel :
                sig
                  type t = Spec.Eval.Kernel.t
                  type params = Spec.Eval.Kernel.params
                  val create : params -> t
                  val get_params : t -> params
                end
              module Inducing :
                sig
                  type t = Spec.Eval.Inducing.t
                  val get_n_points : t -> int
                  val calc_upper : Kernel.t -> t -> Lacaml.D.mat
                end
              module Input :
                sig
                  type t = Spec.Eval.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.Eval.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 = Spec.Hyper.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 = Spec.Inducing.upper
              val calc_shared_upper :
                Eval.Kernel.t -> Eval.Inducing.t -> Lacaml.D.mat * upper
              val calc_deriv_upper :
                upper -> Hyper.t -> Gpr_interfaces.symm_mat_deriv
            end
          module Inputs :
            sig
              type diag = Spec.Inputs.diag
              type cross = Spec.Inputs.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 -> Gpr_interfaces.diag_deriv
              val calc_deriv_cross :
                cross -> Hyper.t -> Gpr_interfaces.mat_deriv
            end
        end
      module Inducing :
        sig
          type t = FITC.Deriv.Inducing.t
          val calc :
            FITC.Eval.Spec.Kernel.t -> FITC.Eval.Spec.Inducing.t -> t
          val calc_eval : t -> FITC.Eval.Inducing.t
        end
      module Inputs :
        sig
          type t = FITC.Deriv.Inputs.t
          val calc : FITC.Deriv.Inducing.t -> FITC.Eval.Spec.Inputs.t -> t
          val calc_eval : t -> FITC.Eval.Inputs.t
        end
      module Model :
        sig
          type t = Variational_FITC.Deriv.Model.t
          type hyper_t = Variational_FITC.Deriv.Model.hyper_t
          val calc : Variational_FITC.Deriv.Inputs.t -> sigma2:float -> t
          val update_sigma2 : t -> float -> t
          val calc_eval : t -> Variational_FITC.Eval.Model.t
          val calc_log_evidence_sigma2 : t -> float
          val prepare_hyper : t -> hyper_t
          val calc_log_evidence :
            hyper_t -> Variational_FITC.Deriv.Spec.Hyper.t -> float
        end
      module Trained :
        sig
          type t = Variational_FITC.Deriv.Trained.t
          type hyper_t = Variational_FITC.Deriv.Trained.hyper_t
          val calc :
            Variational_FITC.Deriv.Model.t -> targets:Lacaml.D.vec -> t
          val calc_eval : t -> Variational_FITC.Eval.Trained.t
          val calc_log_evidence_sigma2 : t -> float
          val prepare_hyper : t -> hyper_t
          val calc_log_evidence :
            hyper_t -> Variational_FITC.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 -> 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 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 -> 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:Spec.Hyper.t array ->
                inputs:Eval.Spec.Inputs.t ->
                targets:Lacaml.D.vec -> unit -> 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:Spec.Hyper.t array ->
                inputs:Eval.Spec.Inputs.t ->
                targets:Lacaml.D.vec -> unit -> t
              val step : t -> t
              val gradient_norm : t -> float
              val get_trained : t -> Eval.Trained.t
              val get_eta : t -> float
              val get_step : t -> int
              val test :
                ?epsabs:float ->
                ?max_iter:int -> ?report:(t -> unit) -> t -> 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:Spec.Hyper.t array ->
                inputs:Eval.Spec.Inputs.t ->
                targets:Lacaml.D.vec -> unit -> t
              val step : t -> t
              val gradient_norm : t -> float
              val get_trained : t -> Eval.Trained.t
              val get_eta : t -> Lacaml.D.vec
              val get_nu : t -> Lacaml.D.vec
              val test :
                ?epsabs:float ->
                ?max_iter:int -> ?report:(t -> unit) -> t -> t
            end
        end
    end
end