1 package net.mattmccutchen.measurements;
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])
11 public static boolean isPureNumber(Measurement a) {
12 for (int i = 0; i < Unit.basicUnits.length; i++)
13 if (a.unitPowers[i] != 0)
18 public static Measurement neg(Measurement a) {
21 return new Measurement(-a.number, a.uncertainty, a.unitPowers);
24 public static Measurement add(Measurement a, Measurement b) {
25 if (a == null || b == null || !unitsSame(a, b))
27 return new Measurement(a.number + b.number,
28 a.uncertainty + b.uncertainty, a.unitPowers);
31 public static Measurement sub(Measurement a, Measurement b) {
32 if (a == null || b == null || !unitsSame(a, b))
34 return new Measurement(a.number - b.number,
35 a.uncertainty + b.uncertainty, a.unitPowers);
38 public static Measurement mul(Measurement a, Measurement b) {
39 if (a == null || b == 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),
50 public static Measurement div(Measurement a, Measurement b) {
51 if (a == null || b == 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),
63 public static Measurement powint(Measurement a, int b) {
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),
74 public static Measurement rootint(Measurement a, int b) {
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)
81 up[i] = a.unitPowers[i] / b;
83 return new Measurement(Math.pow(a.number, 1.0/b),
84 a.uncertainty / b * Math.pow(a.number, (1.0/b)-1),
88 public static Measurement pow(Measurement a, Measurement b) {
89 if (a == null || !isPureNumber(a) || b == null || !isPureNumber(b))
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);
98 public static Measurement exp(Measurement m) {
99 if (m == null || !isPureNumber(m))
101 return new Measurement(Math.exp(m.number),
102 m.uncertainty * Math.exp(m.number),
103 Measurement.pureNumberUnitPowers);
106 public static Measurement ln(Measurement m) {
107 if (m == null || !isPureNumber(m))
109 return new Measurement(Math.log(m.number),
110 m.uncertainty / m.number,
111 Measurement.pureNumberUnitPowers);
114 public static double cmp(Measurement a, Measurement b) {
115 if (a == null || b == null || !unitsSame(a, b))
117 return (a.number - b.number) / (a.uncertainty + b.uncertainty);