# 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
*
* <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