45.5 Error Analysis and Performance

Quantify accuracy, ensure convergence, and measure performance of numerical algorithms.


45.5.1 Error Bounds

// Absolute error
double absError(double computed, double exact) {
  return Math.abs(computed - exact);
}

// Relative error
double relError(double computed, double exact) {
  return Math.abs((computed - exact) / exact);
}

// ULP distance
long ulpDiff(double a, double b) {
  return Math.abs(Double.doubleToLongBits(a) - Double.doubleToLongBits(b));
}

45.5.2 Convergence Criteria

boolean converged(double xOld, double xNew, double absTol, double relTol) {
  double diff = Math.abs(xNew - xOld);
  return diff < absTol || diff / Math.max(Math.abs(xNew), 1e-10) < relTol;
}

45.5.3 JMH Benchmark Sketch

// Requires org.openjdk.jmh:jmh-core and jmh-generator-annprocess
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
public class MathBench {
  double x = 1.234;

  @Benchmark public double mathSin() { return Math.sin(x); }
  @Benchmark public double strictMathSin() { return StrictMath.sin(x); }
  @Benchmark public double mathExp() { return Math.exp(x); }
  @Benchmark public double mathLog() { return Math.log(x); }
}

45.5.4 Validation Strategies

// Test known values
assert Math.abs(Math.sin(Math.PI / 2) - 1.0) < 1e-14;
assert Math.abs(Math.exp(0) - 1.0) < 1e-14;

// Test identities
double x = 0.5;
assert Math.abs(Math.sin(x)*Math.sin(x) + Math.cos(x)*Math.cos(x) - 1.0) < 1e-14;

// Compare against reference
// e.g., Apache Commons Math, GNU Scientific Library results

45.5.5 Precision Tips

  • Use Math.fma(a, b, c) for fused multiply-add (a*b + c) with one rounding
  • Prefer Math.expm1 and Math.log1p for small arguments
  • Avoid subtracting nearly equal numbers (catastrophic cancellation)
  • Scale inputs to avoid overflow/underflow when possible

45.5.6 Performance Considerations

  • Math functions are JVM intrinsics (fast)
  • Repeated calls dominate loop overhead; consider vectorization (Chapter 41)
  • Lookup tables (LUTs) for trig at fixed angles
  • Polynomial approximations for custom ranges