Packages

Wizard is a math and statistics library for Elixir.

Current section

Files

Jump to
wizard lib wizard_math.ex
Raw

lib/wizard_math.ex

defmodule Wizard.Math do
@moduledoc """
Wizard's Mathemagic functions
"""
@doc """
Pi (lel)
"""
def pi do
3.141592653589793
end
@doc """
Euler's number (lel)
"""
def e do
2.718281828459045
end
@doc """
sum(list) - produces the sum of all the elements in a list
"""
@spec sum(list) :: number
def sum(list) do
Enum.reduce(list, 0, fn(x, acc) -> x + acc end)
end
@doc """
Produces the greatest common divsor (GCD) of a and b
TODO: fix negative arguments
"""
@spec gcd(integer, integer) :: integer
def gcd(a,b) do
cond do
b == 0 ->
a
a > b ->
gcd(b, rem(a,b))
a <= b ->
gcd(a, rem(b,a))
end
end
@doc """
factorial(n) - produces n!
"""
@spec factorial(non_neg_integer) :: non_neg_integer
def factorial(n) do
cond do
n < 0 ->
raise ArithmeticError, message: "Argument must be a positive intger."
n == 0 ->
1
n > 0 ->
n * factorial(n-1)
end
end
# """
# sqrt_rough(n) - produces a rough estimate of sqrt(n)
# https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Rough_estimation
# """
@spec sqrt_rough(number, number, non_neg_integer) :: number
defp sqrt_rough(n, prev, acc) do
cond do
n <=0 ->
cond do
prev < 10 ->
2 * pow(10, acc-1)
true ->
6 * pow(10, acc-1)
end
n > 0 ->
sqrt_rough(div(n,100), n, 1+acc)
end
end
# """
# sqrt(n) - produces the square root of n
# """
@spec sqrt(number, number, number) :: number
defp sqrt(s, n, x) do
cond do
x == ((1/n)*((n-1)*x + (s/pow(x,n-1)))) ->
x
true ->
sqrt(s, n, ((1/n)*((n-1)*x + (s/pow(x,n-1)))))
end
end
@doc """
sqrt(n) - produces the square root of n
- wraps the sqrt(s,n,x) function for cleaner use
"""
@spec sqrt(number) :: number
def sqrt(n) do
cond do
n < 0 ->
raise ArithmeticError, message: "Arugment must be a positive number"
n == 0 ->
0
n > 0 ->
sqrt(n, 2, sqrt_rough(n,n,0))
end
end
@doc """
nth_root(a, n) - produces the nth root of a
"""
@spec nth_root(number, non_neg_integer) :: number
def nth_root(a, n) do
cond do
n < 0 ->
raise ArithmeticError, message: "Arugment n must be a positive number"
n == 0 ->
0
n > 0 ->
sqrt(a, n, sqrt_rough(n,n,0))
end
end
@doc """
pow(x, y) - produces x to the yth power
TODO: fix decimal to fraction conversion
the current version creates massive runtimes
"""
@spec pow(number, integer) :: number
def pow(x,y) do
# lol
:math.pow(x,y)
# cond do
# y < 0 ->
# 1/(x * pow(x, -1*y))
# y == 0 ->
# 1
# # y > 0 && y < 1 ->
# # numerator = to_string(y) |> String.split(".") |> List.last() |> String.to_integer
# # denominator = to_string(y) |> String.split(".") |> List.last() |> String.length
# # denominator = pow(10, denominator)
# # IO.puts numerator
# # IO.puts denominator
# # nth_root(pow(x, numerator),denominator)
# y == 1 ->
# x
# y > 0 ->
# x * pow(x, y-1)
# end
end
@doc """
log(b, n) - produces log_b n with default base of e
"""
@spec log(number, number) :: number
def log(b \\ e,n) do
:math.log(n)/:math.log(b)
end
@doc """
permutation(n, k) - produces k-permutations of n
"""
@spec permutation(non_neg_integer, non_neg_integer) :: non_neg_integer
def permutation(n,k) do
div(factorial(n), factorial(n-k))
end
@doc """
combination(n, k) - produces n choose k
"""
@spec combination(non_neg_integer, non_neg_integer) :: non_neg_integer
def combination(n,k) do
div(factorial(n), (factorial(k)*factorial(n-k)))
end
end