(* Sparse or dense vectors *)

open Lacaml.D

type t

(** {1 Accessors} *)

val is_sparse : t -> bool
(** True is the vector is sparse. *)

val is_dense : t -> bool
(** True is the vector is dense. *)

val get : t -> int -> float
(** [get v i] returns the i-th element of [v]. *)

val dim : t -> int
(** Dimension of the vector *)


(** {1 Converters } *)

val to_vec : t -> Vec.t
(** Convert into a Lacaml Vec. *)

val to_assoc_list : ?threshold:float -> t -> (int * float) list
(** Convert into an association list. *)

val sparse_of_dense : ?threshold:float -> t -> t
(** Creates a sparse vector from a dense vector. Default threshold is {!Constants.epsilon}. *)

val dense_of_sparse : t -> t
(** Creates a dense vector from a sparse vector. *)

val dense_of_vec : Vec.t -> t
(** Create a dense vector from a Lacaml Vec *)

val sparse_of_vec : ?threshold:float -> Vec.t -> t
(** Create a sparse vector from a Lacaml Vec. Default threshold is {!Constants.epsilon}. *)

val sparse_of_assoc_list : int -> (int * float) list -> t
(** Create a sparse vector from an association list [(index,value)]. The first integer is
    the size of the vector. *)



(** {1 Operations} *)

val neg : t -> t 
(** Returns the negative of the vector. *)

val scale : ?threshold:float -> float -> t -> t 
(** Scale a vector by a constant *)

val add : ?threshold:float -> t -> t -> t
(** Add two vectors *)

val sub : ?threshold:float -> t -> t -> t
(** Subtract two vectors *)

val axpy : ?threshold:float -> ?alpha:float -> t -> t -> t
(** {% $a \mathbf{x} + \mathbf{y}$ %} *)

val dot : t -> t -> float
(** Dot product. *)

val norm : t -> float
(** l2-norm of the vector : {% $\sqrt{\sum_i x_i^2}$ %} *)

(** {1 Printers } *)

val pp : Format.formatter -> t -> unit


(** {1 Unit testing} *)

val test_case : unit -> (string * [> `Quick ] * (unit -> unit)) list
