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

matrix.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 matrix
#
#  Author: Fridtjof Siebert (siebert@tokiwa.software)
#
# -----------------------------------------------------------------------

# matrix -- matrix based on arbitrary numeric type
#
# matrix provides matrix operations based on an arbitray numeric type
#
matrix<T : numeric<T>> (e array2<T>) : numeric<matrix<T>>, matrices<T>
is

# private:

  # just for brevity
  a => matrix.this

# public:

  # enable generic features in ancestors
  redef thiz => matrix.this
  redef orderedThis => matrix.this

  # basic operations
  redef prefix + => a
  redef infix +  (b matrix<T>) => matrix (array2<T> e.length0 e.length1 i,j->e[i,j]+b.e[i,j])
  redef infix -  (b matrix<T>) => matrix (array2<T> e.length0 e.length1 i,j->e[i,j]-b.e[i,j])
  redef infix *  (b matrix<T>) =>
    matrix (array2<T> e.length0 b.e.length1
      (i,j ->
        for
          v := e[0,0].zero, v+f
          x in e.indices1
          f := a.e[i,x]*b.e[x,j]
        else
          v
        ))
  redef infix /  (b matrix<T>) matrix<T>
    pre
      safety: false
  is
    fuzion.std.panic "'matrix.infix /' not defined."

  # comparison
  redef infix == (b matrix<T>) =>
    for
      x in e
      y in a.e
    until x /= y
      false
    else
      true

  redef infix != (b matrix<T>) => !(a = b)

  # NYI: total order
  redef infix <  (b matrix<T>) => fuzion.std.panic "matrix does not define a total order"
  redef infix <= (b matrix<T>) => fuzion.std.panic "matrix does not define a total order"
  redef infix >  (b matrix<T>) => fuzion.std.panic "matrix does not define a total order"
  redef infix >= (b matrix<T>) => fuzion.std.panic "matrix does not define a total order"

  transpose matrix<T> is
    matrix (array2<T> e.length1 e.length0 i,j->e[j,i])

  redef asString => e.asString

  # NYI: these three should be implemented in matrices, not here:
  redef zero => fuzion.std.panic "matrix.zero not implemented"
  redef one  => fuzion.std.panic "matrix.one not implemented"

  # NYI: 'matrix' misses imlementaton of many abstract features from
  # 'numeric'. Maybe 'matrix' should not inherit from 'numeric' at all?