Mihxil's Statistics

Straight forward code to calculate average and standard deviations of a number of incoming values. Also provides utility to do this in a 'sliding window' in time.

License

License

GroupId

GroupId

org.meeuw
ArtifactId

ArtifactId

mihxil-statistics
Last Version

Last Version

0.4.0
Release Date

Release Date

Type

Type

jar
Description

Description

Mihxil's Statistics
Straight forward code to calculate average and standard deviations of a number of incoming values. Also provides utility to do this in a 'sliding window' in time.

Download mihxil-statistics

How to add to project

<!-- https://jarcasting.com/artifacts/org.meeuw/mihxil-statistics/ -->
<dependency>
    <groupId>org.meeuw</groupId>
    <artifactId>mihxil-statistics</artifactId>
    <version>0.4.0</version>
</dependency>
// https://jarcasting.com/artifacts/org.meeuw/mihxil-statistics/
implementation 'org.meeuw:mihxil-statistics:0.4.0'
// https://jarcasting.com/artifacts/org.meeuw/mihxil-statistics/
implementation ("org.meeuw:mihxil-statistics:0.4.0")
'org.meeuw:mihxil-statistics:jar:0.4.0'
<dependency org="org.meeuw" name="mihxil-statistics" rev="0.4.0">
  <artifact name="mihxil-statistics" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.meeuw', module='mihxil-statistics', version='0.4.0')
)
libraryDependencies += "org.meeuw" % "mihxil-statistics" % "0.4.0"
[org.meeuw/mihxil-statistics "0.4.0"]

Dependencies

compile (1)

Group / Artifact Type Version
org.meeuw : mihxil-math jar 0.4.0

provided (1)

Group / Artifact Type Version
org.projectlombok : lombok jar 1.18.16

test (5)

Group / Artifact Type Version
org.meeuw : mihxil-math-theories jar 0.4.0
org.junit.jupiter : junit-jupiter jar 5.7.0
net.jqwik : jqwik jar 1.3.10
org.assertj : assertj-core jar 3.18.1
org.apache.logging.log4j : log4j-core jar 2.14.0

Project Modules

There are no modules declared in this project.

Algebraic interfaces for Java

Build Status codecov snapshots Maven Central javadoc

See this file in html for proper display of the (few) mathematical equations.

1. mihxil-math

Maven Central javadoc

The core dependency of the modules in the project. It provides the scaffolding for:

  • Abstract algebras to ensure a common interface for basic operations. Java does not provide operator overloading. This provides an alternative. Implementations of these interfaces can be 'property-based' tested, to make sure that the implementation indeed adhere to the contracts.

  • An 'uncertain number' interface, plus an implemention of an algebraic field of uncertain numbers.

  • A Service Provider Interface for formatting the elements of abstract algebras. This core module only provides an implementation to format uncertain numbers, using proper rounding and scientific notation.

1.1. Abstract Algebras

The idea is that every 'abstract algebra' consists of the implementation of two interfaces.

The terminology which is adopted is this:

Algebraic operation operator operator name static operator name result name argument name defined in

addition

+

plus

add

sum

summand

AdditiveSemiGroupElement

subtraction

-

minus

subtract

difference

subtrahend

AdditiveGroupElement

multiplication

times

multiply

product

multiplier

MultiplicativeSemiGroupElement

division

/

dividedBy

divide

quotient

divisor

MultiplicativeGroupElement

negation

-

negation

negate

negation

AdditiveGroupElement

reciprocation

1/

reciprocal

reciprocal

MultiplicativeGroupElement

exponentiation

^

pow

pow

power

exponent

CompleteFieldElement

square root

sqrt

radicand

square root

CompleteFieldElement

sine

sin()

sin

sin

sine

angle

CompleteFieldElement

cosine

cos()

cos

cos

cosine

angle

CompleteFieldElement

metric or distance

d()

distanceTo

metric

distance

MetricSpaceElement

absolute value, distance to zero

||

abs

abs

absolute value

MetricSpaceElement

The methods on the elements take the name of the corresponding operator. So e.g.:

RationalNumber a, b, c;
c = a.times(b);

These methods always take the value of the element itself plus zero parameters (for the unary operators) or one parameter (for the binary operators), and create a new value from the same algebra.

Alternative terminology, like e.g. 'add' for addition would have been possible, but it was chosen to use those verbs when the operation is e.g. implemented statically (void add(e1, e2)) or are modifying the element itself.

Most implementations are strictly read-only, but at least all algebraic operations themselves should be without side effects on the algebraic element itself.

1.1.1. Algebraic structure

Every algebraic element object has a reference to (the same) instance of this structure. The structure itself defines e.g. the 'cardinality'.

Note
If the cardinality is 'countable' (< ℵ1), the structure can also implement Streamable to actually produce all possible elements.

The algebraic structure also contains methods to obtain 'special elements' like the identity elements for multiplication and addition ('one' and 'zero').

1.1.2. Numbers

Some algebraic elements are like 'real' numbers. There are several interfaces dedicated to formalising properties of that.

class/interface description

Scalar

generic interface that defines method to convert to java (primitive) number objects. Like doubleValue() and intValue(). It extends a few interfaces for some properties which can be applied to other structures to, like Sizeable and SignedNumber.

ScalarFieldElement

A Scalar that is also a FieldElement. So this is the link from number to algebra. Well-behaved field elements that also behave as a 'Number' may implement ScalarFieldElement

CompleteFieldElement

Even more similar to the everyday concept of number an algebraic field element are 'complete' field elements. This in some way means 'no gaps', but essentially boils down to the fact that operations like taking square roots and trigonometric function are possible.

NumberOperations

1.1.3. Numbers and propagation of uncertainties

Most real numbers cannot be represented exactly. It may be of interest to keep track of the uncertainty in the value, and try to propagate those uncertainties sensibly when performing operations on them.

The 'physics' module will adds to this that these kinds of uncertainties may originate not only in the finite nature of representing them, but also in the limitations of actually measuring things.

The 'statistics' module introduces uncertain numbers where the uncertainty defined as the standard deviation in a collected set of values. These numbers are examples where the numbers are actually stateful, because new values can be added to the set. This should not actually change the value represented by the object though, only decrease its uncertainty. On performing operations on these kinds of objects you would receive unmodifiable stateless objects with frozen value and uncertainty.

It is not always an absolutely defined how propagations must happen. Some interpretation may be needed sometimes. The choices made are currently collected in `UncertaintyNumberOperations'. This is not currently pluggable or configurable, but it may well be.

operation formula current uncertainty propagation algorithm

summation

\(a ± Δa + b ± Δb\)

\(\sqrt{Δa^2 + Δb^2}\)

multiplication

\(a ± Δa \cdot b ± Δb\)

..

exponentiation

sin/cos

\(\sin(\alpha \pm \Delta\alpha)\)

\(\Delta\alpha\)

Zero

Sometimes the value with uncertainty is exactly zero, so fractional uncertainty leads to division by zero exceptions. Therefore, for now fractional uncertainty is implemented like \( \frac{Δa}{|a| + Δa}\) (rather then \( \frac{Δa}{|a|}\)), where the denominator can never become zero because the uncertainty is strictly bigger than zero.

1.1.4. Testing

In mihxil-math-theories for every algebraic structure interface there are 'theory' interfaces using jqwik. Tests for actual implementation implement these interfaces and provide the code to supply a bunch of example link: {gmt}abstractalgebra/test/ElementTheory.java#L20[elements].

Default methods then test wheter all theoretical possibilities and limitation of the algebraic structure are indeed working.

1.1.5. Implementation of equals/hashcode

When a value has uncertainty then 'equals' also considers it. So objects may e.g. have different toString representation but still be equal, because the difference is considered smaller than te uncertainty, and so the values are at 'probably' equals.

In this case the hashCode must be a fixed value, because otherwise we can’t garantuee that equal values have equal hashCode.

So it’s a bad idea to use uncertain values as hash keys.

1.2. Formatting

A service loader is provided for implementations of AlgebraicElementFormatProvider which can create instances of java.text.Format which in turn can be used to convert algebraic elements to a string. #toString can be based on it.

The formatters have access to a (thread local) configuration object. Like this a consistent way is available to configure how e.g. uncertainties must be represented. Currently, this configuration object can only be filled by code. The base configuration object in itself is empty, but the available `AlgebraicElementFormatProvider`s communicate the 'configuration aspects' which it can use.

The service giving access to the format-providers is FormatService. Which is collection of static functions. It is also responsible for managing the Configuration thread locals.

Like this it can be consulted

Accessing configuration
import static org.meeuw.configuration.Configuration;
import static org.meeuw.math.text.spi.FormatService.*;

 Configuration configuration = FormatService.getConfiguration();
 NumberConfiguration aspect = configuration.getAspect(NumberConfiguration.class);
 int minimalExponent = aspect.getMinimalExponent();

This would however probably mainly be used in implementations.

Actual configuration can be done in two basicly distinct ways.

  • a new configuration object can be set as a thread local

  • global default configuration object can be set

temporary overrides
Configuration configuration = FormatService.getConfiguration();
FormatService.setConfiguration(configuration.toBuilder().aspect(NumberConfiguration.class, (nc) -> nc.withMinimalExponent(8)).build());

... code ...

FormatService.resetToDefaults();

There are some utilities in FormatService that makes this process a bit easier.

temporary overrides utilities
 FormatService.with((configurationBuilder) -> configurationBuilder
   .aspect(TestConfigurationAspect.class, (tc) -> tc.withSomeInt(5))
   .aspect(NumberConfiguration.class, (tc) -> tc.withMinimalExponent(3))
   , () -> {
 ... code ...
 });
----

Gloabel defaults can be set similarly

setting global defaults
 FormatService.defaultConfiguration((con) ->
  con.aspect(NumberConfiguration.class, c -> c.withMinimalExponent(4))
     .aspect(TestConfigurationAspect.class, c -> c.withSomeInt(-1))
 );

2. mihxil-statistics

Maven Central javadoc

Implementations of UncertainDouble, based on calculating standard deviations on sets of incoming data, and using that as the uncertainty value.

Also, it includes some classes to keep track of 'sliding window' values of averages.

3. mihxil-physics

Maven Central javadoc

This module involves mostly around PhysicalNumber and its derivatives. A PhysicalNumber is a UncertainDouble, but the uncertainty is stated (it is a Measurement), and knows how to propagate those uncertainties when doing algebraic operations.

Also, a PhysicalNumber can be assigned Units. This can be used for proper displaying the value, and for dimensional analysis.

PhysicalNumber twoLightyears = new Measurement(2, 0.1, SI.ly);
PhysicalNumber oneParsec = new Measurement(1, 0.1, SI.pc);
log.info("{} + {} = {}", twoLightyears, oneParsec, twoLightyears.plus(oneParsec));
assertThat(twoLightyears.plus(oneParsec).toString()).isEqualTo("5.3 ± 0.3 ly");
assertThat(oneParsec.plus(twoLightyears).toString()).isEqualTo("1.61 ± 0.10 pc");
assertThat(oneParsec.plus(twoLightyears)).isEqualTo(twoLightyears.plus(oneParsec)); //different toString does not mean that they represent a different value.

Physical numbers themselves are actually only forming a multiplicative group, because they cannot be added without constraints. In this example they can only be added to each other because both values have the same dimensions (both are about distance).

Physical numbers can freely multiplied and divided by each other.

4. mihxil-algebra

Maven Central javadoc

This contains various implementations of the algebraic structure interfaces of mihxil-math. Like RationalNumber (modelling of rational numbers ℚ), and the rotation group SO(3).

4.1. Features

4.1.1. Real numbers

The field of real numbers. Backed by java primitive double. A RealNumber is also 'uncertain', which is used to keep track of rounding errors.

4.1.2. Arbitrary precision real numbers

The field of reals numbers, but backed by java’s BigDecimal. This means that it supports arbitrary precision, but, since this still is not exact this still is uncertain, and rounding errors are propagated.

4.1.3. Rational numbers

The field of rational numbers. Implemented using two arbitrary sized BigIntegers.

Also, since division is exact in this field, this does not implement UncertainNumber.

The cardinality is countable (ℵ0) so this does implement Streamable.

4.1.4. Permutations

The permutation group. An example of a non-abelian finite group.

This is group is finite, so streamable. This means that the group also contains an implementation of 'all permutations' (this is non-trivial, it’s using Knuth’s algorithm).

The permutation elements themselves are implemented as a java.util.function.UnaryOperator on Object[] which then performs the actual permutation.

4.1.5. Integers

The most basic algebraic structure which can be created from integers are the integers (ℤ) themselves. They form a ring:

4.1.6. Even integers

As an example of a 'rng' (a ring without the existence of the multiplicative identity 1), the even integers can serve

4.1.7. Natural numbers

In the natural numbers ℕ (the non-negative integers), there can be no subtraction. So they only form a 'monoid' (both additive and multiplicative).

4.1.8. Modulo groups

Integers can be simply restricted via modulo arithmetic to form a finite ring:

If the 'divisor' is a prime, then they even form a field, because the reciprocal can be defined:

4.1.9. Complex numbers

Another well-known field is the field of complex numbers.

4.1.10. Quaternions

Quaternions are forming a 'non-commutative' field, a DivisionRing

4.1.11. Matrix and rotation groups

SO(3)

Another non-abelian (not-commutative) multiplicative group.

4.1.12. Strings

Actually one of the simplest algebraic object you can think of are the strings. They form an additive monoid, an algebraic structure with only one operation (addition).

Their cardinality is only ℵ0, so StringMonoid also contains an implementation to stream all possible strings.

4.1.13. Vector spaces

Versions

Version
0.4.0