对计算数学专业的科研工作者和学生来说, 编程是一项很重要的工作。 如何快速写出高 效的数值实验程序, 并且能反复使用, 是大家非常关心的事情。
我希望通过一系列的文章, 系统介绍如何基于 Python 中常用的科学计算模块, 利用向 量化和面向对象的编程技术, 快速编写有限元、有限差分、有限体积、虚单元等常见的数 值方法程序。
我个人对 Matlab、 C++ 和 Python 都比较熟悉, 有很多相关的编程经验,对这几种编程 语言的优劣有比较丰富的体会。 下面我想谈谈我为什么选择 Python 做为我现在的主要编 程语言。
你可能会说, Python 是大数据时代的热门语言, 我只是在追赶潮流。 确实, 当下机器 学习和人工智能的主流语言是 Python。 但我向来认为一种东西流行, 只是表象, 而我 也不会仅仅因为它流行而去用它。 我用它 最根本的原因在于它真的好用, 可以极大 的提高编程效率, 能大量节约用户的时间。 而对每个人来说, 最宝贵的资源就是时间。 所以, 这里我首先把理由列出来:
- 支持面向对象编程的解释性语言,无需编译,易学易用。
- 语法设计简洁清爽, 写出的代码可读性强, 可以做到 “Code what we think”。
- 有庞大的用户社群,包括 NASA, ANL, Google 等国际知名的科研机构和公司都选择 Python 做为高性能计算的开发语言。Python 的初学者和开发者很容易从社群中获得帮助和开发文档。
- 有丰富的科学计算基础软件包, 如:
- NumPy: http://numpy.scipy.org - Numerical Python,主要提供多维数组及相关运算功能。
- SciPy: http://www.scipy.org - Scientific Python,提供高效的优化、FFT、稀疏矩阵等科学计算模块。
- Matplotlib: http://www.matplotlib.org - Graphics library,提供成熟 2D 和 3D 画图软件功能。
- SymPy: http://www.sympy.org - 数学符号计算。
- 还可以做很多其它的事情, 如系统管理, 网站开发。
- 和其它编译语言的接口灵活,功能很容易扩展。
- 有 mpi4py, pycuda 等并行软件包, 使得并行编程更加容易。
- 开源免费
下面我给出一些解释说明。 首先, Python 是一门解释性语言, 无需编译即可运行。 解 释性带来的好处是交互性, 即你能即时得到反馈。 你在编程过程中, 可以更频繁的测试 程序, 马上知道自己有没有犯语法或逻辑错误, 这样就可快速迭代自己的想法, 大大 提高编程的效率。 对有点 C/C++、 Fortran 等编译语言使用经验的人来说(特别是没有 养成良好编程习惯的初学者 ), 往往要花大量时间在编译调错上, 这是很让人沮丧的编程体验。
Python 的语言设计是非常简介清爽, 没有很多不必要的语法要求, 写同样功能的程序, 你需要敲击键盘的次数更少, 从而大大提高了编辑代码的效率。 比如下面的三段代码
- C++
int sum = 0;
for(int i = 0; i < 10; i++)
{
sum += i;
std::cout<< sum << std::endl;
}
- Matlab
sum = 0;
for i = 0:9
sum = sum + i;
disp(sum);
end
- Python
sum = 0
for i in range(10):
sum += i
print(sum)
Python 的代码行末尾不强制要求加 ;
。 如果 C++ 不加, 就会报语法错误; 而 Matlab
行末不加 ;
, 就会打印本行的计算结果。 Python 是用缩进来区分代码块的开始和结
束, 而且严格要求 4 个缩进空格。 同级缩进的就属于同一个代码块。 这样的缩进强制
要求, 可以让你养成很好程序排版习惯。 这是不同于 C++ 的 {}
, 以及 Matlab 的
end
关键词的, 这些语法要求本质上是不必要的。 Matlab 还有更多这样的要求, 比
如每个文件只能有一个主函数或者类的定义, 而且还必须和文件名同名。
做为解释性的语言, Python 对面向对象编程支持的非常好。 在 Python 中, 一切皆是 对象, 都有它固有的属性和方法。 相比于 C++ 的面向对象, Python 的面向对象语法更 加灵活易用。 而 Matlab 的面向对象, 我就只能说“呵呵”了。
由于 Python 语法设计的考虑的非常全面, 没有那些不必要的语法, 所以可以写出结构 性很好的 代码, 更容易阅读。 因此在 Python 的语言世界里, 是可以做到 "code what we think" 的。
另外, Python 有着庞大的用户社群, 包括 NASA、 ANL 和 Google 等国际知名的科研机 构 和公司都选择 Python 做为主要的高性能计算开发语言。 而且 Python 社群是非常开 放的, 开放带来的好处是初学者和开发者很容易从社群中获得帮助和开发文档。
有的人会说, Python 是解释性的语言, 它的类型是动态的, 虽然灵活, 提高了编写代 码的效率, 但运行速度太慢, 不适合做科学计算。 确实 Python 里的每个变量都是一个 对象, 包括整数、 字符串和浮点数这些基本数据类型都是对象, 它们包含的不仅仅是 一种类型的值, 而且都附加了一些额外的东西, 这才带来了你所体验到的灵活性, 但 付出了运行效率的代价。 但这没关系, Python 还有另外一个灵活性,就是 Python 与 其它语言的接口很灵活, 那些需要高效率执行的代码, 可以用 C/C++ 或者 Fortran 实 现, 然后再接到 Python 里用, 这样就可以兼顾灵活性和效率。 Python 还有一个扩展 叫 Cython, 可以直接翻译成 C 代码, 编译后效率也很高。
Python 中很多用于科学计算基础软件包, 它们的内核就是用编译语言实现的, 然后加了一个 Python 接口。 如前面提到的 NumPy、 Scipy等都是这样实现的。
Python 的另一个优点在于,它的内核很小, 只有二十几兆, 其它的功能都是通过模块的 形式加上去了。 除了科学计算, 开发网站、系统管理什么的 Python 也都能胜任。 对比 一下, Matlab 最新的安装文件有十几个 G, 而且很多科学计算之外的事情还干不了。
最后, Python 还是开源免费的, 注意重点在开源。 开放性对于计算数学的科研 人 员和学生来说, 其实是非常重要的。 我们科研人员有一项重要的工作任务, 就 是设计 更高效的算法。 但新算法必须变成程序, 运行出让人信服的实验结果, 才能发表 推广 。 但一般的新算法都是在旧算法的基础上改进而来。 如果手头有旧算法的开源代码 , 就可以直接在代码上做改进, 这样研究效率就会大大提高。 对学生来说, 他们的主要 任务是学习已有的优秀算法, 并且理解它们为什么可以工作的那么好。 如果有开源的算 法代码, 通过仔细地研读分析, 就可以更好地理解和掌握这些算法。 相反, 如果只用 商业软件, 看不到源代码, 学习和研究计算数学的效率就会大大折扣。
但很多人更喜欢免费的商业软件。 在中国, 免费往往是通过盗版方式实现的。 但这 个世界上所谓“免费"的东西, 深究之后基本上都不是免费的, 因为你不出钱, 总会有其 他人来出钱。 正是我们每一个习惯了使用盗版商业软件的人, 免费为国际商业软件巨头 培养了大量的用户, 帮助它们几乎完全占领了中国的工业软件市场, 中国的制造业每 年要花费大量的金钱来购买这些软件。 中国改革开放的历程, 也是国产工业软件坠入深 渊的历程, 我们的计算机和互联网教育, 以及我们每一个“钟情”盗版软件的人, 都负有 不可推卸的责任。
我们的工业界在付出代价, 而我们每个人也在付出代价。 某一天其它专业的同事来找我 , 因为他的论文数值模拟是用商业软件算的, 但他根本不懂里面的有限元算法,无法回 答审稿人的问题。 还有, 他也不敢在论文里面提他是用商业软件算的, 因为他用的是 盗版。 请问,这样的论文出再多有什么用啊?
我们的教育系统也在付出代价。 设想一下, 现在如果我们的学校没有 Windows 系统用了 , 整个学校就可能没法正常运转了, 没有 PPT 就几乎没法上课了。 而我在 UCI 访问的 时候,看到他们公共机房的机器都是开源的 Ubuntu 系统。
很多时候, 无论是大到国家, 还是小到我们自己, 都需要尽量准备一些额外的选项, 因为只有这样才有可能拥有真正的自由。