Project/build/packaging adjustments + version 1.3
[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 rootint(Measurement a, int b) {
75                 if (a == null)
76                         return null;
77                 int[] up = new int[Unit.basicUnits.length];
78                 for (int i = 0; i < Unit.basicUnits.length; i++) {
79                         if (Math.abs(a.unitPowers[i]) % b != 0)
80                                 return null;
81                         up[i] = a.unitPowers[i] / b;
82                 }
83                 return new Measurement(Math.pow(a.number, 1.0/b),
84                         a.uncertainty / b * Math.pow(a.number, (1.0/b)-1),
85                         up);
86         }
87         
88         public static Measurement pow(Measurement a, Measurement b) {
89                 if (a == null || !isPureNumber(a) || b == null || !isPureNumber(b))
90                         return null;
91                 return new Measurement(Math.pow(a.number, b.number),
92                         b.number * a.uncertainty * Math.pow(a.number, b.number-1)
93                         // think: derivative of e^(b ln a) is b' (ln a) e^(b ln a)
94                         + b.uncertainty * Math.log(a.number) * Math.pow(a.number, b.number),
95                         Measurement.pureNumberUnitPowers);
96         }
97         
98         public static Measurement exp(Measurement m) {
99                 if (m == null || !isPureNumber(m))
100                         return null;
101                 return new Measurement(Math.exp(m.number),
102                         m.uncertainty * Math.exp(m.number),
103                         Measurement.pureNumberUnitPowers);
104         }
105         
106         public static Measurement ln(Measurement m) {
107                 if (m == null || !isPureNumber(m))
108                         return null;
109                 return new Measurement(Math.log(m.number),
110                         m.uncertainty / m.number,
111                         Measurement.pureNumberUnitPowers);
112         }
113         
114         public static double cmp(Measurement a, Measurement b) {
115                 if (a == null || b == null || !unitsSame(a, b))
116                         return Double.NaN;
117                 return (a.number - b.number) / (a.uncertainty + b.uncertainty);
118         }
119 }