From 2ff6c4ea25beeab58239ddf576fb89254ba98630 Mon Sep 17 00:00:00 2001 From: Adrien Hopkins Date: Wed, 16 Oct 2019 17:17:41 -0400 Subject: Added an 'SI' class with all units, dimensions and prefixes in SI. --- src/org/unitConverter/math/StandardDimensions.java | 86 -------- src/org/unitConverter/newUnits/BaseDimension.java | 81 ++++++++ src/org/unitConverter/newUnits/SI.java | 228 +++++++++++++++++++++ 3 files changed, 309 insertions(+), 86 deletions(-) delete mode 100644 src/org/unitConverter/math/StandardDimensions.java create mode 100644 src/org/unitConverter/newUnits/BaseDimension.java create mode 100644 src/org/unitConverter/newUnits/SI.java (limited to 'src') diff --git a/src/org/unitConverter/math/StandardDimensions.java b/src/org/unitConverter/math/StandardDimensions.java deleted file mode 100644 index db5efc3..0000000 --- a/src/org/unitConverter/math/StandardDimensions.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (C) 2018 Adrien Hopkins - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.unitConverter.math; - -import org.unitConverter.dimension.BaseDimension; -import org.unitConverter.dimension.OtherBaseDimension; -import org.unitConverter.dimension.SIBaseDimension; - -/** - * All of the dimensions that are used by the SI. (Test data for the ObjectProductTest) - * - * @author Adrien Hopkins - * @since 2018-12-11 - * @since v0.1.0 - */ -final class StandardDimensions { - // base dimensions - public static final ObjectProduct EMPTY = ObjectProduct.empty(); - public static final ObjectProduct LENGTH = ObjectProduct.oneOf(SIBaseDimension.LENGTH); - public static final ObjectProduct MASS = ObjectProduct.oneOf(SIBaseDimension.MASS); - public static final ObjectProduct TIME = ObjectProduct.oneOf(SIBaseDimension.TIME); - public static final ObjectProduct ELECTRIC_CURRENT = ObjectProduct - .oneOf(SIBaseDimension.ELECTRIC_CURRENT); - public static final ObjectProduct TEMPERATURE = ObjectProduct.oneOf(SIBaseDimension.TEMPERATURE); - public static final ObjectProduct QUANTITY = ObjectProduct.oneOf(SIBaseDimension.QUANTITY); - public static final ObjectProduct LUMINOUS_INTENSITY = ObjectProduct - .oneOf(SIBaseDimension.LUMINOUS_INTENSITY); - public static final ObjectProduct INFORMATION = ObjectProduct.oneOf(OtherBaseDimension.INFORMATION); - public static final ObjectProduct CURRENCY = ObjectProduct.oneOf(OtherBaseDimension.CURRENCY); - // derived dimensions without named SI units - public static final ObjectProduct AREA = LENGTH.times(LENGTH); - - public static final ObjectProduct VOLUME = AREA.times(LENGTH); - public static final ObjectProduct VELOCITY = LENGTH.dividedBy(TIME); - public static final ObjectProduct ACCELERATION = VELOCITY.dividedBy(TIME); - public static final ObjectProduct WAVENUMBER = EMPTY.dividedBy(LENGTH); - public static final ObjectProduct MASS_DENSITY = MASS.dividedBy(VOLUME); - public static final ObjectProduct SURFACE_DENSITY = MASS.dividedBy(AREA); - public static final ObjectProduct SPECIFIC_VOLUME = VOLUME.dividedBy(MASS); - public static final ObjectProduct CURRENT_DENSITY = ELECTRIC_CURRENT.dividedBy(AREA); - public static final ObjectProduct MAGNETIC_FIELD_STRENGTH = ELECTRIC_CURRENT.dividedBy(LENGTH); - public static final ObjectProduct CONCENTRATION = QUANTITY.dividedBy(VOLUME); - public static final ObjectProduct MASS_CONCENTRATION = CONCENTRATION.times(MASS); - public static final ObjectProduct LUMINANCE = LUMINOUS_INTENSITY.dividedBy(AREA); - public static final ObjectProduct REFRACTIVE_INDEX = VELOCITY.dividedBy(VELOCITY); - public static final ObjectProduct REFLACTIVE_PERMEABILITY = EMPTY.times(EMPTY); - public static final ObjectProduct ANGLE = LENGTH.dividedBy(LENGTH); - public static final ObjectProduct SOLID_ANGLE = AREA.dividedBy(AREA); - // derived dimensions with named SI units - public static final ObjectProduct FREQUENCY = EMPTY.dividedBy(TIME); - - public static final ObjectProduct FORCE = MASS.times(ACCELERATION); - public static final ObjectProduct ENERGY = FORCE.times(LENGTH); - public static final ObjectProduct POWER = ENERGY.dividedBy(TIME); - public static final ObjectProduct ELECTRIC_CHARGE = ELECTRIC_CURRENT.times(TIME); - public static final ObjectProduct VOLTAGE = ENERGY.dividedBy(ELECTRIC_CHARGE); - public static final ObjectProduct CAPACITANCE = ELECTRIC_CHARGE.dividedBy(VOLTAGE); - public static final ObjectProduct ELECTRIC_RESISTANCE = VOLTAGE.dividedBy(ELECTRIC_CURRENT); - public static final ObjectProduct ELECTRIC_CONDUCTANCE = ELECTRIC_CURRENT.dividedBy(VOLTAGE); - public static final ObjectProduct MAGNETIC_FLUX = VOLTAGE.times(TIME); - public static final ObjectProduct MAGNETIC_FLUX_DENSITY = MAGNETIC_FLUX.dividedBy(AREA); - public static final ObjectProduct INDUCTANCE = MAGNETIC_FLUX.dividedBy(ELECTRIC_CURRENT); - public static final ObjectProduct LUMINOUS_FLUX = LUMINOUS_INTENSITY.times(SOLID_ANGLE); - public static final ObjectProduct ILLUMINANCE = LUMINOUS_FLUX.dividedBy(AREA); - public static final ObjectProduct SPECIFIC_ENERGY = ENERGY.dividedBy(MASS); - public static final ObjectProduct CATALYTIC_ACTIVITY = QUANTITY.dividedBy(TIME); - - // You may NOT get StandardDimensions instances! - private StandardDimensions() { - throw new AssertionError(); - } -} diff --git a/src/org/unitConverter/newUnits/BaseDimension.java b/src/org/unitConverter/newUnits/BaseDimension.java new file mode 100644 index 0000000..a1cde46 --- /dev/null +++ b/src/org/unitConverter/newUnits/BaseDimension.java @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2019 Adrien Hopkins + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.unitConverter.newUnits; + +import java.util.Objects; + +/** + * A dimension that defines a {@code BaseUnit} + * + * @author Adrien Hopkins + * @since 2019-10-16 + */ +public final class BaseDimension { + /** + * Gets a {@code BaseDimension} with the provided name and symbol. + * + * @param name + * name of dimension + * @param symbol + * symbol used for dimension + * @return dimension + * @since 2019-10-16 + */ + public static BaseDimension valueOf(final String name, final String symbol) { + return new BaseDimension(name, symbol); + } + + private final String name; + private final String symbol; + + /** + * Creates the {@code BaseDimension}. + * + * @param name + * name of unit + * @param symbol + * symbol of unit + * @throws NullPointerException + * if any argument is null + * @since 2019-10-16 + */ + private BaseDimension(final String name, final String symbol) { + this.name = Objects.requireNonNull(name, "name must not be null."); + this.symbol = Objects.requireNonNull(symbol, "symbol must not be null."); + } + + /** + * @return name + * @since 2019-10-16 + */ + public final String getName() { + return this.name; + } + + /** + * @return symbol + * @since 2019-10-16 + */ + public final String getSymbol() { + return this.symbol; + } + + @Override + public String toString() { + return String.format("%s (%s)", this.getName(), this.getSymbol()); + } +} diff --git a/src/org/unitConverter/newUnits/SI.java b/src/org/unitConverter/newUnits/SI.java new file mode 100644 index 0000000..b7a117a --- /dev/null +++ b/src/org/unitConverter/newUnits/SI.java @@ -0,0 +1,228 @@ +/** + * Copyright (C) 2018 Adrien Hopkins + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.unitConverter.newUnits; + +import org.unitConverter.math.ObjectProduct; + +/** + * All of the units, prefixes and dimensions that are used by the SI, as well as some outside the SI. + * + *

+ * This class does not include prefixed units. To obtain prefixed units, use {@link LinearUnit#withPrefix}: + * + *

+ * LinearUnit KILOMETRE = SI.METRE.withPrefix(SI.KILO);
+ * 
+ * + * + * @author Adrien Hopkins + * @since 2019-10-16 + */ +public final class SI { + /// dimensions used by SI units + // base dimensions, as BaseDimensions + public static final class BaseDimensions { + public static final BaseDimension LENGTH = BaseDimension.valueOf("Length", "L"); + public static final BaseDimension MASS = BaseDimension.valueOf("Mass", "M"); + public static final BaseDimension TIME = BaseDimension.valueOf("Time", "T"); + public static final BaseDimension ELECTRIC_CURRENT = BaseDimension.valueOf("Electric Current", "I"); + public static final BaseDimension TEMPERATURE = BaseDimension.valueOf("Temperature", "\u0398"); // theta symbol + public static final BaseDimension QUANTITY = BaseDimension.valueOf("Quantity", "N"); + public static final BaseDimension LUMINOUS_INTENSITY = BaseDimension.valueOf("Luminous Intensity", "J"); + public static final BaseDimension INFORMATION = BaseDimension.valueOf("Information", "Info"); // non-SI + public static final BaseDimension CURRENCY = BaseDimension.valueOf("Currency", "$$"); // non-SI + + // You may NOT get SI.BaseDimensions instances! + private BaseDimensions() { + throw new AssertionError(); + } + } + + /// base units of the SI + // suppressing warnings since these are the same object, but in a different form (class) + @SuppressWarnings("hiding") + public static final class BaseUnits { + public static final BaseUnit METRE = BaseUnit.valueOf(BaseDimensions.LENGTH, "metre", "m"); + public static final BaseUnit KILOGRAM = BaseUnit.valueOf(BaseDimensions.MASS, "kilogram", "kg"); + public static final BaseUnit SECOND = BaseUnit.valueOf(BaseDimensions.TIME, "second", "s"); + public static final BaseUnit AMPERE = BaseUnit.valueOf(BaseDimensions.ELECTRIC_CURRENT, "ampere", "A"); + public static final BaseUnit KELVIN = BaseUnit.valueOf(BaseDimensions.TEMPERATURE, "kelvin", "K"); + public static final BaseUnit MOLE = BaseUnit.valueOf(BaseDimensions.QUANTITY, "mole", "mol"); + public static final BaseUnit CANDELA = BaseUnit.valueOf(BaseDimensions.LUMINOUS_INTENSITY, "candela", "cd"); + public static final BaseUnit BIT = BaseUnit.valueOf(BaseDimensions.INFORMATION, "bit", "b"); + public static final BaseUnit DOLLAR = BaseUnit.valueOf(BaseDimensions.CURRENCY, "dollar", "$"); + + // You may NOT get SI.BaseUnits instances! + private BaseUnits() { + throw new AssertionError(); + } + } + + // dimensions used in the SI, as ObjectProducts + public static final class Dimensions { + public static final ObjectProduct EMPTY = ObjectProduct.empty(); + public static final ObjectProduct LENGTH = ObjectProduct.oneOf(BaseDimensions.LENGTH); + public static final ObjectProduct MASS = ObjectProduct.oneOf(BaseDimensions.MASS); + public static final ObjectProduct TIME = ObjectProduct.oneOf(BaseDimensions.TIME); + public static final ObjectProduct ELECTRIC_CURRENT = ObjectProduct + .oneOf(BaseDimensions.ELECTRIC_CURRENT); + public static final ObjectProduct TEMPERATURE = ObjectProduct.oneOf(BaseDimensions.TEMPERATURE); + public static final ObjectProduct QUANTITY = ObjectProduct.oneOf(BaseDimensions.QUANTITY); + public static final ObjectProduct LUMINOUS_INTENSITY = ObjectProduct + .oneOf(BaseDimensions.LUMINOUS_INTENSITY); + public static final ObjectProduct INFORMATION = ObjectProduct.oneOf(BaseDimensions.INFORMATION); + public static final ObjectProduct CURRENCY = ObjectProduct.oneOf(BaseDimensions.CURRENCY); + // derived dimensions without named SI units + public static final ObjectProduct AREA = LENGTH.times(LENGTH); + + public static final ObjectProduct VOLUME = AREA.times(LENGTH); + public static final ObjectProduct VELOCITY = LENGTH.dividedBy(TIME); + public static final ObjectProduct ACCELERATION = VELOCITY.dividedBy(TIME); + public static final ObjectProduct WAVENUMBER = EMPTY.dividedBy(LENGTH); + public static final ObjectProduct MASS_DENSITY = MASS.dividedBy(VOLUME); + public static final ObjectProduct SURFACE_DENSITY = MASS.dividedBy(AREA); + public static final ObjectProduct SPECIFIC_VOLUME = VOLUME.dividedBy(MASS); + public static final ObjectProduct CURRENT_DENSITY = ELECTRIC_CURRENT.dividedBy(AREA); + public static final ObjectProduct MAGNETIC_FIELD_STRENGTH = ELECTRIC_CURRENT.dividedBy(LENGTH); + public static final ObjectProduct CONCENTRATION = QUANTITY.dividedBy(VOLUME); + public static final ObjectProduct MASS_CONCENTRATION = CONCENTRATION.times(MASS); + public static final ObjectProduct LUMINANCE = LUMINOUS_INTENSITY.dividedBy(AREA); + public static final ObjectProduct REFRACTIVE_INDEX = VELOCITY.dividedBy(VELOCITY); + public static final ObjectProduct REFLACTIVE_PERMEABILITY = EMPTY.times(EMPTY); + public static final ObjectProduct ANGLE = LENGTH.dividedBy(LENGTH); + public static final ObjectProduct SOLID_ANGLE = AREA.dividedBy(AREA); + // derived dimensions with named SI units + public static final ObjectProduct FREQUENCY = EMPTY.dividedBy(TIME); + + public static final ObjectProduct FORCE = MASS.times(ACCELERATION); + public static final ObjectProduct ENERGY = FORCE.times(LENGTH); + public static final ObjectProduct POWER = ENERGY.dividedBy(TIME); + public static final ObjectProduct ELECTRIC_CHARGE = ELECTRIC_CURRENT.times(TIME); + public static final ObjectProduct VOLTAGE = ENERGY.dividedBy(ELECTRIC_CHARGE); + public static final ObjectProduct CAPACITANCE = ELECTRIC_CHARGE.dividedBy(VOLTAGE); + public static final ObjectProduct ELECTRIC_RESISTANCE = VOLTAGE.dividedBy(ELECTRIC_CURRENT); + public static final ObjectProduct ELECTRIC_CONDUCTANCE = ELECTRIC_CURRENT.dividedBy(VOLTAGE); + public static final ObjectProduct MAGNETIC_FLUX = VOLTAGE.times(TIME); + public static final ObjectProduct MAGNETIC_FLUX_DENSITY = MAGNETIC_FLUX.dividedBy(AREA); + public static final ObjectProduct INDUCTANCE = MAGNETIC_FLUX.dividedBy(ELECTRIC_CURRENT); + public static final ObjectProduct LUMINOUS_FLUX = LUMINOUS_INTENSITY.times(SOLID_ANGLE); + public static final ObjectProduct ILLUMINANCE = LUMINOUS_FLUX.dividedBy(AREA); + public static final ObjectProduct SPECIFIC_ENERGY = ENERGY.dividedBy(MASS); + public static final ObjectProduct CATALYTIC_ACTIVITY = QUANTITY.dividedBy(TIME); + + // You may NOT get SI.Dimension instances! + private Dimensions() { + throw new AssertionError(); + } + } + + /// The units of the SI + public static final LinearUnit ONE = LinearUnit.valueOf(ObjectProduct.empty(), 1); + public static final LinearUnit METRE = BaseUnits.METRE.asLinearUnit(); + public static final LinearUnit KILOGRAM = BaseUnits.KILOGRAM.asLinearUnit(); + public static final LinearUnit SECOND = BaseUnits.SECOND.asLinearUnit(); + public static final LinearUnit AMPERE = BaseUnits.AMPERE.asLinearUnit(); + public static final LinearUnit KELVIN = BaseUnits.KELVIN.asLinearUnit(); + public static final LinearUnit MOLE = BaseUnits.MOLE.asLinearUnit(); + public static final LinearUnit CANDELA = BaseUnits.CANDELA.asLinearUnit(); + public static final LinearUnit BIT = BaseUnits.BIT.asLinearUnit(); + public static final LinearUnit DOLLAR = BaseUnits.DOLLAR.asLinearUnit(); + + // Non-base units + public static final LinearUnit RADIAN = METRE.dividedBy(METRE); + public static final LinearUnit STERADIAN = RADIAN.times(RADIAN); + public static final LinearUnit HERTZ = ONE.dividedBy(SECOND); // for periodic phenomena + public static final LinearUnit NEWTON = KILOGRAM.times(METRE).dividedBy(SECOND.times(SECOND)); + public static final LinearUnit PASCAL = NEWTON.dividedBy(METRE.times(METRE)); + public static final LinearUnit JOULE = NEWTON.times(METRE); + public static final LinearUnit WATT = JOULE.dividedBy(SECOND); + public static final LinearUnit COULOMB = AMPERE.times(SECOND); + public static final LinearUnit VOLT = JOULE.dividedBy(COULOMB); + public static final LinearUnit FARAD = COULOMB.dividedBy(VOLT); + public static final LinearUnit OHM = VOLT.dividedBy(AMPERE); + public static final LinearUnit SIEMENS = ONE.dividedBy(OHM); + public static final LinearUnit WEBER = VOLT.times(SECOND); + public static final LinearUnit TESLA = WEBER.dividedBy(METRE.times(METRE)); + public static final LinearUnit HENRY = WEBER.dividedBy(AMPERE); + public static final LinearUnit LUMEN = CANDELA.times(STERADIAN); + public static final LinearUnit LUX = LUMEN.dividedBy(METRE.times(METRE)); + public static final LinearUnit BEQUEREL = ONE.dividedBy(SECOND); // for activity referred to a nucleotide + public static final LinearUnit GRAY = JOULE.dividedBy(KILOGRAM); // for absorbed dose + public static final LinearUnit SIEVERT = JOULE.dividedBy(KILOGRAM); // for dose equivalent + public static final LinearUnit KATAL = MOLE.dividedBy(SECOND); + + // Non-SI units included for convenience + public static final Unit CELSIUS = Unit.fromConversionFunctions(KELVIN.getBase(), tempK -> tempK - 273.15, + tempC -> tempC + 273.15); + public static final LinearUnit MINUTE = SECOND.times(60); + public static final LinearUnit HOUR = MINUTE.times(60); + public static final LinearUnit DAY = HOUR.times(60); + public static final LinearUnit DEGREE = RADIAN.times(360 / (2 * Math.PI)); + public static final LinearUnit ARCMINUTE = DEGREE.dividedBy(60); + public static final LinearUnit ARCSECOND = ARCMINUTE.dividedBy(60); + public static final LinearUnit ASTRONOMICAL_UNIT = METRE.times(149597870700.0); + public static final LinearUnit PARSEC = ASTRONOMICAL_UNIT.times(ARCSECOND); + public static final LinearUnit HECTARE = METRE.times(METRE).times(10000.0); + public static final LinearUnit LITRE = METRE.times(METRE).times(METRE).dividedBy(1000.0); + public static final LinearUnit TONNE = KILOGRAM.times(1000.0); + public static final LinearUnit DALTON = KILOGRAM.times(1.660539040e-27); // approximate value + public static final LinearUnit ELECTRONVOLT = JOULE.times(1.602176634e-19); + public static final Unit NEPER = Unit.fromConversionFunctions(ONE.getBase(), pr -> 0.5 * Math.log(pr), + Np -> Math.exp(2 * Np)); + public static final Unit BEL = Unit.fromConversionFunctions(ONE.getBase(), pr -> Math.log10(pr), + dB -> Math.pow(10, dB)); + public static final Unit DECIBEL = Unit.fromConversionFunctions(ONE.getBase(), pr -> 10 * Math.log10(pr), + dB -> Math.pow(10, dB / 10)); + + /// The prefixes of the SI + // expanding decimal prefixes + public static final UnitPrefix KILO = UnitPrefix.valueOf(1e3); + public static final UnitPrefix MEGA = UnitPrefix.valueOf(1e6); + public static final UnitPrefix GIGA = UnitPrefix.valueOf(1e9); + public static final UnitPrefix TERA = UnitPrefix.valueOf(1e12); + public static final UnitPrefix PETA = UnitPrefix.valueOf(1e15); + public static final UnitPrefix EXA = UnitPrefix.valueOf(1e18); + public static final UnitPrefix ZETTA = UnitPrefix.valueOf(1e21); + public static final UnitPrefix YOTTA = UnitPrefix.valueOf(1e24); + + // contracting decimal prefixes + public static final UnitPrefix MILLI = UnitPrefix.valueOf(1e-3); + public static final UnitPrefix MICRO = UnitPrefix.valueOf(1e-6); + public static final UnitPrefix NANO = UnitPrefix.valueOf(1e-9); + public static final UnitPrefix PICO = UnitPrefix.valueOf(1e-12); + public static final UnitPrefix FEMTO = UnitPrefix.valueOf(1e-15); + public static final UnitPrefix ATTO = UnitPrefix.valueOf(1e-18); + public static final UnitPrefix ZEPTO = UnitPrefix.valueOf(1e-21); + public static final UnitPrefix YOCTO = UnitPrefix.valueOf(1e-24); + + // prefixes that don't match the pattern of thousands + public static final UnitPrefix DEKA = UnitPrefix.valueOf(1e1); + public static final UnitPrefix HECTO = UnitPrefix.valueOf(1e2); + public static final UnitPrefix DECI = UnitPrefix.valueOf(1e-1); + public static final UnitPrefix CENTI = UnitPrefix.valueOf(1e-2); + public static final UnitPrefix KIBI = UnitPrefix.valueOf(1024); + public static final UnitPrefix MEBI = KIBI.times(1024); + public static final UnitPrefix GIBI = MEBI.times(1024); + public static final UnitPrefix TEBI = GIBI.times(1024); + public static final UnitPrefix PEBI = TEBI.times(1024); + public static final UnitPrefix EXBI = PEBI.times(1024); + + // You may NOT get SI instances! + private SI() { + throw new AssertionError(); + } +} -- cgit v1.2.3