Current section
Files
Jump to
Current section
Files
lib/exun_der.ex
defmodule Exun.Der do
import Exun.Fun
import Exun.MProc
@moduledoc """
Derivate expressions
"""
@zero {:numb, 0}
@uno {:numb, 1}
@doc """
Derive function txt for variable x, return string
"""
def deriv(txt, x) when is_binary(txt) and is_binary(x) do
{ast, _ctx} = Exun.parse(txt)
deriv(ast, x)
# |> IO.inspect(label: "reduced")
|> Exun.UI.tostr()
end
def deriv(ast, name) when is_tuple(ast) and is_binary(name) do
der(ast, {:vari, name})
end
defp der({:deriv, fun, x1}, x2) do
der(der(fun, x1), x2)
end
defp der({:fcall, name, args}, x) do
search_name = name <> "(F)"
cond do
(bfunc = base()[search_name]) != nil ->
{ast, _ctx} = Exun.parse(elem(bfunc, 1))
replace_args_internal(ast, args, {:vari, "x"})
(cfunc = compounds()[search_name]) != nil ->
{ast, _ctx} = Exun.parse(cfunc)
replace_args_internal(ast, args, {:vari, "x"})
|> der(x)
true ->
{:deriv, {:fcall, name, args}, x}
end
end
defp der({:numb, _}, _x),
do: @zero
defp der({:unit, _uv, _ut}, _x),
do: @zero
defp der({:vari, var}, {:vari, x}),
do: if(var == x, do: @uno, else: @zero)
defp der({:suma, a, b}, x),
do: parallel({:suma, der(a, x), der(b, x)})
defp der({:rest, a, b}, x),
do: parallel({:rest, der(a, x), der(b, x)})
defp der({:mult, a, b}, x),
do: parallel({:suma, {:mult, der(a, x), b}, {:mult, a, der(b, x)}})
defp der({:divi, a, b}, x),
do:
parallel(
{:divi, {:rest, {:mult, b, der(a, x)}, {:mult, der(b, x), a}}, {:elev, b, {:numb, 2}}}
)
defp der(y = {:elev, f, g}, x),
do:
{:mult, y,
parallel(
{:suma, {:mult, der(g, x), {:fcall, "ln", [f]}}, {:mult, g, {:divi, der(f, x), f}}}
)}
defp der({:integ, f, x}, x) do
f
end
defp der(f, x) do
{:deriv, f, x}
end
end