View Javadoc

1   
2   package edu.iris.Fissures.model;
3   
4   import edu.iris.Fissures.Unit;
5   import edu.iris.Fissures.UnitBase;
6   
7   
8   /*** encapsulates the meaning of a unit. All units are products of SI
9    *  primitive units.<P>
10   *  It has 4 main parts and can be viewed as<BREAK>
11   *  (m * 10^p u) ^ e<BREAK>
12   *  where:<BREAK>
13   *  m is the multiplicative factor,<BREAK>
14   *  p is the power of ten,
15   *  u is either a SI base unit, or a composite unit,
16   *  e is the exponent.<P>
17   *  For example, the unit <EM>per inch<EM> might be represented as<break>
18   *  (2.54 * 10^0 (1.0 * 10^-2 METER) ) ^ -1<BREAK>
19   *  as one inch is 2.54 centimeters, which is 10-2 METERS.
20   *  The -1 takes care of the <em>per<em> part.
21   *
22   */
23  public class UnitImpl extends edu.iris.Fissures.Unit {
24  
25      /*** The CORBA struct that contains the unit data. It is composed of
26       <p>
27       the_unit_base - the base unit, if this is of type BASE, or COMPOSITE if not
28       <BREAK>
29       elements - the elements that make up this composite unit,
30       if this is of type COMPOSITE<BREAK>
31       power - the power of ten for this unit, for example 3 for KILO<BREAK>
32       name - a string name for the unit, for example millisecond or foot<BREAK>
33       multi_factor - multiplicative factor, for example 2.54 together
34       with centimeters would give inches<BREAK>
35       exponent - the exponent of the unit, for example -1 for per second
36       */
37      protected static int numPrimitives = UnitImpl.getNumPrimitives();
38  
39      protected UnitImpl() {}
40  
41      public static java.io.Serializable createEmpty() {
42          return new UnitImpl();
43      }
44  
45      protected UnitImpl(int power, String name, double multi, int exponent) {
46          this.power = power;
47          this.name = name;
48          this.multi_factor = multi;
49          this.exponent = exponent;
50      }
51  
52      /*** creates a simple unit, ie only one type of base unit to a exponent
53       *  with a power for the power of ten. */
54      public UnitImpl(UnitBase baseUnit, int exponent, int power) {
55          this(power, "", 1.0f, exponent);
56          the_unit_base = baseUnit;
57          elements = new edu.iris.Fissures.Unit[0];
58      }
59  
60      public UnitImpl(Unit[] subunits, int power, String name, double multi,
61                      int exponent) {
62          this(power, name, multi, exponent);
63          if (subunits == null) {
64              throw new IllegalArgumentException("Cannot create composite Unit with null subunits.");
65          }
66          if (subunits.length == 0) {
67              throw new IllegalArgumentException("Cannot create composite Unit with 0 subunits.");
68          }
69          the_unit_base = UnitBase.COMPOSITE;
70          elements = subunits;
71      }
72  
73      /*** creates a simple unit, ie only one type of base unit to a exponent
74       *  with a power for the power of ten and with a multiplicative factor
75       *  and a name. */
76      public UnitImpl(UnitBase base, int power, String name, double multi,
77                      int exponent) {
78          this(power, name, multi, exponent);
79          if (base == null) {
80              throw new IllegalArgumentException("Cannot create base Unit with null UnitBase.");
81          }
82          this.the_unit_base = base;
83          elements = new edu.iris.Fissures.Unit[0];
84      }
85  
86      /*** A factory method to make sure that the input edu.iris.Fissures.unit
87       is in fact a edu.iris.Fissurs.model.UnitImpl, to avoid class cast
88       errors. The implementation will only create a new object if the
89       inUnit is not an instance of UnitImpl.
90       */
91      public static UnitImpl createUnitImpl(Unit inUnit) {
92          if (inUnit instanceof UnitImpl) {
93              return (UnitImpl)inUnit;
94          } else {
95              UnitImpl newUnit;
96              if (inUnit.the_unit_base == UnitBase.COMPOSITE) {
97                  UnitImpl[] newSubUnits = new UnitImpl[inUnit.elements.length];
98                  for (int i=0; i<newSubUnits.length; i++) {
99                      newSubUnits[i] = createUnitImpl(inUnit.elements[i]);
100                 } // end of for (int i=0; i<newSubUnits.length; i++)
101                 newUnit = new UnitImpl(newSubUnits,
102                                        inUnit.power,
103                                        inUnit.name,
104                                        inUnit.multi_factor,
105                                        inUnit.exponent);
106             } else {
107                 newUnit = new UnitImpl(inUnit.the_unit_base,
108                                        inUnit.power,
109                                        inUnit.name,
110                                        inUnit.multi_factor,
111                                        inUnit.exponent);
112             }
113             return newUnit;
114         } // end of else
115     }
116 
117     /*** Returns the number of subunits. For example meters per second would
118      *  have 2 subunits and meters per second per second could have either
119      *  2 or 3 depending on how it was constructed. A base unit has 0 subunits.
120      *  @returns the number of subunits. */
121     public int getNumSubUnits() {
122         if (the_unit_base.equals(UnitBase.COMPOSITE)) return elements.length;
123         else return 0;
124     }
125 
126     /*** Returns the ith subunit of this Unit.
127      *  @returns the ith subunit. */
128     public UnitImpl getSubUnit(int i) { return (UnitImpl)elements[i]; }
129 
130     public UnitImpl[] getSubUnits() {
131         if (elements == null || elements.length == 0)  return new UnitImpl[0];
132         UnitImpl[] temp = new UnitImpl[elements.length];
133         System.arraycopy(elements, 0, temp, 0, temp.length);
134         return temp;
135     }
136 
137     public boolean isBaseUnit() {
138         if (the_unit_base == UnitBase.COMPOSITE)  return false;
139         else  return true;
140     }
141 
142     public UnitBase getBaseUnit() { return the_unit_base; }
143 
144     /*** convoluted way to find out how many different unit primitives
145      *  there are, since edu.iris.Fissures.UnitBase
146      *  provides no accessor method and to avoid hard coding the value. */
147     public static int getNumPrimitives() {
148         int numPrimitives = 0;
149         try {
150             while (true) {
151                 UnitBase.from_int(numPrimitives);
152                 numPrimitives++;
153             }
154         } catch(Exception e) {
155             // caught the exception, so
156             // numPrimitives = the number of primitives
157         }
158         return numPrimitives;
159     }
160 
161     /*** Reduces the unit to its most basic SI form, combining all terms
162      possible and bringing any constant factors out.
163      */
164     public UnitImpl getReducedUnit() {
165         int primitiveExponent[] = getBaseExponents();
166 
167         // create a temp unit with the total multiplicative factor and power
168         // of ten. The correct unit base will be put in during the first pass
169         // through the loop
170         UnitImpl unitTemp = new UnitImpl(UnitBase.from_int(0), getTotalPower(),
171                                          "", getTotalMultiFactor(), 1);
172         UnitImpl unitTotal = new UnitImpl(new Unit[primitiveExponent.length],
173                                           getTotalPower(), "",
174                                           getTotalMultiFactor(), 1);
175 
176         int numSubUnits = 0;
177         for (int i=0; i<primitiveExponent.length; i++) {
178             if (primitiveExponent[i] != 0) {
179                 unitTemp.the_unit_base = UnitBase.from_int(i);
180                 unitTemp.exponent = primitiveExponent[i];
181                 unitTotal.elements[numSubUnits] = unitTemp;
182                 numSubUnits++;
183                 // create a new temp unit for the next pass
184                 unitTemp = new UnitImpl(UnitBase.from_int(0), getTotalPower(),
185                                         "", getTotalMultiFactor(), 1);
186             }
187         }
188 
189         if (numSubUnits == 1) {
190             // just a base unit, so just return the first element
191             unitTotal = (UnitImpl)unitTotal.elements[0];
192         }
193         return unitTotal;
194     }
195 
196     /*** Returns the exponents of the subunits of this unit. They are indexed by
197      *  the integers defined in
198      *  edu.iris.Fissures.UnitImplBase.
199      *  This is used primarily to determine if to units can be converted from
200      *  one to the other.
201      */
202     public int[] getBaseExponents() {
203         // now fill out the exponents of the "dimensions"
204         // all are initialized to 0
205         int[] baseExponents = new int[numPrimitives];
206         if (the_unit_base != UnitBase.COMPOSITE) {
207             baseExponents[the_unit_base.value()] = exponent;
208             return baseExponents;
209         }
210         // not a BASE unit, so loop over all subunits
211         for (int i=0; i< elements.length; i++) {
212             UnitImpl subunit = (UnitImpl)elements[i];
213             int[] subExponents = subunit.getBaseExponents();
214             for (int j=0; j<baseExponents.length; j++) {
215                 baseExponents[j] += subExponents[j];
216             }
217         }
218         // all subunits exponents must be multiplied by the unit's exponent,
219         // EX meters per second squared might be represented as a METER
220         // times a composite unit composed of two SECOND units, with the
221         // additional factor of -1 in its exponent. In other words
222         // M * ( S * S ) ^-1
223         for (int j=0; j<baseExponents.length; j++) {
224             baseExponents[j] *= exponent;
225         }
226         return baseExponents;
227     }
228 
229     /*** Returns the exponent for this unit. This ignores any exponents
230      *  from any subunits.
231      */
232     public int getExponent() { return exponent; }
233 
234     /*** Calcultes the total power of ten for this unit relative to the
235      *  MKS base units. Used to convert from one set of units to another. */
236     public int getTotalPower() {
237         if (the_unit_base != UnitBase.COMPOSITE) {
238             return getPower()*getExponent();
239         } else {
240             int power = 0;
241             UnitImpl temp;
242             for (int i=0; i< elements.length; i++) {
243                 temp = (UnitImpl)elements[i];
244                 power += temp.getTotalPower();
245             }
246             // don't forget that there might be a power for the whole composite
247             // unit, so add it. Also, the exponent multiplies the power of ten
248             return (power+getPower())*getExponent();
249         }
250     }
251 
252     /*** Returns the power of ten for this unit. This ignores any powers
253      *  from any subunits.
254      */
255     public int getPower() { return power; }
256 
257     /*** Calcultes the total power of ten for this unit relative to the
258      *  base units. Used to convert from one set of units to another. */
259     public double getTotalMultiFactor() {
260         if (the_unit_base != UnitBase.COMPOSITE) {
261             return getMultiFactor();
262         } else {
263             double multi = 1.0;
264             UnitImpl temp;
265             for (int i=0; i< elements.length; i++) {
266                 temp = (UnitImpl)elements[i];
267                 multi *= temp.getTotalMultiFactor();
268             }
269 
270             // don't forget that there might be a multiplicative factor
271             // for the whole composite unit, so multiply it.
272 
273             return Math.pow(multi * getMultiFactor(), getExponent());
274         }
275     }
276 
277     /*** Returns the multiplicative factor for this unit. This ignores
278      *  any multiplicative factors from any subunits.
279      */
280     public double getMultiFactor() {
281         return multi_factor;
282     }
283 
284     /*** decides whether this unit is convertable to another unit. */
285     public boolean isConvertableTo(UnitImpl otherUnits) {
286         int[] ourExponents = getBaseExponents();
287         int[] otherExponents = otherUnits.getBaseExponents();
288         for (int i=0; i< ourExponents.length; i++) {
289             if (ourExponents[i] != otherExponents[i]) {
290                 return false;
291             }
292         }
293         return true;
294     }
295 
296     public boolean isNamed() {
297         if (name == null ||
298             name.length() == 0) {
299             return false;
300         } else {
301             return true;
302         }
303     }
304 
305     public static String baseToString(UnitBase b) {
306         switch (b.value()) {
307             case UnitBase._METER: return "METER";
308             case UnitBase._GRAM: return "GRAM";
309             case UnitBase._SECOND: return "SECOND";
310             case UnitBase._AMPERE: return "AMPERE";
311             case UnitBase._KELVIN: return "KELVIN";
312             case UnitBase._MOLE: return "MOLE";
313             case UnitBase._CANDELA: return "CANDELA";
314             case UnitBase._COUNT: return "COUNT";
315             default: return null;
316         }
317     }
318 
319     public void toLongString(){
320         System.out.println("*****"+ this +"*****");
321         System.out.println("Base Unit: " + getBaseUnit());
322         System.out.println("Exponents: " + getExponent());
323         System.out.println("Power: " + getPower());
324         System.out.println("Multifactor: " + getMultiFactor());
325         System.out.println("IsBaseUnit: " + isBaseUnit());
326         System.out.println("NumSubUnits: " + getNumSubUnits());
327         System.out.println("Subunits: ");
328         for (int i = 0; i < getNumSubUnits(); i++){
329             getSubUnit(i).toLongString();
330         }
331     }
332 
333     public String toString() {
334         if (isNamed()) {
335             return name;
336         } else {
337             String s;
338 
339             if (multi_factor != 1.0f) {
340                 s = multi_factor+" * ";
341             } else {
342                 s = "";
343             }
344 
345             if (getPrefix(getPower()) != null) {
346                 s+=getPrefix(getPower());
347             } else {
348                 s+="10^"+getPower()+" ";
349             }
350 
351             if (the_unit_base == UnitBase.COMPOSITE) {
352                 if (elements.length != 1) {
353                     s+="(";
354                 }
355                 String tempS = "";
356                 UnitImpl tempUnit;
357                 for (int i=0; i< elements.length; i++) {
358                     tempUnit = (UnitImpl)elements[i];
359                     if (tempUnit.isNamed()) {
360                         tempS = tempUnit.toString()+" ";
361                     } else {
362                         tempS = "("+tempUnit.toString()+") ";
363                     }
364                     s += tempS;
365                 }
366             } else {
367                 String tempS = baseToString(the_unit_base);
368                 if (tempS != null && tempS != "") {
369                     s += tempS;
370                 } else {
371                     s += "UNKNOWN"+the_unit_base.value();
372                 }
373             }
374 
375 
376             if (the_unit_base == UnitBase.COMPOSITE && elements.length != 1) {
377                 s+=")";
378             }
379 
380             if (exponent != 1) {
381                 s += "^"+exponent;
382             }
383             return s;
384         }
385     }
386 
387     public int hashCode(){
388         int result = 27;
389         result = result * 37 + getPower();
390         result = result * 37 + getHashValue(getMultiFactor());
391         result = result * 37 + getExponent();
392         result = result * 37 + (isBaseUnit() ? 0 : 1);
393         return result;
394     }
395 
396     private static int getHashValue(double d){
397         long l = Double.doubleToLongBits(d);
398         return (int)(l^(l>>>32));
399     }
400 
401     public boolean equals(Object o) {
402         if (super.equals(o)) return true;
403         if (o instanceof UnitImpl) {
404             UnitImpl u = (UnitImpl)o;
405             if (u.getPower() != getPower() ||
406                 u.getMultiFactor() != getMultiFactor() ||
407                 u.getExponent() != getExponent() ||
408                 u.isBaseUnit() != isBaseUnit()) {
409                 return false;
410             }
411             if (isBaseUnit()) {
412                 if (u.getBaseUnit() != getBaseUnit()) {
413                     return false;
414                 } else {
415                     return true;
416                 }
417             } else {
418                 if (u.getNumSubUnits() != getNumSubUnits()) {
419                     // warning: this doesn't work if different representations,
420                     // ie m/s/s and m/s^2
421                     return false;
422                 }
423                 for (int i=0; i<getNumSubUnits(); i++) {
424                     if ( ! u.getSubUnit(i).equals(getSubUnit(i))) {
425                         // WARNING: this doesn't work if they are the same but ordered differently
426                         return false;
427                     }
428                 }
429                 return true;
430             }
431         } else {
432             return false;
433         } // end of else
434 
435     }
436 
437     /*** creates and inverse to this unit with a given name.
438      * @returns a new unit that is the inverse (^-1) of this unit.
439      */
440     public UnitImpl inverse() {
441         if (name == null ||
442             name.length() == 0) {
443             return inverse("");
444         } else {
445             return inverse(name+"^-1");
446         }
447     }
448 
449     /*** @returns a new unit that is the inverse (^-1) of this unit.
450      */
451     public UnitImpl inverse(String name) {
452         if (the_unit_base != UnitBase.COMPOSITE) {
453             return new UnitImpl(the_unit_base,
454                                 power,
455                                 name,
456                                 multi_factor,
457                                 exponent * -1);
458         } else {
459             return new UnitImpl(elements,
460                                 power,
461                                 name,
462                                 multi_factor,
463                                 exponent * -1);
464         }
465     }
466 
467     /*** creates a new unit that is the product of a float multiplicative
468      factor and a unit, without a given name. */
469     public static UnitImpl multiply(double f, UnitImpl u) {
470         return multiply(f, u, "");
471     }
472 
473     /*** creates a new unit that is the product of a float multiplicative
474      factor and a unit with a name. */
475     public static UnitImpl multiply(double f, UnitImpl u, String name) {
476         Unit[] elements = new Unit[1];
477         elements[0] = u;
478         return new UnitImpl( elements,
479                             0,
480                             name,
481                             f,
482                             1);
483     }
484 
485     /*** creates a new unit that is the product of the two units. */
486     public static UnitImpl multiply(UnitImpl a, UnitImpl b) {
487         return multiply(a, b, "");
488     }
489 
490     /*** creates a new unit that is the product of the two units. */
491     public static UnitImpl multiply(UnitImpl a, UnitImpl b, String name) {
492         UnitImpl[] elements = new UnitImpl[2];
493         elements[0] = a;
494         elements[1] = b;
495         return new UnitImpl ( elements,
496                              0,
497                              name,
498                              1.0f,
499                              1);
500     }
501 
502     /*** creates a new unit that is the product of the units. */
503     public static UnitImpl multiply(UnitImpl[] units) {
504         return multiply(units, "");
505     }
506 
507     /*** creates a new unit that is the product of the units. */
508     public static UnitImpl multiply(UnitImpl[] units, String name) {
509         return new UnitImpl( units,
510                             0,
511                             name,
512                             1.0f,
513                             1);
514     }
515 
516     /*** creates a new unit that is the product of the first unit and the
517      * inverse of the second unit. */
518     public static UnitImpl divide(UnitImpl a, UnitImpl b) {
519         return divide(a, b, "");
520     }
521 
522     /*** creates a new unit that is the product of the first unit and the
523      * inverse of the second unit. */
524     public static UnitImpl divide(UnitImpl a, UnitImpl b, String name) {
525         UnitImpl[] elements = new
526             UnitImpl[2];
527         elements[0] = a;
528         elements[1] = b.inverse();
529         return new UnitImpl( elements,
530                             0,
531                             name,
532                             1.0f,
533                             1);
534     }
535 
536     /* the powers of common prefixes.
537      *  @returns the string prefix for common powers of ten, or null if
538      *  there is no prefix.
539      */
540     public static final String getPrefix(int power) {
541         switch (power) {
542             case YOTTA: return "yotta";
543             case ZETTA: return "zetta";
544             case EXA: return "exa";
545             case PETA: return "peta";
546             case TERA: return "tera";
547             case GIGA: return "giga";
548             case MEGA: return "mega";
549             case KILO: return "kilo";
550             case HECTO: return "hecto";
551             case DEKA: return "deka";
552             case 0: return "";
553             case DECI: return "deci";
554             case CENTI: return "centi";
555             case MILLI: return "milli";
556             case MICRO: return "micro";
557             case NANO: return "nano";
558             case PICO: return "pico";
559             case FEMTO: return "femto";
560             case ATTO: return "atto";
561             case ZEPTO: return "zepto";
562             case YOCTO: return "yocto";
563             default: return null;
564         }
565     }
566 
567     public static final UnitImpl getUnitFromString(String unitName) throws NoSuchFieldException{
568         try {
569             return (UnitImpl)UnitImpl.class.getField(unitName.toUpperCase()).get(null);
570         } catch (IllegalAccessException e) {
571             //neither this nor the following exception should happen since the
572             //NoSuchFieldException wasn't thrown by class.getField()
573         } catch (IllegalArgumentException e) {}
574         throw new RuntimeException("This was supposed to be unreachable");
575     }
576 
577     public static final int YOTTA = 24;
578     public static final int ZETTA = 21;
579     public static final int EXA = 18;
580     public static final int PETA = 15;
581     public static final int TERA = 12;
582     public static final int GIGA = 9;
583     public static final int MEGA = 6;
584     public static final int KILO = 3;
585     public static final int HECTO = 2;
586     public static final int DEKA = 1;
587 
588     public static final int NONE = 0;
589 
590     public static final int DECI = -1;
591     public static final int CENTI = -2;
592     public static final int MILLI = -3;
593     public static final int MICRO = -6;
594     public static final int NANO = -9;
595     public static final int PICO = -12;
596     public static final int FEMTO = -15;
597     public static final int ATTO = -18;
598     public static final int ZEPTO = -21;
599     public static final int YOCTO = -24;
600 
601     /* common length units. */
602     public static final UnitImpl METER = new UnitImpl(UnitBase.METER, 1, NONE);
603     public static final UnitImpl LENGTH = METER;
604     public static final UnitImpl KILOMETER = new UnitImpl(UnitBase.METER, 1, KILO);
605     public static final UnitImpl CENTIMETER = new UnitImpl(UnitBase.METER, 1, CENTI);
606     public static final UnitImpl MILLIMETER = new UnitImpl(UnitBase.METER, 1, MILLI);
607     public static final UnitImpl MICROMETER = new UnitImpl(UnitBase.METER, 1, MICRO);
608     public static final UnitImpl MICRON = MICROMETER;
609     public static final UnitImpl NANOMETER = new UnitImpl(UnitBase.METER, 1, NANO);
610     public static final UnitImpl PICOMETER = new UnitImpl(UnitBase.METER, 1, PICO);
611     public static final UnitImpl INCH = UnitImpl.multiply(2.54, CENTIMETER, "INCH");
612     public static final UnitImpl FOOT = UnitImpl.multiply(12, INCH, "FOOT");
613     public static final UnitImpl MILE = UnitImpl.multiply(5280, FOOT, "MILE");
614     public static final UnitImpl YARD = UnitImpl.multiply(3, FOOT, "YARD");
615     public static final UnitImpl ROD = UnitImpl.multiply(5.5, YARD, "ROD");
616     public static final UnitImpl FURLONG = UnitImpl.multiply(40, ROD, "FURLONG");
617     public static final UnitImpl LEAGUE = UnitImpl.multiply(3, MILE, "LEAGUE");
618 
619 
620     /* common time units. */
621     public static final UnitImpl SECOND = new UnitImpl(UnitBase.SECOND, 1, NONE);
622     public static final UnitImpl TIME = SECOND;
623     public static final UnitImpl MINUTE = UnitImpl.multiply(60, SECOND, "MINUTE");
624     public static final UnitImpl HOUR = UnitImpl.multiply(60, MINUTE, "HOUR");
625     public static final UnitImpl DAY = UnitImpl.multiply(24, HOUR, "DAY");
626     public static final UnitImpl WEEK = UnitImpl.multiply(7, DAY, "WEEK");
627     public static final UnitImpl FORTNIGHT = UnitImpl.multiply(14, DAY, "FORTNIGHT");
628     public static final UnitImpl GREGORIAN_YEAR = UnitImpl.multiply(365.2425, DAY, "GREGORIAN_YEAR");
629     public static final UnitImpl MILLISECOND = new UnitImpl(UnitBase.SECOND, 1, MILLI);
630     /*** tenth of a milliseconds, useful for SEED time format.*/
631     public static final UnitImpl TENTHMILLISECOND = new UnitImpl(UnitBase.SECOND, 1, -4);
632     public static final UnitImpl MICROSECOND = new UnitImpl(UnitBase.SECOND, 1, MICRO);
633     public static final UnitImpl NANOSECOND = new UnitImpl(UnitBase.SECOND, 1, NANO);
634 
635     public static final UnitImpl HERTZ = new UnitImpl(UnitBase.SECOND, -1, NONE);
636 
637     /* common area units. */
638     public static final UnitImpl SQUARE_METER = new UnitImpl(UnitBase.METER, 2, NONE);
639     public static final UnitImpl AREA = SQUARE_METER;
640     public static final UnitImpl SQUARE_CENTIMETER = new UnitImpl(UnitBase.METER, 2, CENTI);
641 
642     /* common volume units. */
643     public static final UnitImpl CUBIC_METER = new UnitImpl(UnitBase.METER, 3, NONE);
644     public static final UnitImpl VOLUME = CUBIC_METER;
645     public static final UnitImpl CUBIC_CENTIMETER = new UnitImpl(UnitBase.METER, 3, CENTI);
646     public static final UnitImpl LITER = new UnitImpl(UnitBase.METER, 3, DECI);
647 
648     /* common mass units. */
649     public static final UnitImpl GRAM = new UnitImpl(UnitBase.GRAM, 1, NONE);
650     public static final UnitImpl KILOGRAM = new UnitImpl(UnitBase.GRAM, 1, KILO);
651     public static final UnitImpl MASS = KILOGRAM;
652 
653     /* common density units. */
654     public static final UnitImpl DENSITY = UnitImpl.divide(MASS, VOLUME);
655     public static final UnitImpl GRAM_PER_CUBIC_CENTIMETER =
656         UnitImpl.divide(GRAM, CUBIC_CENTIMETER);
657     public static final UnitImpl KILOGRAM_PER_CUBIC_METER =
658         UnitImpl.divide(KILOGRAM, CUBIC_METER);
659 
660     /* common velocity units. */
661     public static final UnitImpl VELOCITY = UnitImpl.divide(LENGTH, TIME);
662     public static final UnitImpl METER_PER_SECOND = UnitImpl.divide(METER, SECOND);
663     public static final UnitImpl KILOMETER_PER_SECOND =
664         UnitImpl.divide(KILOMETER, SECOND);
665     public static final UnitImpl CENTIMETER_PER_SECOND =
666         UnitImpl.divide(CENTIMETER, SECOND);
667     public static final UnitImpl MILLIMETER_PER_SECOND =
668         UnitImpl.divide(MILLIMETER, SECOND);
669     public static final UnitImpl MICROMETER_PER_SECOND =
670         UnitImpl.divide(MICROMETER, SECOND);
671     public static final UnitImpl MICRON_PER_SECOND = MICROMETER_PER_SECOND;
672     public static final UnitImpl NANOMETER_PER_SECOND =
673         UnitImpl.divide(NANOMETER, SECOND);
674 
675     /* common acceleration units. */
676     public static final UnitImpl METER_PER_SECOND_PER_SECOND =
677         UnitImpl.divide(UnitImpl.divide(METER, SECOND), SECOND);
678     public static final UnitImpl ACCELERATION = UnitImpl.divide(VELOCITY, TIME);
679     public static final UnitImpl KILOMETER_PER_SECOND_PER_SECOND =
680         UnitImpl.divide(UnitImpl.divide(KILOMETER, SECOND), SECOND);
681     public static final UnitImpl CENTIMETER_PER_SECOND_PER_SECOND =
682         UnitImpl.divide(UnitImpl.divide(CENTIMETER, SECOND), SECOND);
683     public static final UnitImpl MILLIMETER_PER_SECOND_PER_SECOND =
684         UnitImpl.divide(UnitImpl.divide(MILLIMETER, SECOND), SECOND);
685     public static final UnitImpl MICROMETER_PER_SECOND_PER_SECOND =
686         UnitImpl.divide(UnitImpl.divide(MICROMETER, SECOND), SECOND);
687     public static final UnitImpl NANOMETER_PER_SECOND_PER_SECOND =
688         UnitImpl.divide(UnitImpl.divide(NANOMETER, SECOND), SECOND);
689 
690     /* common force units. */
691     public static final UnitImpl FORCE = UnitImpl.multiply(MASS, ACCELERATION);
692     public static final UnitImpl NEWTON =
693         UnitImpl.multiply(KILOGRAM, METER_PER_SECOND_PER_SECOND, "NEWTON");
694 
695     /* common energy units. */
696     public static final UnitImpl JOULE = UnitImpl.multiply(NEWTON, METER, "JOULE");
697     public static final UnitImpl ENERGY = UnitImpl.multiply(FORCE, LENGTH);
698     public static final UnitImpl DYNE = UnitImpl.multiply(UnitImpl.multiply(GRAM, CENTIMETER_PER_SECOND_PER_SECOND),
699                                                           CENTIMETER, "DYNE");
700     /* common electrical units. */
701     public static final UnitImpl AMPERE = new UnitImpl(UnitBase.AMPERE, 1, NONE);
702     public static final UnitImpl COULOMB = UnitImpl.multiply(AMPERE, SECOND, "COULOMB");
703     public static final UnitImpl VOLT = UnitImpl.divide(JOULE, COULOMB, "VOLT");
704 
705 
706     /* common angular units. */
707     public static final UnitImpl RADIAN = UnitImpl.divide(LENGTH, LENGTH, "RADIAN");
708     public static final UnitImpl DEGREE = UnitImpl.multiply((180.0 / Math.PI),
709                                                             RADIAN, "DEGREE");
710 
711     /* unit for counts */
712     public static final UnitImpl COUNT = new UnitImpl(UnitBase.COUNT, 1, NONE);
713     public static final UnitImpl MILLICOUNT = new UnitImpl(UnitBase.COUNT, 1, MILLI);
714     public static final UnitImpl MICROCOUNT = new UnitImpl(UnitBase.COUNT, 1, MICRO);
715     public static final UnitImpl KILOCOUNT = new UnitImpl(UnitBase.COUNT, 1, KILO);
716     public static final UnitImpl MEGACOUNT = new UnitImpl(UnitBase.COUNT, 1, MEGA);
717 
718     /*** This is really just a COUNT, but is given an empty name to differentiate it from
719      * COUNT.*/
720     public static final UnitImpl DIMENSONLESS = new UnitImpl(UnitBase.COUNT, 0, "", 1.0, 1);
721 
722     /* angular velocity */
723     public static final UnitImpl RADIAN_PER_SECOND = UnitImpl.divide(RADIAN, SECOND);
724 }