sig
  type gramschmidt_type =
    Sundials_LinearSolver_impl.Iterative.gramschmidt_type =
      ModifiedGS
    | ClassicalGS
  val spbcgs :
    ?context:Sundials.Context.t ->
    ?maxl:int ->
    ('d, 'k) Nvector.t ->
    ('m, 'd, 'k, [ `Iter | `Spbcgs ]) Sundials_LinearSolver.t
  val spfgmr :
    ?context:Sundials.Context.t ->
    ?maxl:int ->
    ?max_restarts:int ->
    ?gs_type:gramschmidt_type ->
    ('d, 'k) Nvector.t ->
    ('m, 'd, 'k, [ `Iter | `Spfgmr ]) Sundials_LinearSolver.t
  val spgmr :
    ?context:Sundials.Context.t ->
    ?maxl:int ->
    ?max_restarts:int ->
    ?gs_type:gramschmidt_type ->
    ('d, 'k) Nvector.t ->
    ('m, 'd, 'k, [ `Iter | `Spgmr ]) Sundials_LinearSolver.t
  val sptfqmr :
    ?context:Sundials.Context.t ->
    ?maxl:int ->
    ('d, 'k) Nvector.t ->
    ('m, 'd, 'k, [ `Iter | `Sptfqmr ]) Sundials_LinearSolver.t
  val pcg :
    ?context:Sundials.Context.t ->
    ?maxl:int ->
    ('d, 'k) Nvector.t ->
    ('m, 'd, 'k, [ `Iter | `Pcg ]) Sundials_LinearSolver.t
  module Algorithms :
    sig
      val qr_fact :
        int -> Sundials.RealArray2.t -> Sundials.RealArray.t -> bool -> unit
      val qr_sol :
        int ->
        Sundials.RealArray2.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val modified_gs :
        ('d, 'k) Nvector.t array ->
        Sundials.RealArray2.t -> int -> int -> float
      val classical_gs :
        ('d, 'k) Nvector.t array ->
        Sundials.RealArray2.t ->
        int ->
        int -> Sundials.RealArray.t -> ('d, 'k) Nvector.t array -> float
    end
  val set_maxl :
    ('m, 'd, 'k, [< `Iter | `Pcg | `Spbcgs | `Sptfqmr ])
    Sundials_LinearSolver.t -> int -> unit
  val set_gs_type :
    ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ]) Sundials_LinearSolver.t ->
    gramschmidt_type -> unit
  val set_max_restarts :
    ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ]) Sundials_LinearSolver.t ->
    int -> unit
  type preconditioning_type =
    Sundials_LinearSolver_impl.Iterative.preconditioning_type =
      PrecNone
    | PrecLeft
    | PrecRight
    | PrecBoth
  val set_prec_type :
    ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
    preconditioning_type -> unit
  val set_info_file :
    ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
    ?print_level:bool -> Sundials.Logfile.t -> unit
  val set_print_level :
    ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t -> bool -> unit
  type 'd prec_solve_arg = {
    rhs : 'd;
    gamma : float;
    delta : float;
    left : bool;
  }
  type 'd prec_solve_fn =
      (unit, 'd) Cvode.jacobian_arg ->
      'Cvode.Spils.prec_solve_arg -> '-> unit
  type 'd prec_setup_fn =
      (unit, 'd) Cvode.jacobian_arg -> bool -> float -> bool
  type ('d, 'k) preconditioner =
      ('d, 'k) Cvode_impl.SpilsTypes.preconditioner
  val prec_none : ('d, 'k) Cvode.Spils.preconditioner
  val prec_left :
    ?setup:'Cvode.Spils.prec_setup_fn ->
    'Cvode.Spils.prec_solve_fn -> ('d, 'k) Cvode.Spils.preconditioner
  val prec_right :
    ?setup:'Cvode.Spils.prec_setup_fn ->
    'Cvode.Spils.prec_solve_fn -> ('d, 'k) Cvode.Spils.preconditioner
  val prec_both :
    ?setup:'Cvode.Spils.prec_setup_fn ->
    'Cvode.Spils.prec_solve_fn -> ('d, 'k) Cvode.Spils.preconditioner
  module Banded :
    sig
      type bandrange = { mupper : int; mlower : int; }
      val prec_left :
        Cvode.Spils.Banded.bandrange ->
        (Nvector_serial.data, [> Nvector_serial.kind ])
        Cvode.Spils.preconditioner
      val prec_right :
        Cvode.Spils.Banded.bandrange ->
        (Nvector_serial.data, [> Nvector_serial.kind ])
        Cvode.Spils.preconditioner
      val prec_both :
        Cvode.Spils.Banded.bandrange ->
        (Nvector_serial.data, [> Nvector_serial.kind ])
        Cvode.Spils.preconditioner
      val get_work_space :
        [> Nvector_serial.kind ] Cvode.serial_session -> int * int
      val get_num_rhs_evals :
        [> Nvector_serial.kind ] Cvode.serial_session -> int
    end
  type 'd jac_times_setup_fn = (unit, 'd) Cvode.jacobian_arg -> unit
  type 'd jac_times_vec_fn = ('d, 'd) Cvode.jacobian_arg -> '-> '-> unit
  val solver :
    ('m, 'd, 'k, [> `Iter ]) Sundials.LinearSolver.t ->
    ?jac_times_vec:'Cvode.Spils.jac_times_setup_fn option *
                   'Cvode.Spils.jac_times_vec_fn ->
    ?jac_times_rhs:'Cvode.rhsfn ->
    ('d, 'k) Cvode.Spils.preconditioner -> ('d, 'k) Cvode.linear_solver
  val set_jac_eval_frequency : ('d, 'k) Cvode.session -> int -> unit
  val set_lsetup_frequency : ('d, 'k) Cvode.session -> int -> unit
  val set_linear_solution_scaling : ('d, 'k) Cvode.session -> bool -> unit
  val set_eps_lin : ('d, 'k) Cvode.session -> float -> unit
  val set_ls_norm_factor : ('d, 'k) Cvode.session -> float -> unit
  val get_work_space : ('d, 'k) Cvode.session -> int * int
  val get_num_lin_iters : ('d, 'k) Cvode.session -> int
  val get_num_lin_conv_fails : ('d, 'k) Cvode.session -> int
  val get_num_prec_evals : ('d, 'k) Cvode.session -> int
  val get_num_prec_solves : ('d, 'k) Cvode.session -> int
  val get_num_jtsetup_evals : ('d, 'k) Cvode.session -> int
  val get_num_jtimes_evals : ('d, 'k) Cvode.session -> int
  val get_num_lin_rhs_evals : ('d, 'k) Cvode.session -> int
  val set_preconditioner :
    ('d, 'k) Cvode.session ->
    ?setup:'Cvode.Spils.prec_setup_fn ->
    'Cvode.Spils.prec_solve_fn -> unit
  val set_jac_times :
    ('d, 'k) Cvode.session ->
    ?jac_times_setup:'Cvode.Spils.jac_times_setup_fn ->
    'Cvode.Spils.jac_times_vec_fn -> unit
  val clear_jac_times : ('d, 'k) Cvode.session -> unit
end