sig
  type ('m, 'd) matrix_ops = {
    m_clone : '-> 'm;
    m_zero : '-> unit;
    m_copy : '-> '-> unit;
    m_scale_add : float -> '-> '-> unit;
    m_scale_addi : float -> '-> unit;
    m_matvec_setup : ('-> unit) option;
    m_matvec : '-> '-> '-> unit;
    m_space : '-> int * int;
  }
  exception Invalidated
  exception IncompatibleArguments
  exception ZeroDiagonalElement of int
  module Dense :
    sig
      type t
      val make : int -> int -> float -> Sundials_Matrix.Dense.t
      val create : int -> int -> Sundials_Matrix.Dense.t
      val size : Sundials_Matrix.Dense.t -> int * int
      val pp : Stdlib.Format.formatter -> Sundials_Matrix.Dense.t -> unit
      val ppi :
        ?start:string ->
        ?stop:string ->
        ?sep:string ->
        ?indent:int ->
        ?itemsep:string ->
        ?item:(Stdlib.Format.formatter -> int -> int -> float -> unit) ->
        unit -> Stdlib.Format.formatter -> Sundials_Matrix.Dense.t -> unit
      val get : Sundials_Matrix.Dense.t -> int -> int -> float
      val set : Sundials_Matrix.Dense.t -> int -> int -> float -> unit
      val update :
        Sundials_Matrix.Dense.t -> int -> int -> (float -> float) -> unit
      val unwrap : Sundials_Matrix.Dense.t -> Sundials.RealArray2.data
      val ops :
        (Sundials_Matrix.Dense.t, Nvector_serial.data)
        Sundials_Matrix.matrix_ops
      val scale_add :
        float -> Sundials_Matrix.Dense.t -> Sundials_Matrix.Dense.t -> unit
      val scale_addi : float -> Sundials_Matrix.Dense.t -> unit
      val matvec :
        Sundials_Matrix.Dense.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val set_to_zero : Sundials_Matrix.Dense.t -> unit
      val blit :
        src:Sundials_Matrix.Dense.t -> dst:Sundials_Matrix.Dense.t -> unit
      val space : Sundials_Matrix.Dense.t -> int * int
      val invalidate : Sundials_Matrix.Dense.t -> unit
    end
  module Band :
    sig
      type t
      type dimensions = { n : int; mu : int; smu : int; ml : int; }
      val make :
        Sundials_Matrix.Band.dimensions -> float -> Sundials_Matrix.Band.t
      val create : Sundials_Matrix.Band.dimensions -> Sundials_Matrix.Band.t
      val size : Sundials_Matrix.Band.t -> int * int
      val dims : Sundials_Matrix.Band.t -> Sundials_Matrix.Band.dimensions
      val pp : Stdlib.Format.formatter -> Sundials_Matrix.Band.t -> unit
      val ppi :
        ?start:string ->
        ?stop:string ->
        ?sep:string ->
        ?indent:int ->
        ?itemsep:string ->
        ?empty:string ->
        ?item:(Stdlib.Format.formatter -> int -> int -> float -> unit) ->
        unit -> Stdlib.Format.formatter -> Sundials_Matrix.Band.t -> unit
      val get : Sundials_Matrix.Band.t -> int -> int -> float
      val set : Sundials_Matrix.Band.t -> int -> int -> float -> unit
      val update :
        Sundials_Matrix.Band.t -> int -> int -> (float -> float) -> unit
      val unwrap : Sundials_Matrix.Band.t -> Sundials.RealArray2.data
      val ops :
        (Sundials_Matrix.Band.t, Nvector_serial.data)
        Sundials_Matrix.matrix_ops
      val scale_add :
        float -> Sundials_Matrix.Band.t -> Sundials_Matrix.Band.t -> unit
      val scale_addi : float -> Sundials_Matrix.Band.t -> unit
      val matvec :
        Sundials_Matrix.Band.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val set_to_zero : Sundials_Matrix.Band.t -> unit
      val blit :
        src:Sundials_Matrix.Band.t -> dst:Sundials_Matrix.Band.t -> unit
      val space : Sundials_Matrix.Band.t -> int * int
      val invalidate : Sundials_Matrix.Band.t -> unit
    end
  module Sparse :
    sig
      type csc
      type csr
      type _ sformat =
          CSC : Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.sformat
        | CSR : Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.sformat
      type 's t
      type index_array =
          (Sundials.Index.t, Sundials.Index.index_elt,
           Stdlib.Bigarray.c_layout)
          Stdlib.Bigarray.Array1.t
      val make :
        'Sundials_Matrix.Sparse.sformat ->
        int -> int -> int -> 'Sundials_Matrix.Sparse.t
      val from_dense :
        'Sundials_Matrix.Sparse.sformat ->
        float -> Sundials_Matrix.Dense.t -> 'Sundials_Matrix.Sparse.t
      val from_band :
        'Sundials_Matrix.Sparse.sformat ->
        float -> Sundials_Matrix.Band.t -> 'Sundials_Matrix.Sparse.t
      val sformat :
        'Sundials_Matrix.Sparse.t -> 'Sundials_Matrix.Sparse.sformat
      val is_csc : 'Sundials_Matrix.Sparse.t -> bool
      val size : 'Sundials_Matrix.Sparse.t -> int * int
      val dims : 'Sundials_Matrix.Sparse.t -> int * int
      val pp : Stdlib.Format.formatter -> 'Sundials_Matrix.Sparse.t -> unit
      val ppi :
        ?start:string ->
        ?stop:string ->
        ?sep:string ->
        ?indent:int ->
        ?itemsep:string ->
        ?rowcol:(Stdlib.Format.formatter -> int -> unit) ->
        ?item:(Stdlib.Format.formatter -> int -> float -> unit) ->
        unit ->
        Stdlib.Format.formatter -> 'Sundials_Matrix.Sparse.t -> unit
      val set_col :
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t ->
        int -> int -> unit
      val get_col :
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t -> int -> int
      val set_row :
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t ->
        int -> int -> unit
      val get_row :
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t -> int -> int
      val set : 'Sundials_Matrix.Sparse.t -> int -> int -> float -> unit
      val get : 'Sundials_Matrix.Sparse.t -> int -> int * float
      val unwrap :
        'Sundials_Matrix.Sparse.t ->
        Sundials_Matrix.Sparse.index_array *
        Sundials_Matrix.Sparse.index_array * Sundials.RealArray.t
      val resize : ?nnz:int -> 'Sundials_Matrix.Sparse.t -> unit
      val ops :
        ('Sundials_Matrix.Sparse.t, Nvector_serial.data)
        Sundials_Matrix.matrix_ops
      val scale_add :
        float ->
        'Sundials_Matrix.Sparse.t -> 'Sundials_Matrix.Sparse.t -> unit
      val scale_addi : float -> 'Sundials_Matrix.Sparse.t -> unit
      val matvec :
        'Sundials_Matrix.Sparse.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val set_to_zero : 'Sundials_Matrix.Sparse.t -> unit
      val blit :
        src:'Sundials_Matrix.Sparse.t ->
        dst:'Sundials_Matrix.Sparse.t -> unit
      val copy_to_csr :
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t ->
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t
      val copy_to_csc :
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t ->
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t
      val space : 'Sundials_Matrix.Sparse.t -> int * int
      val set_rowval :
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t ->
        int -> int -> unit
      val get_rowval :
        Sundials_Matrix.Sparse.csc Sundials_Matrix.Sparse.t -> int -> int
      val set_colval :
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t ->
        int -> int -> unit
      val get_colval :
        Sundials_Matrix.Sparse.csr Sundials_Matrix.Sparse.t -> int -> int
      val set_data : 'Sundials_Matrix.Sparse.t -> int -> float -> unit
      val get_data : 'Sundials_Matrix.Sparse.t -> int -> float
      val invalidate : 'Sundials_Matrix.Sparse.t -> unit
    end
  module ArrayDense :
    sig
      type t = Sundials.RealArray2.t
      val make : int -> int -> float -> Sundials_Matrix.ArrayDense.t
      val create : int -> int -> Sundials_Matrix.ArrayDense.t
      val size : Sundials_Matrix.ArrayDense.t -> int * int
      val pp :
        Stdlib.Format.formatter -> Sundials_Matrix.ArrayDense.t -> unit
      val get : Sundials_Matrix.ArrayDense.t -> int -> int -> float
      val set : Sundials_Matrix.ArrayDense.t -> int -> int -> float -> unit
      val update :
        Sundials_Matrix.ArrayDense.t ->
        int -> int -> (float -> float) -> unit
      val unwrap : Sundials_Matrix.ArrayDense.t -> Sundials.RealArray2.data
      val ops :
        (Sundials_Matrix.ArrayDense.t, Sundials.RealArray.t)
        Sundials_Matrix.matrix_ops
      val scale_add :
        float ->
        Sundials_Matrix.ArrayDense.t -> Sundials_Matrix.ArrayDense.t -> unit
      val scale_addi : float -> Sundials_Matrix.ArrayDense.t -> unit
      val matvec :
        Sundials_Matrix.ArrayDense.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val set_to_zero : Sundials_Matrix.ArrayDense.t -> unit
      val blit :
        src:Sundials_Matrix.ArrayDense.t ->
        dst:Sundials_Matrix.ArrayDense.t -> unit
      val space : Sundials_Matrix.ArrayDense.t -> int * int
      val add_identity : Sundials_Matrix.ArrayDense.t -> unit
      val scale : float -> Sundials_Matrix.ArrayDense.t -> unit
      val getrf :
        Sundials_Matrix.ArrayDense.t -> Sundials.LintArray.t -> unit
      val getrs :
        Sundials_Matrix.ArrayDense.t ->
        Sundials.LintArray.t -> Sundials.RealArray.t -> unit
      val getrs' :
        Sundials_Matrix.ArrayDense.t ->
        Sundials.LintArray.t -> Sundials.RealArray.t -> int -> unit
      val potrf : Sundials_Matrix.ArrayDense.t -> unit
      val potrs :
        Sundials_Matrix.ArrayDense.t -> Sundials.RealArray.t -> unit
      val geqrf :
        Sundials_Matrix.ArrayDense.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val ormqr :
        a:Sundials_Matrix.ArrayDense.t ->
        beta:Sundials.RealArray.t ->
        v:Sundials.RealArray.t ->
        w:Sundials.RealArray.t -> work:Sundials.RealArray.t -> unit
    end
  module ArrayBand :
    sig
      type smu = int
      type mu = int
      type ml = int
      type t =
          Sundials.RealArray2.t *
          (Sundials_Matrix.ArrayBand.smu * Sundials_Matrix.ArrayBand.mu *
           Sundials_Matrix.ArrayBand.ml)
      val make :
        Sundials_Matrix.ArrayBand.smu * Sundials_Matrix.ArrayBand.mu *
        Sundials_Matrix.ArrayBand.ml ->
        int -> float -> Sundials_Matrix.ArrayBand.t
      val create :
        Sundials_Matrix.ArrayBand.smu * Sundials_Matrix.ArrayBand.mu *
        Sundials_Matrix.ArrayBand.ml -> int -> Sundials_Matrix.ArrayBand.t
      val size : Sundials_Matrix.ArrayBand.t -> int * int
      val dims :
        Sundials_Matrix.ArrayBand.t ->
        Sundials_Matrix.ArrayBand.smu * Sundials_Matrix.ArrayBand.mu *
        Sundials_Matrix.ArrayBand.ml
      val pp : Stdlib.Format.formatter -> Sundials_Matrix.ArrayBand.t -> unit
      val ppi :
        ?start:string ->
        ?stop:string ->
        ?sep:string ->
        ?indent:int ->
        ?itemsep:string ->
        ?empty:string ->
        ?item:(Stdlib.Format.formatter -> int -> int -> float -> unit) ->
        unit ->
        Stdlib.Format.formatter -> Sundials_Matrix.ArrayBand.t -> unit
      val get : Sundials_Matrix.ArrayBand.t -> int -> int -> float
      val set : Sundials_Matrix.ArrayBand.t -> int -> int -> float -> unit
      val update :
        Sundials_Matrix.ArrayBand.t -> int -> int -> (float -> float) -> unit
      val unwrap : Sundials_Matrix.ArrayBand.t -> Sundials.RealArray2.data
      val ops :
        (Sundials_Matrix.ArrayBand.t, Sundials.RealArray.t)
        Sundials_Matrix.matrix_ops
      val scale_add :
        float ->
        Sundials_Matrix.ArrayBand.t -> Sundials_Matrix.ArrayBand.t -> unit
      val scale_addi : float -> Sundials_Matrix.ArrayBand.t -> unit
      val matvec :
        Sundials_Matrix.ArrayBand.t ->
        Sundials.RealArray.t -> Sundials.RealArray.t -> unit
      val set_to_zero : Sundials_Matrix.ArrayBand.t -> unit
      val blit :
        src:Sundials_Matrix.ArrayBand.t ->
        dst:Sundials_Matrix.ArrayBand.t -> unit
      val space : Sundials_Matrix.ArrayBand.t -> int * int
      val add_identity : Sundials_Matrix.ArrayBand.t -> unit
      val scale : float -> Sundials_Matrix.ArrayBand.t -> unit
      val gbtrf : Sundials_Matrix.ArrayBand.t -> Sundials.LintArray.t -> unit
      val gbtrs :
        Sundials_Matrix.ArrayBand.t ->
        Sundials.LintArray.t -> Sundials.RealArray.t -> unit
    end
  type standard
  type custom
  type ('k, 'm, 'nd, 'nk) t
  type 'nk dense =
      (Sundials_Matrix.standard, Sundials_Matrix.Dense.t,
       Nvector_serial.data, 'nk)
      Sundials_Matrix.t
    constraint 'nk = [> Nvector_serial.kind ]
  val dense :
    ?context:Sundials.Context.t ->
    ?m:int ->
    ?i:float -> int -> [> Nvector_serial.kind ] Sundials_Matrix.dense
  val wrap_dense :
    ?context:Sundials.Context.t ->
    Sundials_Matrix.Dense.t -> [> Nvector_serial.kind ] Sundials_Matrix.dense
  type 'nk band =
      (Sundials_Matrix.standard, Sundials_Matrix.Band.t, Nvector_serial.data,
       'nk)
      Sundials_Matrix.t
    constraint 'nk = [> Nvector_serial.kind ]
  val band :
    ?context:Sundials.Context.t ->
    ?mu:int ->
    ?smu:int ->
    ?ml:int ->
    ?i:float -> int -> [> Nvector_serial.kind ] Sundials_Matrix.band
  val wrap_band :
    ?context:Sundials.Context.t ->
    Sundials_Matrix.Band.t -> [> Nvector_serial.kind ] Sundials_Matrix.band
  type ('s, 'nk) sparse =
      (Sundials_Matrix.standard, 'Sundials_Matrix.Sparse.t,
       Nvector_serial.data, 'nk)
      Sundials_Matrix.t
    constraint 'nk = [> Nvector_serial.kind ]
  val sparse_csc :
    ?context:Sundials.Context.t ->
    ?m:int ->
    ?nnz:int ->
    int ->
    (Sundials_Matrix.Sparse.csc, [> Nvector_serial.kind ])
    Sundials_Matrix.sparse
  val sparse_csr :
    ?context:Sundials.Context.t ->
    ?m:int ->
    ?nnz:int ->
    int ->
    (Sundials_Matrix.Sparse.csr, [> Nvector_serial.kind ])
    Sundials_Matrix.sparse
  val wrap_sparse :
    ?context:Sundials.Context.t ->
    'Sundials_Matrix.Sparse.t ->
    ('s, [> Nvector_serial.kind ]) Sundials_Matrix.sparse
  type 'nk arraydense =
      (Sundials_Matrix.custom, Sundials_Matrix.ArrayDense.t,
       Sundials.RealArray.t, 'nk)
      Sundials_Matrix.t
  val arraydense :
    ?context:Sundials.Context.t ->
    ?m:int -> ?i:float -> int -> 'nk Sundials_Matrix.arraydense
  val wrap_arraydense :
    ?context:Sundials.Context.t ->
    Sundials_Matrix.ArrayDense.t -> 'nk Sundials_Matrix.arraydense
  type 'nk arrayband =
      (Sundials_Matrix.custom, Sundials_Matrix.ArrayBand.t,
       Sundials.RealArray.t, 'nk)
      Sundials_Matrix.t
  val arrayband :
    ?context:Sundials.Context.t ->
    ?mu:int ->
    ?smu:int -> ?ml:int -> ?i:float -> int -> 'nk Sundials_Matrix.arrayband
  val wrap_arrayband :
    ?context:Sundials.Context.t ->
    Sundials_Matrix.ArrayBand.t -> 'nk Sundials_Matrix.arrayband
  val wrap_custom :
    ('m, 'nd) Sundials_Matrix.matrix_ops ->
    ?context:Sundials.Context.t ->
    '-> (Sundials_Matrix.custom, 'm, 'nd, 'nk) Sundials_Matrix.t
  type (_, _, _, _) id =
      Dense :
        (Sundials_Matrix.standard, Sundials_Matrix.Dense.t,
         Nvector_serial.data, [> Nvector_serial.kind ])
        Sundials_Matrix.id
    | Band :
        (Sundials_Matrix.standard, Sundials_Matrix.Band.t,
         Nvector_serial.data, [> Nvector_serial.kind ])
        Sundials_Matrix.id
    | Sparse :
        (Sundials_Matrix.standard, 'Sundials_Matrix.Sparse.t,
         Nvector_serial.data, [> Nvector_serial.kind ])
        Sundials_Matrix.id
    | Custom : (Sundials_Matrix.custom, 'm, 'nd, 'nk) Sundials_Matrix.id
    | ArrayDense :
        (Sundials_Matrix.custom, Sundials_Matrix.ArrayDense.t,
         Sundials.RealArray.t, 'nk)
        Sundials_Matrix.id
    | ArrayBand :
        (Sundials_Matrix.custom, Sundials_Matrix.ArrayBand.t,
         Sundials.RealArray.t, 'nk)
        Sundials_Matrix.id
  val get_ops :
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.t ->
    ('m, 'nd) Sundials_Matrix.matrix_ops
  val get_id :
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.t ->
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.id
  val unwrap : ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> 'm
  val scale_add :
    float ->
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.t ->
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
  val scale_addi : float -> ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
  val matvec_setup : ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
  val matvec :
    ('k, 'm, 'nd, 'nk) Sundials_Matrix.t ->
    ('nd, 'nk) Nvector.t -> ('nd, 'nk) Nvector.t -> unit
  val set_to_zero : ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
  val blit :
    src:('k, 'm, 'nd, 'nk) Sundials_Matrix.t ->
    dst:('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
  val space : ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> int * int
  val print_dense :
    [> Nvector_serial.kind ] Sundials_Matrix.dense ->
    Sundials.Logfile.t -> unit
  val print_band :
    [> Nvector_serial.kind ] Sundials_Matrix.band ->
    Sundials.Logfile.t -> unit
  val print_sparse :
    ('s, [> Nvector_serial.kind ]) Sundials_Matrix.sparse ->
    Sundials.Logfile.t -> unit
  val pp :
    Stdlib.Format.formatter -> ('k, 'm, 'nd, 'nk) Sundials_Matrix.t -> unit
end