Big O notation
一般我们描述算法复杂度时,会使用大O符号。例如冒泡排序的复杂度是O(n^2),快排与归并排序的复杂度为O(nlogn)。那么什么是大O符号呢。
一般呢,我们说f(x)=O(g(x)),即指f(x)与g(x)的量级差不多,使用数学语言呢,即是:
使
时
如g(x)=x^2 与 f(x)=3x^2+5x+2 。当x>=10的时候,只要M为4。f(x)一定小于Mg(x)。这时候我们可以说3x^2+5x+2=O(x^2)。而如果g(x)换做x。我们找不到一个x0和M满足于这个条件。因为当x趋近于无穷大时,f(x)始终>Mg(x)。
同时还存在一个小o符号。他的意义为f(x)=o(g(x))时,f(x)量级严重小于与g(x)。类似x^2=o(x^3)使用数学语言呢,即是:
使
时
大家感兴趣可以代入公式试一试。
我们一般使用大O符号描述算法的复杂度。这种方式可以清晰地看出不同算法执行时所需要消耗的资源多少,时间长短的对比与关系。以及当算法中元素增加时,耗费资源时间增长的剧烈程度。
极限与导数
关于极限与导数基本上都是高数中的核心内容。即表示函数以及变化的趋势。
与上面的内容结合起来。如果我们说f(x)=o(g(x)),那么在x趋近于无穷大时,f(x)/g(x)一定为0。
因为根据极限的定义我们可得
使
时
即
即 f(x)=o(g(x))。
同理如果是大O符号,那么结果一定是小于等于大O符号中定义为M的一个常数。
另外python中有一个Sympy库,可以使用符号进行求导。
另外对于导数延伸开来,有一个费马引理,即:
函数f(x)在点a的某邻域U(a)内有定义,并且在a处可导,如果对于任意的x∈U(a),都有f(x)≤f(a) (或f(x)≥f(a) ),那么f '(a)=0。
通俗来说就是区间内如果存在极值,那么此点的导数一定为0。
而从此又延伸出罗尔定理:
如果 R 上的函数 f(x) 满足以下条件:
(3)f(a)=f(b),则至少存在一个 ∈(a,b),使得 f'(
)=0。
因为函数 f(x) 在闭区间[a,b] 上连续,所以存在最大值与最小值,分别用 M 和 m 表示,分两种情况讨论:
1. 若 M=m,则函数 f(x) 在闭区间 [a,b] 上必为常函数,结论显然成立。
2. 若 M>m,则因为 f(a)=f(b) 使得最大值 M 与最小值 m 至少有一个在 (a,b) 内某点处取得,从而
是f(x)的极值点,又条件 f(x) 在开区间 (a,b) 内可导得,f(x) 在
处取得极值,由费马引理,可导的极值点一定是驻点,推知:f'(
)=0。
另又从罗尔定理可延伸到拉格朗日中值定理:
如果函数f(x)满足:
(2)在开区间(a,b)内可导;
那么在开区间(a,b)内至少有一点
使等式
成立。
只需要构造函数。
这样我们可得g(a)=g(b)。根据罗尔定理则有一点使g'(
)=0。同时g'(
)=f'(
)即证。
根据此我们可以推导出如何逼近一个函数,进而得到拉格朗日余项泰勒展开。
有兴趣的可以自己推导尝试,过程不在此详细说明。
通过拉格朗日余项泰勒展开我们就可以通过多项式来逼近任何一个可导函数。
凸函数
通俗来讲,我们称二阶导数不变号的函数为凸函数。上凸函数则二阶导<0,下凸函数则二阶导>0。根据定义则是在函数f(x)上划一条线,线公式为g(x),有两个交点a,b(a<b)。则对于任意(a<x<b)都有f(
)>g(
) (上凸函数)/ f(
)<g(
) (下凸函数)。
其实就是描述一个函数变化的趋势是不变的。一直变大就是下凸,一直变小就是上凸。
在机器学习中应用广泛的凸优化问题即是基于凸函数的定义。