函数是一个太大的题目。我们仅选择几个和程序员直接相关的点来说一下:
函数图象
其实,我们在初中就已经开始学习了函数了。还记得我们当时学过哪些函数吗?
多项式函数
一次函数
二次函数
……
反比例函数
指数函数
对数函数
三角函数 ……
还记得它们的图像吗?(下图是一些例子)给定函数画出其对应的图像——这一点非常重要!
在对函数求导数或者微分的过程中,如果能够知道原函数的图像,对照图像去理解各点的导数、微分、梯度等概念,比纯粹靠函数式理解要直观得多。
比如:深度学习中常见的激活函数,为什么要有那么多种呢?因为各自的性质不同,因此用处也不同啊。
为什么性质不同呢?先不用计算,看看它们的图象,往往就能有些体会了:
函数的定义
中学期间我们学了那么那么多函数,总体上感觉,函数就是:一个数学式子,里面有xx,最后等于一个yy。
但其实,这只是函数的一种表现形式。
真正的函数定义是:在数学里,函数是两个集合之间的一个映射,或者说是一种对应关系——输入值集合中的每个元素都能对应到唯一的一个输出值集合中的元素(反之未必)。
用图形描述起来,是这样的:一个函数就好像一个黑盒,或者一部机器,我们把输入值当作原料倒进去,经过内部的一番映射过程,就会产生出输出值来。我们习惯性地用xx表示输入值,而用yy来代表输出值,而把这个“机器”把xx“加工”成yy的过程用表示为 y = f(x)y=f(x)
至于在这个“机器”(f)里面具体是一个含xx的式子,还是有一套规则把xx转成yy,其实都是可以的。
只要输入和输出之间有一个确定的映射关系,且所有的输入都有一个唯一对应的输出,那么之间的映射过程,就是函数!
甚至于,这个“机器”的输入和输出都未必是数字、字母之类的符号。只要符合输入->输出 1 对 1 的关系,任意的输入和输出集合之间的映射,都是函数。
下面这样的例子——输入是带颜色的多边形,输出是带颜色的圆型,是函数:
甚至下面这样——输入是好多的苹果,“机器”做得事情就是一切两半,每一个完整苹果进去,出来的就是两块半个的苹果,它还是函数:
函数:从数学到编程
从上面函数的介绍不难看出,函数的功能是“加工”。函数具备一个天然的特性,就是“封装”——把“加工”的过程封在一个“盒子”(或“车间”)里。
函数这一概念被几乎所有的高级程序设计语言借鉴,在编程过程中把纯粹数学运算的输入集合到输出集合的映射过程,替换成了一系列指令组成的操作过程。
程序设计中的函数从数学中的函数处借鉴了输入、输出、加工和封装的要素,是一个有严格的开头和结尾格式的命令序列(代码块)。
程序设计中,通过使用“函数”把变的(动态的)和不变的(静态)的代码分开,用不变的部分描述的是一个特定的功能,而变的部分则用于指代这个特定功能所加诸的对象。
函数是每一个程序员天天都要用到的东西,程序员可以自定义各式各样的函数(到了面向对象编程的时候,函数改叫方法了,不过基本要素没什么变化),在函数里可以书写任意代码。
在程序里编写函数的时候,你有没有想过,虽然你写的不是一个个含有xx的算式,但是你写的东西比中学时写的那些狭义的函数式更接近数学中广义的函数定义呢?
大 O 记号
所有程序员应该都接触过算法,在描述算法性质的时候,我们会用到两个基础指标:时间复杂度和空间复杂度。
一个算法的时空复杂度大多和它要处理的数据量级有关系,所以算法的时空复杂度一般会被描述为数据量(通常用nn表示)的函数。
但是这个复杂度函数和一般的形式不太一样,它前面有一个特殊符号:OO,读作大OO(英语:Big O)。
大OO是一个数学记号,它描述了一个函数在其参数达到某一特定值或者无穷大时的极限行为。这个记号体现了函数的增长率。
假设有两个函数 f(x) 和 g(x),如果存在常数 c > 0 和 x0,当 x >= x0 时,总有 f(x) <= cg(x),则我们说 f(x) = O(g(x))。
比如下面这个例子,图中的红线表示 f(x),而蓝线表示 g(x):
通过几个直观的例子不难看出,用了大OO记号之后,函数的表达式变得比以前简单了。因此,大OO记号的作用可以简单理解为:聚焦主要因素,忽略次要因素。
这些复杂度写成式子没什么感觉,画出图来就直观多了。大家看看下图,当nn达到了一定的大小以后,nn越是增加,不同时间复杂度差别也就越大!
注意:这里要说明一下 O(1)
O(1)表示常数。这个常数可能是 1,也可能是 25, 是 36, 是 7000, 80000, 14762853, ……,但它是一个确定的,不变的数值。
对于大OO的理解并不难,但是因为这个符号一般来讲我们是从计算机课程中学习到的,因为往往会忽视它是一个数学符号这一点。
结果就是不求甚解,没有完全搞清楚它的含义和用法,而以为只要放在时空复杂度函数之前就好了。
如果大家能够通过本 chat 把之前不甚清楚的大OO符号搞明白,也算是不虚此读了。
三角函数
最后还专门要说一下三角函数。大家还记得三角函数吧?高中时候学的,一类关于角度的函数。
三角函数用直角三角形的两个边的比值,或者是单位圆有关的各种线段的长度来定义直角三角形的内角:主要的几个函数图象如下:最初,三角函数被用于计算未知的边长和角度,在航海、测绘、工程和物理学中得到了广泛的应用。
随着解析几何等分析学工具的引进,三角函数被定义为无穷级数,成了研究周期性现象的基础数学工具。
再后来,有一位大神:傅立叶,通过发明以他自己命名的傅立叶级数,把任意周期函数或周期信号分解成了由正弦函数和余弦函数组成的组合:以傅立叶级数为基础的傅立叶变换使得信号可以在时域(或空域)和频域之间变换。
这一巧妙的积分变换最早应用于物理和工程学之中,后来被引入信号处理领域,将信号(波)分解成振幅分量和频率分量。
到了信号这一步就有意思了,我们知道通讯信号是信号,同样声波也是一种信号。
远的不说,就说当前人工智能领域两个半落地点中最趋近成熟的语音处理一项,能够将语音信息从时域的幅值量转换为频谱数据的理论基础,就是傅立叶变换。而这个看起来令人晕眩的变换,就是从简单的 sin, cos 函数开始的。
“众智汇”愿景
尽职尽才,允公允能 —— 本社群不定期举行线上分享,组织群友分享知识、经验、资源,以达到让我们每个人的职业生涯得到最大程度的发展的目的。
欢迎扫面下列二维码关注“悦思悦读”公众微信号