Packages

A high-performance, analytical Datalog engine for Gleam

Current section

Files

Jump to
aarondb src aarondb@vector.erl
Raw

src/aarondb@vector.erl

-module(aarondb@vector).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aarondb/vector.gleam").
-export([dot_product/2, magnitude/1, cosine_similarity/2, euclidean_distance/2, normalize/1, dimensions/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/aarondb/vector.gleam", 8).
-spec do_dot_product(list(float()), list(float()), float()) -> float().
do_dot_product(V1, V2, Acc) ->
case {V1, V2} of
{[X | Xs], [Y | Ys]} ->
do_dot_product(Xs, Ys, Acc + (X * Y));
{_, _} ->
Acc
end.
-file("src/aarondb/vector.gleam", 4).
-spec dot_product(list(float()), list(float())) -> float().
dot_product(V1, V2) ->
do_dot_product(V1, V2, +0.0).
-file("src/aarondb/vector.gleam", 15).
-spec magnitude(list(float())) -> float().
magnitude(V) ->
Sum_sq = gleam@list:fold(V, +0.0, fun(Acc, X) -> Acc + (X * X) end),
case gleam@float:square_root(Sum_sq) of
{ok, M} ->
M;
{error, _} ->
+0.0
end.
-file("src/aarondb/vector.gleam", 23).
-spec cosine_similarity(list(float()), list(float())) -> float().
cosine_similarity(V1, V2) ->
Mag1 = magnitude(V1),
Mag2 = magnitude(V2),
case (Mag1 =:= +0.0) orelse (Mag2 =:= +0.0) of
true ->
+0.0;
false ->
case (Mag1 * Mag2) of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> dot_product(V1, V2) / Gleam@denominator
end
end.
-file("src/aarondb/vector.gleam", 34).
?DOC(" L2 (Euclidean) distance between two vectors.\n").
-spec euclidean_distance(list(float()), list(float())) -> float().
euclidean_distance(V1, V2) ->
Sum_sq = begin
_pipe = gleam@list:zip(V1, V2),
gleam@list:fold(
_pipe,
+0.0,
fun(Acc, Pair) ->
Diff = erlang:element(1, Pair) - erlang:element(2, Pair),
Acc + (Diff * Diff)
end
)
end,
case gleam@float:square_root(Sum_sq) of
{ok, D} ->
D;
{error, _} ->
+0.0
end.
-file("src/aarondb/vector.gleam", 48).
?DOC(" Normalize a vector to unit length.\n").
-spec normalize(list(float())) -> list(float()).
normalize(V) ->
Mag = magnitude(V),
case Mag =:= +0.0 of
true ->
V;
false ->
gleam@list:map(V, fun(X) -> case Mag of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> X / Gleam@denominator
end end)
end.
-file("src/aarondb/vector.gleam", 57).
?DOC(" Number of dimensions.\n").
-spec dimensions(list(float())) -> integer().
dimensions(V) ->
erlang:length(V).