001: // Copyright (c) 1997 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.math;
005:
006: /** A quantity with a unit.
007: * This generalizes the DSSSL quantity type (to more than lengths).
008: * @author Per Bothner
009: */
010:
011: public abstract class Quantity extends Numeric {
012: public Unit unit() {
013: return Unit.Empty;
014: }
015:
016: public Dimensions dimensions() {
017: return unit().dimensions();
018: }
019:
020: public abstract Complex number();
021:
022: /** The value of the real component, as a RealNum.
023: * The unit() is not factored in, so you actually need to multiply
024: * by unit() to get the true real component.
025: */
026: public RealNum re() {
027: return number().re();
028: }
029:
030: /** The value of the imaginary component, as a RealNum.
031: * The unit() is not factored in, so you actually need to multiply
032: * by unit() to get the true imaginary component.
033: */
034: public RealNum im() {
035: return number().im();
036: }
037:
038: /** The value of the real component, as a double.
039: * This is relative to the unit().dims - i.e. unit().doubleValue()
040: * is factored in.
041: * A final alias for the virtual doubleValue. */
042: public final double reValue() {
043: return doubleValue();
044: }
045:
046: /** The value of the imaginary component, as a double.
047: * This is relative to the unit().dims - i.e. unit().doubleValue()
048: * is factored in.
049: * A final alias for the virtual doubleImagValue. */
050: public final double imValue() {
051: return doubleImagValue();
052: }
053:
054: /** The value of the real component, as a double.
055: * This is relative to the unit().dims - i.e. unit()/doubleValue()
056: * is factored in. */
057: public double doubleValue() {
058: return unit().doubleValue() * re().doubleValue();
059: }
060:
061: /** The value of the imaginary component, as a double.
062: * This is relative to the unit().dims - i.e. unit()/doubleValue()
063: * is factored in. */
064: public double doubleImagValue() {
065: return unit().doubleValue() * im().doubleValue();
066: }
067:
068: public static Quantity make(Complex x, Unit u) {
069: if (u == Unit.Empty)
070: return x;
071: if (x instanceof DFloNum)
072: return new DQuantity(x.doubleValue(), u);
073: return new CQuantity(x, u);
074: }
075:
076: public static Quantity make(RealNum re, RealNum im, Unit unit) {
077: if (unit == Unit.Empty)
078: return Complex.make(re, im);
079: if (im.isZero() && (!re.isExact() || !im.isExact()))
080: return new DQuantity(re.doubleValue(), unit);
081: return new CQuantity(re, im, unit);
082: }
083:
084: public static Quantity make(double re, double im, Unit unit) {
085: if (unit == Unit.Empty)
086: return Complex.make(re, im);
087: if (im == 0.0)
088: return new DQuantity(re, unit);
089: return new CQuantity(new DFloNum(re), new DFloNum(im), unit);
090: }
091:
092: /*
093: public static Quantity make (Quantity x, Quantity y)
094: {
095: double x_factor = x.unit().doubleValue();
096: if (x.unit() != y.unit())
097: {
098: if (x.dimensions() != y.dimensions())
099: throw new ArithmeticException ("units mis-match");
100: double re = x.doubleValue() / x_factor;
101: double im = y.doubleValue() / x_factor;
102: return Complex.make (re, im, x.unit());
103: }
104: if (! x.isExact() || ! y.isExact())
105: {
106: return Complex.make (x.doubleValue () / x_factor,
107: y.doubleValue () / x_factor, x.unit());
108: }
109: return Complex.make (x.re(), y.re(), x.unit());
110: }
111: */
112:
113: public Numeric neg() {
114: return make((Complex) number().neg(), unit());
115: }
116:
117: public Numeric abs() {
118: return make((Complex) number().abs(), unit());
119: }
120:
121: public static int compare(Quantity x, Quantity y) {
122: if (x.unit() == y.unit())
123: return Complex.compare(x.number(), y.number());
124: if (x.dimensions() != y.dimensions()
125: || x.imValue() != y.imValue())
126: return -3;
127: return DFloNum.compare(x.reValue(), y.reValue());
128: }
129:
130: public int compare(Object obj) {
131: if (!(obj instanceof Quantity))
132: return ((Numeric) obj).compareReversed(this );
133: return compare(this , (Quantity) obj);
134: }
135:
136: public int compareReversed(Numeric x) {
137: if (x instanceof Quantity)
138: return compare((Quantity) x, this );
139: throw new IllegalArgumentException();
140: }
141:
142: public static Quantity add(Quantity x, Quantity y, int k) {
143: if (x.unit() == y.unit())
144: return make(Complex.add(x.number(), y.number(), k), x
145: .unit());
146: else if (x.dimensions() != y.dimensions())
147: throw new ArithmeticException("units mis-match");
148: else {
149: double x_factor = x.unit().doubleValue();
150: double re = (x.reValue() + k * y.reValue()) / x_factor;
151: double im = (x.imValue() + k * y.imValue()) / x_factor;
152: return Quantity.make(re, im, x.unit());
153: }
154: }
155:
156: public Numeric add(Object y, int k) {
157: if (y instanceof Quantity)
158: return add(this , (Quantity) y, k);
159: return ((Numeric) y).addReversed(this , k);
160: }
161:
162: public Numeric addReversed(Numeric x, int k) {
163: if (x instanceof Quantity)
164: return add((Quantity) x, this , k);
165: throw new IllegalArgumentException();
166: }
167:
168: public static Quantity times(Quantity x, Quantity y) {
169: Unit unit = Unit.times(x.unit(), y.unit());
170: // return Quantity.make (Complex.times(x.number(), y.number()), unit);
171: Numeric num = x.number().mul(y.number());
172: return Quantity.make((Complex) num, unit);
173: }
174:
175: public Numeric mul(Object y) {
176: if (y instanceof Quantity)
177: return times(this , (Quantity) y);
178: return ((Numeric) y).mulReversed(this );
179: }
180:
181: public Numeric mulReversed(Numeric x) {
182: if (x instanceof Quantity)
183: return times((Quantity) x, this );
184: throw new IllegalArgumentException();
185: }
186:
187: public static Quantity divide(Quantity x, Quantity y) {
188: Unit unit = Unit.divide(x.unit(), y.unit());
189: Numeric num = x.number().div(y.number());
190: return Quantity.make((Complex) num, unit);
191: }
192:
193: public Numeric div(Object y) {
194: if (y instanceof Quantity)
195: return divide(this , (Quantity) y);
196: return ((Numeric) y).divReversed(this );
197: }
198:
199: public Numeric divReversed(Numeric x) {
200: if (x instanceof Quantity)
201: return divide((Quantity) x, this );
202: throw new IllegalArgumentException();
203: }
204:
205: public String toString(int radix) {
206: String str = number().toString(radix);
207: if (unit() == Unit.Empty)
208: return str;
209: return str + unit().toString();
210: }
211: }
|