现在用牛顿法来实现一元函数求极值问题

首先给出这样一个问题,如果有这么一个函数$f(x) = x^6+x$,那么如何求这个函数的极值点

先在jupyter上简单画个图形

%matplotlib inline
import numpy as np
x = np.linspace(-1.3,1.3,1000)
plt.scatter(x,x**6+x)
plt.show()

用牛顿法求极值的话,那就要用到泰勒展开

$f(x) \approx f(x_0)+f'(x_0)(x-x_0)+\frac{1}{2}f''(x_0){(x-x_0)}^2$

注意,这里的$x_0$是一个起始点,我们要求$x$,而极值点必须要$f'(x)=0$,而不是这里面的$f'(x_0)=0$,所以这里我们左右两边进行求导,得到

$f'(x)=f'(x_0)+f''(x_0)(x-x_0)$

这里令$f'(x)=0$,则$f'(x_0)+f''(x_0)(x-x_0)=0$,那么即可得到$x = x_0-\frac{f'(x_0)}{f''(x_0)}$,一直迭代则得到

$x_{n+1} = x_n-\frac{f'(x_n)}{f''(x_n)}$

那么我们可以设置一个精度,如果在精度范围内,即可停止迭代

# 牛顿法求极值
# 函数为x**6+x
# orgin函数是初始函数
def func_origin(x):
result = x**6+x
return result # first是一阶导函数
def func_first(x):
result = 6*x**5+1
return result # second是二阶导函数
def func_second(x):
result = 30*x**4
return result # 迭代,传入精度和初始给定值
def newton(accuracy,x):
count = 1
new_x = x
acc = accuracy + 1
while acc > accuracy:
print("final %d round is %.6f"%(count,new_x))
acc = abs(func_first(new_x))
# print("acc",acc)
x_origin = func_origin(new_x)
x_first = func_first(new_x)
x_second = func_second(new_x)
new_x = new_x - x_first/x_second
count += 1
newton(1e-06,10)

final 1 round is 10.000000
final 2 round is 7.999997
...
final 35 round is -0.698860
final 36 round is -0.698827

同时,因为二阶导可能为0,又或者其他原因,实际上我们可能不去计算二阶导,而把二阶导设置为定值(本例不太适用,可尝试更改一下看看结果)

尝试另外一例,函数为:$f(x) = -x^2+4x$,那么其一阶导为$-2x+4$,其二阶导为$-2$

# 牛顿法求极值
# 函数为-x**2+4*x
# orgin函数是初始函数
def func_origin(x):
result = -x**2+4*x
return result # first是一阶导函数
def func_first(x):
result = -2*x+4
return result # second是二阶导函数
def func_second(x):
return -2 # 迭代,传入精度和初始给定值
def newton(accuracy,x):
count = 1
new_x = x
acc = accuracy + 1
while acc > accuracy:
print("final %d round is %.6f"%(count,new_x))
acc = abs(func_first(new_x))
# print("acc",acc)
x_origin = func_origin(new_x)
x_first = func_first(new_x)
x_second = func_second(new_x)
new_x = new_x - x_first/x_second
count += 1

在这里我们发现不论初始值设为多少,都是两步到达终点,究其原因,一元二次函数太过简单,非常容易求,比如修改一元二次函数为$f(x) = -4x^2+4x$

# 牛顿法求极值
# 函数为-x**2+4*x
# orgin函数是初始函数
def func_origin(x):
result = -4*x**2+4*x
return result # first是一阶导函数
def func_first(x):
result = -8*x+4
return result # second是二阶导函数
def func_second(x):
return -8 # 迭代,传入精度和初始给定值
def newton(accuracy,x):
count = 1
new_x = x
acc = accuracy + 1
while acc > accuracy:
print("final %d round is %.6f"%(count,new_x))
acc = abs(func_first(new_x))
# print("acc",acc)
x_origin = func_origin(new_x)
x_first = func_first(new_x)
x_second = func_second(new_x)
new_x = new_x - x_first/x_second
count += 1
newton(1e-06,1.3)

final 1 round is 1.300000
final 2 round is 0.500000

如果还要深究的话,想要弄明白为什么前面的一元六次函数要迭代那么多次,而一元二次函数总是只要两次

就需要弄明白泰勒展开,因为一开始我们的一元六次对应的泰勒展开,是近似的,实际上展开的三次及以上被我们抛弃了

而这些三次项,在我们后面的一元二次函数中,是高阶无穷小,舍去对结果无影响,自然只需要两次即可

牛顿法在西瓜书上公式3.29中就有应用,就是用的当前点减去二阶导分之一阶导

python牛顿法求一元多次函数极值的更多相关文章

  1. Python编写“求一元二次方程的解”

    #求一元二次方程的解 import math def equation(a,b,c): h=b*b-4*a*c #一元二次方程的解,百度来的 if h>=0: x1=(-b+math.sqrt( ...

  2. 【Python实践-1】求一元二次方程的两个解

    知识点: import sys, sys模块包含了与Python解释器和它的环境有关的函数. “sys”是“system”的缩写.sys.exit() 中途退出程序, (注:0是正常退出,其他为不正常 ...

  3. python二分法、牛顿法求根

    二分法求根 思路:对于一个连续函数,左值f(a)*右值f(b)如果<0,那么在这个区间内[a,b]必存在一个c使得f(c)=0 那么思路便是取中间点,分成两段区间,然后对这两段区间分别再比较,跳 ...

  4. [洛谷U62364]三次函数极值

    U62364 三次函数极值 题面 给定一个三次函数\(f(x)=a_3x^3+a_2x^2+a_1x+a_0\) 求其极值. 格式 输入包括一行四个整数\(a_3,a_2,a_1,a_0\) 输出包括 ...

  5. Python学习【第九篇】函数

    函数 函数是什么? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上而下实现功能,其往往用一段代码来实现指定功能,开发过 ...

  6. 翻译《Writing Idiomatic Python》(二):函数、异常

    原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...

  7. MATLAB学习笔记(七)——MATLAB解方程与函数极值

    (一)线性方程组求解 包含n个未知数,由n个方程构成的线性方程组为: 其矩阵表示形式为: 其中 一.直接求解法 1.左除法 x=A\b; 如果A是奇异的,或者接近奇异的.MATLAB会发出警告信息的. ...

  8. OpenJudge计算概论-求一元二次方程的根【含复数根的计算、浮点数与0的大小比较】

    /*====================================================================== 求一元二次方程的根 总时间限制: 1000ms 内存限 ...

  9. Python学习入门教程,字符串函数扩充详解

    因有用户反映,在基础文章对字符串函数的讲解太过少,故写一篇文章详细讲解一下常用字符串函数.本文章是对:程序员带你十天快速入门Python,玩转电脑软件开发(三)中字符串函数的详解与扩充. 如果您想学习 ...

随机推荐

  1. zookeeper 负载均衡和 nginx 负载均衡区别?

    zk 的负载均衡是可以调控,nginx 只是能调权重,其他需要可控的都需要自己写插件:但是 nginx 的吞吐量比 zk 大很多,应该说按业务选择用哪种方式.

  2. piwik安装部署

    1.piwik介绍 Piwik是一个PHP和MySQL的开放源代码的Web统计软件,它给你一些关于你的网站的实用统计报告,比如网页浏览人数,访问最多的页面,搜索引擎关键词等等. Piwik拥有众多不同 ...

  3. C语言泛型编程——泛型冒泡排序

    在实际编程中,常常会需要一些方法(函数),比如排序,它们具体实现基本一致,仅仅只有参数类型不同, 那么可不可以有一种通用的函数,不管是什么类型的参数都可以通用呢? 泛型编程:泛型即是指具有在多种数据类 ...

  4. 制作任意波形发生器MAX038

  5. JS:数组中push对象,覆盖问题

    发现将对象push进数组,后面的值会覆盖前面的值,最后输出的都是最后一次的值.其实这一切都是引用数据类型惹的祸.如果你也有类似问题,可以继续看下去哦.下面代码模拟:将json对象的每个键值对,单独搞成 ...

  6. SpringCloud微服务治理技术入门(SCN)

    1.集群.分布式.微服务 首先先理解三个感念 什么是集群?: 同一个业务,部署在多个服务器上,目的是实现高可用,保证节点可用! 什么是分布式?: 一个业务分拆成多个子业务,部署在不同的服务器上,每个子 ...

  7. Android回到页面并刷新数据

    通过对Android Activity的生命周期的了解,需要在后退页面重写onResume()的方法. 建立自己更新数据的函数,并在onCreate()方法中调用. @Override protect ...

  8. vue中图片预览(v-viewer库使用)

    效果图:   注释: 可拖拽,可放大缩小旋转,全屏,功能齐全,底部有操作按钮 属性: npm install v-viewer --save //安装 //在main.js中引入 import Vie ...

  9. Mybatis插入数据

    对上文->Mybatis快速入门-<进行代码修改 1.在UserMapper.xml中添加插入操作 <!-- 插入操作--> <insert id="save& ...

  10. JavaWeb知识梳理(可收藏)

    **JavaWeb相关知识 ** 1.Servlet 1.1 Status Code(Http状态码) 1.1xx 请求信息 Http状态码 Http Status Code Http状态码含义中文说 ...