Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

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


  # basic operations
  public fixed redef prefix + complex C => complex.this
  public fixed redef infix + (b complex C) complex C => complex real+b.real imag+b.imag
  public fixed redef infix - (b complex C) complex C => complex real-b.real imag-b.imag
  public fixed redef infix * (b complex C) complex C => complex real*b.real-imag*b.imag real*b.imag+imag*b.real
  public fixed redef infix / (b complex C) complex C
  =>
    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 redef type.equality(a, b num.complex C) bool =>
    a.real = b.real && a.imag = b.imag


  # total order ignoring imag
  #
  public fixed redef type.lteq(a, b num.complex C) bool =>
    # lexicographic order
    #
    # see ORDERING COMPLEX NUMBERS. . . NOT* by David Angell:
    # https://web.maths.unsw.edu.au/~angell/articles/complexorder.pdf
    #
    # NOTE: order is not compatible with addition/multiplication
    #
    a.real < b.real || (a.real = b.real && a.imag <= b.imag)


  public abs² C => real*real+imag*imag


  public redef as_string 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 redef type.zero num.complex C =>
    num.complex C.zero C.zero


  # identity element for 'infix *'
  #
  public fixed redef 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: 2025-07-10