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

首先给出这样一个问题,如果有这么一个函数$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. 详解 IOC

    什么是IOC: IOC-Inversion Of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,IOC意味着将你设计好的对象交给容器控制,而不是 ...

  2. 学习 MongoDB(一)

    1.介绍 MongoDB是C++语言编写,是一个基于分布式文件存储的开源数据库系统,MongoDB将数据存储为一个文档, 数据结构由键值对(key=>value)组成,MongoDB文档类似于 ...

  3. Django中间件 (middleware)

    中间件是处理django的请求和响应的框架级别的钩子,本质是一个类(直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作) 由于其影响的是全局,所以需要谨慎使用,使用不当会影响性 ...

  4. 攻防世界PHP2

    PHP2 进入环境就一个英文其他啥都没有,英文也没啥提示信息 我们使用dirsearch扫描一下,一开始确实没扫到什么东西,到最后看了wp发现原来源码是在index.phps中,这里只提供一个思路,不 ...

  5. d面试题汇总

    HTML Doctype作用,HTML5 为什么只需要写<!DOCTYPE HTML>? html5有哪些新特性?移除了哪些元素? 简述一下你对HTML语义化的理解? 行内元素有哪些,块级 ...

  6. 基于腾讯开源的msec来进行php开发模块

    msecphp 毫秒服务引擎(Mass Service Engine in Cluster)是一个开源框架,适用于在廉价机器组成的集群上开发和运营分布式后台服务. 毫秒服务引擎集RPC.名字发现服务. ...

  7. 设置IDEA启动时不打开上次项目

    步骤 1.启动IDEA,点击File 2.点击setting,在Appearance&Behavior中找到System Setting 3.取消勾选Reopen projects on st ...

  8. Qt QPropertyAnimation+QTimer实现自制悬浮窗

    目录 Qt下的悬浮窗 QPropertyAnimation QTimer 事件过滤 图标变换 自适应窗口大小 使用方法 Qt下的悬浮窗 最近项目需要一个类似于360悬浮球类似的悬浮窗,当鼠标放入停留一 ...

  9. Windows和ubuntu下更改pip国内镜像

    windows下更改pip国内镜像 # 在C:\Users\admin路径下创建pip文件夹,然后创建pip.ini文件, 并在文件下写入 [global] index-url = http://py ...

  10. oracle各种用户登录的方式

    Oracle有3种用户: system.sys.scott 1.system和sys的差别在与是否能创建数据库2.sys用户登录创建数据库,3.scott是给刚開始学习的人学习的用户.学习者能够用Sc ...