数学有两种学法。第一种是学习数学概念和知识,应用于工作中,这种比较狭义,应用领域比较窄;第二种是学习数学语言和方法,应用于工作中,这种比较广义,应用领域就非常多了。
先说“学习数学概念和知识,应用于工作中”。
UI开发够普遍吧。数学比较好的话,可以脱离官方的GUI 框架的限制,直接利用更底层的 API 来更高效、简练的去做些事情。这些我在项目和产品中做过的应用有:(1)建立了一套轻量级 Flash UI 库,用它开发一系列复杂交互性应用; (2) 将这套 UI 移植到 html5 / canvas 下,做了套简单的带动画的渲染系统;(3) 将这套机制移植到 winform 下,winform 下控件都是 windows 窗体,非常重量级,做复杂的UI应用限制很大,自己的UI机制,可以高效、高性能解决很多问题,作出近似 wpf 的效果;(4)将这套机制移植到 Android 下,将以前的Flash应用移植为Android APP;(5)将这套机制移植到 Xamarin 下,达到跨 windows,mac,iOS,Android 的效果。这个(5)做好之后,我就有一套高效的跨平台的UI库了,代码资产可以有效的在各个平台下移植。
官方GUI框架各种各样,差异比较大。我的搞法就是,拿一个官方GUI的基本的UI类做容器,抽象它的绘制机制,将自己的UI寄生进去。这样,我的接口、我的逻辑,在各个平台下是统一的,是针对我的业务定制的。
这套UI库,依赖平台的API比较少,不用学很多关于平台的知识,移植成本低。这就保障了我在业务上的投资。
而从下向上根据自己业务搭建这么一套UI体系,就需要比较多的数学知识了。
最开始,我是用高中平面几何+三角,后来捡起线性代数了,发现,线性代数将平面几何+三角秒成渣渣了。举几个例子:
(1)经常会在界面上测量某些参数,比如,一个点到一个线段的投影,用三角函数算起来很恶心的,用线性代数的话,假设点为A,线段为BC,就等于是计算矢量BA到BC的投影,将矢量BC缩放成标准矢量,求下点积,对标准矢量缩放就出来了;以前都是用平面几何+三角搞这些,痛苦的不得了,自从换成矢量运算后,很爽;如果你觉得求一个点到一个线段的投影还不恶心的话,那么,再来求一个点到一个线段旋转90度后的投影 ……
(2)做图像裁剪框,裁剪框要能移动、旋转,我写过好多版本的裁剪框,最开始也是基于平面几何+三角写的,把需要的功能写下来,差不多1000行,最近一个版本,我用的线性代数来重写它,大概300多行搞定;
(3)设置摄像机在一个房间的位置和角度,最开始用的是手写参数,不直观,后来改成在界面上拖拽和旋转。一个摄像机在房间里要能拖动,旋转,这个界面怎么写?我是这样写的,一个摄像机的图标发出两个延长线,作为视野。摄像机的视野区域用不同颜色跟其他区域做区分。延长线跟房间边缘存在两个交点,移动交点来改变摄像机的视角。没有相当的数学知识,写好这个UI不容易。最后还要根据用户的拖拽,计算摄像机参数,其中一个参数,就是摄像机的视角角度,用数学来说,就是,已知摄像机的位置和两个交点位置,求视角,用三角计算,又是很麻烦的,用矢量运算,一个点积,一个叉积,再反余弦就搞定了。
我们对UI元素间的逻辑通畅认识就是坐标、布局、旋转,平面几何+三角函数基本能搞定。但是,自从大量的应用了线性代数东东后,很多事情都简化了。
有这种感觉,就是,线性代数是比平面几何+三角更本质的东西。我的那套UI,就几个类,大部分UI上的业务需求,凭借线性代数知识和基本类,可以很快抽象出一个定制的UI类出来。
俺经常自嘲,我是个不会Flash的Flash程序员。而作为C#程序员,别说Asp.Net 不怎么会,WPF不怎么会,就连Winform控件都不怎么会用。作为APP开发程序员,对官方的API也是半生不熟的。但是,在这些平台上,我都能很好的实现我的业务需求,且能比这些平台的绝大部分原生程序员更好的实现。
既然在这个二维世界里就有这么大的优势,那么在更多维的世界里呢?
我们就从“学习数学概念和知识,应用于工作中”,向“学习数学语言和方法,应用于工作中”进军。
众所周知,“变化”是常态。程序要响应变化。怎么有效的响应变化?靠经验是吧?靠设计模式是吧?其实设计模式也是经验范畴。《程序员修炼之道》里提到了正交化分解,稍稍有点数学味道。
现在开始,来用数学的语言和方法,来对“变化”建模。
假设一个三维空间里有一个球在做直线运动,这个运动(“变化”)可以用 1 维空间下的模型来描述,也可以用3维空间里的模型来描述。如果在3维空间里建N个观察点,那么,也可以用N维模型来描述。从1维到3维到N维,这个复杂度是剧烈增加的。写程序时,你处理变化点,是按1维来处理,还是3维,还是N维,区别就大了。
我们几乎可以原封不动的将线性代数里的概念构建思路拿过来。假设一个“变化”S可以有4个“子变化” A,B,C,D来组成,假设“子变化”A不能有其它的“子变化”来组成,这就成功找出一个子空间了。假设B,C,D也如是,不能由其它子变化来组成,这就实现了子空间的分解。也就是,A,B,C,D 能够组成变化S。而如果A,B,C,D 之间又没有交叉(在数学上,就是两个子空间除了0外,没重叠的地方),那么就认为A,B,C,D之间互相独立。用程序语言来说,就是,A,B,C,D之间没有副作用。这里定义正交,假设A和B之间没有副作用,就认为A和B之间正交。这就对《程序员修炼之道》里的“正交化分解”有了严格的定义了。如果不懂数学,看到“正交化分解”,一扫就过去了。会数学思维,就能从这个点挖掘下去,挖掘很多内容。
举例子来说,图像裁剪框,假设图像裁剪框的长宽比不变,可以移动、旋转、缩放,正交化分解后的变化点有三个:中心点位置、尺度、旋转角度(方案A)。你如果用长、宽、中心点位置、角度来描述它,就是4个变化点了(方案B),你如果用4个顶点的坐标来描述它,也是4个变化点了(方案C)。方案A几个变化点(子空间)是独立的,且正好响应了我们处理裁剪框的移动、旋转和缩放的需求。方案B里变化点里,长和宽不是独立的(它们之间存在长宽比的约束)。方案C里,变化点也不是独立的。还有方案D,就是用对角的两个点的坐标来描述。方案D的变化分解是独立的,但是这个子空间分解的不够彻底。综合而言,方案A最优。
通过正交化分解及对多种分解方案的评估,我们就能得到最优方案。代码中,我们用一个类、一个参数来响应一个子空间,多个类的组合,就响应全部变化了。对问题的分解,不用数学,用日常语言或模式语言很难描述它,通常,我们用“经验”和“业务理解”来称呼它!这是错误的!你可以把线性代数那一套思路拿过来直接用的!
把实物期权套进来,就可以对各种各样的设计有经济上的考量,从而评价不同设计的优劣。这话题往深处扯能扯很多。这也是我现在构思的另外一件事情,叫“代码奸商”。
所谓“代码奸商”,就是说,如何象“奸商”一样写代码?如何构建一套可操作的思维模型和方法论,在成本、当前价值和未来价值里取得平衡。好听点的说法,叫代码经济学。
我这就是完全抛开了经验范畴(软件架构啊,设计模式啊),而借用数学思路和思想,直接深入到一个更为本质的层面,去追求一个更为本质的结果 —— 钱!。
有趣且好玩吧!
再继续。
我们回到程序的本质。
程序的本质就是计算。
如果一个事物和现象不进行数学建模,计算个毛啊!如果你对事物和现象来进行数学建模,就能写程序计算它了!
恋爱啊,反腐败啊,法治啊 。。。 都能来写程序计算的!!
我最近对中国社会运行有了个假说,叫“双阈值”假说。“双阈值” 是工程中常用的策略,比如,检测声音时,设定一个高阈值,超出高阈值,认为是人的声音。设定一个低阈值,从检测出来的区域,向前后扫描,扫描大于低阈值的区域,作为最终的扫描结果。在检测图像边缘时,Canny 算法也是,对设定梯度的高阈值和低阈值,通过高阈值检测出种子像素,然后找和种子像素联通的大于低阈值的像素,作为最终结果。
这个策略有两个特点:(1)比较少的检测出噪点;(2)可调节空间比单阈值大。
可以从中国社会的运行中发现大量的“双阈值”现象。拿反腐败来说,腐败很普遍的,现在的反腐败实际就是双阈值策略。低阈值就是法治底线,高阈值就是人治线。当腐败程度超出了人治线后,通常就会拿你开刀,然后深挖,把超出法治线的都挖出来。
不光反腐败,很多领域都能用这个来建模,就是法治线和人治线的双阈值模型。
什么叫宏观调控?因为法治线是法律规定的,不能随便动的,宏观调控,就是发文提升或下降高阈值(人治线),来在宏观上控制社会和经济的运行。
什么叫依法治国?就是慢慢的调整法治线,让法治线和人治线之间的空间变窄。
什么叫猫论?就是说,法治线和人治线之间的空间,这是灰色地带,可以试着去闯。先闯,再用制度来规范。闯的结果好,就抬高低阈值,让你这种行为合法。闯的结果差,就降低高阈值线,来收拾你。
什么叫政左经右?就是双阈值。政治底线是低阈值,经济现实是高阈值。
然后,就可以理解我党各种各样的莫名其妙的政策。比如说,墙的问题,电视盒子的问题。这里不做道德评价,只是探讨逻辑。墙和盒子,我党在试图建立一个宏观调控的低阈值线,在必要时,可以通过宏观调控手段,将高阈值压低。
什么叫潜规则?潜规则就是高阈值这个线上下的运作规则。
有了这个模型后,是不是就可以想办法测量高阈值了?观察高阈值的变化了?可以用大数据建模了?可以计算指数了?
差序结构、双阈值、三种规则(需求规则、关系规则和市场规则),了解这些,可以对中国社会的规则和发展有深入理解。扯远了,这又是另外话题了。。。
数学就是种语言,跟日常语言作用差不多。一件事情,可以用日常语言来描述,也可以用数学来描述。用数学语言处理后,能够加深理解,能够更准确的传递,能够计算。从这个角度去想,数学、工作、生活、程序、算法,其实是相通的。
差序结构是费孝通提的,以自己为圆心,亲疏关系向外一圈一圈的,越靠近圆心越近,越靠近外边,越远;
三种规则是《人情与面子:中国人的权力游戏》中提出的,中国人与人之间打交道有三种规则:(1)需求原则-双方关系特别近,比如,父子,是需求原则,对方需要的,自己能给的,尽量给;(2)关系原则-双方关系适中的,遵循关系原则,拉关系这种;(3)市场原则—双方关系更远的,遵循市场交易的原则。
昨晚和老婆讨论了很久,
初步有两个想法:
1、用最少的底层引用重建一套自用的系统 好处是把技术学习成本降到最低。
让自己所有精力尽可能放在原理的学习上。
2、用数学语言建模并计算整个世界
好处是,通过数学的语言来描述现象,可以更好地完成预建模。而一旦建模完成,可以通过计算来完成决策而不依赖经验判断。
那么,最后,具体到自己要做的行为也有两个:
1、多读算法数学书
让自己习惯算法和数学的语言,继而习惯用算法和数学的语言来描述观察到的现象。
2、在现有业务实现的基础上,用更底层的技术进行重构
重构出依赖更少技术点的自用系统,以便更灵活地应对其它业务的开发,尽可能降低技术学习成本。同时研究更多的用底层技术实现上层技术的原理。