Packages

A collection of useful mathematical functions in Elixir with a slant towards statistics, linear algebra and machine learning

Current section

Files

Jump to
numerix lib linear_algebra.ex
Raw

lib/linear_algebra.ex

defmodule Numerix.LinearAlgebra do
@moduledoc """
Linear algebra functions used for vector operations,
matrix factorization and matrix transformation.
"""
alias Numerix.{Common, Math}
@doc """
The sum of the products of two vectors.
"""
@spec dot_product([number], [number]) :: Common.maybe_float
def dot_product(vector1, vector2) do
vector1
|> multiply(vector2)
|> Enum.sum
end
@doc """
The L1 norm of a vector, also known as Manhattan norm.
"""
@spec l1_norm(Common.maybe_vector) :: Common.maybe_float
def l1_norm(vector) do
1 |> norm(vector)
end
@doc """
The L2 norm of a vector, also known as Euclidean norm.
"""
@spec l2_norm(Common.maybe_vector) :: Common.maybe_float
def l2_norm(vector) do
2 |> norm(vector)
end
@doc """
The p-norm of a vector.
"""
@spec norm(integer, Common.maybe_vector) :: Common.maybe_float
def norm(_p, nil), do: nil
def norm(p, vector) do
vector
|> Stream.map(fn x ->
abs(x) |> :math.pow(p)
end)
|> Enum.sum
|> Math.nth_root(p)
end
@doc """
Subtracts a vector from another.
Returns a stream of the differences.
"""
@spec subtract([number], [number]) :: Common.maybe_vector
def subtract(vector1, vector2) do
fn(x, y) -> x - y end
|> vec_apply(vector1, vector2)
end
@doc """
Multiplies a vector with another.
Returns a stream of the products.
"""
@spec multiply([number], [number]) :: Common.maybe_vector
def multiply(vector1, vector2) do
fn(x, y) -> x * y end
|> vec_apply(vector1, vector2)
end
defp vec_apply(_fun, [], _), do: nil
defp vec_apply(_fun, _, []), do: nil
defp vec_apply(fun, vector1, vector2) do
vector1
|> Stream.zip(vector2)
|> Stream.map(fn {x, y} -> fun.(x, y) end)
end
end