Packages

FunLand adds Behaviours to define Algebraic Data Types ('Container' data types) to Elixir, such as Functors, Monoids and Monads.

Current section

Files

Jump to
fun_land lib vector.ex
Raw

lib/vector.ex

defmodule Vector do
import Kernel, except: [length: 1]
defmodule Inspect do
@doc false
def inspect(vector, _opts) do
"#Vector<(#{Tensor.Inspect.dimension_string(vector)})#{inspect Vector.to_list(vector)}>"
end
end
def new() do
Tensor.new([], [0], 0)
end
def new(length_or_list_or_range, identity \\ 0)
def new(list, identity) when is_list(list) do
Tensor.new(list, [Kernel.length(list)], identity)
end
def new(length, identity) when is_number(length) do
Tensor.new([], [length], identity)
end
def new(range = _.._, identity) do
new(range |> Enum.to_list, identity)
end
def length(vector) do
hd(vector.dimensions)
end
def to_list(vector) do
Tensor.to_list(vector)
end
def from_list(list, identity \\ 0) do
Tensor.new(list, [Kernel.length(list)], identity)
end
def reverse(vector = %Tensor{dimensions: [l]}) do
new_contents =
for {i, v} <- vector.contents, into: %{} do
{l-1 - i, v}
end
%Tensor{vector | contents: new_contents}
end
def dot_product(a = %Tensor{dimensions: [l]}, b = %Tensor{dimensions: [l]}) do
products =
for i <- 0..(l-1) do
a[i] * b[i]
end
Enum.sum(products)
end
def dot_product(_a, _b), do: raise Tensor.ArithmeticError, "Two Vectors have to have the same length to be able to compute the dot product"
@doc """
Returns the current identity of vector `vector`.
"""
defdelegate identity(vector), to: Tensor
@doc """
`true` if `a` is a Vector.
"""
defdelegate vector?(a), to: Tensor
@doc """
Returns the element at `index` from `vector`.
"""
defdelegate fetch(vector, index), to: Tensor
@doc """
Returns the element at `index` from `vector`. If `index` is out of bounds, returns `default`.
"""
defdelegate get(vector, index, default), to: Tensor
defdelegate pop(vector, index, default), to: Tensor
defdelegate get_and_update(vector, index, function), to: Tensor
defdelegate merge_with_index(vector_a, vector_b, function), to: Tensor
defdelegate merge(vector_a, vector_b, function), to: Tensor
defdelegate to_list(vector), to: Tensor
defdelegate lift(vector), to: Tensor
defdelegate map(vector, function), to: Tensor
defdelegate with_coordinates(vector), to: Tensor
defdelegate sparse_map_with_coordinates(vector, function), to: Tensor
defdelegate dense_map_with_coordinates(vector, function), to: Tensor
defdelegate add(a, b), to: Tensor
defdelegate sub(a, b), to: Tensor
defdelegate mul(a, b), to: Tensor
defdelegate div(a, b), to: Tensor
defdelegate add_number(a, b), to: Tensor
defdelegate sub_number(a, b), to: Tensor
defdelegate mul_number(a, b), to: Tensor
defdelegate div_number(a, b), to: Tensor
@doc """
Elementwise addition of vectors `vector_a` and `vector_b`.
"""
defdelegate add_vector(vector_a, vector_b), to: Tensor, as: :add_tensor
@doc """
Elementwise subtraction of `vector_b` from `vector_a`.
"""
defdelegate sub_vector(vector_a, vector_b), to: Tensor, as: :sub_tensor
@doc """
Elementwise multiplication of `vector_a` with `vector_b`.
"""
defdelegate mul_vector(vector_a, vector_b), to: Tensor, as: :mul_tensor
@doc """
Elementwise division of `vector_a` and `vector_b`.
Make sure that the identity of `vector_b` isn't 0 before doing this.
"""
defdelegate div_vector(vector_a, vector_b), to: Tensor, as: :div_tensor
end