container/numeric_sequence.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 numeric_sequence
#
# Author: Michael Lill (michael.lill@tokiwa.software)
#
# -----------------------------------------------------------------------
# numeric_sequence -- a Sequence whose elements inherit from numeric
#
public numeric_sequence(public N type : numeric,
redef from Sequence N ) : searchable_sequence N from,
property.equatable
is
# the arithmetic mean of the sequence
# https://en.wikipedia.org/wiki/Arithmetic_mean
public average option N =>
if is_empty
nil
else
cnt := (map N (_ -> N.one)).fold N.sum
sum := fold N.sum
sum / cnt
# the variance of the sequence
# https://en.wikipedia.org/wiki/Variance
public variance option N =>
match average
nil => nil
avg N =>
cnt := (map N (_ -> N.one )).fold N.sum
sum := (map N (x -> (x - avg)**N.two)).fold N.sum
sum / cnt
# minimum value in the sequence
public min option N =>
if is_empty
nil
else
reduce first ((r,t) -> if r ≤ t then r else t)
# maximum value in the sequence
public max option N =>
if is_empty
nil
else
reduce first ((r,t) -> if r ≤ t then t else r)
# the median of the sequence
# https://en.wikipedia.org/wiki/Median
public median option N =>
if is_empty
nil
else
arr := sorted_array_of numeric_sequence.this
if arr.length % 2 = 1
arr[arr.length / 2]
else
(arr[(arr.length / 2) - 1] + arr[(arr.length / 2)]) / (N.two)
# equality check implementation for inherited property.equatable
#
public fixed type.equality(a, b container.numeric_sequence N) bool =>
aa := a.as_array
ba := b.as_array
aa.count = ba.count
&& ((0..(a.count - 1)) ∀ (i -> aa[i] = ba[i]))