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

首先给出这样一个问题,如果有这么一个函数$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. Swing 是线程安全的?

    不是,Swing 不是线程安全的.你不能通过任何线程来更新 Swing 组件,如 JTable.JList 或 JPanel,事实上,它们只能通过 GUI 或 AWT 线程来更新. 这就是为什么 Sw ...

  2. Linux 基础优化

    1.操作的最小化原则 1)安装系统最小化 一般情况下安装OS时,软件安装包组(Package Group)的选择: base--------------------------基本环境 editors ...

  3. 数组(Array)和列表(ArrayList)有什么区别

    Array可以包含基本类型和对象类型,ArrayList只能包含对象类型 Array大小固定,ArrayList的大小是动态变化的. ArrayList提供了更多的方法和特性:比如 :addAll() ...

  4. c/c++中的i++和++i的区别

    使用 i++ vs. ++i i++是先赋值再加1 ++i是先加1再赋值 到目前为止,你已经学习了如何编写下面这样的 C++ for 循环: for (int i = 0; i < 10; i+ ...

  5. 总结一下各种0.5px的线

    在PC端用1px的边框线,看起来还好,但在手机端看起来就很难看了,而0.5px的分割线会有种精致的感觉.用普通写法border:solid 0.5px red;iPhone可以正常显示,android ...

  6. H5打造3d场景不完全攻略(一): H5 3d表现形式

    前言 日前,taobao造物节H5放肆地火了一把.相信接下来将3d嵌入网站的这种营销方式会被越来越多的人留意到.工作之余体验了若干个3d H5页面,感觉这类的H5互动体验性明显要比普通的要强,把二维的 ...

  7. 利用AudioContext来实现网易云音乐的鲸鱼音效

    一直觉得网易云音乐的用户体验是很不错的,很早就注意到了里面的鲸鱼音效,如下图,就是一个环形的跟着音乐节拍跳动的特效. gif动图可能效果不太理想,可以直接在手机上体验 身为前端凭着本能的好奇心和探索心 ...

  8. 解决使用 swiper 常见的问题

    使用 swiper 的过程中个人总结 1. swiper插件使用方法, 直接查看文档 swiper基础演示 swiper API文档 2.swiper近视初始化时, 其父级元素处于隐藏状态(displ ...

  9. Jackson 和 fastJSON 导包异常

    内容 一.异常信息 HTTP Status 400 - type Status report message org.springframework.http.converter.HttpMessag ...

  10. vue简单的父子组件之间传值

     todo-list为例子: 代码: 父传子--------------属性  v-bind 子传父--------------$emit <!DOCTYPE html> <html ...