sig
  type ('matrix, 'data, 'kind, 'tag) t =
      ('matrix, 'data, 'kind, 'tag) Sundials_LinearSolver_impl.linear_solver
  type ('mat, 'kind, 'tag) serial_t =
      ('mat, Nvector_serial.data, 'kind, 'tag) Sundials_LinearSolver.t
    constraint 'kind = [> Nvector_serial.kind ]
  type linear_solver_type =
      Direct
    | Iterative
    | MatrixIterative
    | MatrixEmbedded
  type linear_solver_id =
      Band
    | Dense
    | Klu
    | LapackBand
    | LapackDense
    | Pcg
    | Spbcgs
    | Spfgmr
    | Spgmr
    | Sptfqmr
    | Superludist
    | Superlumt
    | Custom
  type 'data atimesfn = 'data -> 'data -> unit
  type psetupfn = unit -> unit
  type 'data psolvefn = 'data -> 'data -> float -> bool -> unit
  module Direct :
    sig
      val dense :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.dense ->
        (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
        Sundials_LinearSolver.serial_t
      val lapack_dense :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.dense ->
        (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
        Sundials_LinearSolver.serial_t
      val band :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.band ->
        (Sundials.Matrix.Band.t, 'a, [ `Dls ]) Sundials_LinearSolver.serial_t
      val lapack_band :
        ?context:Sundials.Context.t ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        'Sundials.Matrix.band ->
        (Sundials.Matrix.Band.t, 'a, [ `Dls ]) Sundials_LinearSolver.serial_t
      module Klu :
        sig
          type ordering =
            Sundials_LinearSolver_impl.Klu.ordering =
              Amd
            | ColAmd
            | Natural
          val make :
            ?context:Sundials.Context.t ->
            ?ordering:Sundials_LinearSolver.Direct.Klu.ordering ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
            Sundials_LinearSolver.serial_t
          val reinit :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ] as 'a,
             [> `Klu ])
            Sundials_LinearSolver.serial_t ->
            ('s, 'a) Sundials.Matrix.sparse -> ?nnz:int -> unit -> unit
          val set_ordering :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
             [> `Klu ])
            Sundials_LinearSolver.serial_t ->
            Sundials_LinearSolver.Direct.Klu.ordering -> unit
        end
      val klu :
        ?context:Sundials.Context.t ->
        ?ordering:Sundials_LinearSolver.Direct.Klu.ordering ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        ('s, 'a) Sundials.Matrix.sparse ->
        ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
        Sundials_LinearSolver.serial_t
      module Superlumt :
        sig
          type ordering =
            Sundials_LinearSolver_impl.Superlumt.ordering =
              Natural
            | MinDegreeProd
            | MinDegreeSum
            | ColAmd
          val make :
            ?context:Sundials.Context.t ->
            ?ordering:Sundials_LinearSolver.Direct.Superlumt.ordering ->
            nthreads:int ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Slu ])
            Sundials_LinearSolver.serial_t
          val set_ordering :
            ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
             [> `Slu ])
            Sundials_LinearSolver.serial_t ->
            Sundials_LinearSolver.Direct.Superlumt.ordering -> unit
        end
      val superlumt :
        ?context:Sundials.Context.t ->
        ?ordering:Sundials_LinearSolver.Direct.Superlumt.ordering ->
        nthreads:int ->
        ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
        ('s, 'a) Sundials.Matrix.sparse ->
        ('Sundials.Matrix.Sparse.t, 'a, [> `Dls | `Slu ])
        Sundials_LinearSolver.serial_t
    end
  module Iterative :
    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:Sundials_LinearSolver.Iterative.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:Sundials_LinearSolver.Iterative.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 ->
        Sundials_LinearSolver.Iterative.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 ->
        Sundials_LinearSolver.Iterative.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
    end
  module Custom :
    sig
      type ('data, 'kind) atimesfn =
          ('data, 'kind) Nvector.t -> ('data, 'kind) Nvector.t -> unit
      type psetupfn = unit -> unit
      type ('data, 'kind) psolvefn =
          ('data, 'kind) Nvector.t ->
          ('data, 'kind) Nvector.t -> float -> bool -> unit
      type ('matrix, 'data, 'kind, 'lsolver) ops = {
        solver_type : Sundials_LinearSolver.linear_solver_type;
        solver_id : Sundials_LinearSolver.linear_solver_id;
        init : ('lsolver -> unit) option;
        setup : ('lsolver -> 'matrix -> unit) option;
        solve : 'lsolver -> 'matrix -> 'data -> 'data -> float -> unit;
        set_atimes :
          ('lsolver ->
           ('data, 'kind) Sundials_LinearSolver.Custom.atimesfn -> unit)
          option;
        set_preconditioner :
          ('lsolver ->
           Sundials_LinearSolver.Custom.psetupfn option ->
           ('data, 'kind) Sundials_LinearSolver.Custom.psolvefn option ->
           unit)
          option;
        set_scaling_vectors :
          ('lsolver -> 'data option -> 'data option -> unit) option;
        set_zero_guess : ('lsolver -> bool -> unit) option;
        get_num_iters : ('lsolver -> int) option;
        get_res_norm : ('lsolver -> float) option;
        get_res_id : ('lsolver -> ('data, 'kind) Nvector.t) option;
        get_last_flag : ('lsolver -> int) option;
        get_work_space : ('lsolver -> int * int) option;
        set_prec_type :
          ('lsolver ->
           Sundials_LinearSolver.Iterative.preconditioning_type -> unit)
          option;
      }
      val make_ops :
        ?solver_id:Sundials_LinearSolver.linear_solver_id ->
        ?init:('lsolver -> unit) ->
        ?setup:('lsolver -> 'matrix -> unit) ->
        ?set_atimes:('lsolver ->
                     ('data, 'kind) Sundials_LinearSolver.Custom.atimesfn ->
                     unit) ->
        ?set_preconditioner:('lsolver ->
                             Sundials_LinearSolver.Custom.psetupfn option ->
                             ('data, 'kind)
                             Sundials_LinearSolver.Custom.psolvefn option ->
                             unit) ->
        ?set_scaling_vectors:('lsolver ->
                              'data option -> 'data option -> unit) ->
        ?set_zero_guess:('lsolver -> bool -> unit) ->
        ?get_num_iters:('lsolver -> int) ->
        ?get_res_norm:('lsolver -> float) ->
        ?get_res_id:('lsolver -> ('data, 'kind) Nvector.t) ->
        ?get_last_flag:('lsolver -> int) ->
        ?get_work_space:('lsolver -> int * int) ->
        ?set_prec_type:('lsolver ->
                        Sundials_LinearSolver.Iterative.preconditioning_type ->
                        unit) ->
        solver_type:Sundials_LinearSolver.linear_solver_type ->
        solve:('lsolver -> 'matrix -> 'data -> 'data -> float -> unit) ->
        unit ->
        ('matrix, 'data, 'kind, 'lsolver) Sundials_LinearSolver.Custom.ops
      val make_with_matrix :
        ('matrix, 'data, 'kind, 'lsolver) Sundials_LinearSolver.Custom.ops ->
        ?context:Sundials.Context.t ->
        'lsolver ->
        ('matrixkind, 'matrix, 'data, 'kind) Sundials.Matrix.t ->
        ('matrix, 'data, 'kind, [ `Custom of 'lsolver | `Dls | `Iter ])
        Sundials_LinearSolver.t
      val make_without_matrix :
        (unit, 'data, 'kind, 'lsolver) Sundials_LinearSolver.Custom.ops ->
        ?context:Sundials.Context.t ->
        'lsolver ->
        (unit, 'data, 'kind, [ `Custom of 'lsolver | `Iter | `MatE ])
        Sundials_LinearSolver.t
      val unwrap :
        ('m, 'data, 'kind, [> `Custom of 'lsolver ]) Sundials_LinearSolver.t ->
        'lsolver
      type ('matrix, 'data, 'kind, 'lsolver) dls_ops = {
        init : ('lsolver -> unit) option;
        setup : ('lsolver -> 'matrix -> unit) option;
        solve : 'lsolver -> 'matrix -> 'data -> 'data -> float -> unit;
        space : ('lsolver -> int * int) option;
      }
      val make_dls :
        ('matrix, 'data, 'kind, 'lsolver)
        Sundials_LinearSolver.Custom.dls_ops ->
        ?context:Sundials.Context.t ->
        'lsolver ->
        ('matrixkind, 'matrix, 'data, 'kind) Sundials.Matrix.t ->
        ('matrix, 'data, 'kind, [ `Custom of 'lsolver | `Dls ])
        Sundials_LinearSolver.t
    end
  val set_atimes :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    'Sundials_LinearSolver.atimesfn -> unit
  val set_preconditioner :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    Sundials_LinearSolver.psetupfn ->
    'Sundials_LinearSolver.psolvefn -> unit
  val set_scaling_vectors :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    ('d, 'k) Nvector.t -> ('d, 'k) Nvector.t -> unit
  val set_zero_guess :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> bool -> unit
  val init : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> unit
  val setup :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    ('a, 'm, 'd, 'k) Sundials.Matrix.t -> unit
  val solve :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    ('a, 'm, 'd, 'k) Sundials.Matrix.t ->
    ('d, 'k) Nvector.t -> ('d, 'k) Nvector.t -> float -> unit
  val get_num_iters : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> int
  val get_res_norm : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> float
  val get_res_id : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> 'd
  val get_type :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    Sundials_LinearSolver.linear_solver_type
  val get_id :
    ('m, 'd, 'k, 't) Sundials_LinearSolver.t ->
    Sundials_LinearSolver.linear_solver_id
  val get_last_flag : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> int
  val get_work_space : ('m, 'd, 'k, 't) Sundials_LinearSolver.t -> int * int
  exception InvalidLinearSolver
  exception UnrecoverableFailure of bool
  exception MatrixNotSquare
  exception MatrixVectorMismatch
  exception InsufficientStorageUpperBandwidth
  exception LinearSolverInUse
  exception ATimesFailure of bool
  exception PSetFailure of bool
  exception PSolveFailure of bool
  exception GSFailure
  exception QRSolFailure
  exception VectorOpError
  exception ResReduced
  exception ConvFailure
  exception QRfactFailure
  exception LUfactFailure
  exception PackageFailure of bool
  exception IllegalPrecType
  exception InternalFailure of (string * int)
  exception ZeroInDiagonal of int
end