diff --git a/Notebooks/SpVec.ipynb b/Notebooks/SpVec.ipynb index 3e0623c..29df2ae 100644 --- a/Notebooks/SpVec.ipynb +++ b/Notebooks/SpVec.ipynb @@ -3,9 +3,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -149,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -158,7 +156,7 @@ "val pp : Format.formatter -> t -> unit = \n" ] }, - "execution_count": 3, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -167,12 +165,21 @@ "let pp ppf t =\n", " let pp_data ppf t =\n", " for i=1 to t.nnz do\n", - " Format.fprintf ppf \"@[(%d,@ %f)@]@;\" t.indices.{i} t.values.{i}\n", + " Format.fprintf ppf \"@[(%d,@ %g)@]@;\" t.indices.{i} t.values.{i}\n", " done\n", " in\n", " Format.fprintf ppf \"@[{@[dim:@ %d@]@;@[%a@]}@]\" t.dim pp_data t" ] }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "#install_printer pp" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -180,55 +187,6 @@ "# Creators" ] }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val of_vec : ?threshold:float -> Lacaml.D.vec -> t = \n" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let of_vec ?(threshold=0.) v =\n", - " let dim = L.Vec.dim v in\n", - " let buffer_idx = Bigarray.(Array1.create int fortran_layout) dim in\n", - " let buffer_val = Bigarray.(Array1.create float64 fortran_layout) dim in\n", - " let check = \n", - " if threshold = 0. then\n", - " fun x -> x <> 0.\n", - " else\n", - " fun x -> (abs_float x) > 0.\n", - " in\n", - " let rec aux k i =\n", - " if i > dim then\n", - " k-1\n", - " else if check v.{i} then\n", - " ( buffer_idx.{k} <- i ;\n", - " buffer_val.{k} <- v.{i} ;\n", - " aux (k+1) (i+1)\n", - " )\n", - " else\n", - " aux k (i+1)\n", - " in\n", - " let nnz = aux 1 1 in\n", - " let indices = Bigarray.(Array1.create int fortran_layout) nnz in\n", - " let values = L.Vec.create nnz in\n", - " for i=1 to nnz do\n", - " indices.{i} <- buffer_idx.{i};\n", - " values.{i} <- buffer_val.{i};\n", - " done ;\n", - " { dim ; nnz ; indices ; values }\n", - "\n" - ] - }, { "cell_type": "code", "execution_count": 5, @@ -256,7 +214,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -265,17 +223,7 @@ "val of_vec : ?threshold:float -> Lacaml.D.vec -> t = \n" ] }, - "execution_count": 77, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val of_array : ?threshold:float -> float array -> t = \n" - ] - }, - "execution_count": 77, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -309,9 +257,26 @@ " indices.{i} <- buffer_idx.{i};\n", " values.{i} <- buffer_val.{i};\n", " done ;\n", - " { dim ; nnz ; indices ; values }\n", - "\n", - "\n", + " { dim ; nnz ; indices ; values }" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val of_array : ?threshold:float -> float array -> t = \n" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ "let of_array ?(threshold=0.) a =\n", " L.Vec.of_array a\n", " |> of_vec ~threshold " @@ -319,7 +284,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -328,7 +293,7 @@ "val copy : t -> t = \n" ] }, - "execution_count": 78, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -345,59 +310,117 @@ " indices ; values }" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Test" - ] - }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "val x : t =\n", - " {dim = 10; nnz = 0; indices = ;\n", - " values =\n", - " R1 R2 R3 R30 R31 R32\n", - " 6.9331E-310 6.9331E-310 0 ... 6.9331E-310 6.9331E-310 6.9331E-310}\n" + "val map : ?threshold:float -> (float -> float) -> t -> t = \n" ] }, - "execution_count": 79, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let map ?(threshold=0.) f t =\n", + " let indices = \n", + " Bigarray.(Array1.create int fortran_layout) t.nnz\n", + " in\n", + " let check =\n", + " if threshold = 0. then\n", + " fun x -> x <> 0.\n", + " else\n", + " fun x -> abs_float x > threshold\n", + " in\n", + " let values = L.Vec.create t.nnz in\n", + " let nnz = ref 0 in\n", + " for i=1 to t.nnz do\n", + " let w = f t.values.{i} in\n", + " if check w then (\n", + " incr nnz;\n", + " values.{!nnz} <- w ;\n", + " indices.{!nnz} <- t.indices.{i}\n", + " )\n", + " done;\n", + " { dim = t.dim ;\n", + " nnz = !nnz ;\n", + " indices ; values }" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val x : t = {dim: 10 }\n" + ] + }, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ - "val dense_a : t =\n", - " {dim = 9; nnz = 5; indices = ;\n", - " values = R1 R2 R3 R4 R5\n", - " 1 -2 0.5 1E-08 3}\n" + "val dense_a : Lacaml.D.vec = R1 R2 R3 R7 R8 R9\n", + " 1 -2 0 ... 0 3 0\n" ] }, - "execution_count": 79, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, { - "ename": "error", - "evalue": "compile_error", - "output_type": "error", - "traceback": [ - "\u001b[32mFile \"[79]\", line 6, characters 22-29:\n\u001b[31mError: This expression has type t but an expression was expected of type\n Lacaml.D.vec =\n (float, Bigarray.float64_elt, Bigarray.fortran_layout)\n Bigarray.Array1.t\n\u001b[36m 5: \u001b[30m \n\u001b[36m 6: \u001b[30mlet sparse_a = of_vec \u001b[4mdense_a\u001b[0m\u001b[30m \n\u001b[36m 7: \u001b[30m\u001b[0m\n" - ] + "data": { + "text/plain": [ + "val sparse_a : t = {dim: 9 (1, 1) (2, -2) (5, 0.5) (6, 1e-08) (8, 3) }\n" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = false\n" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "let x = make0 10 \n", "\n", "let dense_a = \n", - " of_array [| 1. ; -2. ; 0. ; 0. ; 0.5 ; 1.e-8 ; 0. ; 3. ; 0. |]\n", + " L.Vec.of_array [| 1. ; -2. ; 0. ; 0. ; 0.5 ; 1.e-8 ; 0. ; 3. ; 0. |]\n", " \n", "let sparse_a = of_vec dense_a \n", "\n", @@ -405,17 +428,526 @@ " copy sparse_a = sparse_a\n", " \n", "let _ =\n", - " copy sparse_a == sparse_a\n", - "\n", - "let () = \n", - " Format.printf \"@.@[%a@]@.\" pp sparse_a" + " copy sparse_a == sparse_a\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# aX + Y\n", + "# Accessors" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val dim : t -> int = \n" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val nnz : t -> int = \n" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val indices :\n", + " t -> (int, Bigarray.int_elt, Bigarray.fortran_layout) Bigarray.Array1.t =\n", + " \n" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val values : t -> L.Vec.t = \n" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val density : t -> float = \n" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let dim t = t.dim\n", + "let nnz t = t.nnz\n", + "let indices t = t.indices\n", + "let values t = t.values\n", + "let density t = float_of_int t.nnz /. float_of_int t.dim" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val get : t -> int -> float = \n" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let get t i =\n", + " if i < 1 || i > dim t then invalid_arg \"index out of bounds\";\n", + " \n", + " let rec binary_search index value low high =\n", + " if high = low then\n", + " if index.{low} = value then\n", + " low\n", + " else\n", + " raise Not_found\n", + " else let mid = (low + high) / 2 in\n", + " if index.{mid} > value then\n", + " binary_search index value low (mid - 1)\n", + " else if index.{mid} < value then\n", + " binary_search index value (mid + 1) high\n", + " else\n", + " mid\n", + " in\n", + " try\n", + " let k = \n", + " let id = indices t in\n", + " binary_search id i id.{1} (nnz t)\n", + " in\n", + " t.values.{k}\n", + " with Not_found -> 0." + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val iter : (int -> float -> 'a) -> t -> unit = \n" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let iter f t =\n", + " for k=1 to nnz t do\n", + " f t.indices.{k} t.values.{k}\n", + " done" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test " + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 1.000000\n", + "2 -2.000000\n", + "5 0.500000\n", + "6 0.000000\n", + "8 3.000000\n" + ] + }, + { + "data": { + "text/plain": [ + "- : unit = ()\n" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dense_a = L.Vec.init (dim sparse_a) (get sparse_a);;\n", + "iter (fun i v -> Printf.printf \"%d %f\\n%!\" i v) sparse_a;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Converters" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val to_assoc_list : t -> (int * float) list = \n" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val to_vec : t -> Lacaml.D.vec = \n" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let to_assoc_list t = \n", + " let rec aux k accu =\n", + " if k = 0 then\n", + " accu\n", + " else\n", + " aux (k-1) ( (t.indices.{k}, t.values.{k})::accu )\n", + " in\n", + " aux (nnz t) []\n", + " \n", + " \n", + "let to_vec t =\n", + " let result = L.Vec.make0 (dim t) in\n", + " iter (fun k v -> result.{k} <- v) t;\n", + " result\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "- : (int * float) list = [(1, 1.); (2, -2.); (5, 0.5); (6, 1e-08); (8, 3.)]\n" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "to_assoc_list sparse_a;;\n", + "to_vec sparse_a = dense_a;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## One-vector operations" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val immutable : (t -> 'a) -> t -> t = \n" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val scale_mut : float -> t -> unit = \n" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val scale : float -> t -> t = \n" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val neg : t -> t = \n" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val norm : t -> float = \n" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let immutable f t =\n", + " let result = copy t in\n", + " f result;\n", + " result\n", + " \n", + "let scale_mut x t = \n", + " L.scal x t.values \n", + "\n", + "let scale x = immutable @@ scale_mut x\n", + " \n", + "let neg t =\n", + " { t with values = L.Vec.neg t.values }\n", + " \n", + "let norm t =\n", + " L.nrm2 t.values\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val sparse_b : t = {dim: 9 (1, 1) (2, -2) (5, 0.5) (6, 1e-08) (8, 3) }\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : unit = ()\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val dense_b : L.vec = R1 R2 R3 R7 R8 R9\n", + " 1 -2 0 ... 0 3 0\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : unit = ()\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val sparse_c : t = {dim: 9 (1, 0.5) (2, -1) (5, 0.25) (6, 5e-09) (8, 1.5) }\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "- : bool = true\n" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let sparse_b = copy sparse_a;;\n", + "scale_mut 0.5 sparse_b;;\n", + "\n", + "equal sparse_b @@ map (fun x -> x *. 0.5) sparse_a;;\n", + "\n", + "\n", + "let dense_b = L.copy dense_a;;\n", + "L.scal 0.5 dense_b;;\n", + "\n", + "let sparse_c = scale 0.5 sparse_a;;\n", + "\n", + "equal sparse_b sparse_c;;\n", + " \n", + "let _ =\n", + " let n1 = neg sparse_a in\n", + " neg n1 = sparse_a" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Two-vector operations" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val equal : t -> t -> bool = \n" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let equal x y =\n", + " (x.nnz + y.nnz = 0) || (\n", + " (x.dim = y.dim) &&\n", + " (x.nnz = y.nnz) &&\n", + " Bigarray.Array1.(sub x.indices 1 x.nnz = sub y.indices 1 y.nnz) &&\n", + " (Array.sub (L.Vec.to_array x.values) 0 (x.nnz-1) = Array.sub (L.Vec.to_array y.values) 0 (y.nnz-1) )\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## aX + Y\n", "\n", "Run along all the entries of `X` and `Y` simultaneously with indices `k` and `l`. `m` is the index of the new array.\n", "\n", @@ -428,7 +960,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -437,7 +969,7 @@ "val axpy : ?threshold:float -> ?alpha:float -> t -> t -> t = \n" ] }, - "execution_count": 105, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -452,7 +984,7 @@ " if threshold = 0. then\n", " fun x -> x <> 0.\n", " else\n", - " fun x -> abs_float x > 0.\n", + " fun x -> abs_float x > threshold\n", " in\n", " \n", " let f = (* if a=1 in ax+y, then do x+y. If a=0 then do y *)\n", @@ -477,25 +1009,25 @@ " let w = f x.values.{k} 0. in\n", " if check w then (\n", " new_indices.{m} <- x.indices.{k};\n", - " new_values.{m} <- w\n", - " );\n", - " (aux [@tailcall]) (k+1) l (m+1)\n", + " new_values.{m} <- w ;\n", + " (aux [@tailcall]) (k+1) l (m+1)\n", + " ) else (aux [@tailcall]) (k+1) l m\n", " )\n", " else if x.indices.{k} > y.indices.{l} then (\n", " let w = y.values.{l} in\n", " if check w then (\n", " new_indices.{m} <- y.indices.{l};\n", - " new_values.{m} <- w\n", - " );\n", - " (aux [@tailcall]) k (l+1) (m+1)\n", + " new_values.{m} <- w;\n", + " (aux [@tailcall]) k (l+1) (m+1)\n", + " ) else (aux [@tailcall]) k (l+1) m\n", " )\n", " else (\n", " let w = f x.values.{k} y.values.{l} in\n", " if check w then (\n", " new_indices.{m} <- x.indices.{k};\n", - " new_values.{m} <- w\n", - " );\n", - " (aux [@tailcall]) (k+1) (l+1) (m+1)\n", + " new_values.{m} <- w;\n", + " (aux [@tailcall]) (k+1) (l+1) (m+1)\n", + " ) else (aux [@tailcall]) (k+1) (l+1) m\n", " )\n", " end\n", " | false, true -> (* Array x is done running *)\n", @@ -531,19 +1063,50 @@ " " ] }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val add : ?threshold:float -> t -> t -> t = \n" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val sub : ?threshold:float -> t -> t -> t = \n" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let add ?(threshold=0.) x y = axpy ~threshold ~alpha:1. x y\n", + "\n", + "let sub ?(threshold=0.) x y = axpy ~threshold ~alpha:(-1.) y x\n", + " " + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Test" + "### Test" ] }, { "cell_type": "code", - "execution_count": 108, - "metadata": { - "collapsed": true - }, + "execution_count": 22, + "metadata": {}, "outputs": [ { "data": { @@ -552,7 +1115,7 @@ " 1 2 0 ... -0.001 0 0\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -563,33 +1126,27 @@ " 0 1 2 ... 0 -0.001 2\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ - "val m_As : t =\n", - " {dim = 10; nnz = 5; indices = ;\n", - " values = R1 R2 R3 R4 R5\n", - " 1 2 0.01 -2 -0.001}\n" + "val m_As : t = {dim: 10 (1, 1 (2, 2 (5, 0.01 (6, -2 (8, -0.001 }\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ - "val m_Bs : t =\n", - " {dim = 10; nnz = 6; indices = ;\n", - " values = R1 R2 R3 R4 R5 R6\n", - " 1 2 0.01 -2 -0.001 2}\n" + "val m_Bs : t = {dim: 10 (2, 1 (3, 2 (6, 0.01 (7, -2 (9, -0.001 (10, 2 }\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -600,7 +1157,7 @@ " 0 1 2 ... 0 -0.001 2\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -610,7 +1167,7 @@ "- : unit = ()\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -621,7 +1178,7 @@ " 2 5 2 ... -0.002 -0.001 2\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -632,7 +1189,7 @@ " 1 2 0 ... -0.001 0 0\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -642,7 +1199,7 @@ "- : unit = ()\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -653,7 +1210,7 @@ " 1 4 4 ... -0.001 -0.002 4\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -661,23 +1218,21 @@ "data": { "text/plain": [ "val m_Cs : t =\n", - " {dim = 10; nnz = 9; indices = ;\n", - " values =\n", - " R1 R2 R3 R9 R10 R11\n", - " 2 5 2 ... 2 1.04136E-71 8.95166E+271}\n" + " {dim: 10\n", + " (1, 2 (2, 5 (3, 2 (5, 0.02 (6, -3.99 (7, -2 (8, -0.002 (9, -0.001 (10, 2 }\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ - "- : bool = false\n" + "- : bool = true\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, @@ -685,75 +1240,21 @@ "data": { "text/plain": [ "val m_Ds : t =\n", - " {dim = 10; nnz = 9; indices = ;\n", - " values =\n", - " R1 R2 R3 R9 R10 R11\n", - " 1 4 4 ... 4 6.82475E-38 8.26993E-72}\n" + " {dim: 10\n", + " (1, 1 (2, 4 (3, 4 (5, 0.01 (6, -1.98 (7, -4 (8, -0.001 (9, -0.002 (10, 4 }\n" ] }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ - "- : bool = false\n" + "- : bool = true\n" ] }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 2.000000 2.000000\n", - "2 5.000000 5.000000\n", - "3 2.000000 2.000000\n", - "4 0.000000 0.000000\n", - "5 0.020000 0.020000\n", - "6 -3.990000 -3.990000\n", - "7 -2.000000 -2.000000\n", - "8 -0.002000 -0.002000\n", - "9 -0.001000 -0.001000\n", - "10 2.000000 2.000000\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 1.000000 1.000000\n", - "2 4.000000 4.000000\n", - "3 4.000000 4.000000\n", - "4 0.000000 0.000000\n", - "5 0.010000 0.010000\n", - "6 -1.980000 -1.980000\n", - "7 -4.000000 -4.000000\n", - "8 -0.001000 -0.001000\n", - "9 -0.002000 -0.002000\n", - "10 4.000000 4.000000\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 108, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -776,361 +1277,56 @@ "let m_Cs = axpy ~alpha:2. m_As m_Bs\n", "\n", "\n", - "let _ = of_vec m_C = m_Cs;;\n", + "let _ = equal (of_vec m_C) m_Cs;;\n", "\n", "let m_Ds = axpy ~alpha:2. m_Bs m_As\n", "\n", - "let _ = of_vec m_D = m_Ds;;\n", + "let _ = equal (of_vec m_D) m_Ds;;\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dot product" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val dot : t -> t -> float = \n" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let dot x y =\n", "\n", - "L.Vec.iteri (fun i x -> Format.printf \"%d %f %f\\n%!\" i x (get m_Cs i)) m_C;;\n", - "L.Vec.iteri (fun i x -> Format.printf \"%d %f %f\\n%!\" i x (get m_Ds i)) m_D;;\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Accessors" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "val dim : t -> int = \n" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val nnz : t -> int = \n" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val indices :\n", - " t -> (int, Bigarray.int_elt, Bigarray.fortran_layout) Bigarray.Array1.t =\n", - " \n" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val values : t -> L.Vec.t = \n" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let dim t = t.dim\n", - "let nnz t = t.nnz\n", - "let indices t = t.indices\n", - "let values t = t.values" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val get : t -> int -> float = \n" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let get t i =\n", - " if i < 1 || i > dim t then invalid_arg \"index out of bounds\";\n", - " \n", - " let rec binary_search index value low high =\n", - " if high = low then\n", - " if index.{low} = value then\n", - " low\n", - " else\n", - " raise Not_found\n", - " else let mid = (low + high) / 2 in\n", - " if index.{mid} > value then\n", - " binary_search index value low (mid - 1)\n", - " else if index.{mid} < value then\n", - " binary_search index value (mid + 1) high\n", - " else\n", - " mid\n", - " in\n", - " try\n", - " let k = \n", - " let id = indices t in\n", - " binary_search id i id.{1} (nnz t)\n", - " in\n", - " t.values.{k}\n", - " with Not_found -> 0." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val iter : (int -> float -> 'a) -> t -> unit = \n" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let iter f t =\n", - " for k=1 to nnz t do\n", - " f t.indices.{k} t.values.{k}\n", - " done" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Test " - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "- : bool = true\n" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 1.000000\n", - "2 -2.000000\n", - "5 0.500000\n", - "6 0.000000\n", - "8 3.000000\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dense_a = L.Vec.init (dim sparse_a) (get sparse_a);;\n", - "iter (fun i v -> Printf.printf \"%d %f\\n%!\" i v) sparse_a;;" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Converters" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val to_assoc_list : t -> (int * float) list = \n" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val to_vec : t -> Lacaml.D.vec = \n" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let to_assoc_list t = \n", - " let rec aux k accu =\n", - " if k = 0 then\n", - " accu\n", + " let rec aux accu k l =\n", + " if k <= x.nnz && l <= y.nnz then\n", + " begin\n", + " if x.indices.{k} < y.indices.{l} then \n", + " (aux [@tailcall]) accu (k+1) l\n", + " else if x.indices.{k} > y.indices.{l} then (\n", + " (aux [@tailcall]) accu k (l+1)\n", + " )\n", + " else (\n", + " (aux [@tailcall]) (accu +. x.values.{k} *. y.values.{l}) (k+1) (l+1)\n", + " )\n", + " end\n", " else\n", - " aux (k-1) ( (t.indices.{k}, t.values.{k})::accu )\n", + " accu\n", " in\n", - " aux (nnz t) []\n", - " \n", - " \n", - "let to_vec t =\n", - " let result = L.Vec.make0 (dim t) in\n", - " iter (fun k v -> result.{k} <- v) t;\n", - " result" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Test" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "- : (int * float) list = [(1, 1.); (2, -2.); (5, 0.5); (6, 1e-08); (8, 3.)]\n" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "- : bool = true\n" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "to_assoc_list sparse_a;;\n", - "to_vec sparse_a = dense_a;;" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Operations" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## One-vector operations" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val immutable : (t -> 'a) -> t -> t = \n" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val scale_mut : float -> t -> unit = \n" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val scale : float -> t -> t = \n" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val neg : t -> t = \n" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let immutable f t =\n", - " let result = copy t in\n", - " f result;\n", - " result\n", - " \n", - "let scale_mut x t = \n", - " L.scal x t.values \n", - "\n", - "let scale x = immutable @@ scale_mut x\n", - " \n", - "let neg t =\n", - " { t with values = L.Vec.neg t.values }\n", - " " + " aux 0. 1 1\n" ] }, { @@ -1142,148 +1338,415 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 24, "metadata": {}, "outputs": [ - { - "data": { - "text/plain": [ - "val sparse_b : t =\n", - " {dim = 9; nnz = 5; indices = ;\n", - " values = R1 R2 R3 R4 R5\n", - " 1 -2 0.5 1E-08 3}\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "val sparse_c : t =\n", - " {dim = 9; nnz = 5; indices = ;\n", - " values = R1 R2 R3 R4 R5\n", - " 0.5 -1 0.25 5E-09 1.5}\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{dim: 9\n", - "(1, 1.000000) (2, -2.000000) (5, 0.500000) (6, 0.000000) (8, 3.000000) }\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{dim: 9\n", - "(1, 0.500000) (2, -1.000000) (5, 0.250000) (6, 0.000000) (8, 1.500000) }\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{dim: 9\n", - "(1, 0.500000) (2, -1.000000) (5, 0.250000) (6, 0.000000) (8, 1.500000) }\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{dim: 9\n", - "(1, -1.000000) (2, 2.000000) (5, -0.500000) (6, -0.000000) (8, -3.000000) }\n" - ] - }, - { - "data": { - "text/plain": [ - "- : unit = ()\n" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - }, { "data": { "text/plain": [ "- : bool = true\n" ] }, - "execution_count": 67, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "let sparse_b = copy sparse_a;;\n", - "scale_mut 0.5 sparse_b;;\n", - "let sparse_c = scale 0.5 sparse_a;;\n", - "Format.printf \"%a@.\" pp sparse_a;;\n", - "Format.printf \"%a@.\" pp sparse_b;;\n", - "Format.printf \"%a@.\" pp sparse_c;;\n", - "Format.printf \"%a@.\" pp (neg sparse_a);;\n", - " \n", - "let _ =\n", - " let n1 = neg sparse_a in\n", - " neg n1 = sparse_a" + "dot sparse_a sparse_b = L.dot dense_a dense_b;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tests" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/scemama/qp2/external/opam/default/lib/astring: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/astring/astring.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/cmdliner: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/cmdliner/cmdliner.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/seq: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/stdlib-shims: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/stdlib-shims/stdlib_shims.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/fmt: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/fmt/fmt.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/fmt/fmt_cli.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/fmt/fmt_tty.cma: loaded\n", + "/home/scemama/qp2/external/opam/default/lib/alcotest: added to search path\n", + "/home/scemama/qp2/external/opam/default/lib/alcotest/alcotest.cma: loaded\n" + ] + } + ], + "source": [ + "#require \"alcotest\";;" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val x1 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 0.852078 0 0 ... 0 0.656419 0\n", + "val x2 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " -0.606197 0.411059 0 ... -0.368989 0 0.9001\n" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val x3 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.70416 0 0 ... 0 1.31284 0\n", + "val x4 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 0.245881 0.411059 0 ... -0.368989 0.656419 0.9001\n", + "val x5 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.45827 -0.411059 0 ... 0.368989 0.656419 -0.9001\n", + "val x6 : L.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.95004 0.411059 0 ... -0.368989 1.96926 0.9001\n" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val v1 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 0.852078 0 0 ... 0 0.656419 0\n", + "val v2 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " -0.606197 0.411059 0 ... -0.368989 0 0.9001\n", + "val v3 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.70416 0 0 ... 0 1.31284 0\n", + "val v4 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 0.245881 0.411059 0 ... -0.368989 0.656419 0.9001\n", + "val v5 : Lacaml.D.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.45827 -0.411059 0 ... 0.368989 0.656419 -0.9001\n", + "val v6 : L.vec =\n", + " R1 R2 R3 R98 R99 R100\n", + " 1.95004 0.411059 0 ... -0.368989 1.96926 0.9001\n" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val v1_s : t =\n", + " {dim: 100\n", + " (1, 0.852078 (4, 0.733763 (7, -0.818022 (10, -0.692304 (11, -0.980468\n", + " (15, 0.974355 (16, -0.665109 (24, 0.889086 (27, 0.736393 (30, -0.843748\n", + " (31, -0.750514 (34, 0.778919 (38, -0.790597 (40, 0.720996 (41, 0.978861\n", + " (42, -0.679388 (43, -0.853596 (46, 0.977185 (47, -0.811648 (49, -0.702925\n", + " (50, 0.89789 (54, -0.675687 (56, 0.752085 (57, -0.626277 (66, 0.664662\n", + " (67, 0.855765 (69, 0.673572 (71, -0.764248 (72, 0.61481 (73, -0.849851\n", + " (74, -0.983965 (84, -0.764701 (87, -0.834976 (92, -0.851806 (94, 0.696202\n", + " (95, 0.844479 (99, 0.656419 }\n", + "val v2_s : t =\n", + " {dim: 100\n", + " (1, -0.606197 (2, 0.411059 (4, 0.329122 (5, -0.740514 (7, 0.387312\n", + " (8, 0.977894 (9, -0.43281 (11, -0.971917 (15, -0.471397 (16, 0.863036\n", + " (17, -0.497091 (19, 0.8659 (20, 0.572763 (21, 0.963705 (23, -0.568959\n", + " (24, 0.643522 (25, 0.697603 (26, -0.706857 (29, -0.874151 (30, 0.559791\n", + " (32, -0.392582 (34, -0.488787 (36, -0.988593 (38, -0.817274 (39, -0.78555\n", + " (42, 0.505945 (43, 0.370838 (44, -0.734224 (45, -0.634506 (46, 0.304503\n", + " (47, -0.330526 (48, -0.800156 (49, -0.570671 (50, -0.514998 (51, -0.47082\n", + " (52, 0.731985 (53, -0.501758 (54, -0.856375 (55, 0.422431 (56, 0.819669\n", + " (57, 0.847078 (58, 0.301306 (59, -0.917181 (60, 0.391153 (61, -0.936169\n", + " (62, 0.855439 (63, 0.730839 (64, 0.763087 (65, 0.777606 (66, 0.945573\n", + " (67, -0.584689 (68, 0.312286 (69, 0.840451 (72, 0.980958 (73, 0.383844\n", + " (77, 0.509676 (79, 0.86618 (80, -0.767171 (82, -0.955884 (83, -0.326832\n", + " (88, 0.846553 (89, -0.578475 (90, -0.522823 (91, 0.802248 (92, 0.975437\n", + " (95, -0.816165 (96, -0.999559 (97, 0.738769 (98, -0.368989 (100, 0.9001 }\n", + "val v3_s : t =\n", + " {dim: 100\n", + " (1, 1.70416 (4, 1.46753 (7, -1.63604 (10, -1.38461 (11, -1.96094\n", + " (15, 1.94871 (16, -1.33022 (24, 1.77817 (27, 1.47279 (30, -1.6875\n", + " (31, -1.50103 (34, 1.55784 (38, -1.58119 (40, 1.44199 (41, 1.95772\n", + " (42, -1.35878 (43, -1.70719 (46, 1.95437 (47, -1.6233 (49, -1.40585\n", + " (50, 1.79578 (54, -1.35137 (56, 1.50417 (57, -1.25255 (66, 1.32932\n", + " (67, 1.71153 (69, 1.34714 (71, -1.5285 (72, 1.22962 (73, -1.6997\n", + " (74, -1.96793 (84, -1.5294 (87, -1.66995 (92, -1.70361 (94, 1.3924\n", + " (95, 1.68896 (99, 1.31284 }\n", + "val v4_s : t =\n", + " {dim: 100\n", + " (1, 0.245881 (2, 0.411059 (4, 1.06289 (5, -0.740514 (7, -0.43071\n", + " (8, 0.977894 (9, -0.43281 (10, -0.692304 (11, -1.95238 (15, 0.502957\n", + " (16, 0.197927 (17, -0.497091 (19, 0.8659 (20, 0.572763 (21, 0.963705\n", + " (23, -0.568959 (24, 1.53261 (25, 0.697603 (26, -0.706857 (27, 0.736393\n", + " (29, -0.874151 (30, -0.283957 (31, -0.750514 (32, -0.392582 (34, 0.290132\n", + " (36, -0.988593 (38, -1.60787 (39, -0.78555 (40, 0.720996 (41, 0.978861\n", + " (42, -0.173443 (43, -0.482758 (44, -0.734224 (45, -0.634506 (46, 1.28169\n", + " (47, -1.14217 (48, -0.800156 (49, -1.2736 (50, 0.382892 (51, -0.47082\n", + " (52, 0.731985 (53, -0.501758 (54, -1.53206 (55, 0.422431 (56, 1.57175\n", + " (57, 0.220801 (58, 0.301306 (59, -0.917181 (60, 0.391153 (61, -0.936169\n", + " (62, 0.855439 (63, 0.730839 (64, 0.763087 (65, 0.777606 (66, 1.61024\n", + " (67, 0.271076 (68, 0.312286 (69, 1.51402 (71, -0.764248 (72, 1.59577\n", + " (73, -0.466006 (74, -0.983965 (77, 0.509676 (79, 0.86618 (80, -0.767171\n", + " (82, -0.955884 (83, -0.326832 (84, -0.764701 (87, -0.834976 (88, 0.846553\n", + " (89, -0.578475 (90, -0.522823 (91, 0.802248 (92, 0.123631 (94, 0.696202\n", + " (95, 0.0283147 (96, -0.999559 (97, 0.738769 (98, -0.368989 (99, 0.656419\n", + " (100, 0.9001 }\n", + "val v5_s : t =\n", + " {dim: 100\n", + " (1, 1.45827 (2, -0.411059 (4, 0.404641 (5, 0.740514 (7, -1.20533\n", + " (8, -0.977894 (9, 0.43281 (10, -0.692304 (11, -0.00855015 (15, 1.44575\n", + " (16, -1.52814 (17, 0.497091 (19, -0.8659 (20, -0.572763 (21, -0.963705\n", + " (23, 0.568959 (24, 0.245564 (25, -0.697603 (26, 0.706857 (27, 0.736393\n", + " (29, 0.874151 (30, -1.40354 (31, -0.750514 (32, 0.392582 (34, 1.26771\n", + " (36, 0.988593 (38, 0.0266769 (39, 0.78555 (40, 0.720996 (41, 0.978861\n", + " (42, -1.18533 (43, -1.22443 (44, 0.734224 (45, 0.634506 (46, 0.672682\n", + " (47, -0.481123 (48, 0.800156 (49, -0.132254 (50, 1.41289 (51, 0.47082\n", + " (52, -0.731985 (53, 0.501758 (54, 0.180688 (55, -0.422431 (56, -0.067584\n", + " (57, -1.47335 (58, -0.301306 (59, 0.917181 (60, -0.391153 (61, 0.936169\n", + " (62, -0.855439 (63, -0.730839 (64, -0.763087 (65, -0.777606 (66, -0.280911\n", + " (67, 1.44045 (68, -0.312286 (69, -0.166879 (71, -0.764248 (72, -0.366148\n", + " (73, -1.2337 (74, -0.983965 (77, -0.509676 (79, -0.86618 (80, 0.767171\n", + " (82, 0.955884 (83, 0.326832 (84, -0.764701 (87, -0.834976 (88, -0.846553\n", + " (89, 0.578475 (90, 0.522823 (91, -0.802248 (92, -1.82724 (94, 0.696202\n", + " (95, 1.66064 (96, 0.999559 (97, -0.738769 (98, 0.368989 (99, 0.656419\n", + " (100, -0.9001 }\n", + "val v6_s : t =\n", + " {dim: 100\n", + " (1, 1.95004 (2, 0.411059 (4, 2.53041 (5, -0.740514 (7, -2.06675\n", + " (8, 0.977894 (9, -0.43281 (10, -2.07691 (11, -3.91332 (15, 2.45167\n", + " (16, -1.13229 (17, -0.497091 (19, 0.8659 (20, 0.572763 (21, 0.963705\n", + " (23, -0.568959 (24, 3.31078 (25, 0.697603 (26, -0.706857 (27, 2.20918\n", + " (29, -0.874151 (30, -1.97145 (31, -2.25154 (32, -0.392582 (34, 1.84797\n", + " (36, -0.988593 (38, -3.18907 (39, -0.78555 (40, 2.16299 (41, 2.93658\n", + " (42, -1.53222 (43, -2.18995 (44, -0.734224 (45, -0.634506 (46, 3.23606\n", + " (47, -2.76547 (48, -0.800156 (49, -2.67945 (50, 2.17867 (51, -0.47082\n", + " (52, 0.731985 (53, -0.501758 (54, -2.88344 (55, 0.422431 (56, 3.07592\n", + " (57, -1.03175 (58, 0.301306 (59, -0.917181 (60, 0.391153 (61, -0.936169\n", + " (62, 0.855439 (63, 0.730839 (64, 0.763087 (65, 0.777606 (66, 2.93956\n", + " (67, 1.98261 (68, 0.312286 (69, 2.86117 (71, -2.29274 (72, 2.82539\n", + " (73, -2.16571 (74, -2.9519 (77, 0.509676 (79, 0.86618 (80, -0.767171\n", + " (82, -0.955884 (83, -0.326832 (84, -2.2941 (87, -2.50493 (88, 0.846553\n", + " (89, -0.578475 (90, -0.522823 (91, 0.802248 (92, -1.57998 (94, 2.0886\n", + " (95, 1.71727 (96, -0.999559 (97, 0.738769 (98, -0.368989 (99, 1.96926\n", + " (100, 0.9001 }\n" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val zero : Lacaml.D.vec = R1 R2 R3 R98 R99 R100\n", + " 0 0 0 ... 0 0 0\n", + "val zero_s : t = {dim: 100 }\n" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let x1 = L.Vec.map (fun x -> if abs_float x < 0.6 then 0. else x) (L.Vec.random 100)\n", + "and x2 = L.Vec.map (fun x -> if abs_float x < 0.3 then 0. else x) (L.Vec.random 100) \n", + "\n", + "let x3 = L.Vec.map (fun x -> 2. *. x) x1\n", + "and x4 = L.Vec.add x1 x2\n", + "and x5 = L.Vec.sub x1 x2\n", + "and x6 = \n", + " let v = L.copy x2 in\n", + " L.axpy ~alpha:3. x1 v;\n", + " v \n", + "\n", + " \n", + "let v1 = x1\n", + "and v2 = x2\n", + "and v3 = x3 \n", + "and v4 = x4 \n", + "and v5 = x5 \n", + "and v6 = x6 \n", + "\n", + " \n", + "let v1_s = of_vec x1\n", + "and v2_s = of_vec x2\n", + "and v3_s = of_vec x3\n", + "and v4_s = of_vec x4\n", + "and v5_s = of_vec x5\n", + "and v6_s = of_vec x6\n", + "\n", + " \n", + "let zero = L.Vec.make0 100\n", + "and zero_s = of_vec (L.Vec.make0 100)\n", + "\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val test_conversion : unit -> unit = \n" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val test_operations : unit -> unit = \n" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val test_dot : unit -> unit = \n" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "val test_case : unit -> (string * [> `Quick ] * (unit -> unit)) list = \n" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + " let test_conversion () =\n", + " Alcotest.(check bool) \"sparse -> dense 1\" true (to_vec v1_s = v1 );\n", + " Alcotest.(check bool) \"sparse -> dense 2\" true (to_vec v2_s = v2 );\n", + " Alcotest.(check bool) \"dense -> sparse 1\" true (of_vec v1 = v1_s);\n", + " Alcotest.(check bool) \"dense -> sparse 2\" true (of_vec v2 = v2_s)\n", + " \n", + " \n", + " let test_operations () =\n", + " Alcotest.(check bool) \"dense scale\" true (let w = L.copy v1 in L.scal 2. w ; w = v3);\n", + " Alcotest.(check bool) \"sparse scale\" true (scale 2. v1_s = v3_s);\n", + " \n", + " Alcotest.(check bool) \"dense dense add\" true (L.Vec.add v1 v2 = v4);\n", + " (*\n", + " Alcotest.(check bool) \"dense sparse add\" true (add v1 v2_s = v4_s);\n", + " Alcotest.(check bool) \"sparse dense add\" true (add v1_s v2 = v4_s);\n", + " Alcotest.(check bool) \"sparse dense add\" true (add v1 v2_s = v4_s);\n", + " *)\n", + " Alcotest.(check bool) \"sparse sparse add\" true (equal (add v1_s v2_s) v4_s);\n", + " \n", + " Alcotest.(check bool) \"dense dense sub\" true (L.Vec.sub v1 v2 = v5);\n", + " (*\n", + " Alcotest.(check bool) \"dense sparse sub\" true (sub v1 v2_s = v5_s);\n", + " Alcotest.(check bool) \"sparse dense sub\" true (sub v1_s v2 = v5_s);\n", + " Alcotest.(check bool) \"sparse dense sub\" true (sub v1 v2_s = v5_s);\n", + " *)\n", + " Alcotest.(check bool) \"sparse sparse sub\" true (equal (sub v1_s v2_s) v5_s);\n", + " \n", + " Alcotest.(check bool) \"dense dense sub\" true (L.Vec.sub v1 v1 = zero);\n", + " (*\n", + " Alcotest.(check bool) \"dense sparse sub\" true (sub v1 v1_s = zero_s);\n", + " Alcotest.(check bool) \"sparse dense sub\" true (sub v1_s v1 = zero_s);\n", + " *)\n", + " Alcotest.(check bool) \"sparse sparse sub\" true (equal (sub v1_s v1_s) zero_s);\n", + " \n", + " Alcotest.(check bool) \"dense dense axpy\" true (let w = L.copy v2 in L.axpy ~alpha:3. v1 w ; w = v6);\n", + " (*\n", + " Alcotest.(check bool) \"dense sparse axpy\" true (sub ~threshold:1.e-12 (axpy ~alpha:3. v1 v2_s) v6_s = zero_s);\n", + " Alcotest.(check bool) \"sparse dense axpy\" true (sub ~threshold:1.e-12 (axpy ~alpha:3. v1_s v2) v6_s = zero_s);\n", + " *)\n", + " Alcotest.(check bool) \"sparse sparse axpy\" true (equal (sub ~threshold:1.e-12 (axpy ~alpha:3. v1_s v2_s) v6_s) zero_s)\n", + " \n", + "let test_dot () = \n", + " let d1d2 = L.dot x1 x2\n", + " and d1d1 = L.dot x1 x1\n", + " and d2d2 = L.dot x2 x2 \n", + " in\n", + " (*\n", + " Alcotest.(check (float 1.e-10)) \"sparse x dense 1\" (dot v1_s v2 ) d1d2;\n", + " Alcotest.(check (float 1.e-10)) \"sparse x dense 2\" (dot v1_s v1 ) d1d1;\n", + " Alcotest.(check (float 1.e-10)) \"sparse x dense 3\" (dot v2_s v2 ) d2d2;\n", + " Alcotest.(check (float 1.e-10)) \"dense x sparse 1\" (dot v1 v2_s) d1d2;\n", + " Alcotest.(check (float 1.e-10)) \"dense x sparse 2\" (dot v1 v1_s) d1d1;\n", + " Alcotest.(check (float 1.e-10)) \"dense x sparse 3\" (dot v2 v2_s) d2d2;\n", + " *)\n", + " Alcotest.(check (float 1.e-10)) \"sparse x sparse 1\" (dot v1_s v2_s) d1d2;\n", + " Alcotest.(check (float 1.e-10)) \"sparse x sparse 2\" (dot v1_s v1_s) d1d1;\n", + " Alcotest.(check (float 1.e-10)) \"sparse x sparse 3\" (dot v2_s v2_s) d2d2\n", + " \n", + " \n", + "let test_case () = \n", + " [ \n", + " \"Conversion\", `Quick, test_conversion;\n", + " \"Operations\", `Quick, test_operations;\n", + " \"Dot product\", `Quick, test_dot;\n", + " ] " + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "File \"[28]\", line 1, characters 0-3:\n", + "Warning 1: this `(*' is the start of a comment.\n", + "Hint: Did you forget spaces when writing the infix operator `( * )'?\n" + ] + } + ], + "source": [ + "(*)\n", + "Alcotest.run ~argv:[|\"ignored\"|] \"Unit tests\" [\n", + " \"SpVec\", test_case ();\n", + "];;\n", + "Printf.printf \"%!\";;\n", + "*)" + ] } ], "metadata": {