sig
  module type S =
    sig
      module Mat : Matrix.S
      type var
      type matrix_expr =
          Const of Mat.t
        | Var of Lmi.S.var
        | Zeros of int * int
        | Eye of int
        | Kron of int * int * int
        | Kron_sym of int * int * int
        | Block of Lmi.S.matrix_expr array array
        | Lift_block of Lmi.S.matrix_expr * int * int * int * int
        | Transpose of Lmi.S.matrix_expr
        | Minus of Lmi.S.matrix_expr
        | Add of Lmi.S.matrix_expr * Lmi.S.matrix_expr
        | Sub of Lmi.S.matrix_expr * Lmi.S.matrix_expr
        | Mult of Lmi.S.matrix_expr * Lmi.S.matrix_expr
        | Power of Lmi.S.matrix_expr * int
      val var : string -> int -> Lmi.S.matrix_expr
      val var_var : string -> int -> Lmi.S.var * Lmi.S.matrix_expr
      val const : Mat.t -> Lmi.S.matrix_expr
      val scalar : Mat.Coeff.t -> Lmi.S.matrix_expr
      val zeros : int -> int -> Lmi.S.matrix_expr
      val eye : int -> Lmi.S.matrix_expr
      val kron : int -> int -> int -> Lmi.S.matrix_expr
      val kron_sym : int -> int -> int -> Lmi.S.matrix_expr
      val block : Lmi.S.matrix_expr array array -> Lmi.S.matrix_expr
      val lift_block :
        Lmi.S.matrix_expr -> int -> int -> int -> int -> Lmi.S.matrix_expr
      val transpose : Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val minus : Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val add : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val sub : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val mult : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val power : Lmi.S.matrix_expr -> int -> Lmi.S.matrix_expr
      val nb_lines : Lmi.S.matrix_expr -> int
      val nb_cols : Lmi.S.matrix_expr -> int
      val is_symmetric : Lmi.S.matrix_expr -> bool
      val ( !! ) : Mat.t -> Lmi.S.matrix_expr
      val ( ! ) : Mat.Coeff.t -> Lmi.S.matrix_expr
      val ( ~: ) : Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( *. ) : Mat.Coeff.t -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( ~- ) : Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( + ) : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( - ) : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( * ) : Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( ** ) : Lmi.S.matrix_expr -> int -> Lmi.S.matrix_expr
      val ( >= ) :
        Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      val ( <= ) :
        Lmi.S.matrix_expr -> Lmi.S.matrix_expr -> Lmi.S.matrix_expr
      type options = { sdp : Sdp.options; verbose : int; pad : float; }
      val default : Lmi.S.options
      type obj =
          Minimize of Lmi.S.matrix_expr
        | Maximize of Lmi.S.matrix_expr
        | Purefeas
      type values
      exception Dimension_error of string
      exception Not_linear
      exception Not_symmetric
      val solve :
        ?options:Lmi.S.options ->
        ?solver:Sdp.solver ->
        Lmi.S.obj ->
        Lmi.S.matrix_expr list -> SdpRet.t * (float * float) * Lmi.S.values
      val empty_values : unit -> Lmi.S.values
      val value : Lmi.S.matrix_expr -> Lmi.S.values -> Mat.Coeff.t
      val value_mat : Lmi.S.matrix_expr -> Lmi.S.values -> Mat.t
      val register_value :
        Lmi.S.var -> Mat.Coeff.t -> Lmi.S.values -> Lmi.S.values
      val check :
        ?options:Lmi.S.options ->
        ?values:Lmi.S.values -> Lmi.S.matrix_expr -> bool
      val pp : Stdlib.Format.formatter -> Lmi.S.matrix_expr -> unit
      val pp_values : Stdlib.Format.formatter -> Lmi.S.values -> unit
    end
  module Make :
    functor (M : Matrix.S->
      sig
        module Mat :
          sig
            module Coeff :
              sig
                type t = M.Coeff.t
                val compare : t -> t -> int
                val zero : t
                val one : t
                val of_float : float -> t
                val to_float : t -> float
                val of_q : Q.t -> t
                val to_q : t -> Q.t
                val add : t -> t -> t
                val sub : t -> t -> t
                val mult : t -> t -> t
                val div : t -> t -> t
                val pp : Format.formatter -> t -> unit
                val minus_one : t
                val of_int : int -> t
                val neg : t -> t
                val inv : t -> t
                val equal : t -> t -> bool
                val leq : t -> t -> bool
                val geq : t -> t -> bool
                val lt : t -> t -> bool
                val gt : t -> t -> bool
                val sign : t -> int
                val ( ~- ) : t -> t
                val ( + ) : t -> t -> t
                val ( - ) : t -> t -> t
                val ( * ) : t -> t -> t
                val ( / ) : t -> t -> t
                val ( = ) : t -> t -> bool
                val ( <> ) : t -> t -> bool
                val ( <= ) : t -> t -> bool
                val ( >= ) : t -> t -> bool
                val ( < ) : t -> t -> bool
                val ( > ) : t -> t -> bool
              end
            type t = M.t
            exception Dimension_error of string
            val of_list_list : Coeff.t list list -> t
            val to_list_list : t -> Coeff.t list list
            val of_array_array : Coeff.t array array -> t
            val to_array_array : t -> Coeff.t array array
            val zeros : int -> int -> t
            val eye : int -> t
            val kron : int -> int -> int -> t
            val kron_sym : int -> int -> int -> t
            val block : t array array -> t
            val lift_block : t -> int -> int -> int -> int -> t
            val transpose : t -> t
            val minus : t -> t
            val mult_scalar : Coeff.t -> t -> t
            val add : t -> t -> t
            val sub : t -> t -> t
            val mult : t -> t -> t
            val power : t -> int -> t
            val nb_lines : t -> int
            val nb_cols : t -> int
            val is_symmetric : t -> bool
            val remove_0_row_cols : t -> t
            val gauss_split : t -> int * t * t
            val ( ~: ) : t -> t
            val ( ~- ) : t -> t
            val ( *. ) : Coeff.t -> t -> t
            val ( + ) : t -> t -> t
            val ( - ) : t -> t -> t
            val ( * ) : t -> t -> t
            val ( ** ) : t -> int -> t
            val pp : Format.formatter -> t -> unit
          end
        type var
        type matrix_expr =
            Const of Mat.t
          | Var of var
          | Zeros of int * int
          | Eye of int
          | Kron of int * int * int
          | Kron_sym of int * int * int
          | Block of matrix_expr array array
          | Lift_block of matrix_expr * int * int * int * int
          | Transpose of matrix_expr
          | Minus of matrix_expr
          | Add of matrix_expr * matrix_expr
          | Sub of matrix_expr * matrix_expr
          | Mult of matrix_expr * matrix_expr
          | Power of matrix_expr * int
        val var : string -> int -> matrix_expr
        val var_var : string -> int -> var * matrix_expr
        val const : Mat.t -> matrix_expr
        val scalar : Mat.Coeff.t -> matrix_expr
        val zeros : int -> int -> matrix_expr
        val eye : int -> matrix_expr
        val kron : int -> int -> int -> matrix_expr
        val kron_sym : int -> int -> int -> matrix_expr
        val block : matrix_expr array array -> matrix_expr
        val lift_block :
          matrix_expr -> int -> int -> int -> int -> matrix_expr
        val transpose : matrix_expr -> matrix_expr
        val minus : matrix_expr -> matrix_expr
        val add : matrix_expr -> matrix_expr -> matrix_expr
        val sub : matrix_expr -> matrix_expr -> matrix_expr
        val mult : matrix_expr -> matrix_expr -> matrix_expr
        val power : matrix_expr -> int -> matrix_expr
        val nb_lines : matrix_expr -> int
        val nb_cols : matrix_expr -> int
        val is_symmetric : matrix_expr -> bool
        val ( !! ) : Mat.t -> matrix_expr
        val ( ! ) : Mat.Coeff.t -> matrix_expr
        val ( ~: ) : matrix_expr -> matrix_expr
        val ( *. ) : Mat.Coeff.t -> matrix_expr -> matrix_expr
        val ( ~- ) : matrix_expr -> matrix_expr
        val ( + ) : matrix_expr -> matrix_expr -> matrix_expr
        val ( - ) : matrix_expr -> matrix_expr -> matrix_expr
        val ( * ) : matrix_expr -> matrix_expr -> matrix_expr
        val ( ** ) : matrix_expr -> int -> matrix_expr
        val ( >= ) : matrix_expr -> matrix_expr -> matrix_expr
        val ( <= ) : matrix_expr -> matrix_expr -> matrix_expr
        type options = { sdp : Sdp.options; verbose : int; pad : float; }
        val default : options
        type obj =
            Minimize of matrix_expr
          | Maximize of matrix_expr
          | Purefeas
        type values
        exception Dimension_error of string
        exception Not_linear
        exception Not_symmetric
        val solve :
          ?options:options ->
          ?solver:Sdp.solver ->
          obj -> matrix_expr list -> SdpRet.t * (float * float) * values
        val empty_values : unit -> values
        val value : matrix_expr -> values -> Mat.Coeff.t
        val value_mat : matrix_expr -> values -> Mat.t
        val register_value : var -> Mat.Coeff.t -> values -> values
        val check : ?options:options -> ?values:values -> matrix_expr -> bool
        val pp : Format.formatter -> matrix_expr -> unit
        val pp_values : Format.formatter -> values -> unit
      end
  module Q :
    sig
      module Mat :
        sig
          module Coeff :
            sig
              type t = Q.t
              val compare : t -> t -> int
              val zero : t
              val one : t
              val of_float : float -> t
              val to_float : t -> float
              val of_q : Q.t -> t
              val to_q : t -> Q.t
              val add : t -> t -> t
              val sub : t -> t -> t
              val mult : t -> t -> t
              val div : t -> t -> t
              val pp : Format.formatter -> t -> unit
              val minus_one : t
              val of_int : int -> t
              val neg : t -> t
              val inv : t -> t
              val equal : t -> t -> bool
              val leq : t -> t -> bool
              val geq : t -> t -> bool
              val lt : t -> t -> bool
              val gt : t -> t -> bool
              val sign : t -> int
              val ( ~- ) : t -> t
              val ( + ) : t -> t -> t
              val ( - ) : t -> t -> t
              val ( * ) : t -> t -> t
              val ( / ) : t -> t -> t
              val ( = ) : t -> t -> bool
              val ( <> ) : t -> t -> bool
              val ( <= ) : t -> t -> bool
              val ( >= ) : t -> t -> bool
              val ( < ) : t -> t -> bool
              val ( > ) : t -> t -> bool
            end
          type t = Matrix.Q.t
          exception Dimension_error of string
          val of_list_list : Coeff.t list list -> t
          val to_list_list : t -> Coeff.t list list
          val of_array_array : Coeff.t array array -> t
          val to_array_array : t -> Coeff.t array array
          val zeros : int -> int -> t
          val eye : int -> t
          val kron : int -> int -> int -> t
          val kron_sym : int -> int -> int -> t
          val block : t array array -> t
          val lift_block : t -> int -> int -> int -> int -> t
          val transpose : t -> t
          val minus : t -> t
          val mult_scalar : Coeff.t -> t -> t
          val add : t -> t -> t
          val sub : t -> t -> t
          val mult : t -> t -> t
          val power : t -> int -> t
          val nb_lines : t -> int
          val nb_cols : t -> int
          val is_symmetric : t -> bool
          val remove_0_row_cols : t -> t
          val gauss_split : t -> int * t * t
          val ( ~: ) : t -> t
          val ( ~- ) : t -> t
          val ( *. ) : Coeff.t -> t -> t
          val ( + ) : t -> t -> t
          val ( - ) : t -> t -> t
          val ( * ) : t -> t -> t
          val ( ** ) : t -> int -> t
          val pp : Format.formatter -> t -> unit
        end
      type var
      type matrix_expr =
          Const of Mat.t
        | Var of var
        | Zeros of int * int
        | Eye of int
        | Kron of int * int * int
        | Kron_sym of int * int * int
        | Block of matrix_expr array array
        | Lift_block of matrix_expr * int * int * int * int
        | Transpose of matrix_expr
        | Minus of matrix_expr
        | Add of matrix_expr * matrix_expr
        | Sub of matrix_expr * matrix_expr
        | Mult of matrix_expr * matrix_expr
        | Power of matrix_expr * int
      val var : string -> int -> matrix_expr
      val var_var : string -> int -> var * matrix_expr
      val const : Mat.t -> matrix_expr
      val scalar : Mat.Coeff.t -> matrix_expr
      val zeros : int -> int -> matrix_expr
      val eye : int -> matrix_expr
      val kron : int -> int -> int -> matrix_expr
      val kron_sym : int -> int -> int -> matrix_expr
      val block : matrix_expr array array -> matrix_expr
      val lift_block : matrix_expr -> int -> int -> int -> int -> matrix_expr
      val transpose : matrix_expr -> matrix_expr
      val minus : matrix_expr -> matrix_expr
      val add : matrix_expr -> matrix_expr -> matrix_expr
      val sub : matrix_expr -> matrix_expr -> matrix_expr
      val mult : matrix_expr -> matrix_expr -> matrix_expr
      val power : matrix_expr -> int -> matrix_expr
      val nb_lines : matrix_expr -> int
      val nb_cols : matrix_expr -> int
      val is_symmetric : matrix_expr -> bool
      val ( !! ) : Mat.t -> matrix_expr
      val ( ! ) : Mat.Coeff.t -> matrix_expr
      val ( ~: ) : matrix_expr -> matrix_expr
      val ( *. ) : Mat.Coeff.t -> matrix_expr -> matrix_expr
      val ( ~- ) : matrix_expr -> matrix_expr
      val ( + ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( - ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( * ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( ** ) : matrix_expr -> int -> matrix_expr
      val ( >= ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( <= ) : matrix_expr -> matrix_expr -> matrix_expr
      type options = { sdp : Sdp.options; verbose : int; pad : float; }
      val default : options
      type obj = Minimize of matrix_expr | Maximize of matrix_expr | Purefeas
      type values
      exception Dimension_error of string
      exception Not_linear
      exception Not_symmetric
      val solve :
        ?options:options ->
        ?solver:Sdp.solver ->
        obj -> matrix_expr list -> SdpRet.t * (float * float) * values
      val empty_values : unit -> values
      val value : matrix_expr -> values -> Mat.Coeff.t
      val value_mat : matrix_expr -> values -> Mat.t
      val register_value : var -> Mat.Coeff.t -> values -> values
      val check : ?options:options -> ?values:values -> matrix_expr -> bool
      val pp : Format.formatter -> matrix_expr -> unit
      val pp_values : Format.formatter -> values -> unit
    end
  module Float :
    sig
      module Mat :
        sig
          module Coeff :
            sig
              type t = float
              val compare : t -> t -> int
              val zero : t
              val one : t
              val of_float : float -> t
              val to_float : t -> float
              val of_q : Q.t -> t
              val to_q : t -> Q.t
              val add : t -> t -> t
              val sub : t -> t -> t
              val mult : t -> t -> t
              val div : t -> t -> t
              val pp : Format.formatter -> t -> unit
              val minus_one : t
              val of_int : int -> t
              val neg : t -> t
              val inv : t -> t
              val equal : t -> t -> bool
              val leq : t -> t -> bool
              val geq : t -> t -> bool
              val lt : t -> t -> bool
              val gt : t -> t -> bool
              val sign : t -> int
              val ( ~- ) : t -> t
              val ( + ) : t -> t -> t
              val ( - ) : t -> t -> t
              val ( * ) : t -> t -> t
              val ( / ) : t -> t -> t
              val ( = ) : t -> t -> bool
              val ( <> ) : t -> t -> bool
              val ( <= ) : t -> t -> bool
              val ( >= ) : t -> t -> bool
              val ( < ) : t -> t -> bool
              val ( > ) : t -> t -> bool
            end
          type t = Matrix.Float.t
          exception Dimension_error of string
          val of_list_list : Coeff.t list list -> t
          val to_list_list : t -> Coeff.t list list
          val of_array_array : Coeff.t array array -> t
          val to_array_array : t -> Coeff.t array array
          val zeros : int -> int -> t
          val eye : int -> t
          val kron : int -> int -> int -> t
          val kron_sym : int -> int -> int -> t
          val block : t array array -> t
          val lift_block : t -> int -> int -> int -> int -> t
          val transpose : t -> t
          val minus : t -> t
          val mult_scalar : Coeff.t -> t -> t
          val add : t -> t -> t
          val sub : t -> t -> t
          val mult : t -> t -> t
          val power : t -> int -> t
          val nb_lines : t -> int
          val nb_cols : t -> int
          val is_symmetric : t -> bool
          val remove_0_row_cols : t -> t
          val gauss_split : t -> int * t * t
          val ( ~: ) : t -> t
          val ( ~- ) : t -> t
          val ( *. ) : Coeff.t -> t -> t
          val ( + ) : t -> t -> t
          val ( - ) : t -> t -> t
          val ( * ) : t -> t -> t
          val ( ** ) : t -> int -> t
          val pp : Format.formatter -> t -> unit
        end
      type var
      type matrix_expr =
          Const of Mat.t
        | Var of var
        | Zeros of int * int
        | Eye of int
        | Kron of int * int * int
        | Kron_sym of int * int * int
        | Block of matrix_expr array array
        | Lift_block of matrix_expr * int * int * int * int
        | Transpose of matrix_expr
        | Minus of matrix_expr
        | Add of matrix_expr * matrix_expr
        | Sub of matrix_expr * matrix_expr
        | Mult of matrix_expr * matrix_expr
        | Power of matrix_expr * int
      val var : string -> int -> matrix_expr
      val var_var : string -> int -> var * matrix_expr
      val const : Mat.t -> matrix_expr
      val scalar : Mat.Coeff.t -> matrix_expr
      val zeros : int -> int -> matrix_expr
      val eye : int -> matrix_expr
      val kron : int -> int -> int -> matrix_expr
      val kron_sym : int -> int -> int -> matrix_expr
      val block : matrix_expr array array -> matrix_expr
      val lift_block : matrix_expr -> int -> int -> int -> int -> matrix_expr
      val transpose : matrix_expr -> matrix_expr
      val minus : matrix_expr -> matrix_expr
      val add : matrix_expr -> matrix_expr -> matrix_expr
      val sub : matrix_expr -> matrix_expr -> matrix_expr
      val mult : matrix_expr -> matrix_expr -> matrix_expr
      val power : matrix_expr -> int -> matrix_expr
      val nb_lines : matrix_expr -> int
      val nb_cols : matrix_expr -> int
      val is_symmetric : matrix_expr -> bool
      val ( !! ) : Mat.t -> matrix_expr
      val ( ! ) : Mat.Coeff.t -> matrix_expr
      val ( ~: ) : matrix_expr -> matrix_expr
      val ( *. ) : Mat.Coeff.t -> matrix_expr -> matrix_expr
      val ( ~- ) : matrix_expr -> matrix_expr
      val ( + ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( - ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( * ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( ** ) : matrix_expr -> int -> matrix_expr
      val ( >= ) : matrix_expr -> matrix_expr -> matrix_expr
      val ( <= ) : matrix_expr -> matrix_expr -> matrix_expr
      type options = { sdp : Sdp.options; verbose : int; pad : float; }
      val default : options
      type obj = Minimize of matrix_expr | Maximize of matrix_expr | Purefeas
      type values
      exception Dimension_error of string
      exception Not_linear
      exception Not_symmetric
      val solve :
        ?options:options ->
        ?solver:Sdp.solver ->
        obj -> matrix_expr list -> SdpRet.t * (float * float) * values
      val empty_values : unit -> values
      val value : matrix_expr -> values -> Mat.Coeff.t
      val value_mat : matrix_expr -> values -> Mat.t
      val register_value : var -> Mat.Coeff.t -> values -> values
      val check : ?options:options -> ?values:values -> matrix_expr -> bool
      val pp : Format.formatter -> matrix_expr -> unit
      val pp_values : Format.formatter -> values -> unit
    end
end