# Calculus via Lambdas in Java 8

Consider the following functional interface:

package com.michaelcotterell.math; import static java.lang.Math.abs; import java.util.function.Function; /** * A function that maps Real values to Real values. Here, the term "Real" is * equivalent to <code>double</code>. This functional interface allows users to * easily take derivatives and find zeros of the function using established * techniques. * * <p> * This interface is intended to be used with lambda expressions in order to * provide easy access to it's default methods. * * @author Michael E. Cotterell <mepcotterell@gmail.com> */ @FunctionalInterface public interface RealFunction extends Function<Double, Double> { /** The value used for determining if two <code>double</code> values are essentially equal. */ public static final double EPSILON = 1E-11; /** The half-width uses for two-sided differentiation. */ public static final double H = EPSILON; /** * Estimate the derivative of the function at <code>x</code> using a * two-sided method (central difference). * * @param x the point at which to estimate the derivative * @return derivative of the function evaluated at <code>x</code> (estimate) */ default double derivative(double x) { return derivative().apply(x); } // derivative /** * Returns the first derivative of the function. * * @return first derivative */ default RealFunction derivative() { return x -> (apply(x + H) - apply(x - H)) / ((x + H) - (x - H)); } // derivative /** * Find the root (zero ) of this {@link com.michaelcotterell.math.RealFunction} * using Newton's method, given a <code>guess</code> of where the root is. * This implementation of Newton's method finds an approximation to the * root of the function using enough consecutive terms of the function's * Taylor series such that the value of the function at the estimated root * is essentially zero using {@link com.michaelcotterell.math.Constants#EPSILON}. * * @param guess a guess of where the root is * @return the root of the function, using Newton's method */ default double zero(double guess) { double x = guess; while (abs(apply(x)) > EPSILON) x = x - apply(x) / derivative(x); return x; } // newtonZero /** * Find the root (zero ) of this {@link com.michaelcotterell.math.RealFunction} * using Newton's method. This implementation of Newton's method finds an * approximation to the root of the function using enough consecutive terms * of the function's Taylor series such that the value of the function at * the estimated root is essentially zero using * {@link com.michaelcotterell.math.Constants#EPSILON}. * * <p> * This particular method sets the initial guess of where the root is to 10. * * @return the root of the function, using Newton's method */ default double zero() { return zero(10); } // newtonZero } // RealFunction

With this functional interface, we can take derivatives of functions expressed as lambda expressions:

RealFunction f = x -> x * x; RealFunction df = f.derivative(); System.out.println(df.apply(4.0)); // ~ 8.0 System.out.println(df.apply(4.5)); // ~ 9.0

Here is a neat implementation of finding the positive square root of a number using Newton's method (as implemented by the default method zero in the interface):

/** * Return the positive square root of <code>n</code> using Newton's method. * * @param n a value * @return the positive square root of <code>n</code> */ public static double sqrt(double n) { RealFunction f = x -> x * x - n; // the square root function double guess = 0.3 * n; // arbitrary starting place; seemed good return f.zero(guess); } // sqrt