package net.mattmccutchen.measurements; public class MeasurementMath { public static boolean unitsSame(Measurement a, Measurement b) { for (int i = 0; i < Unit.basicUnits.length; i++) if (a.unitPowers[i] != b.unitPowers[i]) return false; return true; } public static boolean isPureNumber(Measurement a) { for (int i = 0; i < Unit.basicUnits.length; i++) if (a.unitPowers[i] != 0) return false; return true; } public static Measurement neg(Measurement a) { if (a == null) return null; return new Measurement(-a.number, a.uncertainty, a.unitPowers); } public static Measurement add(Measurement a, Measurement b) { if (a == null || b == null || !unitsSame(a, b)) return null; return new Measurement(a.number + b.number, a.uncertainty + b.uncertainty, a.unitPowers); } public static Measurement sub(Measurement a, Measurement b) { if (a == null || b == null || !unitsSame(a, b)) return null; return new Measurement(a.number - b.number, a.uncertainty + b.uncertainty, a.unitPowers); } public static Measurement mul(Measurement a, Measurement b) { if (a == null || b == null) return null; int[] up = new int[Unit.basicUnits.length]; for (int i = 0; i < Unit.basicUnits.length; i++) up[i] = a.unitPowers[i] + b.unitPowers[i]; return new Measurement(a.number * b.number, a.uncertainty * Math.abs(b.number) + b.uncertainty * Math.abs(a.number), up); } public static Measurement div(Measurement a, Measurement b) { if (a == null || b == null) return null; int[] up = new int[Unit.basicUnits.length]; for (int i = 0; i < Unit.basicUnits.length; i++) up[i] = a.unitPowers[i] - b.unitPowers[i]; return new Measurement(a.number / b.number, // Compare to quotient rule for differentiation a.uncertainty / Math.abs(b.number) + Math.abs(a.number) * b.uncertainty / (b.number * b.number), up); } public static Measurement powint(Measurement a, int b) { if (a == null) return null; int[] up = new int[Unit.basicUnits.length]; for (int i = 0; i < Unit.basicUnits.length; i++) up[i] = a.unitPowers[i] * b; return new Measurement(Math.pow(a.number, b), b * a.uncertainty * Math.pow(a.number, b-1), up); } public static Measurement pow(Measurement a, Measurement b) { if (a == null || !isPureNumber(a) || b == null || !isPureNumber(b)) return null; return new Measurement(Math.pow(a.number, b.number), b.number * a.uncertainty * Math.pow(a.number, b.number-1) // think: derivative of e^(b ln a) is b' (ln a) e^(b ln a) + b.uncertainty * Math.log(a.number) * Math.pow(a.number, b.number), Measurement.pureNumberUnitPowers); } public static double cmp(Measurement a, Measurement b) { if (a == null || b == null || !unitsSame(a, b)) return Double.NaN; return (a.number - b.number) / (a.uncertainty + b.uncertainty); } }