duf*_*ymo 5 java lambda java-8
我为指数函数汇总了Taylor系列扩展的快速Java实现,因为它简单而有趣:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我很惭愧承认我的雇主仍在使用JDK 6和JDK 7; 我在工作期间没有写JDK 8.我还没有弄清楚JDK中的所有新功能,包括lambdas.
我通过使用lambda编写了一个针对pi的泰勒系列扩展来热身.它简单而优雅.令人惊讶的是,它需要一百万个术语才能收敛到六位精度,但这就是该系列的本质.
我决定尝试使用lambda实现指数函数.我不想做天真的事情并使用Math.pow
或factorial
功能; 我发布的没有lambdas的实现很好地完成了.
我看不出如何让lambda中的每一步都记住上一个术语的价值.任何人都可以帮助lambda初学者并举个例子吗?
一个可能的解决方案是实现一个有状态函数来返回序列中的下一项:
public static double exp(double x, int n) {
return DoubleStream.iterate(1, new DoubleUnaryOperator() {
private int i = 1;
@Override
public double applyAsDouble(double operand) {
return operand * x / i++;
}
}).limit(n).sum();
}
Run Code Online (Sandbox Code Playgroud)
这将在种子为 1 的方法和返回下一个值的函数DoubleStream
的帮助下创建,只需增加当前迭代次数并将前一个值与 相乘。流仅限于元素,并且总和通过 检索。iterate(seed, f)
i
x / i
n
limit
sum()
调用代码示例:
public static void main(String[] args) {
System.out.println(exp(3, 500)); // prints "20.085536923187668"
}
Run Code Online (Sandbox Code Playgroud)
结果非常接近真实的。
归档时间: |
|
查看次数: |
186 次 |
最近记录: |