Initial commit of Matt's measurement add-in for OpenOffice.org Calc.
[measurements/measurements.git] / src / net / mattmccutchen / measurements / MeasurementMath.java
CommitLineData
3f5430db
MM
1package net.mattmccutchen.measurements;
2
3public 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}