// // QuantityDimension.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad; import java.io.Serializable; /** * This class represents the dimension of a quantity. For example, consider a * nonrelativistic particle of mass <VAR>m</VAR> in uniform motion which travels * a distance <VAR>l</VAR> in a time <VAR>t</VAR>. Its velocity is * <VAR>v=l/t</VAR> and its kinetic energy is * <VAR>E=mv<SUP>2</SUP>/2=ml<SUP>2</SUP>t<SUP>-2</SUP>/2</VAR>. The dimension * of <VAR>E</VAR> is dim <VAR>E</VAR>=ML<SUP>2</SUP>T<SUP>-2</SUP> and the * dimensional exponents are 1, 2, and -2. * * A QuantityDimension is immutable. */ public final class QuantityDimension implements Serializable, Comparable { /** * The dimensional exponents. */ private/* final */byte[] exponents; /** * Constructs from nothing (i.e. constructs a dimensionless quantity). */ public QuantityDimension() { initialize(0); } /** * Constructs from another dimension of a quantity. */ public QuantityDimension(final QuantityDimension that) { initialize(that.exponents.length); System .arraycopy(that.exponents, 0, exponents, 0, that.exponents.length); } /** * Constructs from an existing Unit. */ public QuantityDimension(final Unit unit) throws UnitException { initialize(unit.getDerivedUnit()); } /** * Initialize from a number of base quantities. Private to ensure use of the * public constructors and the concomitant setting of the dimensional * exponents. */ private void initialize(final int n) { exponents = new byte[n]; } /** * Initialize from a DerivedUnit. */ private void initialize(final DerivedUnit unit) throws UnitException { initialize(BaseQuantity.size()); for (int i = 0; i < unit.factors.length; ++i) { final String name = unit.factors[i].baseUnit.quantityName(); final BaseQuantity baseQuantity = BaseQuantity.get(name); if (baseQuantity == null) { throw new UnitException("No base quantity for \"" + name + "\""); } exponents[baseQuantity.getIndex()] = (byte) unit.factors[i].power; } } /** * Compare this dimension of a quantity to another. */ public int compareTo(final Object obj) { final QuantityDimension that = (QuantityDimension) obj; return isShorterThan(that) ? compare(this, that) : -compare(that, this); } /** * Indicate whether or not this dimension of a quantity is shorter or equal * to another. */ private boolean isShorterThan(final QuantityDimension that) { return exponents.length < that.exponents.length; } /** * Compare a shorter dimensional quantity to a longer one. * * @precondition <code>shorter.exponents.length <= * longer.exponents.length</code>. */ private static int compare(final QuantityDimension shorter, final QuantityDimension longer) { int n = 0; for (int i = 0; n == 0 && i < shorter.exponents.length; ++i) { n = shorter.exponents[i] - longer.exponents[i]; } for (int i = shorter.exponents.length; n == 0 && i < longer.exponents.length; ++i) { n = -longer.exponents[i]; } return n; } /** * Indicate whether or not this dimension of a quantity is the same as * another. */ @Override public boolean equals(final Object obj) { return compareTo(obj) == 0; } /** * Raise this dimension of a quantity by a power. */ public QuantityDimension raise(final int power) { final QuantityDimension newDimension = new QuantityDimension(this); for (int i = 0; i < newDimension.exponents.length; ++i) { newDimension.exponents[i] *= power; } return newDimension; } /** * Multiply this dimension of a quantity by another. */ public QuantityDimension multiply(final QuantityDimension that) { return isShorterThan(that) ? multiply(this, that) : multiply(that, this); } /** * Multiply a shorter dimension of a quantity by a longer one. */ private static QuantityDimension multiply(final QuantityDimension shorter, final QuantityDimension longer) { final QuantityDimension newDimension = new QuantityDimension(longer); for (int i = 0; i < shorter.exponents.length; ++i) { newDimension.exponents[i] += shorter.exponents[i]; } return newDimension; } /** * Divide this dimension of a quantity by another. */ public QuantityDimension divide(final QuantityDimension that) { return multiply(that.raise(-1)); } /** * Indicate whether or not this dimension of a quantity is dimensionless. */ public boolean isDimensionless() { for (int i = 0; i < exponents.length; ++i) { if (exponents[i] != 0) { return false; } } return true; } /** * Return a string representation of this dimension of a quantity. */ @Override public String toString() { String rep; if (isDimensionless()) { rep = "1"; // dimensionless quantity } else { final StringBuffer buf = new StringBuffer(128); for (int i = 0; i < exponents.length; ++i) { final int exponent = exponents[i]; if (exponent != 0) { if (buf.length() > 0) { buf.append(" "); } buf.append("("); buf.append(BaseQuantity.get(i).getName()); buf.append(")"); if (exponent != 1) { buf.append("^"); buf.append(exponent); } } } rep = buf.toString(); } return rep; } /** * Test this class. */ // /* public static void main(final String[] args) { final QuantityDimension dim1 = new QuantityDimension(); dim1.exponents[0] = -3; dim1.exponents[1] = -2; dim1.exponents[2] = -1; dim1.exponents[3] = 0; dim1.exponents[4] = 1; dim1.exponents[5] = 2; dim1.exponents[6] = 3; dim1.exponents[7] = 4; System.out.println("dim1=(" + dim1 + ")"); System.out.println("dim1.equals(dim1)=" + dim1.equals(dim1)); System.out.println("dim1.compareTo(dim1)=" + dim1.compareTo(dim1)); final QuantityDimension dim2 = new QuantityDimension(); dim2.exponents[0] = -3; dim2.exponents[1] = -2; dim2.exponents[2] = -1; dim2.exponents[3] = 1; dim2.exponents[4] = 1; dim2.exponents[5] = 2; dim2.exponents[6] = 3; dim2.exponents[7] = 4; System.out.println("dim2=(" + dim2 + ")"); System.out.println("dim1.equals(dim2)=" + dim1.equals(dim2)); System.out.println("dim1.compareTo(dim2)=" + dim1.compareTo(dim2)); } // */ }