Skip to content

Instantly share code, notes, and snippets.

@Ssenseii
Last active September 29, 2024 08:44
Show Gist options
  • Select an option

  • Save Ssenseii/3616b3646db9949fe235f62d526ce0bd to your computer and use it in GitHub Desktop.

Select an option

Save Ssenseii/3616b3646db9949fe235f62d526ce0bd to your computer and use it in GitHub Desktop.
Elixir Module for More Complex Number Operations than the ones provided by the Complex Module
# thank you u/al2o3cr for the constructive feedback!!
defmodule Complex do
defstruct real: 0, imag: 0
@type t :: %Complex{real: number, imag: number}
def add(%Complex{real: r1, imag: i1}, %Complex{real: r2, imag: i2}) do
%Complex{real: r1 + r2, imag: i1 + i2}
end
def subtract(%Complex{real: r1, imag: i1}, %Complex{real: r2, imag: i2}) do
%Complex{real: r1 - r2, imag: i1 - i2}
end
def multiply(%Complex{real: r1, imag: i1}, %Complex{real: r2, imag: i2}) do
%Complex{
real: r1 * r2 - i1 * i2,
imag: r1 * i2 + i1 * r2
}
end
def divide(%Complex{real: r1, imag: i1}, %Complex{real: r2, imag: i2}) do
denom = r2 * r2 + i2 * i2
%Complex{
real: (r1 * r2 + i1 * i2) / denom,
imag: (i1 * r2 - r1 * i2) / denom
}
end
def to_string(%Complex{real: r, imag: i}) do
"#{r} + #{i}i"
end
def modulus(%Complex{real: r, imag: i}) do
:math.sqrt(r * r + i * i)
end
def conjugate(%Complex{real: r, imag: i}) do
%Complex{real: r, imag: -i}
end
def exponentiate(%Complex{real: r, imag: i}, n) when is_integer(n) do
case n do
0 -> %Complex{real: 1, imag: 0}
_ -> exponentiate_helper(%Complex{real: r, imag: i}, n)
end
end
defp exponentiate_helper(_, 0), do: %Complex{real: 1, imag: 0}
defp exponentiate_helper(c, n) do
multiply(c, exponentiate_helper(c, n - 1))
end
def magnitude(%Complex{real: r, imag: i}) do
:math.sqrt(:math.pow(r, 2) + :math.pow(i, 2));
end
def argument(%Complex{real: r, imag: i}) do
:math.atan2(i, r);
end
def polar_form_conversion(%Complex{real: r, imag: i}) do
re = magnitude(%Complex{real: r, imag: i});
teta = argument(%Complex{real: r, imag: i})
form = re * (:math.cos(teta) + :math.sin(teta));
{re, teta, form}
end
def polar_form_representation(%Complex{real: r, imag: i}) do
re = magnitude(%Complex{real: r, imag: i});
teta = argument(%Complex{real: r, imag: i})
"#{re} * (cos#{teta}+ sin#{teta})"
end
def exponential_form(%Complex{real: r, imag: i}) do
{re, teta, _} = polar_form_conversion(%Complex{real: r, imag: i})
"#{re} * exp(#{teta}i)"
end
def square_root(%Complex{real: r, imag: i}) do
{re, theta} = polar_form_conversion(%Complex{real: r, imag: i})
sqrt_re = :math.sqrt(re)
sqrt_theta = theta / 2
{sqrt_re * :math.cos(sqrt_theta), sqrt_re * :math.sin(sqrt_theta)} # Returns the square root in rectangular form
end
def raise_to_power(%Complex{real: r, imag: i}, n) do
{re, theta} = polar_form_conversion(%Complex{real: r, imag: i})
new_re = :math.pow(re, n)
new_theta = n * theta
{new_re * :math.cos(new_theta), new_re * :math.sin(new_theta)} # Returns z^n in rectangular form
end
def root_extraction(%Complex{real: r, imag: i}, n) do
{re, theta} = polar_form_conversion(%Complex{real: r, imag: i})
root_re = :math.pow(re, 1 / n)
# Create a list of roots using list comprehension
roots = for k <- 0..(n-1) do
{root_re * :math.cos((theta + 2 * :math.pi * k) / n), root_re * :math.sin((theta + 2 * :math.pi * k) / n)}
end
roots # Return the list of roots
end
def complex_exponentiation(%Complex{real: r, imag: i}) do
e_to_r = :math.exp(r)
{e_to_r * :math.cos(i), e_to_r * :math.sin(i)} # Returns e^z in rectangular form
end
def logarithm(%Complex{real: r, imag: i}) do
{re, theta} = polar_form_conversion(%Complex{real: r, imag: i})
{ :math.log(re), theta } # Returns log(z) as {ln|z|, arg(z)}
end
def sine(%Complex{real: r, imag: i}) do
sin_r = :math.sin(r) * :math.cosh(i)
cos_r = :math.cos(r) * :math.sinh(i)
{sin_r, cos_r} # Returns sin(z) in rectangular form
end
def cosine(%Complex{real: r, imag: i}) do
cos_r = :math.cos(r) * :math.cosh(i)
sin_r = - :math.sin(r) * :math.sinh(i)
{cos_r, sin_r} # Returns cos(z) in rectangular form
end
def tangent(%Complex{real: r, imag: i}) do
{sin_r, cos_r} = sine(%Complex{real: r, imag: i})
{sin_r / cos_r} # Returns tan(z) in rectangular form
end
def hyperbolic_sine(%Complex{real: r, imag: i}) do
sinh_r = :math.sinh(r) * :math.cos(i)
cosh_r = :math.cosh(r) * :math.sin(i)
{sinh_r, cosh_r} # Returns sinh(z) in rectangular form
end
def hyperbolic_cosine(%Complex{real: r, imag: i}) do
cosh_r = :math.cosh(r) * :math.cos(i)
sinh_r = :math.sinh(r) * :math.sin(i)
{cosh_r, sinh_r} # Returns cosh(z) in rectangular form
end
def hyperbolic_tangent(%Complex{real: r, imag: i}) do
{sinh_r, cosh_r} = hyperbolic_sine(%Complex{real: r, imag: i})
{sinh_r / cosh_r} # Returns tanh(z) in rectangular form
end
def comparison(%Complex{real: r1, imag: i1}, %Complex{real: r2, imag: i2}) do
r1 == r2 and i1 == i2 # Returns true if both real and imaginary parts are equal
end
end
@Ssenseii

Copy link
Copy Markdown
Author

Faster Exponential Function

def fast_exponentiate(_, 0), do: %Complex{real: 1, imag: 0}

  def fast_exponentiate(z, n) when rem(n,2) == 0 do
    fast_exponentiate(multiply(z, z), div(n, 2))
  end

  def fast_exponentiate(z, n) do
    multiply(z, fast_exponentiate(z, n-1))
  end
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment