All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.qudtlib.model.FactorUnits Maven / Gradle / Ivy

There is a newer version: 6.7.0
Show newest version
package io.github.qudtlib.model;

import static java.util.stream.Collectors.toList;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class FactorUnits {
    private final List factorUnits;
    private final BigDecimal scaleFactor;

    public FactorUnits(List factorUnits, BigDecimal scaleFactor) {
        this.factorUnits = factorUnits.stream().collect(Collectors.toUnmodifiableList());
        this.scaleFactor = scaleFactor;
    }

    public FactorUnits(List factorUnits) {
        this(factorUnits, new BigDecimal("1"));
    }

    public static FactorUnits ofUnit(Unit unit) {
        return new FactorUnits(
                List.of(FactorUnit.builder().unit(Unit.definition(unit)).exponent(1).build()));
    }

    /**
     * Accepts up to 7 pairs of <Unit, Integer> which are interpreted as factor units and
     * respective exponents.
     *
     * @param factorUnitSpec array of up to 7 %lt;Unit, Integer%gt; pairs
     * @return true if the specified unit/exponent combination identifies this unit.
     *     (overspecification is counted as a match)
     */
    public static FactorUnits ofFactorUnitSpec(Object... factorUnitSpec) {
        if (factorUnitSpec.length % 2 != 0) {
            throw new IllegalArgumentException("An even number of arguments is required");
        }
        if (factorUnitSpec.length > 14) {
            throw new IllegalArgumentException(
                    "No more than 14 arguments (7 factor units) supported");
        }
        List factorUnits = new ArrayList<>();
        for (int i = 0; i < factorUnitSpec.length; i += 2) {
            Unit requestedUnit;
            requestedUnit = ((Unit) factorUnitSpec[i]);
            Integer requestedExponent = (Integer) factorUnitSpec[i + 1];
            factorUnits.add(
                    FactorUnit.builder()
                            .unit(Unit.definition(requestedUnit))
                            .exponent(requestedExponent)
                            .build());
        }
        return new FactorUnits(factorUnits);
    }

    public static FactorUnits ofFactorUnitSpec(
            Collection> factorUnitSpec) {
        Object[] arr = new Object[factorUnitSpec.size() * 2];
        return FactorUnits.ofFactorUnitSpec(
                factorUnitSpec.stream()
                        .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
                        .collect(toList())
                        .toArray(arr));
    }

    public List getFactorUnits() {
        return factorUnits;
    }

    public BigDecimal getScaleFactor() {
        return scaleFactor;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FactorUnits that = (FactorUnits) o;

        return scaleFactor.compareTo(that.scaleFactor) == 0
                && new HashSet<>(factorUnits).equals(new HashSet<>(that.factorUnits));
    }

    @Override
    public int hashCode() {
        return Objects.hash(factorUnits, scaleFactor);
    }

    @Override
    public String toString() {
        return (this.scaleFactor.compareTo(BigDecimal.ONE) == 0
                        ? ""
                        : this.scaleFactor.toString() + "*")
                + factorUnits;
    }

    public FactorUnits pow(int exponent) {
        return new FactorUnits(
                this.factorUnits.stream().map(fu -> fu.pow(exponent)).collect(toList()),
                this.scaleFactor.pow(exponent, MathContext.DECIMAL128));
    }

    public FactorUnits combineWith(FactorUnits other) {
        if (other == null) {
            return this;
        }
        return new FactorUnits(
                FactorUnit.contractExponents(
                        Stream.concat(this.factorUnits.stream(), other.factorUnits.stream())
                                .collect(Collectors.toList())),
                this.scaleFactor.multiply(other.scaleFactor, MathContext.DECIMAL128));
    }

    public boolean isRatioOfSameUnits() {
        return this.factorUnits.size() == 2
                && this.factorUnits.get(0).getUnit().equals(this.factorUnits.get(1).getUnit())
                && this.factorUnits.get(0).getExponent() == this.factorUnits.get(1).getExponent();
    }

    public FactorUnits reduceExponents() {
        return new FactorUnits(FactorUnit.reduceExponents(this.factorUnits), this.scaleFactor);
    }

    public FactorUnits scale(BigDecimal by) {
        return new FactorUnits(this.factorUnits, this.scaleFactor.multiply(by));
    }

    public FactorUnits normalize() {
        FactorUnits normalized = FactorUnit.normalizeFactorUnits(this.factorUnits);
        return new FactorUnits(
                normalized.getFactorUnits(),
                normalized.getScaleFactor().multiply(this.scaleFactor));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy