Initial commit of Matt's measurement add-in for OpenOffice.org Calc.
[measurements/measurements.git] / src / net / mattmccutchen / measurements / MeasurementMath.java
1 package net.mattmccutchen.measurements;
2
3 public class MeasurementMath {
4         public static boolean unitsSame(Measurement a, Measurement b) {
5                 for (int i = 0; i < Unit.basicUnits.length; i++)
6                         if (a.unitPowers[i] != b.unitPowers[i])
7                                 return false;
8                 return true;
9         }
10         
11         public static boolean isPureNumber(Measurement a) {
12                 for (int i = 0; i < Unit.basicUnits.length; i++)
13                         if (a.unitPowers[i] != 0)
14                                 return false;
15                 return true;
16         }
17         
18         public static Measurement neg(Measurement a) {
19                 if (a == null)
20                         return null;
21                 return new Measurement(-a.number, a.uncertainty, a.unitPowers);
22         }
23         
24         public static Measurement add(Measurement a, Measurement b) {
25                 if (a == null || b == null || !unitsSame(a, b))
26                         return null;
27                 return new Measurement(a.number + b.number,
28                         a.uncertainty + b.uncertainty, a.unitPowers);
29         }
30         
31         public static Measurement sub(Measurement a, Measurement b) {
32                 if (a == null || b == null || !unitsSame(a, b))
33                         return null;
34                 return new Measurement(a.number - b.number,
35                         a.uncertainty + b.uncertainty, a.unitPowers);
36         }
37         
38         public static Measurement mul(Measurement a, Measurement b) {
39                 if (a == null || b == null)
40                         return null;
41                 int[] up = new int[Unit.basicUnits.length];
42                 for (int i = 0; i < Unit.basicUnits.length; i++)
43                         up[i] = a.unitPowers[i] + b.unitPowers[i];
44                 return new Measurement(a.number * b.number,
45                         a.uncertainty * Math.abs(b.number)
46                         + b.uncertainty * Math.abs(a.number),
47                         up);
48         }
49         
50         public static Measurement div(Measurement a, Measurement b) {
51                 if (a == null || b == null)
52                         return null;
53                 int[] up = new int[Unit.basicUnits.length];
54                 for (int i = 0; i < Unit.basicUnits.length; i++)
55                         up[i] = a.unitPowers[i] - b.unitPowers[i];
56                 return new Measurement(a.number / b.number,
57                         // Compare to quotient rule for differentiation
58                         a.uncertainty / Math.abs(b.number)
59                         + Math.abs(a.number) * b.uncertainty / (b.number * b.number),
60                         up);
61         }
62         
63         public static Measurement powint(Measurement a, int b) {
64                 if (a == null)
65                         return null;
66                 int[] up = new int[Unit.basicUnits.length];
67                 for (int i = 0; i < Unit.basicUnits.length; i++)
68                         up[i] = a.unitPowers[i] * b;
69                 return new Measurement(Math.pow(a.number, b),
70                         b * a.uncertainty * Math.pow(a.number, b-1),
71                         up);
72         }
73         
74         public static Measurement pow(Measurement a, Measurement b) {
75                 if (a == null || !isPureNumber(a) || b == null || !isPureNumber(b))
76                         return null;
77                 return new Measurement(Math.pow(a.number, b.number),
78                         b.number * a.uncertainty * Math.pow(a.number, b.number-1)
79                         // think: derivative of e^(b ln a) is b' (ln a) e^(b ln a)
80                         + b.uncertainty * Math.log(a.number) * Math.pow(a.number, b.number),
81                         Measurement.pureNumberUnitPowers);
82         }
83         
84         public static double cmp(Measurement a, Measurement b) {
85                 if (a == null || b == null || !unitsSame(a, b))
86                         return Double.NaN;
87                 return (a.number - b.number) / (a.uncertainty + b.uncertainty);
88         }
89 }