KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > osgi > util > measurement > Measurement


1 /*
2  * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Measurement.java,v 1.14 2006/07/11 00:54:06 hargrave Exp $
3  *
4  * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.osgi.util.measurement;
19
20
21 /**
22  * Represents a value with an error, a unit and a time-stamp.
23  *
24  * <p>
25  * A <code>Measurement</code> object is used for maintaining the tuple of value,
26  * error, unit and time-stamp. The value and error are represented as doubles
27  * and the time is measured in milliseconds since midnight, January 1, 1970 UTC.
28  *
29  * <p>
30  * Mathematic methods are provided that correctly calculate taking the error
31  * into account. A runtime error will occur when two measurements are used in an
32  * incompatible way. E.g., when a speed (m/s) is added to a distance (m). The
33  * measurement class will correctly track changes in unit during multiplication
34  * and division, always coercing the result to the most simple form. See
35  * {@link Unit} for more information on the supported units.
36  *
37  * <p>
38  * Errors in the measurement class are absolute errors. Measurement errors
39  * should use the P95 rule. Actual values must fall in the range value +/- error
40  * 95% or more of the time.
41  *
42  * <p>
43  * A <code>Measurement</code> object is immutable in order to be easily shared.
44  *
45  * <p>
46  * Note: This class has a natural ordering that is inconsistent with equals. See
47  * {@link #compareTo}.
48  *
49  * @version $Revision: 1.14 $
50  */

51 public class Measurement implements Comparable JavaDoc {
52     /* package private so it can be accessed by Unit */
53     final double value;
54     final double error;
55     final long time;
56     final Unit unit;
57     private transient String JavaDoc name;
58
59     /**
60      * Create a new <code>Measurement</code> object.
61      *
62      * @param value The value of the <code>Measurement</code>.
63      * @param error The error of the <code>Measurement</code>.
64      * @param unit The <code>Unit</code> object in which the value is measured. If
65      * this argument is <code>null</code>, then the unit will be set to
66      * {@link Unit#unity}.
67      * @param time The time measured in milliseconds since midnight, January 1,
68      * 1970 UTC.
69      */

70     public Measurement(double value, double error, Unit unit, long time) {
71         this.value = value;
72         this.error = Math.abs(error);
73         this.unit = (unit != null) ? unit : Unit.unity;
74         this.time = time;
75     }
76
77     /**
78      * Create a new <code>Measurement</code> object with a time of zero.
79      *
80      * @param value The value of the <code>Measurement</code>.
81      * @param error The error of the <code>Measurement</code>.
82      * @param unit The <code>Unit</code> object in which the value is measured. If
83      * this argument is <code>null</code>, then the unit will be set to
84      * {@link Unit#unity}.
85      */

86     public Measurement(double value, double error, Unit unit) {
87         this(value, error, unit, 0l);
88     }
89
90     /**
91      * Create a new <code>Measurement</code> object with an error of 0.0 and a
92      * time of zero.
93      *
94      * @param value The value of the <code>Measurement</code>.
95      * @param unit The <code>Unit</code> in which the value is measured. If this
96      * argument is <code>null</code>, then the unit will be set to
97      * {@link Unit#unity}.
98      */

99     public Measurement(double value, Unit unit) {
100         this(value, 0.0d, unit, 0l);
101     }
102
103     /**
104      * Create a new <code>Measurement</code> object with an error of 0.0, a unit
105      * of {@link Unit#unity} and a time of zero.
106      *
107      * @param value The value of the <code>Measurement</code>.
108      */

109     public Measurement(double value) {
110         this(value, 0.0d, null, 0l);
111     }
112
113     /**
114      * Returns the value of this <code>Measurement</code> object.
115      *
116      * @return The value of this <code>Measurement</code> object as a double.
117      */

118     public final double getValue() {
119         return value;
120     }
121
122     /**
123      * Returns the error of this <code>Measurement</code> object. The error is
124      * always a positive value.
125      *
126      * @return The error of this <code>Measurement</code> as a double.
127      */

128     public final double getError() {
129         return error;
130     }
131
132     /**
133      * Returns the <code>Unit</code> object of this <code>Measurement</code> object.
134      *
135      * @return The <code>Unit</code> object of this <code>Measurement</code> object.
136      *
137      * @see Unit
138      */

139     public final Unit getUnit() {
140         return unit;
141     }
142
143     /**
144      * Returns the time at which this <code>Measurement</code> object was taken.
145      * The time is measured in milliseconds since midnight, January 1, 1970 UTC,
146      * or zero when not defined.
147      *
148      * @return The time at which this <code>Measurement</code> object was taken or
149      * zero.
150      */

151     public final long getTime() {
152         return time;
153     }
154
155     /**
156      * Returns a new <code>Measurement</code> object that is the product of this
157      * object multiplied by the specified object.
158      *
159      * @param m The <code>Measurement</code> object that will be multiplied with
160      * this object.
161      * @return A new <code>Measurement</code> that is the product of this object
162      * multiplied by the specified object. The error and unit of the new
163      * object are computed. The time of the new object is set to the
164      * time of this object.
165      * @throws ArithmeticException If the <code>Unit</code> objects of this object
166      * and the specified object cannot be multiplied.
167      * @see Unit
168      */

169     public Measurement mul(Measurement m) {
170         double mvalue = m.value;
171         return new Measurement(value * mvalue, Math.abs(value) * m.error
172                 + error * Math.abs(mvalue), unit.mul(m.unit), time);
173     }
174
175     /**
176      * Returns a new <code>Measurement</code> object that is the product of this
177      * object multiplied by the specified value.
178      *
179      * @param d The value that will be multiplied with this object.
180      * @param u The <code>Unit</code> of the specified value.
181      * @return A new <code>Measurement</code> object that is the product of this
182      * object multiplied by the specified value. The error and unit of
183      * the new object are computed. The time of the new object is set to
184      * the time of this object.
185      * @throws ArithmeticException If the units of this object and the specified
186      * value cannot be multiplied.
187      * @see Unit
188      */

189     public Measurement mul(double d, Unit u) {
190         return new Measurement(value * d, error * Math.abs(d), unit.mul(u),
191                 time);
192     }
193
194     /**
195      * Returns a new <code>Measurement</code> object that is the product of this
196      * object multiplied by the specified value.
197      *
198      * @param d The value that will be multiplied with this object.
199      * @return A new <code>Measurement</code> object that is the product of this
200      * object multiplied by the specified value. The error of the new
201      * object is computed. The unit and time of the new object is set to
202      * the unit and time of this object.
203      */

204     public Measurement mul(double d) {
205         return new Measurement(value * d, error * Math.abs(d), unit, time);
206     }
207
208     /**
209      * Returns a new <code>Measurement</code> object that is the quotient of this
210      * object divided by the specified object.
211      *
212      * @param m The <code>Measurement</code> object that will be the divisor of
213      * this object.
214      * @return A new <code>Measurement</code> object that is the quotient of this
215      * object divided by the specified object. The error and unit of the
216      * new object are computed. The time of the new object is set to the
217      * time of this object.
218      * @throws ArithmeticException If the <code>Unit</code> objects of this object
219      * and the specified object cannot be divided.
220      * @see Unit
221      */

222     public Measurement div(Measurement m) {
223         double mvalue = m.value;
224         return new Measurement(value / mvalue,
225                 (Math.abs(value) * m.error + error * Math.abs(mvalue))
226                         / (mvalue * mvalue), unit.div(m.unit), time);
227     }
228
229     /**
230      * Returns a new <code>Measurement</code> object that is the quotient of this
231      * object divided by the specified value.
232      *
233      * @param d The value that will be the divisor of this object.
234      * @param u The <code>Unit</code> object of the specified value.
235      * @return A new <code>Measurement</code> that is the quotient of this object
236      * divided by the specified value. The error and unit of the new
237      * object are computed. The time of the new object is set to the
238      * time of this object.
239      * @throws ArithmeticException If the <code>Unit</code> objects of this object
240      * and the specified object cannot be divided.
241      * @see Unit
242      */

243     public Measurement div(double d, Unit u) {
244         return new Measurement(value / d, error / Math.abs(d), unit.div(u),
245                 time);
246     }
247
248     /**
249      * Returns a new <code>Measurement</code> object that is the quotient of this
250      * object divided by the specified value.
251      *
252      * @param d The value that will be the divisor of this object.
253      * @return A new <code>Measurement</code> object that is the quotient of this
254      * object divided by the specified value. The error of the new
255      * object is computed. The unit and time of the new object is set to
256      * the <code>Unit</code> and time of this object.
257      */

258     public Measurement div(double d) {
259         return new Measurement(value / d, error / Math.abs(d), unit, time);
260     }
261
262     /**
263      * Returns a new <code>Measurement</code> object that is the sum of this
264      * object added to the specified object.
265      *
266      * The error and unit of the new object are computed. The time of the new
267      * object is set to the time of this object.
268      *
269      * @param m The <code>Measurement</code> object that will be added with this
270      * object.
271      * @return A new <code>Measurement</code> object that is the sum of this and
272      * m.
273      * @see Unit
274      * @throws ArithmeticException If the <code>Unit</code> objects of this object
275      * and the specified object cannot be added.
276      */

277     public Measurement add(Measurement m) {
278         return new Measurement(value + m.value, error + m.error, unit
279                 .add(m.unit), time);
280     }
281
282     /**
283      * Returns a new <code>Measurement</code> object that is the sum of this
284      * object added to the specified value.
285      *
286      * @param d The value that will be added with this object.
287      * @param u The <code>Unit</code> object of the specified value.
288      * @return A new <code>Measurement</code> object that is the sum of this
289      * object added to the specified value. The unit of the new object
290      * is computed. The error and time of the new object is set to the
291      * error and time of this object.
292      * @throws ArithmeticException If the <code>Unit</code> objects of this object
293      * and the specified value cannot be added.
294      * @see Unit
295      */

296     public Measurement add(double d, Unit u) {
297         return new Measurement(value + d, error, unit.add(u), time);
298     }
299
300     /**
301      * Returns a new <code>Measurement</code> object that is the sum of this
302      * object added to the specified value.
303      *
304      * @param d The value that will be added with this object.
305      * @return A new <code>Measurement</code> object that is the sum of this
306      * object added to the specified value. The error, unit, and time of
307      * the new object is set to the error, <code>Unit</code> and time of
308      * this object.
309      */

310     public Measurement add(double d) {
311         return new Measurement(value + d, error, unit, time);
312     }
313
314     /**
315      * Returns a new <code>Measurement</code> object that is the subtraction of
316      * the specified object from this object.
317      *
318      * @param m The <code>Measurement</code> object that will be subtracted from
319      * this object.
320      * @return A new <code>Measurement</code> object that is the subtraction of
321      * the specified object from this object. The error and unit of the
322      * new object are computed. The time of the new object is set to the
323      * time of this object.
324      * @throws ArithmeticException If the <code>Unit</code> objects of this object
325      * and the specified object cannot be subtracted.
326      * @see Unit
327      */

328     public Measurement sub(Measurement m) {
329         return new Measurement(value - m.value, error + m.error, unit
330                 .sub(m.unit), time);
331     }
332
333     /**
334      * Returns a new <code>Measurement</code> object that is the subtraction of
335      * the specified value from this object.
336      *
337      * @param d The value that will be subtracted from this object.
338      * @param u The <code>Unit</code> object of the specified value.
339      * @return A new <code>Measurement</code> object that is the subtraction of
340      * the specified value from this object. The unit of the new object
341      * is computed. The error and time of the new object is set to the
342      * error and time of this object.
343      * @throws ArithmeticException If the <code>Unit</code> objects of this object
344      * and the specified object cannot be subtracted.
345      * @see Unit
346      */

347     public Measurement sub(double d, Unit u) {
348         return new Measurement(value - d, error, unit.sub(u), time);
349     }
350
351     /**
352      * Returns a new <code>Measurement</code> object that is the subtraction of
353      * the specified value from this object.
354      *
355      * @param d The value that will be subtracted from this object.
356      * @return A new <code>Measurement</code> object that is the subtraction of
357      * the specified value from this object. The error, unit and time of
358      * the new object is set to the error, <code>Unit</code> object and
359      * time of this object.
360      */

361     public Measurement sub(double d) {
362         return new Measurement(value - d, error, unit, time);
363     }
364
365     /**
366      * Returns a <code>String</code> object representing this <code>Measurement</code>
367      * object.
368      *
369      * @return a <code>String</code> object representing this <code>Measurement</code>
370      * object.
371      */

372     public String JavaDoc toString() {
373         if (name == null) {
374             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
375             sb.append(value);
376             if (error != 0.0d) {
377                 sb.append(" +/- ");
378                 sb.append(error);
379             }
380             String JavaDoc u = unit.toString();
381             if (u.length() > 0) {
382                 sb.append(" ");
383                 sb.append(u);
384             }
385             name = sb.toString();
386         }
387         return name;
388     }
389
390     /**
391      * Compares this object with the specified object for order. Returns a
392      * negative integer, zero, or a positive integer if this object is less
393      * than, equal to, or greater than the specified object.
394      *
395      * <p>
396      * Note: This class has a natural ordering that is inconsistent with equals.
397      * For this method, another <code>Measurement</code> object is considered
398      * equal if there is some <code>x</code> such that
399      *
400      * <pre>
401      * getValue() - getError() &lt;= x &lt;= getValue() + getError()
402      * </pre>
403      *
404      * for both <code>Measurement</code> objects being compared.
405      *
406      * @param obj The object to be compared.
407      * @return A negative integer, zero, or a positive integer if this object is
408      * less than, equal to, or greater than the specified object.
409      *
410      * @throws ClassCastException If the specified object is not of type
411      * <code>Measurement</code>.
412      * @throws ArithmeticException If the unit of the specified
413      * <code>Measurement</code> object is not equal to the <code>Unit</code>
414      * object of this object.
415      */

416     public int compareTo(Object JavaDoc obj) {
417         if (this == obj) {
418             return 0;
419         }
420         Measurement that = (Measurement) obj;
421         if (!unit.equals(that.unit)) {
422             throw new ArithmeticException JavaDoc("Cannot compare " + this + " and "
423                     + that);
424         }
425         if (value == that.value) {
426             return 0;
427         }
428         if (value < that.value) {
429             if ((value + error) >= (that.value - that.error)) {
430                 return 0;
431             }
432             else {
433                 return -1;
434             }
435         }
436         else {
437             if ((value - error) <= (that.value + that.error)) {
438                 return 0;
439             }
440             else {
441                 return 1;
442             }
443         }
444     }
445
446     /**
447      * Returns a hash code value for this object.
448      *
449      * @return A hash code value for this object.
450      */

451     public int hashCode() {
452         long bits = Double.doubleToLongBits(value + error);
453         return ((int) (bits ^ (bits >>> 32))) ^ unit.hashCode();
454     }
455
456     /**
457      * Returns whether the specified object is equal to this object. Two
458      * <code>Measurement</code> objects are equal if they have same value, error
459      * and <code>Unit</code>.
460      *
461      * <p>
462      * Note: This class has a natural ordering that is inconsistent with equals.
463      * See {@link #compareTo}.
464      *
465      * @param obj The object to compare with this object.
466      * @return <code>true</code> if this object is equal to the specified object;
467      * <code>false</code> otherwise.
468      */

469     public boolean equals(Object JavaDoc obj) {
470         if (this == obj) {
471             return true;
472         }
473         if (!(obj instanceof Measurement)) {
474             return false;
475         }
476         Measurement that = (Measurement) obj;
477         return (value == that.value) && (error == that.error)
478                 && unit.equals(that.unit);
479     }
480 }
481
Popular Tags