Remember last value returned from a JDK 8 lambda

Viewed 351

I threw together a quick Java implementation of a Taylor series expansion for the exponential function, because it was easy and fun:

package math.series;

import java.util.stream.IntStream;

/**
 * Created by Michael
 * Creation date 3/6/2016.
 * @link https://stackoverflow.com/questions/35826081/calculating-ex-in-c-sharp
 * @link https://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80
 */
public class TaylorSeries {


    public static final int DEFAULT_NUM_TERMS = 10;

    public static void main(String[] args) {
        int n = (args.length > 0) ? Integer.parseInt(args[0]) : DEFAULT_NUM_TERMS;
        System.out.println("pi");
        System.out.println(String.format("%10s %10s %10s %10s", "n", "series", "expected", "error"));
        double expected = Math.PI;
        double series = TaylorSeries.pi(0.0, n);
        double error = expected - series;
        System.out.println(String.format("%10d %10.6f %10.6f %10.6f", n, series, expected, error));

        System.out.println("exp");
        System.out.println(String.format("%10s %10s %10s %10s", "x", "series", "expected", "error"));
        for (double x = 0.0; x <= 3.0; x += 0.25) {
            expected = Math.exp(x);
            series = TaylorSeries.exp(x, n);
            error = expected - series;
            System.out.println(String.format("%10.6f %10.6f %10.6f %10.6f", x, series, expected, error));
        }
    }

    public static double exp(double x, int n) {
        double sum = 1.0;
        double term = 1.0;
        for (int i = 1; i <= n; ++i) {
            term *= x / i;
            sum += term;
        }
        return sum;
    }

    public static double pi(double x, int n) {
        return IntStream.range(0, n)
                .mapToDouble(i -> 8.0/(4*i+1)/(4*i+3))
                .sum();
    }
}

I'm ashamed to admit that my employer is still using JDK 6 and JDK 7; I'm not writing on JDK 8 during my work day yet. I have not groked all new features in the JDK, including lambdas.

I warmed up by writing a Taylor series expansion for pi using lambda. It's easy and elegant. Surprisingly, it requires a million terms to converge to six digits of accuracy, but that's the nature of the series.

I decided to try and implement the exponential function using a lambda. I don't want to do the naive thing and use the Math.pow or factorial functions; the implementation I posted without lambdas accomplishes both nicely.

I can't see how to have each step in the lambda remember what the value of the previous term was. Can anyone help a lambda beginner and give an example?

5 Answers
Related