View Javadoc

1   /*** MeasuredValue.java - part of the MirkE (say murky) application for colormetric analysis emphesizing 
2    kinetics.
3    
4    Created by: Scott Menor on 21 July, 2004.
5    Last modified by: José Faleon on 10 January, 2005
6    
7    Copyright (c) 2004 Arizona State University - Cancer Research Institute. All rights reserved.
8    
9    MirkE is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   MirkE is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18   
19   You should have received a copy of the GNU General Public License
20   along with MirkE; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
22   */
23  
24  /* 
25   * Modified on 10.01.05 by jafaleon  
26   * adapted to the new Unit.class 
27   */ 
28  
29  package edu.asu.cri.MirkE.dataStructures;
30  
31  /*** A <code>UnitValue</code> along with a first statistical moment (standard deviation)
32   
33   TODO - add support to store and propagate arbitrary moments
34   */
35  public class MeasuredValue extends UnitValue{
36      /*** default constructor
37       
38       */
39      public MeasuredValue() {}
40      
41      /*** constructor
42       
43       @param value
44       @param standardDeviation
45       @param units
46       */
47      public MeasuredValue(
48              double value,
49              double standardDeviation,
50              Unit units) {
51          setValue(value);
52          setStandardDeviation(standardDeviation);
53          setUnits(units);
54      }
55      
56      /*** constructor
57       
58       @param value
59       @param standardDeviation
60       @param units
61       */
62      public MeasuredValue(
63              Double value,
64              Double standardDeviation,
65              Unit units) {
66          setValue(value.doubleValue());
67          setStandardDeviation(standardDeviation.doubleValue());
68          setUnits(units);
69      }
70      
71      /*** 
72       * constructor
73       * 
74       * @param unitValue
75       */
76      public MeasuredValue(UnitValue unitValue) {
77          setValue(unitValue.getValue());
78          setUnits(unitValue.getUnits());
79          setStandardDeviation(0);
80      }
81      
82      /*** add a <code>MeasuredValue</code> to this and return the sum (if it exists) 
83       * 
84       * @param measuredValue
85       * @return sum of this and <code>measuredValue</code>
86       */
87      public MeasuredValue add(MeasuredValue measuredValue) { 
88          MeasuredValue sumMeasuredValue = null; 
89          Unit finalUnits = measuredValue.getUnits(); 
90          double valueOfSum; 
91          double standardDeviationOfSum; 
92          
93          if (this.getUnits().equals(finalUnits)) { 
94              //If Units are the same not need to convert. 
95              valueOfSum = this.getValue() + measuredValue.getValue(); 
96              standardDeviationOfSum = Math.sqrt(Math.pow(this.getStandardDeviation(), 2) +  
97                      Math.pow(measuredValue.getStandardDeviation(), 2)); 
98              
99              sumMeasuredValue = new MeasuredValue(valueOfSum,  
100                     standardDeviationOfSum, 
101                     finalUnits); 
102             
103         } else if (this.getUnits().isCompatible(finalUnits)) { 
104             //they are compatible but conversion needed. 
105             double ownValue = this.getUnits(). 
106             convertTo(this.getValue(), finalUnits); 
107             
108             valueOfSum = ownValue + measuredValue.getValue(); 
109             
110             ownValue = this.getUnits().convertTo(this.getStandardDeviation(), finalUnits); 
111             standardDeviationOfSum = Math.sqrt(
112                     Math.pow(ownValue, 2) +  
113                     Math.pow(measuredValue.getStandardDeviation(), 2)); 
114             
115             sumMeasuredValue = new MeasuredValue(valueOfSum,  
116                     standardDeviationOfSum, 
117                     measuredValue.getUnits()); 
118         }//else units are not compatible. (TODO - throw an exception)
119         
120         return sumMeasuredValue; 
121     } 
122     
123     /*** add a <code>MeasuredValue</code> to this and return the sum (if it exists) 
124      * @param unitValue
125      * @return sum of this and <code>unitValue</code>
126      */
127     public MeasuredValue add(UnitValue unitValue) {  
128         return add(new MeasuredValue(unitValue));
129     }
130     
131     /*** add a <code>MeasuredValue</code> to this and return the sum (if it exists) 
132      * @param unitValue
133      * @return sum of this and <code>unitValue</code>
134      */
135     public MeasuredValue subtract(UnitValue unitValue) {  
136         return subtract(new MeasuredValue(unitValue));
137     }
138     
139     /*** subtract a <code>MeasuredValue</code> from this and return the difference (if it exists)  
140      
141      @param measuredValue 
142      
143      @return differenceMeasuredValue 
144      
145      */ 
146     public MeasuredValue subtract(MeasuredValue measuredValue) { 
147         MeasuredValue differenceMeasuredValue = null; 
148         Unit finalUnits = measuredValue.getUnits(); 
149         double valueOfDifference; 
150         double standardDeviationOfDifference; 
151         
152         if (this.getUnits().equals(finalUnits)) { 
153             //If Units are the same not need to convert. 
154             valueOfDifference = this.getValue() - measuredValue.getValue(); 
155             standardDeviationOfDifference = Math.sqrt(
156                     Math.pow(this.getStandardDeviation(), 2) +  
157                     Math.pow(measuredValue.getStandardDeviation(), 2) 
158             ); 
159             differenceMeasuredValue = new MeasuredValue(
160                     valueOfDifference,  
161                     standardDeviationOfDifference, 
162                     finalUnits); 
163             
164         } else if (this.getUnits().isCompatible(measuredValue.getUnits())) { 
165             //conversion between units is necessary 
166             double ownValue = this.getUnits(). 
167             convertTo(this.getValue(), finalUnits); 
168             valueOfDifference = ownValue - measuredValue.getValue(); 
169             
170             ownValue = this.getUnits().convertTo(this.getStandardDeviation(), finalUnits); 
171             standardDeviationOfDifference = Math.sqrt(
172                     Math.pow(ownValue, 2) +  
173                     Math.pow(measuredValue.getStandardDeviation(), 2)); 
174             
175             differenceMeasuredValue = new MeasuredValue(
176                     valueOfDifference,  
177                     standardDeviationOfDifference, 
178                     finalUnits); 
179         }//else units are not compatible.  (TODO - throw an exception)
180         
181         return differenceMeasuredValue; 
182     } 
183     
184     
185     /*** multiply a <code>double</code> to this and return the product 
186      * @param scalarMultiplier
187      * @return productMeasuredValue
188      */
189     public MeasuredValue multiply(double scalarMultiplier) {
190         MeasuredValue productMeasuredValue = null;
191         
192         Unit unitsOfProduct = this.getUnits();
193         double valueOfProduct = this.getValue() * scalarMultiplier;
194         double standardDeviationOfProduct = this.getStandardDeviation() * scalarMultiplier;
195         
196         productMeasuredValue = new MeasuredValue(valueOfProduct, 
197                 standardDeviationOfProduct,
198                 unitsOfProduct);
199         
200         return productMeasuredValue;
201     }
202     
203     /*** multiply a <code>MeasuredValue</code> to this and return the product 
204      
205      @param measuredValue
206      
207      @return productMeasuredValue
208      
209      */
210     public MeasuredValue multiply(MeasuredValue measuredValue) {
211         MeasuredValue productMeasuredValue = null;
212         
213         Unit unitsOfProduct = Unit.createUnit(this.getUnits().getUnitName() + measuredValue.getUnits().getUnitName()); // TODO - how do we deal with units commuting? (since u1*u2 == u2*u1) 
214         double valueOfProduct = this.getValue() * measuredValue.getValue(); 
215         double standardDeviationOfProduct = Math.sqrt(Math.pow(this.getStandardDeviation() *
216                 measuredValue.getValue(), 
217                 2) + 
218                 Math.pow(measuredValue.getStandardDeviation() *
219                         this.getValue(), 
220                         2));
221         
222         productMeasuredValue = new MeasuredValue(valueOfProduct, 
223                 standardDeviationOfProduct,
224                 unitsOfProduct);
225         
226         return productMeasuredValue;
227     }
228     
229     /*** divide this by a <code>MeasuredValue</code> and return the result  
230      * 
231      * @param measuredValue 
232      * 
233      * @return <code>this</code> / <code>measuredValue</code> 
234      */ 
235     public MeasuredValue divide(MeasuredValue measuredValue) { 
236         MeasuredValue divisionMeasuredValue = null; 
237         Unit finalUnits = null; 
238         double valueOfDivision; 
239         double standardDeviationOfDivision; 
240         
241         if (this.getUnits().isCompatible(measuredValue.getUnits())){ 
242             
243             double ownValue = this.getUnits().convertTo(this.getValue(), measuredValue.getUnits()); 
244             finalUnits = Unit.createUnit(""); 
245             
246             valueOfDivision = ownValue / measuredValue.getValue(); 
247             double ownStandardDeviation = this.getUnits().convertTo(this.getStandardDeviation(), measuredValue.getUnits());
248            
249             standardDeviationOfDivision = Math.sqrt(
250                     Math.pow(ownStandardDeviation, 2) + 
251                     Math.pow(measuredValue.getStandardDeviation()*ownValue/measuredValue.getValue(),2)
252                     ) / measuredValue.getValue();
253             
254             
255         } else {
256             valueOfDivision = this.getValue() / measuredValue.getValue();;
257                 
258             finalUnits = Unit.createUnit(this.getUnits() + "/" + measuredValue.getUnits());
259             standardDeviationOfDivision = Math.sqrt(
260                     Math.pow(this.getStandardDeviation(), 2) + 
261                     Math.pow(measuredValue.getStandardDeviation()*this.getValue()/measuredValue.getValue(),2)
262                     ) / measuredValue.getValue();
263         }
264 
265         divisionMeasuredValue = new MeasuredValue(
266                 valueOfDivision, 
267                 standardDeviationOfDivision,
268                 finalUnits);
269         
270         return divisionMeasuredValue; 
271     } 
272     
273     /*** return the nth power of this <code>MeasuredValue</code>       
274      * @param power      
275      * @return powerOfMeasuredValue      
276      */ 
277     public MeasuredValue raiseToPower(double power) { 
278         MeasuredValue powerOfMeasuredValue = null; 
279         
280         double valueOfPower = Math.pow(this.getValue(),  
281                 power);  
282         
283         double standardDeviationOfPower = this.getStandardDeviation() * power * Math.pow(this.getValue(), power - 1); 
284         
285         Unit unitsOfPower = Unit.createUnit(this.getUnits().getUnitName() + "^" + power); // TODO - need a better way to deal with this ((a^b)^c == (a^c)^b == a^(b + c))
286         
287         powerOfMeasuredValue = new MeasuredValue(valueOfPower,  
288                 standardDeviationOfPower, 
289                 unitsOfPower); 
290         
291         return powerOfMeasuredValue; 
292     }    
293     
294     private double standardDeviation;
295     
296     /***
297      * @see java.lang.Object#equals(java.lang.Object)
298      */
299     public boolean equals(Object object) {
300         if (object.getClass().getName().equals(this.getClass().getName())) {
301             MeasuredValue comparisonMeasuredValue = (MeasuredValue)object;
302             
303             if (comparisonMeasuredValue.getUnits().isCompatible(this.getUnits())) {
304                double comparisonUnitValueInThisUnits = this.getUnits().convertTo(comparisonMeasuredValue.getValue(), this.getUnits());
305                
306                if  (comparisonUnitValueInThisUnits == this.getValue()) { // TODO - add a cutoff for equality (we may want to consider these equal even if the values aren't exactly identical)
307                    return true;
308                }
309             }
310         }
311         
312         return false;
313     } 
314     
315     /***
316      @param standardDeviation
317      */
318     public void setStandardDeviation(double standardDeviation) {
319         this.standardDeviation = standardDeviation;
320     }
321     
322     /***
323      @return standardDeviation
324      */
325     public double getStandardDeviation() {
326         return this.standardDeviation;
327     }
328     
329     /***
330      @return stringValue
331      */
332     public String toString() {
333         return "" + getValue() + "+- " + getStandardDeviation() + " (" + getUnits().toString() + ")";  
334     }
335 }