org.tensorics.core.quantity.options.JScienceQuantificationStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tensorics-core Show documentation
Show all versions of tensorics-core Show documentation
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.
// @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)));
}
}