num/complex.fz
# This file is part of the Fuzion language implementation.
#
# The Fuzion language implementation is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, version 3 of the License.
#
# The Fuzion language implementation is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License along with The
# Fuzion language implementation. If not, see <https://www.gnu.org/licenses/>.
# -----------------------------------------------------------------------
#
# Tokiwa Software GmbH, Germany
#
# Source code of Fuzion standard library feature complex
#
# Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------
# complex -- complex numbers based on arbitrary numeric type
#
# complex provides complex numbers based on a numeric type (e.g. f64, i32).
# A complex number consists of a real and an imaginary part.
#
public complex (
public C type : numeric,
public real, # real part
imag C # imaginary part
) : numeric
is
# enable generic features in ancestors
public thiz => complex real imag
# basic operations
public fixed redef prefix + => thiz
public fixed redef infix + (b complex.this) => complex real+b.real imag+b.imag
public fixed redef infix - (b complex.this) => complex real-b.real imag-b.imag
public fixed redef infix * (b complex.this) => complex real*b.real-imag*b.imag real*b.imag+imag*b.real
public fixed redef infix / (b complex.this)
pre
# NYI: use type features
# safety: b != zero
safety: b.real != C.zero || b.imag != C.zero
=>
n := b.real*b.real+b.imag*b.imag
complex (real*b.real+imag*b.imag)/n (imag*b.real-real*b.imag)/n
# equality
#
public fixed type.equality(a, b num.complex C) bool =>
a.real = b.real && a.imag = b.imag
# total order ignoring imag
#
# NYI: Does this make sense mathematically?
#
public fixed type.lteq(a, b num.complex C) bool =>
a.real ≤ b.real
public abs² => real*real+imag*imag
public redef as_string =>
si :=
for c in ($imag).as_codepoints
until !("0123456789.+-".contains c)
"($imag)"
else
$imag
p := if (si.starts_with "-") then "" else "+"
"{real}$p{si}i"
# identity element for 'infix +'
#
public fixed type.zero num.complex C =>
num.complex C.zero C.zero
# identity element for 'infix *'
#
public fixed type.one num.complex C =>
num.complex C.one C.zero
# the imaginary unit
#
public fixed type.i num.complex C =>
num.complex C.zero C.one
last changed: 2024-03-07