python牛顿法求一元多次函数极值
现在用牛顿法来实现一元函数求极值问题
首先给出这样一个问题,如果有这么一个函数$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牛顿法求一元多次函数极值的更多相关文章
- Python编写“求一元二次方程的解”
#求一元二次方程的解 import math def equation(a,b,c): h=b*b-4*a*c #一元二次方程的解,百度来的 if h>=0: x1=(-b+math.sqrt( ...
- 【Python实践-1】求一元二次方程的两个解
知识点: import sys, sys模块包含了与Python解释器和它的环境有关的函数. “sys”是“system”的缩写.sys.exit() 中途退出程序, (注:0是正常退出,其他为不正常 ...
- python二分法、牛顿法求根
二分法求根 思路:对于一个连续函数,左值f(a)*右值f(b)如果<0,那么在这个区间内[a,b]必存在一个c使得f(c)=0 那么思路便是取中间点,分成两段区间,然后对这两段区间分别再比较,跳 ...
- [洛谷U62364]三次函数极值
U62364 三次函数极值 题面 给定一个三次函数\(f(x)=a_3x^3+a_2x^2+a_1x+a_0\) 求其极值. 格式 输入包括一行四个整数\(a_3,a_2,a_1,a_0\) 输出包括 ...
- Python学习【第九篇】函数
函数 函数是什么? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上而下实现功能,其往往用一段代码来实现指定功能,开发过 ...
- 翻译《Writing Idiomatic Python》(二):函数、异常
原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...
- MATLAB学习笔记(七)——MATLAB解方程与函数极值
(一)线性方程组求解 包含n个未知数,由n个方程构成的线性方程组为: 其矩阵表示形式为: 其中 一.直接求解法 1.左除法 x=A\b; 如果A是奇异的,或者接近奇异的.MATLAB会发出警告信息的. ...
- OpenJudge计算概论-求一元二次方程的根【含复数根的计算、浮点数与0的大小比较】
/*====================================================================== 求一元二次方程的根 总时间限制: 1000ms 内存限 ...
- Python学习入门教程,字符串函数扩充详解
因有用户反映,在基础文章对字符串函数的讲解太过少,故写一篇文章详细讲解一下常用字符串函数.本文章是对:程序员带你十天快速入门Python,玩转电脑软件开发(三)中字符串函数的详解与扩充. 如果您想学习 ...
随机推荐
- (stm32学习总结)—对寄存器的理解 _
芯片里面有什么 我们看到的 STM32 芯片是已经封装好的成品,主要由内核和片上外设组成.若与电脑类比,内核与外设就如同电脑上的 CPU 与主板.内存.显卡.硬盘的关系.STM32F103 采用的是 ...
- 前端面试题整理——手写flatern摊平数组
// flatern 是摊平数组 function flat(arr) { const isDeep = arr.some(item => item instanceof Array) if(! ...
- python-逆序输出
输入一行字符串,然后对其进行如下处理. 输入格式: 字符串中的元素以空格或者多个空格分隔. 输出格式: 逆序输出字符串中的所有元素.然后输出原列表.然后逆序输出原列表每个元素,中间以1个空格分隔.注意 ...
- Android Studio安装问题
安装问题可以参考:https://blog.csdn.net/y74364/article/details/96121530 但是gradle安装缓慢,需要FQ.有加速器FQ的可以开加速器安装,没有的 ...
- Node的重要性
一. 为什么要学Node 1. 是自己更全面, 有大局观 2. 提升话语权 3. 升职加薪的筹码 二. Node的作用和应用 1. 脱离浏览器运行 js 2. 后台API编写 3. webpack, ...
- java基础-java异常处理
异常* A:异常的概述 * 异常就是Java程序在运行过程中出现的错误.* B:异常的分类 * Error:服务器宕机,数据库崩溃等 * ExceptionC:异常的继承体系 * Throwable ...
- EMS邮件统计
前提条件:管理员拥有"Organization Management"权限.并且启用邮件跟踪日志. 1.统计时间段内邮件发送情况 案例任务:统计一段时间内服务器"MAIL ...
- Java安全之Commons Collections6分析
Java安全之Commons Collections6分析 0x00 前言 其实在分析的几条链中都大致相同,都是基于前面一些链的变形,在本文的CC6链中,就和前面的有点小小的区别.在CC6链中也和CC ...
- c++对c的拓展_using
using 声明:使指定标识符可用 注意:与其他同名标识符有作用域冲突时产生二义性即报错 using 编辑指令: 使整个命名空间标识符可用 注意:与其他同名标识符作用域发生冲突使时优先使用局部变量 ...
- Oracle集群 & Grid(rac)配置,反推创建过程(重要)。
目前机器上,oracle都是安装好的,那么我们怎么知道,之前的安装过程大概是什么样子呢? 大致安装oracle集群的内容: 一.准备和配置: 1.网卡 2.ip资源 3.scanip 4.hosts ...