Current section
Files
Jump to
Current section
Files
lib/exun_math.ex
defmodule Exun.Math do
@moduledoc """
Simple transformation of a tree
"""
@doc """
Change sign of AST
"""
@uno {:numb, 1}
@muno {:numb, -1}
def chsign({:vari, var}) do
{:mult, @muno, {:vari, var}}
end
def chsign({:unit, a, b}) do
{:unit, chsign(a), b}
end
def chsign({:elev, a, b}) do
{:mult, @muno, {:elev, a, b}}
end
def chsign({:numb, n}) do
{:numb, -n}
end
def chsign({:mult, a, b}) do
{:mult, chsign(a), b}
end
def chsign({:divi, a, b}) do
{:divi, chsign(a), b}
end
def chsign({:suma, a, b}) do
{:suma, chsign(a), chsign(b)}
end
def chsign({:rest, a, b}) do
{:rest, b, a}
end
def chsign({{:m, :mult}, lst}) do
{{:m, :mult}, [@muno | lst] |> Enum.sort()}
end
def chsign({{:m, :suma}, lst}) do
{{:m, :suma},
Enum.map(lst, fn el ->
chsign(el)
end)
|> Enum.sort()}
end
def chsign(ast) do
{:mult, @muno, ast}
end
@doc """
Change power sign of AST (expon * -1 or 1/tree)
"""
def chpow({:vari, var}) do
{:elev, {:vari, var}, {:numb, -1}}
end
def chpow({:unit, a, b}) do
{:unit, chpow(a), chpow(b)}
end
def chpow({:elev, a, b}) do
{:elev, a, chsign(b)}
end
def chpow({:numb, n}) do
{:numb, 1 / n}
end
def chpow({:mult, a, b}) do
{:mult, chpow(a), chpow(b)}
end
def chpow({:divi, a, b}) do
{:divi, b, a}
end
def chpow({:suma, a, b}) do
{:divi, @uno, {:suma, a, b}}
end
def chpow({:rest, a, b}) do
{:divi, @uno, {:rest, a, b}}
end
def chpow({{:m, :mult}, lst}) do
{{:m, :mult}, Enum.map(lst, fn el -> chpow(el) end)}
end
def chpow(suma = {{:m, :suma}, _lst}) do
{:divi, @uno, suma}
end
end