《用 Python 学微积分》原文见参考资料 1。

13、大 O 记法

比较两个函数时,我们会想知道,随着输入值 x 的增长或减小,两个函数的输出值增长或减小的速度究竟谁快谁慢。通过绘制函数图,我们可以获得一些客观的感受。

比较 x!、ex、x3 和 log(x) 的变化趋势。

importnumpy as npimportsympyimportmatplotlib.pyplot as plt

x= range(1,7)

factorial= [np.math.factorial(i) for i inx]

exponential= [np.e**i for i inx]

polynomial= [i**3 for i inx]

logarithmic= [np.log(i) for i inx]

plt.plot(x,factorial,'black',\

x,exponential,'blue',\

x,polynomial,'green',\

x,logarithmic,'red')

plt.show()

View Code

根据上图,当 x—>∞ 时,x!>ex>x3>ln(x)。要想证明的话,可以取极限,用洛必达法则,例如:

$$\lim_{x\rightarrow \infty}\frac{e^x}{x^3}=\infty$$

表明当 x—>∞ 时,虽然分子分母都在趋向无穷大,但分子远远凌驾于分母之上。类似地,也可以这样看:

$$\lim_{x\rightarrow \infty}\frac{ln(x)}{x^3}=0$$

表明分母远远凌驾于分子之上。

SymPy 是 Python 的数学符号计算库,用它可以进行数学公式的符号推导。下面代码用 SymPy 来推导上面两式。

importsympyfrom sympy.abc importx#sympy中无限infty用oo表示

print ((sympy.E**x)/(x**3)).limit(x,sympy.oo)#result is: oo

print (sympy.ln(x)/x**3).limit(x,sympy.oo)#result is 0

View Code

为了描述这种随着 x—>∞ 或 x—>0 时函数的表现,我们定义如下大 O 记法:

若我们称函数 f(x) 在 x—>0 时是 O(g(x)),则需要找到一个常数 C,对于所有足够小的 x,均有 |f(x)|

若我们称函数 f(x) 在 x—>∞ 时是 O(g(x)),则需要找到一个常数 C,对于所有足够大的 x,均有 |f(x)|

之所以叫大 O 记法,是因为函数的增长速率很多时候被称为函数的阶(Order)。

例如,当 x—>∞ 时,x(1+x2)1/2 是 O(x2),下面来个直观感受。

下图是两个函数的变化趋势,红线是 x(1+x2)1/2 ,蓝线是 2x2 。

importsympyfrom sympy.abc importximportnumpy as npimportmatplotlib.pyplot as plt

xvals= np.linspace(0,100,1000)

f= x*sympy.sqrt(1+x**2)

g= 2*x**2y1= [f.evalf(subs={x:xval}) for xval inxvals]

y2= [g.evalf(subs={x:xval}) for xval inxvals]

plt.plot(xvals[:10],y1[:10],'r',xvals[:10],y2[:10],'b')#plt.plot(xvals,y1,'r',xvals,y2,'b')

plt.show()

View Code

Sympy 可以帮助我们分析函数的阶,如下面求 x(1+x2)1/2 的阶。

importsympyfrom sympy.abc importx

f= x*sympy.sqrt(1+x**2)printsympy.O(f, (x, sympy.oo))#result is : O(x**2, (x, oo))

计算机中使用大 O 记法,通常是分析当输入数据 —>∞ 时,程序在时间或空间上的表现。然而,从上面的介绍,我们知道这个位置可以是 0,甚至可以是任何有意义的位置。

importsympyfrom sympy.abc importx

f= x*sympy.sqrt(1+x**2)printsympy.O(f, (x, 0))#result is : O(x)

在前面泰勒级数一节,利用 Sympy 取函数泰勒级数的前几项时,代码是这样:

importsympyfrom sympy.abc importx

exp= sympy.E**x

sum15= exp.series(x,0,15).removeO()print sum15

其中 removeO() 的作用是让 sympy 忽略掉级数展开后的大 O 表示项。不然结果如下:

importsympyfrom sympy.abc importx

exp= sympy.E**xprint exp.series(x, 0, 3)#result is: 1 + x + x**2/2 + O(x**3)

这表示从泰勒级数的第 4 项起,剩余所有项在 x—>0 时是 O(x3)。这表明,当 x—>0 时,用 1+x+0.5x2 来近似 ex ,我们得到的误差上限将是 Cx3,其中 C 是一个常数。也就是说,大 O 记法能用来描述我们使用多项式近似时的误差。

另外大 O 记法也可以直接参与计算中去,例如要计算:

$$cos(x^2)\sqrt{(x)}$$

在 x—>0 时阶 O(x5) 以内的多项式近似,可以这样:

$$cos(x^2)\sqrt{(x)}=(1-\frac{1}{2}x^4+O(x^6))x^{\frac{1}{2}}$$

$$\qquad = x^{\frac{1}{2}}-    \frac{1}{2}x^{\frac{9}{2}} + O(x^{\frac{13}{2}})$$

importsympyfrom sympy.abc importxprint (sympy.cos(x**2)*sympy.sqrt(x)).series(x,0,5)#result is: sqrt(x) - x**(9/2)/2 + O(x**5)

14、导数

对函数某一点求导,得到的是函数在该点处切线的斜率。选中函数图像中某一点,不断放大,最后会发现函数图像一条直线,这条直线就是切线。下面获得一些直观的感受。

import numpy asnpfromsympy.abc import x

import matplotlib.pyplotasplt

# 函数

f= x**3-2*x-6# 在x=6处正切于函数的切线

line= 106*x-438d1= np.linspace(2,10,1000)

d2= np.linspace(4,8,1000)

d3= np.linspace(5,7,1000)

d4= np.linspace(5.8,6.2,100)

domains=[d1,d2,d3,d4]

# 画图的函数

def makeplot(f,l,d):

plt.plot(d,[f.evalf(subs={x:xval}) for xval in d],'b',\

d,[l.evalf(subs={x:xval}) for xval in d],'r')for i inrange(len(domains)):

# 绘制包含多个子图的图表

plt.subplot(2, 2, i+1)

makeplot(f,line,domains[i])

plt.show()

View Code

导数定义 1:

$$f'(a)=\frac{df}{dx}\bigg|_{x=a}=\lim_{x\rightarrow a}\frac{f(x)-f(a)}{x-a}$$

若该极限不存在,则函数在 x=a 处的导数不存在。

导数定义 2:

$$f'(a)=\frac{df}{dx}\bigg|_{x=a}=\lim_{h\rightarrow 0}\frac{f(a+h)-f(a)}{h}$$

若该极限不存在,则函数在 x=a 处的导数不存在。

导数定义 3:

函数 f(x) 在 x=a 处的导数 f'(a) 是满足如下条件的常数 C,对于在 a 附近输入值的微小变化 h,有 f(a+h)=f(a)+Ch+O(h2) 始终成立。也就是说导数 C 输入值变化中一阶项的系数。上式稍加变化,两边同时除以 h,并同时取极限可得:

$$\lim_{h\rightarrow 0}\frac{f(a+h)-f(a)}{h}=\lim_{h\rightarrow 0}C+O(h)=C$$

便与上面定义 2 相一致了。

例如求 cos(x) 在 x=a 处的导数:

$$cos(a+h)=cos(a)cos(h)-sin(a)sin(h)$$

$$\qquad = cos(a)(1+O(h^2))-sin(a)(h+O(h^3))$$

$$\qquad = cos(a)-sin(a)h +O(h^2)$$

所以:

$$\frac{d}{dx}{cos(x)}\bigg|_{x=a}=-sin(a)$$

我们可以自己定义求导的函数:

importnumpy as npfrom sympy.abc importx

f= lambda x: x**3-2*x-6

#我们设定参数h的默认值,如果调用函数时没有指明参数h的值,便会使用默认值

def derivative(f,h=0.00001):return lambda x: float(f(x+h)-f(x))/h

fprime=derivative(f)print fprime(6)#result is:106.000179994

Sympy 也提供求导的方法:

from sympy.abc importx

f= x**3-2*x-6

printf.diff()#result is :3*x**2 - 2

print f.diff().evalf(subs={x:6})#result is : 106.0000000000

依据导数的定义 3,有  f(a+h)=f(a)+f'(a)h+O(h2),如果将高阶项丢掉,就获得了 f(a+h) 的线性近似式子:f(a+h)≈f(a)+f'(a)h。

例如,用线性近似的方法估算 2551/2:

$$\sqrt{256-1}\approx \sqrt{256}+\frac{1}{2\sqrt{256}}(-1)$$

$$\qquad = 16 - \frac{1}{32}$$

$$\qquad = 15\frac{31}{32}$$

15、牛顿迭代法

如何在不使用 x1/2 前提下求 C 的正二次根。

上述问题等价于求 f(x)=x2+C=0 的解,根据上面介绍的线性近似:f(x+h)≈f(x)+f'(x)h 。如果 f(x+h)=0,那么:

$$h\approx -\frac{f(x)}{f'(x)}$$

$$x+h\approx x - \frac{f(x)}{f'(x)}$$

如果我们对 f(x)=0 的解有一个初始估计 x0,便可以用上面的近似不断获取更加准确的估计值,方法为:

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

将 f(x)=x2+C 代入上式,即得 xn 的更新规则:

$$x_{n+1} = \frac{1}{2}(x_{n}+\frac{C}{x_{n}})$$

from sympy.abc importxdef mysqrt(c, x = 1, maxiter = 10, prt_step =False):for i inrange(maxiter):

x= 0.5*(x+ c/x)if prt_step ==True:#在输出时,{0}和{1}将被i+1和x所替代

print "After {0} iteration, the root value is updated to {1}".format(i+1,x)returnxprint mysqrt(2,maxiter =4,prt_step =True)#After 1 iteration, the root value is updated to 1.5#After 2 iteration, the root value is updated to 1.41666666667#After 3 iteration, the root value is updated to 1.41421568627#After 4 iteration, the root value is updated to 1.41421356237#1.41421356237

通过绘图进一步了解这个方法,例如,我们要猜 f(x)=x2-2x-4=0 的解,从 x0=2 开始,找到 f(x) 在 x=x0 处的切线 y=2x-8,找到其与 y=0 的交点 (4,0),将该交点作为新的猜测解 x1=4,如此循环。

importnumpy as npimportmatplotlib.pyplot as plt

f= lambda x: x**2-2*x-4l1= lambda x: 2*x-8l2= lambda x: 6*x-20x= np.linspace(0,5,100)

plt.plot(x,f(x),'black')

plt.plot(x[30:80],l1(x[30:80]),'blue', linestyle = '--')

plt.plot(x[66:],l2(x[66:]),'blue', linestyle = '--')

l= plt.axhline(y=0,xmin=0,xmax=1,color = 'black')

l= plt.axvline(x=2,ymin=2.0/18,ymax=6.0/18, linestyle = '--')

l= plt.axvline(x=4,ymin=6.0/18,ymax=10.0/18, linestyle = '--')

plt.text(1.9,0.5,r"$x_0$", fontsize = 18)

plt.text(3.9,-1.5,r"$x_1$", fontsize = 18)

plt.text(3.1,1.3,r"$x_2$", fontsize = 18)

plt.plot(2,0,marker = 'o', color = 'r')

plt.plot(2,-4,marker = 'o', color = 'r')

plt.plot(4,0,marker = 'o', color = 'r')

plt.plot(4,4,marker = 'o', color = 'r')

plt.plot(10.0/3,0,marker = 'o', color = 'r')

plt.show()

View Code

如下定义牛顿迭代法:

def NewTon(f, s = 1, maxiter = 100, prt_step =False):for i inrange(maxiter):#相较于f.evalf(subs={x:s}),subs()是更好的将值带入并计算的方法。

s = s - f.subs(x,s)/f.diff().subs(x,s)if prt_step ==True:print "After {0} iteration, the solution is updated to {1}".format(i+1,s)returnsfrom sympy.abc importx

f= x**2-2*x-4

print NewTon(f, s = 2, maxiter = 4, prt_step =True)#After 1 iteration, the solution is updated to 4#After 2 iteration, the solution is updated to 10/3#After 3 iteration, the solution is updated to 68/21#After 4 iteration, the solution is updated to 3194/987#3194/987

Sympy 可以帮助我们求解方程:

importsympyfrom sympy.abc importx

f= x**2-2*x-4

printsympy.solve(f,x)#result is:[1 + sqrt(5), -sqrt(5) + 1]

参考资料:

[1] https://ryancheunggit.gitbooks.io/calculus-with-python/content/

python 微积分_《用 Python 学微积分》笔记 2相关推荐

  1. 第一章 第一节:Python基础_认识Python

    Python基础入门(全套保姆级教程) 第一章 第一节:Python基础_认识Python 1. 什么是编程 通俗易懂,编程就是用代码编写程序,编写程序有很多种办法,像c语言,javaPython语言 ...

  2. 第一门语言学python好_零基础学编程,哪一门语言比较适合入门?

    最近,有不少小伙伴问我,说零基础学编程,第一门语言学哪个好?有人推荐学Python,理由是Python简单,对新人友好,上手快,那Python到底适不合适新人学呢. 我今天就这个问题给大家稍微的展开一 ...

  3. pythoncookbook和流畅的python对比_为什么你学Python效率比别人慢?因为你没有这套完整的学习资料...

    以下资源免费获取方式! 关注!转发!私信"资料"即可免费领取! 入门书籍 1.<Python基础教程>(Beginning Python From Novice to ...

  4. 阿里云python课程_阿里云大学编程语言免费精华课程集锦

    阿里云云栖社区 近期在微博免费开放了大数据报告以及多种课程,这不仅给互联网商业战略分析专家带来了福音同时也给有兴趣学习编程的同学们带来了免费知识大餐,因不允许发相关链接,请关注私信小编,小编会发给你链 ...

  5. 计算机语言python发音_最难学的七大编程语言,VB 第一,Python垫底,看你学的排第几...

    原标题:最难学的七大编程语言,VB 第一,Python垫底,看你学的排第几 在很多人眼里程序员的标配就是黑框眼镜+格子衫+双肩包+牛仔裤+运动鞋,拥有了这些可能就被判定为一个程序员. 而如何判定一个程 ...

  6. 教孩子学编程python豆瓣_教孩子学编程 Python

    教孩子学习Python目录第1章Python编程基础知识:了解环境111知道Python 312编写的Python程序513运行Python程序514章总结615编程挑战7章2只乌龟图:图纸与Pyth ...

  7. 零基础学python张志强_零基础学Python最新章节_张志强著_掌阅小说网

    1.5 Python的开发工具 Python的开发工具非常丰富,有许多强大的IDE(Integrated Development Environment)工具,如Komodo.PythonWin.Ec ...

  8. 会c++有必要学python吗_你应该学Python还是C++

    前面有一段时间,我学习了Python这门语言,所以到现在,总会有人问我:"你觉得Python还是C++实用?哪个更好用?"接下来的文章就想给大家介绍下两者的一些区别以及优缺点. 首 ...

  9. python 字符识别_使用python进行光学字符识别入门

    python 字符识别 语言模型设计 (Language Model Designing) Optical Character Recognition is the conversion of 2-D ...

  10. excel python插件_利用 Python 插件 xlwings 读写 Excel

    Python 通过 xlwings 读取 Excel 数据 去年底公司让我做设备管理,多次委婉拒绝,最终还是做了.其实我比较喜欢技术.做管理后发现现场没有停机率统计,而原始数据有,每次要自己在Exce ...

最新文章

  1. 基于Lucene查询原理分析Elasticsearch的性能
  2. 2019.08.04 新建随笔
  3. Django 3.2.5博客开发教程:实现网站首页
  4. go 数据类型和操作符
  5. Git 常用命令及讲解(不断更新)
  6. SAP Freestyle UI5 和 SAP Fiori Elements 应用的区别
  7. windows+caffe(三)——求取图片的均值
  8. 探索 .NET团队对API的设计流程
  9. 如何匹配两段文本的语义?
  10. Linux学习总结(37)——CentOS7下Firewall防火墙配置用法详解
  11. mvn dependency命令
  12. 【poj2373】Dividing the Path【单调队列优化dp】
  13. Hibernate 的HQL和sql有什么区别
  14. 测试人员入门级的数据库知识(SQL语句)
  15. (四)Loadrunner 代理录制
  16. 战争机器5加速器信息:开发工作已经完成 更多内容将在科隆展上披露
  17. 服务器更新维护公告,10月15日(周四)服务器更新维护公告
  18. android 带箭头的按钮,用Dialog创建带箭头的对话框
  19. python signal模块_Python signal 信号模块和进程
  20. [NOIP2005提高组]过河

热门文章

  1. [UWP]用Shape做动画(2):使用与扩展PointAnimation
  2. php 中的 mysqli事务处理
  3. android 获取应用的当前版本号获取当前android系统的版本号
  4. iOS开发:Objective-C优雅的语法
  5. linux 死锁分析
  6. 使用HSRP和SLB实现服务器群负载均衡和冗余
  7. linux下ssh登录PIX防火墙
  8. legend3---lavarel中使用qq邮箱发送邮件
  9. 锤子辩论有感——我该如何定义成功
  10. Django REST framework快速入门