Iawen's Blog

我喜欢这样自由的随手涂鸦, 因为我喜欢风......

科学计算(scientific computing)是指在科学与工程领域, 使用计算机数学建模和数值分析技术分析和解决问题的过程。科学问题包括不同科学学科中的问题, 如地球科学、空间科学、社会科学、生命科学、物理学和形式科学。

数学建模是指利用数学术语表示设备、物体、现象和观念的行为的建模行为。一般情况下, 数学建模可以帮助人们更好地理解观念、设备和物体的行为或观测值。它可以帮助人们解释观测值, 并对未来的行为进行预测, 或者推导出还没有被观测或测量的结果。

1. 数学部分

1.1 线性方程组

由于线性方程对非线性方程的近似, 或代数方程对差分方程的近似

1.2 非线性方程组

非线性方程组是指一组联立方程, 其中未知变量的阶数大于1。这个系统可以是一维, 也可以是多维。

非线性方程和非线性方程组的解法很多。一维非线性方程的解法有:

  • 二分法(bisection method)
  • 牛顿法(Newton’s method)
  • 割线法(secant method)
  • 插值法(interpolation method)
  • 逆插值法(inverse interpolation method)
  • 逆二次插值法(inverse quadratic interpolation, IQI)
  • 线性分式插值法(linear fractional interpolation)

非线性方程组的解法有:

  • 牛顿法
  • 割线法(secant updating method)
  • 阻尼牛顿法(damped Newton’s method)
  • Broyden法

1.3 最优化方法

模型的可行解都有一个取值范围, 有最大值或最小值。
SciPy有一个优化技术软件包, 具体内容可以参考: http://docs.scipy.org/doc/scipy/reference/optimize.html

1.4 内插法

人们经常通过抽样或实验获取大量数据。这些数据点可以看成某个函数一些自变量位置上的值。人们通常需要估计这个函数在样本范围内的某个位置上的值。估计的过程称为内插法(interpolation)。通常借助曲线拟合与回归分析方法求解。

内插法如下所示:

  • 分段常数内插法(piecewise constant interpolation)
  • 线性内插法(linear interpolation)
  • 多项式内插法(polynomial interpolation)
  • 样条内插法(spline interpolation)
  • 基于高斯过程的内插法(interpolation via Gaussian processes)

1.5 外插法

另一种类似的方法是外插法(extrapolation)。这个方法是要估计函数在样本范围之外的值。
外插法如下所示:

  • 线性外插法(linear extrapolation)
  • 多项式外插法(polynomial extrapolation)
  • 锥外插法(conic extrapolation)
  • 法国曲线外插法(French curve extrapolation)

1.6 数值积分

数值积分(numerical integration)是用数值分析技术求取积分近似值的过程。积分的数值计算过程称为求积分(quadrature)。之所以要使用近似方法求积分, 是因为有些函数不能通过解析方法求精确解。
SciPy程序包提供了积分模块, 请参考: http://docs.scipy.org/doc/scipy/reference/integrate.html

  • 辛普森法则(Simpson’s rule)
  • 梯形法则(trapezoidal rule)
  • 精炼梯形法则(refined trapezoidal rule)
  • 高斯积分法则(Gaussian quadrature rule)
  • 牛顿—柯特斯积分法则(Newton-Cotes quadrature rule)
  • 高斯—勒让德积分法则(Gauss-Legendre integration)

1.7 数值微分

数值微分(numerical differentiation)是利用已知的函数值估计函数导数的过程。
为了计算的快速和便利起见, 人们往往更喜欢用离散值估计函数的导数, 而不是寻找精确解, 因为它虽然存在, 但是往往很难求解。微分方法经常被用于解决最优化问题。

  • 有限差分近似法(finite difference approximation)
  • 微分求积法(differential quadrature)
  • 有限差分系数(finite difference coefficients)
  • 插值微分法(differentiation by interpolation)

1.8 微分方程

微分方程(differential equation)是一种描述导数与其函数关系的数学方程式。如果函数是一个物理量, 那么导数就是这个物理量的变化率, 微分方程就是这个物理量和其变化率的关系。
许多情况下, 微分方程可能无法直接求解。因此, 通常都用数值方法求近似解。
微分方程可以分为两类:常微分方程(ordinary differential equations, ODE)和偏微分方程(partial differential equations, PDE)。常微分方程是包含一个自变量的函数及其偏导数的微分方程。偏微分方程是包含多个自变量的函数及其导数的微分方程。多自变量函数的偏导数就是函数对每一个自变量的导数。

解常微分方程的方法如下:

  • 欧拉方法(Euler’s method)
  • 泰勒级数法(Taylor series method)
  • 龙格—库塔法(Runge-Kutta method)
  • 四阶龙格—库塔法(Runge-Kutta fourth order formula)
  • 预估—校正法(predictor-corrector method)

解偏微分方程的方法如下:

  • 有限元法(finite element method)
  • 有限差分法(finite difference method)
  • 有限体积法(finite volume method)

1.9 随机数生成器

随机数生成器是一种产生不包含任意模式的序列的算法或过程。之所以称为随机数, 是因为它们没有任何模式可循。
随机数生成器主要有两类, 真随机数生成器和伪随机数生成器。真随机数生成器通过真实的物理过程生成随机数, 例如硬盘的实际读写时间。伪随机数生成器通过计算机算法生成随机数。还有一种随机数生成器通过统计分布生成随机数, 例如泊松分布、指数分布、正态分布、高斯分布等。
一些伪随机数生成器如下所示:

  • BBS随机数生成器(Blum Blum Shub)
  • Wichmann-Hill随机数生成器(Wichmann-Hill)
  • 进位—互补—乘法随机数生成器(complementary-multiply-with-carry)
  • 反向同余随机数生成器(inversive congruential generator)
  • ISAAC随机数生成器(ISAAC (cipher))
  • 滞后斐波那契随机数生成器(lagged Fibonacci generator)
  • 线性同余随机数生成器(linear congruential generator)
  • 线性反馈移位寄存器(linear-feedback shift register)
  • 最大周期(索菲·热尔曼质数)倒数随机数生成器(maximal periodic reciprocals)
  • 梅森旋转随机数生成器(Mersenne twister)
  • 进位相乘随机数生成器(multiply-with-carry)
  • Naor-Reingold伪随机数生成器(Naor-Reingold pseudo-random function)
  • Park-Miller随机数生成器(Park-Miller random number generator)
  • WELL伪随机数生成器(Well-equidistributed long-period linear)

2. Python 科学计算

  • 画图:目前, 最流行的二维图制作程序库是matplotlib。还有许多画图包, 如Visvis、 Plotly、HippoDraw、 Chaco、 MayaVI、 Biggles、 Pychart、 Bokeh。还有一些画图程序包是在matplotlib的基础上改进功能, 如Seaborn和Prettyplotlib。
  • 最优化: SciPy程序包里有最优化模块。 OpenOpt和CVXOpt同样具有最优化功能。
  • 高级数据分析: Python可以通过RPy或R/S-Plus接口与R语言配合使用, 实现高级的数据分析功能。 Python自己的高级数据分析工具就是大名鼎鼎的pandas了。
  • 数据库: PyTables是一种用于管理分层数据库的工具。这个软件包是以HDF5数据库为基础建立的, 用于处理较大的数据集。
  • 交互式命令行: IPython是Python的交互式编程工具。
  • 符号计算: Python具有符号计算功能的程序包有SymPy和PyDSTool。本章后面会介绍符号计算方法。

2.1 SciKits

SciKits程序库为SciPy、 NumPy和Python提供了专业化的扩展。 SciKits的一些软件包如下:

  • scikit-aero: Python航空工程计算程序包。
  • scikit-bio:提供生物信息学领域的数据结构、算法和教育资源程序包。
  • scikit-commpy: Python数字通信算法程序包。
  • scikit-image: SciPy图像处理程序包。
  • scikit-learn: Python机器学习和数据挖掘程序包。
  • scikit-monaco: Python蒙特卡罗算法程序包。
  • scikit-spectra:建立在Python pandas上的光谱学程序包。
  • scikit-tensor: Python多线性代数和张量分解(tensor factorizations)程序包。
  • scikit-tracker:细胞生物学的目标检测和跟踪程序包。
  • scikit-xray: X射线科学的数据分析工具。
  • bvp_solver: Python求解两点边界问题的程序包。
  • datasmooth: SciKits提供的数据平滑程序包。
  • optimization: Python数值优化程序包。
  • statsmodels: SciPy统计学计算与建模程序包。

2.2 NumPy

NumPy 是Python科学计算的基础程序包。它提供了多维数组和基本数学运算的功能, 比如线性代数。

N维数组(NumPy的ndarray对象)与列表类似, 但是更加灵活高效。 N维数组是一个数组对象, 可以表示固定数量的多维数组。这个数组应该是齐次的(homogeneous)。它通过dtype类型的对象定义数组中元素的数据类型。这个对象可以定义数据的类型(整型、浮点型或Python对象类型)、数据的字节数以及字节存储顺序(byte ordering, 包括big-endian高位至低位与little-endian低位至高位)。另外, 如果数据类型是record或sub-array, 类型还会包含具体的细节信息。真实的数组可以通过numpy.array、 numpy.zeros、 numpy.empty三种方法创建。

N维数组另一个重要特性是数组大小是可以动态调整的。而且如果用户需要从数组中移除一些元素, 可以通过NumPy的模块实现戴面具数组(masked array)。在许多科学计算场景中, 人们都需要删除/清理异常数据。 numpy.ma模块能够实现为数组戴面具的功能, 轻松地移除数组中的元素。

通用函数(unfunc)是对ndarray进行一个元素一个元素操作的函数。它也支持广播、类型转换和一些其他重要的特征。在NumPy中, 广播是对不同维度数组的操作过程。

NumPy加入了特定功能的模块, 例如线性代数、离散傅里叶变换、随机采样和矩阵代数库:

  • numpy.linalg:这个模块支持线性代数的各种功能, 如数组和向量的内积、外积和点积;向量和矩阵的范数;线性矩阵方程的解;矩阵转置的方法。
  • numpy.fft:离散傅里叶变换在数字信号处理中有广泛的应用。这个模块中的函数可以计算各种类型的离散傅里叶变换, 包括一维、二维、多维、转置和傅里叶变换。
  • numpy.matlib:这个模块包括那些默认返回矩阵对象而不是ndarray对象的函数。这些函数包括empty、 zeros、 ones、 eye、 rapmat、 rand、 randn、 bmat、 mat和matrix。
  • numpy.random:这个模块包括在特定人群或范围中执行随机抽样的函数。它也支持随机排列组合的生成。另外, 它还包括一些支持各种基于统计分布生成的随机抽样数值的函数。

numpy.histogram2d() 可以在地图图片的网格中统计二维散列点的频度。

numpy 差集、异或集、并集、交集 setdiff1d() setxor1d() union1d() intersect1d()

2.3 SciPy

SciPy是一个为科学家和工程师开发的Python程序库, 用来完成科学计算相关的功能。它有许多功能, 如最优化方法、线性代数、积分、插值方法、图像处理、快速傅里叶变换、信号处理以及一些特殊函数。它可以解常微分方程以及其他科学与工程问题。它建立在NumPy数组对象的基础上, 是NumPy技术栈的重要成员之一。

SciPy包括以下子程序包。

  • constants:物理常数和转换因子。
  • cluster:层次聚类、矢量量化和K-means聚类。
  • fftpack:离散傅里叶变换算法。
  • integrate:数值积分程序。
  • interpolate:插值工具。
  • io:数据输入输出。
  • lib: Python外部库包装器。
  • linalg:线性代数程序。
  • misc:附件(例如图像读写操作)。
  • ndimage:多维图像处理的各种功能。
  • optimize:优化算法, 包括线性规划。
  • signal:信号处理工具。
  • sparse:稀疏矩阵及其相关算法。
  • spatial: KD树、 RNN(最近邻搜索)算法、距离函数。
  • special:特殊函数。
  • stats:统计学函数。
  • weave:可以把C/C++代码写成Python多行字符串执行的工具。

2.4 pandas

pandas是一个用于数据分析和数据操作的工具包。 pandas由一些数据结构组成, 这些数据结构在Python中用于科学数据分析。 pandas开发的终极目标是设计一个强大和灵活的数据操作和分析工具。pandas数学功能不足, 目前只支持一些简单的回归方法。但是, 我们可以从statsmodels和scikit-learn里找到其他功能。

pandas数据结构的范围可以从一维到三维。 Series是一维的, DataFrame是二维的, Panel是三维甚至更高维的数据结构。

  • Series
    Series是一维对象, 类似于数组、列表或表格中的一列。它可以存储任意Python数据类型, 包括整型、浮点型、字符串以及任意Python对象。

  • DataFrame
    pandas的二维数据结构叫DataFrame。 DataFrame是由行和列构成的数据结构, 类似于数据库表或Excel表格。

  • Panel(not supported by the pandas module version that is above 0.25.)
    Panel数据结构可以存储三维数据。这个名称源自统计学和计量经济学, 里面的多维数据经常有多个时间周期。通常, Panel包括同一个组织或人的多个时间周期的多项数据。
    Panel数据结构有三个组成部分——项目(item)、主轴(major axis)和次轴(minor axis), 解释如下:

    • items:指的是Panel里每个DataFrame的数据项。
    • major axis:指的是每个DataFrame的索引(行标签)。
    • minor axis:指的是每个DataFrame的列。

2.5 sympy

SymPy包括许多功能, 从基本的符号算术到多项式、微积分、求解方程、离散数学、几何、统计和物理。它主要处理三种类型的数据:整型数据、实数和有理数。整数即不带小数点的数字, 而实数是带小数点的数字。有理数包括两个部分:分子和分母。可以用Ration类定义有理数, 该类需要两个数字。

3. 数据可视化

3.1 matplotlib

matplotlib是Python最流行的画二维图形和图表的软件包。它为不同类型的图形和图表提供了简便快捷的数据可视化方式。它还支持不同的图形导出格式。

最重要的matplotlib对象是Figure。它包含并管理着图表/图形的所有元素。 matplotlib将图形的显示和操作与Figure对象在用户界面屏幕或设备上的渲染分离开来。

matplotlib的架构分为三层, 分别是后端(backend)、艺术家(artist)和脚本(scripting)。这三层构成一个栈, 上层架构懂得与下层架构通信的方式, 而下层架构不知道上层架构的动作。其中, 后端架构是底层, 脚本架构是顶层, 艺术家层是中间层。

  • 脚本层(pyplot)
    matplotlib的pyplot接口非常直观, 科学家和分析师使用起来非常简单。它简化了完成数据分析与可视化的常规操作。 pyplot接口管理创建图形、坐标轴以及它们与后端层的连接。它隐藏了表现图形和坐标轴的数据结构的内部细节。

  • 艺术家层
    这个层的基类是matplotlib.artist.Artist。它知道如何将要画的内容渲染到画布上。
    在matplotlib的Figure中显示的每个对象都是Artist的一个实例, 包括图形标题、坐标轴和数字标签、图像、线、条形图与点。每一个Artist实例都是为了这些元素而创建的

  • 后端层
    后端层是matplotlib的底层, 里面实现了大量的抽象接口类, 即FigureCanvas、 Renderer和Event类。其中, FigureCanvas类扮演绘画底板的角色。与真实的绘画类比, FigureCanvas就像是绘画用的纸。 Renderer类实现上色的功能, 好像是真实绘画中使用的刷子。 Event类处理键盘与鼠标动作。

matplotlib为图形提供了不同的颜色、线形和标记。绘图函数的第三个参数表示线条的颜色、线形和标记。第一个字符表示颜色, 它的值可以是b、 g、r、 c、 m、 y、 k和w中的任何一个。其中k表示黑色(black), 其他字母的含义都很明显。第二个字符表示线条的形状, 可以用-、 –、 -..和:表示。这些符号分别表示实线、虚线、点划线和点线。最后一个字符表示标记, 如.、 x、 +、 o和*。