《用 Python 学微积分》笔记 3
《用 Python 学微积分》原文见参考资料 1。
16、优化
用一个给定边长 4 的正方形来折一个没有盖的纸盒,设纸盒的底部边长为 l,则纸盒的高为 (4-l)/2,那么纸盒的体积为:
$$V(l)=l^2\frac{4-l}{2}$$
怎样才能使纸盒的容积最大?也就是在 l>0,4-l>0 的限制条件下,函数 V(l) 的最大值是多少?
优化问题关心的就是这样的问题,在满足限制条件的前提下,怎么才能使目标函数最大(或最小)?
先来看下 V(l) 的函数图形:
import numpy as np
import matplotlib.pyplot as plt l = np.linspace(0,4,100)
V = lambda l: 0.5*l**2*(4-l)
plt.plot(l,V(l)) plt.show()
看得出来,V(l) 在大约 2.5 处最大。
如果给定一个函数,知道它在点 x=a 处的函数导数为 0,或者该点的导数不存在,则称该点为关键点。要想知道 f(a) 是局部最大值还是局部最小值,可以使用二次导数测试。
如果 f''(a)>0,则函数 f 在 a 处的函数值是局部最小值。
如果 f''(a)<0,则函数 f 在 a 处的函数值是局部最大值。
如果 f''(a)=0,则测试无法告诉我们结论。
上述二次导数测试可以从泰勒级数中推导出来。f(x) 在 x=a 处的泰勒级数为:
$$f(x)=f(a)+f'(a)(x-a)+\frac{1}{2}f''(a)(x-a)^2+\dots$$
因为 a 为关键点,f'(a)=0,所以:
$$f(x)=f(a)+\frac{1}{2}f''(a)(x-a)^2+O(x^3)$$
当 f''(a)≠0 时,f(x) 在 x=a 附近的表现近似于二次函数,二次项的系数 0.5f''(a) 决定了抛物线的开口朝向,因而决定了函数值在该点是怎样的。
回到之前求最大盒子体积的问题,解法如下:
import sympy
from sympy.abc import l
V = 0.5*l**2*(4-l)
# 看看一次导函数:
print V.diff(l)
# output is : -0.5*l**2 + 1.0*l*(-l + 4)
# 一次导函数的定义域为(-oo,oo),因此关键点为V'(l)=0的根
cp = sympy.solve(V.diff(l),l)
print cp
# output is: [0.0, 2.66666666666667]
# 找到关键点后,使用二次导数测试:
for p in cp:
print V.diff(l,2).subs(l,p)
# output is: 4, -4
# 因此知道在l=2.666666处时,纸盒的体积最大
17、线性回归
二维平面上有 n 个数据点,pi=(xi,yi),现尝试找到一条经过原点的直线,y=ax,使得所有数据点到该直线的残差的平方和最小。
import numpy as np
import matplotlib.pyplot as plt # 设定好随机函数种子,确保模拟数据的可重现性
np.random.seed(123) # 随机生成一些带误差的数据
x = np.linspace(0,10,10)
res = np.random.randint(-5,5,10)
y = 3*x + res # 求解回归线的系数
a = sum(x*y)/sum(x**2) # 绘图
plt.plot(x,y,'o')
plt.plot(x,a*x,'red')
for i in range(len(x)):
plt.axvline(x[i],min((a*x[i]+5)/35.0,(y[i]+5)/35.0),\
max((a*x[i]+5)/35.0,(y[i]+5)/35.0),linestyle = '--',\
color = 'black') plt.show()
要找到这样一条直线,实际上是一个优化问题:
$$\underset{a}{min}Err(a)=\sum_{i}{(y_i-ax_i)}^2$$
要找出函数 Err(a) 的最小值,首先计算一次导函数:
$$\frac{dErr}{da}=\sum_{i}2(y_i-ax_i)(-x_i)$$
$$\qquad = -2\sum_{i}x_iy_i + 2a\sum_{i}x_i^2$$
令该函数为 0,求解出关键点:
$$a = \frac{\sum_{i}x_iy_i}{\sum_{i}x_i^2}$$
使用二次导数测试:
$$\frac{d^2Err}{da^2}=2\sum_ix_i^2>0$$
因此
$$a = \frac{\sum_{i}x_iy_i}{\sum_{i}x_i^2}$$
是能够使函数值最小。这也是上面 Python 代码中,求解回归线斜率所用的计算公式。
如果不限定直线一定经过原点,即公式为 y=ax+b,则同样还是一个优化问题,只不过涉及的变量变成两个。
$$\underset{a}{min}Err(a,b)=\sum_i{(y_i-ax_i-b)}^2$$
这个问题是多元微积分里要分析的问题,这里先给出 Python 中的求解方法。红线为经过原点的直线,蓝线为不限定经过原点的直线。
import numpy as np
import matplotlib.pyplot as plt # 设定好随机函数种子,确保模拟数据的可重现性
np.random.seed(123) # 随机生成一些带误差的数据
x = np.linspace(0,10,10)
res = np.random.randint(-5,5,10)
y = 3*x + res # 求解回归线的系数
a = sum(x*y)/sum(x**2) slope, intercept = np.polyfit(x,y,1) # 绘图
plt.plot(x,y,'o')
plt.plot(x,a*x,'red')
plt.plot(x,slope*x+intercept, 'blue')
for i in range(len(x)):
plt.axvline(x[i],min((a*x[i]+5)/35.0,(y[i]+5)/35.0),\
max((a*x[i]+5)/35.0,(y[i]+5)/35.0),linestyle = '--',\
color = 'black') plt.show()
18、不定积分
根据加速度 a(t) 求速度 v(t),可得:
$$\frac{dv}{dt}=a(t)$$
一旦找到了 v(t),那么
$$\forall C\in\mathbb{R}, v(t)+C$$
也都是方程的解,因此常微分方程的解是 v(t)+C 这样一系列函数。得出这一系列函数后,只需知道任一时刻汽车的速度,便可求出常数项 C。
Python 中积分的方法:
import sympy t = sympy.Symbol('t')
v = t**3-3*t-6
a = v.diff()
print a.integrate()
# result is : t**3 - 3*t
print sympy.integrate(sympy.E**t+3*t**2)
# result is : t**3 + exp(t)
参考资料:
[1] https://ryancheunggit.gitbooks.io/calculus-with-python/content/
《用 Python 学微积分》笔记 3的更多相关文章
- 《用 Python 学微积分》笔记 2
<用 Python 学微积分>原文见参考资料 1. 13.大 O 记法 比较两个函数时,我们会想知道,随着输入值 x 的增长或减小,两个函数的输出值增长或减小的速度究竟谁快谁慢.通过绘制函 ...
- 《用 Python 学微积分》笔记 1
<用 Python 学微积分>原文见参考资料 1. 1.多项式 f(x)=x3-5x2+9 def f(x): return x**3 - 5*x**2 + 9 print f(3) pr ...
- python 学记笔记 SQLalchemy
数据库表是一个二维表,包含多行多列.把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含id和name的user表 ...
- python学记笔记 2 异步IO
在IO编程中,我们知道CPU的速度远远快于磁盘,网络IO,在一个线程中,CPU执行速度的代码非常快,然而遇到IO操作就需要阻塞 需要等待IO操作完成才能继续下一步的动作.这种情况叫做同步IO 在IO操 ...
- [新手必备]Python 基础入门必学知识点笔记
Python 作为近几年越来越流行的语言,吸引了大量的学员开始学习,为了方便新手小白在学习过程中,更加快捷方便的查漏补缺.根据网上各种乱七八糟的资料以及实验楼的 Python 基础内容整理了一份极度适 ...
- python基础学习笔记(纸质)
大一的时候学的python做的笔记.
- 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL
周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...
- 《简明python教程》笔记一
读<简明Python教程>笔记: 本书的官方网站是www.byteofpython.info 安装就不说了,网上很多,这里就记录下我在安装时的问题,首先到python官网下载,选好安装路 ...
- python 正则使用笔记
python正则使用笔记 def remove_br(content): """去除两边换行符""" content = content.r ...
随机推荐
- Mybatis框架学习总结-Mybatis框架搭建和使用
Mybatis介绍 Mybatis是一个支持普通SQL查询,存储过程,和高级映射的优秀持久层框架.Mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.Mybatis可以使 ...
- 细说PHP7
PHP7带来的新东西 1.类型的声明. 可以使用字符串(string), 整数 (int), 浮点数 (float), 以及布尔值 (bool),来声明函数的参数类型与函数返回值. declare(s ...
- (转)C语言中Exit函数的使用
C语言中Exit函数的使用 exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如 ...
- st试用笔记
1.关于轮询 我的写法: var time_count = 0; var timer = setInterval(function(){ async.ajax({ url:'', data:'', s ...
- 工作笔记——区块链POC
1.基础配置 安装SecureCRT 8.0链接到虚拟服务器,并配置docker 安装文件上传到服务器工具FileZilla
- [笔记] Python实现全排列算法
所谓全排列,就是给定数组,将所有的可能排列组合都枚举出来,n个元素共有n!种排列组合. 举例,对于['1', '2', '3'],全排列结果为:123,132,213,231,312,321,共有3! ...
- Problem A. Array Factory XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016
思路: 直接二分长度不可行,因为有负数. 考虑枚举坐便删l个数,那如果可以在短时间内求出符合条件的右边最小删的数的个数,这题便可做了. 即:当左边删l个数时,要使sum[n]-sum[l]-fsum[ ...
- Unity本地数据存储---Sqlite和JSON
2014-05-04更新 SqliteDatabase.cs这个文件的初始方法有问题,具体是如果指定URL已经存在了DB文件,就不会重新覆盖DB文件. 这导致我们修改之后的DB文件无法产生效果. 本人 ...
- php 输出 sql语句
第一种方法 $data = M('news')->field("title,date_format(postdate,'%Y-%m-%d') as postdate,content&q ...
- mspdb100.dll不见了的解决办法
一.如果在运行某软件或编译程序时提示缺少.找不到mspdb100.dll等类似提示,将下载来的mspdb100.dll拷贝到指定目录即可 (一般是system系统目录或放到软件同级目录里面),或者重新 ...