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

org.tensorics.core.quantity.options.JScienceQuantificationStrategy Maven / Gradle / Ivy

Go to download

Tensorics is a java framework which uses a tensor as a central object. A tensor represents a set of values placed in an N-dimensional space. Wherever you are tempted to use maps of maps, a tensor might be a good choice ;-) Tensorics provides methods to create, transform and performing calculations with those tensors.

There is a newer version: 0.0.81
Show newest version
// @formatter:off
 /*******************************************************************************
 *
 * This file is part of tensorics.
 * 
 * Copyright (c) 2008-2011, CERN. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 ******************************************************************************/
// @formatter:on

package org.tensorics.core.quantity.options;

import javax.measure.converter.UnitConverter;

import org.tensorics.core.math.Cheating;
import org.tensorics.core.quantity.ErronousValue;
import org.tensorics.core.quantity.ImmutableErronousValue;
import org.tensorics.core.quantity.Quantified;
import org.tensorics.core.units.JScienceUnit;
import org.tensorics.core.units.Unit;

/**
 * Encapsulates all the calculations and transformations of units that are based on the jscience unit system. Currently,
 * this is the only implemented way of dealing with units in tensorics. However, later on it is planned that all the
 * unit calculations could be based on the field structure, so that this class would get obsolete.
 * 
 * @author kfuchsbe
 * @param  the type of the field elements, on which the calculations are based on
 */
public class JScienceQuantificationStrategy implements QuantificationStrategy {

    private static final Unit UNIT_ONE = JScienceUnit.of(javax.measure.unit.Unit.ONE);

    private final Cheating cheating;

    public JScienceQuantificationStrategy(Cheating cheating) {
        super();
        this.cheating = cheating;
    }

    @Override
    public  & Quantified> OperandPair asSameUnit(S left, S right) {
        if (left.unit().equals(right.unit())) {
            return OperandPair.ofLeftRightUnit(left, right, left.unit());
        } else {
            final Unit standardUnitOfLeft = standardUnitOf(left);
            final Unit standardUnitOfRight = standardUnitOf(right);
            if (!standardUnitOfLeft.equals(standardUnitOfRight)) {
                throw new IllegalArgumentException("Units '" + standardUnitOfLeft + "' and '" + standardUnitOfRight
                        + "' are not consistent or convertible");
            }
            return OperandPair.ofLeftRightUnit(toStandardUnit(left), toStandardUnit(right), standardUnitOfLeft);
        }
    }

    private  Unit standardUnitOf(S scalar) {
        Unit unit = scalar.unit();
        throwIfNotJScience(unit);
        return JScienceUnit.of(((JScienceUnit) unit).getUnit().getStandardUnit());
    }

    private  & Quantified> ErronousValue toStandardUnit(S scalar) {
        Unit unit = scalar.unit();
        throwIfNotJScience(unit);
        UnitConverter converter = extract(unit).toStandardUnit();
        return convert(converter, scalar);
    }

    private  & Quantified> ImmutableErronousValue convert(UnitConverter converter,
            S scalar) {
        T value = convert(converter, scalar.value());
        if (scalar.error().isPresent()) {
            return ImmutableErronousValue.ofValueAndError(value, convert(converter, scalar.error().get()));
        }
        return ImmutableErronousValue.ofValue(value);
    }

    private T convert(UnitConverter converter, T value) {
        return cheating.fromDouble(converter.convert(cheating.toDouble(value)));
    }

    @Override
    public Unit multiply(Unit left, Unit right) {
        throwIfNotJScience(left, right);
        return JScienceUnit.of(extract(left).times(extract(right)));
    }

    @Override
    public Unit divide(Unit left, Unit right) {
        throwIfNotJScience(left, right);
        return JScienceUnit.of(extract(left).divide(extract(right)));
    }

    @Override
    public  & Quantified> ErronousValue convertValueToUnit(V value, Unit targetUnit) {
        throwIfNotJScience(value.unit(), targetUnit);
        UnitConverter converter = extract(value.unit()).getConverterTo(extract(targetUnit));
        return convert(converter, value);
    }

    private javax.measure.unit.Unit extract(Unit unit) {
        return ((JScienceUnit) unit).getUnit();
    }

    private void throwIfNotJScience(Unit... units) {
        for (Unit unit : units) {
            if (!(unit instanceof JScienceUnit)) {
                throw new UnsupportedOperationException("Not yet implemented.");
            }
        }
    }

    @Override
    public Unit one() {
        return UNIT_ONE;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public Class getMarkerInterface() {
        return QuantificationStrategy.class;
    }

    @Override
    public Unit root(Unit left, T right) {
        throwIfNotJScience(left);
        return JScienceUnit.of(extract(left).root((int) cheating.toDouble(right)));
    }

    @Override
    public Unit power(Unit left, T rigth) {
        throwIfNotJScience(left);
        return JScienceUnit.of(extract(left).pow((int) cheating.toDouble(rigth)));
    }

}