org.tensorics.core.iterable.operations.IterableVar Maven / Gradle / Ivy
Show all versions of tensorics-core Show documentation
/**
* Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
*/
package org.tensorics.core.iterable.operations;
import static com.google.common.collect.Iterables.isEmpty;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.tensorics.core.math.ExtendedField;
import org.tensorics.core.scalar.lang.ScalarSupport;
/**
* An operation that takes and iterable of a certain type of values (for which a field has to be provided) and
* calculates the variance out of it.
*
* For the definition of the variance, have a look at wikipedia.
*
* @author caguiler
* @param the type of the scalars (elements of the field on which the variance will be based)
*/
public class IterableVar extends ScalarSupport implements IterableOperation {
private final IterableAverage iterableAverage;
private final ExtendedField field;
public IterableVar(ExtendedField field) {
super(field);
this.field = field;
this.iterableAverage = new IterableAverage<>(field);
}
@Override
public V apply(Iterable values) {
if (isEmpty(values)) {
throw new IllegalArgumentException("variance of empty value set is not possible.");
}
final V average = iterableAverage.apply(values);
// @formatter:off
Iterable squaredDifferences = StreamSupport.stream(values.spliterator(), false)
.map(v -> calculate(v).minus(average))
.map(difference -> calculate(difference).toThePowerOf(field.two()))
.collect(Collectors.toList());
// @formatter:on
return iterableAverage.apply(squaredDifferences);
}
}