86 lines
1.7 KiB
Plaintext
86 lines
1.7 KiB
Plaintext
defmodule Complex do
|
|
import Kernel, except: [abs: 1, div: 2]
|
|
|
|
defstruct real: 0, imag: 0
|
|
|
|
def new(real, imag) do
|
|
%__MODULE__{real: real, imag: imag}
|
|
end
|
|
|
|
def add(a, b) do
|
|
{a, b} = convert(a, b)
|
|
new(a.real + b.real, a.imag + b.imag)
|
|
end
|
|
|
|
def sub(a, b) do
|
|
{a, b} = convert(a, b)
|
|
new(a.real - b.real, a.imag - b.imag)
|
|
end
|
|
|
|
def mul(a, b) do
|
|
{a, b} = convert(a, b)
|
|
new(a.real*b.real - a.imag*b.imag, a.imag*b.real + a.real*b.imag)
|
|
end
|
|
|
|
def div(a, b) do
|
|
{a, b} = convert(a, b)
|
|
divisor = abs2(b)
|
|
new((a.real*b.real + a.imag*b.imag) / divisor,
|
|
(a.imag*b.real - a.real*b.imag) / divisor)
|
|
end
|
|
|
|
def neg(a) do
|
|
a = convert(a)
|
|
new(-a.real, -a.imag)
|
|
end
|
|
|
|
def inv(a) do
|
|
a = convert(a)
|
|
divisor = abs2(a)
|
|
new(a.real / divisor, -a.imag / divisor)
|
|
end
|
|
|
|
def conj(a) do
|
|
a = convert(a)
|
|
new(a.real, -a.imag)
|
|
end
|
|
|
|
def abs(a) do
|
|
:math.sqrt(abs2(a))
|
|
end
|
|
|
|
defp abs2(a) do
|
|
a = convert(a)
|
|
a.real*a.real + a.imag*a.imag
|
|
end
|
|
|
|
defp convert(a) when is_number(a), do: new(a, 0)
|
|
defp convert(%__MODULE__{} = a), do: a
|
|
|
|
defp convert(a, b), do: {convert(a), convert(b)}
|
|
|
|
def task do
|
|
a = new(1, 3)
|
|
b = new(5, 2)
|
|
IO.puts "a = #{a}"
|
|
IO.puts "b = #{b}"
|
|
IO.puts "add(a,b): #{add(a, b)}"
|
|
IO.puts "sub(a,b): #{sub(a, b)}"
|
|
IO.puts "mul(a,b): #{mul(a, b)}"
|
|
IO.puts "div(a,b): #{div(a, b)}"
|
|
IO.puts "div(b,a): #{div(b, a)}"
|
|
IO.puts "neg(a) : #{neg(a)}"
|
|
IO.puts "inv(a) : #{inv(a)}"
|
|
IO.puts "conj(a) : #{conj(a)}"
|
|
end
|
|
end
|
|
|
|
defimpl String.Chars, for: Complex do
|
|
def to_string(%Complex{real: real, imag: imag}) do
|
|
if imag >= 0, do: "#{real}+#{imag}j",
|
|
else: "#{real}#{imag}j"
|
|
end
|
|
end
|
|
|
|
Complex.task
|