之前在SICP上看到一个很厉害的东西,考虑三个问题:

计算从 a 到 b 间所有整数的和

计算从 a 到 b 间所有整数的三次方之和

求解序列

\(\frac{1}{1 \cdot 3} + \frac{1}{5 \cdot 7} + \frac{1}{9 \cdot 11} + ....\)

下面的三段代码可以分别解决这三个问题

(define (sum-integers a b)

(cond ((> a b) 0)

(else (+ a (sum-integers (+ a 1) b)))))

(define (sum-cubes a b)

(define (cube k)

(* k k k))

(cond ((> a b) 0)

(else (+ (cube a) (sum-cubes (+ a 1) b))))

)

(define (pi-sum a b)

(cond ((> a b) 0)

(else (+ (/ 1.0 (* a (+ a 2))) (pi-sum (+ a 4) b)))))

虽然解决的是不同的问题,但是在代码中却存在相似的结构,即如下所示

(define ( a b)

(cond ((> a b) 0)

(else (+ ( a) ( ( a) b)))))

也就是说,同样是求和过程,但是不同的细节操作可以表达出不同的算法需求,如果我们将特定的操作(比如func、inc) 这些函数作为参数传入高阶函数,那么就能得到更具表达力的过程。

(define (sum func inc a b)

(cond ((> a b) 0)

(else (+ (func a) (sum func inc (inc a) b)))))

使用 sum 函数作为基本构件,可以重写前面的问题,这里以第三个为例

(define (pi-sum2 a b)

(sum (lambda (x) (+ (/ 1.0 (* x (+ x 2)))))

(lambda (x) (+ x 4))

a

b))

所以这个 sum 函数就很厉害了,它可以定义一大类求和问题。考虑到许多数值积分其实也都是求和过程,例如复化梯形积分公式

\[\int_a^b f(x)\mathrm{d}x = \frac h 2 f(a) + \frac h 2 f(b) + h * \sum_{i=1}^{n-1}f(x_i),\quad h = \frac{b - a}{n}, \quad x_i = a + i h\]

下面为使用 sum 函数的代码实现

(define (integral2 f a b n)

(define h (/ (- b a) n))

(define (g i)

(f (+ a (* i h))))

(+ (* (/ h 2) (g 0))

(* (/ h 2) (g n))

(* h (sum g

(lambda (x) (+ x 1))

1

(- n 1))))

)

注意在上面的代码中,为了方便,使用了 \(g(i) = f(x_i) = f(a + i h)\)

Java 版实现

既然从 version 8 开始,Java 也支持 lambda 表达式了,那么使用 Java 写这样的函数也不是难事。首先是定义 sum 函数

double sum(Function func, Function inc,

int a, int b) {

if(a > b)

return 0;

return func.apply(a) + sum(func, inc, inc.apply(a), b);

}

为了求解效率,下面我们使用4阶的复化 Newton-Cotes 公式来求积分。有的书上直接抛出了最终的公式形态,我觉得不太适用于代码编写,所以在此之前先看看基本的 Newton-Cotes 公式

\[\int_{t}^{t + h} f(x)\mathrm{d}x = \sum_{i = 0}^m C_i^{(m)} f(x_i)\]

其中 \(x_i = t + i * d,\quad d = \frac h m\), \(C_i^{m}\) 是 m 阶 Newton-Cotes 公式的系数,若 \(m =4\),则有

\[C_i = \frac 7 {90} , \frac{32}{90} ,\frac{12}{90}, \frac{32}{90} , \frac{7}{90}, \quad i = 0,1,2,3,4\]

于是

\[\int_{t}^{t + h} f(x)\mathrm{d}x = \frac h {90} [7 f(t) + 32 f(t + d) + 12 f(t + 2d) + 32 f(t + 3d) + 7 f(t + 4d)]\]

由于基本的积分公式只在很小的区间上才能得到较精确的值。对于大段积分区间,更好的处理方式是将其分割为许多小段,然后在每个小段上应用上面的公式,这就产生了复化求积公式

\[\int_a^b f(x)\mathrm{d}x = \sum_{i=0}^{n-1} \int_{x_i}^{x_i +h} f(x)\mathrm{d}x\]

然后定义

\[g(i) = \int_{x_i}^{x_i +h} f(x)\mathrm{d}x\]

于是有

\[\int_a^b f(x)\mathrm{d}x = \sum_{i=0}^{n-1} g(i)\]

这种简单的形式非常利于代码实现,下面给出了 Java 代码

public double integral(Function f,

double a, double b, int n) {

double h = (b - a) / (double) n;

double d = h / 4.0;

Function g = i -> h / 90.0

* (7 * (f.apply(a + i * h) + f.apply(a + i * h + 4 * d))

+ 32 * (f.apply(a + i * h + d) + f.apply(a + i * h + 3 * d))

+ 12 * f.apply(a + i * h + 2 * d));

return sum(g, x -> x+1, 0, n - 1);

}

java分部积分任务代码实现_数值积分 Java 实现相关推荐

  1. java 静态代码块_关于Java你不知道的那些事之代码块

    前言 普通代码块:在方法或语句中出现的{},就被称为代码块 静态代码块:静态代码块有且仅加载一次,也就是在这个类被加载至内存的时候 普通代码块和一般语句执行顺序由他们在代码中出现的次序决定,先出现先执 ...

  2. java 金数据推送数据_基于JAVA的黄金数据接口调用代码实例

    代码描述:基于JAVA的黄金数据接口调用代码实例 接口地址:http://www.juhe.cn/docs/api/id/29 1.[代码][Java]代码 import java.io.Buffer ...

  3. 学java用什么写比较好_学习Java需要什么基础,初学Java如何写好代码

    原标题:学习Java需要什么基础,初学Java如何写好代码 初学Java的同学时常会遇到这样的情况,跟着入门教程看过一遍,但需要自己写代码的时候却无从下手:写代码的时候时常会遇到不懂的地方,如果停下来 ...

  4. java 代码封装_封装 java代码

    Java工程师必知词汇:封装 |名词定义| 封装(Encapsulation)是将数据和处理数据的程序组合起来,仅对外公开接口,达到信息隐藏的功能.封装的优点是能减少耦合.Java定义对象都是在语法中 ...

  5. java制作一个简单的画板_【Java】Thymeleaf一个简单示例

    Thymeleaf简单介绍 Thymeleaf是用来开发Web和独立环境项目的服务器端的Java模版引擎 Spring官方支持的服务的渲染模板中,并不包含jsp.而是Thymeleaf和Freemar ...

  6. java 必须try catch的异常_【java基础之异常】死了都要try,不淋漓尽致地catch我不痛快!...

    @ 1.异常 1.1 异常概念 异常 :简单说就是不正常运行,最终导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象.Java处 ...

  7. java带参数的方法笔记_具有Java参数的方法的类声明

    类声明可以包含在Java中具有参数的方法.演示此过程的程序如下: 示例class Message { public void messagePrint(String msg) { System.out ...

  8. java中随机数怎么定义类_浅析Java中的随机数类

    Java中的随机数是否可以重复?Java中产生的随机数能否可以用来产生数据库主键?带着这个问题,我们做了一系列测试. 1.测试一: 使用不带参数的Random()构造函数 * @author Carl ...

  9. java web开源项目源码_适合Java新手的开源项目集合——在 GitHub 学编程

    作者:HelloGitHub-老荀 当今互联网份额最大的编程语言是哪一个?是 Java!这两年一直有听说 Java 要不行了.在走下坡路了.没错,Java 的确在走下坡路,未来的事情的确不好说,但是瘦 ...

最新文章

  1. 可疑文件_如何识别文件的真假
  2. python输出个人信息_Python如何输出警告信息
  3. android 7.0 调用系统相机崩溃的解决方案(非谷歌官方推荐)
  4. 浅谈.Net异步编程的前世今生----异步函数篇(完结)
  5. A. And Then There Were K
  6. 邓公数据结构C++语言版学习笔记——二叉树
  7. webpack打包生成的map文件_一站式搞明白webpack中的代码分割
  8. OkHttp3详细使用教程(2)
  9. http://blog.csdn.net/u011277123/article/details/53665302
  10. JVM学习04-垃圾回收概念与算法
  11. LeetCode OJ:Linked List Cycle(链表循环)
  12. 利用Python爬虫建立自己的磁力搜索引擎
  13. 小程序 login获取出错: 40125, errmsg: invalid appSecret
  14. android ViewPager2的使用教程
  15. 扶贫?教育?地铁?这里有跨界也能实现的企业数字化新操作!
  16. 机器学习(四):剪枝技术(基础篇)
  17. 车灯线光源的优化设计matlab,车灯线光源的优化设计
  18. win10启动项在什么地方
  19. ただの南條きみつだ。
  20. 使用convert命令将pdf转成图片时遇到的一个问题

热门文章

  1. vue 判断两对象是否一致_vue - 比较两个Json对象是否相等
  2. mysql select大全_Mysql select 大全
  3. 卡内基梅隆 计算机音乐,音乐留学|卡内基梅隆音乐技术专业和申请要求详解!...
  4. 修改wifi密码后连接不上服务器,WiFi修改密码后,手机电脑连接不上
  5. jieba分词怎么操作_常用分词工具使用教程
  6. mysql数据库查询要注意事项_三种mysql高级查询技巧_数据库_mysql函数_课课家
  7. 能“社交”的机器人助理问世 可“察言观色”
  8. 集中云数据加密能否填补安全漏洞?
  9. linux 混杂设备 miscdevice设备介绍
  10. mybatis获取mysql自增主键_Mybatis获取数据库自增主键