forked from pgvector/pgvector-elixir
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhalf_vector.ex
More file actions
55 lines (46 loc) · 1.38 KB
/
half_vector.ex
File metadata and controls
55 lines (46 loc) · 1.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
defmodule Pgvector.HalfVector do
@moduledoc """
A half vector struct for pgvector
"""
defstruct [:data]
@doc """
Creates a new half vector from a list, tensor, or half vector
"""
def new(list) when is_list(list) do
dim = list |> length()
bin = for v <- list, into: "", do: <<v::float-16>>
from_binary(<<dim::unsigned-16, 0::unsigned-16, bin::binary>>)
end
def new(%Pgvector.HalfVector{} = vector) do
vector
end
if Code.ensure_loaded?(Nx) do
def new(tensor) when is_struct(tensor, Nx.Tensor) do
if Nx.rank(tensor) != 1 do
raise ArgumentError, "expected rank to be 1"
end
dim = tensor |> Nx.size()
bin = tensor |> Nx.as_type(:f16) |> Nx.to_binary() |> f16_native_to_big()
from_binary(<<dim::unsigned-16, 0::unsigned-16, bin::binary>>)
end
defp f16_native_to_big(binary) do
if System.endianness() == :big do
binary
else
for <<n::float-16-little <- binary>>, into: "", do: <<n::float-16-big>>
end
end
end
@doc """
Creates a new half vector from its binary representation
"""
def from_binary(binary) when is_binary(binary) do
%Pgvector.HalfVector{data: binary}
end
end
defimpl Inspect, for: Pgvector.HalfVector do
import Inspect.Algebra
def inspect(vector, opts) do
concat(["Pgvector.HalfVector.new(", to_doc(Pgvector.to_list(vector), opts), ")"])
end
end