MATHEMATICA 教程

关于内部实现的一些注释

引言

有关 Mathematica 内部实现的一般讨论在 "Mathematica 的内部信息" 一节给出. 这里给出的是特殊特征的简短注释.

这些注释适用于版本7. 算法以及实现的其它方面随将来版本中的修改而改变.

需要强调的是,这些注释给出的只是所用到的基本方法和算法的大致描述. 实际的实现通常涉及其它许多要素.

举例来说,注释仅简单的说 DSolve 使用Kovacic 算法求解二阶线性微分方程. 但是用于实现这一功能的内部代码却有60多页长,包含了大量其它算法和大量精妙的思想.

数据结构和内存管理

一个 Mathematica 表达式在内部是由一组邻接的指针构成,第一个指针指向头部,其余指针指向它的后续元素.

每一个表达式包含一个特殊形式的哈希代码,这个代码用在模式匹配和计算中.

对每个符号来说,则存在一个重要的符号表入口,用于记录该符号的所有信息.

大部分的原始对象,如串和数,被单独分配;而计算中生成的小整数和特定近似数的唯一副本却一直保留.

Mathematica 使用的每一块内存保留了一个记载它被调用的次数的记录. 当这个记录为0时,内存自动释放.

表达式中元素的连续存放减少了内存的分块和交换. 但是,当一个长表达式中一个单独的元素被修改时,这可能导致对指针数组全部复制. 为了避免这种复制,Mathematica 使用了许多基于调用次数和预分配的优化技术.

在适当的场合,大的数列和嵌套数列自动以机器整数或实数的打包数组存放. Mathematica 编译器自动被用来编译将要重复用到这种打包数组上的复杂函数. MathLinkDumpSave 及各种 ImportExport 格式在外部使用打包数组.

基本的系统特性

Mathematica 实质上是一个解释程序,它通过调用由头的符号表入口指向的内部代码扫描它遇到的表达式.

任何变换法则 —— 无论是以 的形式还是在一个定义中给出 —— 都自动编译成允许快速模式匹配的一种形式. 许多不同类型的模式通过特殊代码加以区分和处理.

考虑到空白和模式的其它特征,在模式匹配中使用了一个哈希表.

与模式匹配有关的内部代码约有250页.

字符串的模式的执行是通过使用一个 PCRE 正则表达式库的符号扩展实现.

当大量的定义用于描述一特定符号时,会自动使用 Dispatch 格式生成一个哈希表,以便能迅速找到合适的法则.

数值及相关函数

数的表示和数值计算

  • 大型整数和高精确度近似数,根据机器整数的长度以 位储存.
  • 精确度在内部作为浮点数保存.
  • IntegerDigitsRealDigits 和相关的进制转换函数使用的是递归分治算法. 相似的算法用于数的输入和输出.
  • N 使用一个自适应过程来提高它内部工作精确度以便达到所要求的任意一种总体精确度.
  • FloorCeiling 和相关的函数使用类似于 N 的自适应过程由准确输入生成准确的结果.

基本算法

  • 大整数和高精度近似数的乘法通过使用交叉教科书、Karatsuba、三通 Toom-Coo k和数论变换算法实现.
  • 机器代码具体架构的优化通过使用GMP实现.
  • 整数幂通过左右二进制分解算法得到.
  • 近似数的倒数和有理数幂使用 Newton 法实现.
  • 准确的根由数值估计起始得到.
  • 默认使用有效算术来实现不等于机器精度的近似数的所有运算.

伪随机数

  • 对于 RandomRealRandomInteger 等函数,默认的伪随机数生成器使用一种基于元细胞自动操作的算法.

数论函数

  • GCD 使用HGCD 算法、Jebelean-Sorenson-WebG 加速GCD算法,加上一个由 Euclid 算法与一个基于2的幂循环排除算法组合而成的算法.
  • PrimeQ 首先使用小素数检测整除性,然后使用 Miller-Rabin 强伪素数检测2进制和3进制,最后使用一个 Lucas 测试检测.
  • 至1997年为止,该过程仅对 证明是正确的,并且可以猜想的是,对于更大的 ,该过程仍可能将一个复合数判定是素数.
  • Primality Proving Package 包中包含了一个较慢的算法,该算法被证明对所有的 都是正确的. 它能对是否是素数返回一个明确认证.
  • FactorInteger 在试除法、Pollard 、Pollard rho、椭圆曲线和二次筛算法之间切换.
  • PrimePrimePi 使用稀疏缓存和筛选. 对于较大的 PrimePi 使用的是基于素数密度的渐进估计的 Lagarias Miller Odlyzko 算法,并被转换给出 Prime.
  • LatticeReduce 使用的是 Lenstra-Lenstra-Lovasz 网格缩减算法的 Storjohann 变形.
  • 为了找到所要求的一定数目的项, ContinuedFraction 使用修正Lehmer间接法,并通过一种自动重启的分治算法来降低每一步所必需的数值精确度.

复合函数

  • 大部分复合函数使用稀疏缓存和递归法.
  • Binomial 及其相关函数使用一个分治算法来平衡中间乘积的位数.
  • n! 使用一种基于素数幂动态分解的 Schönhage 的 算法.
  • Fibonacci[n] 使用基于 的二进制序列的迭代方法.
  • 对于较小的 PartitionsP[n] 使用 Euler 五边形公式,而对较大 ,则使用非递归的 Hardy-Ramanujan-Rademacher 方法.
  • 伯努利数的计算使用的是递归方程或 Fillebrown 算法,这取决于数的指数.
  • Bernoulli 多项式是由 Bernoulli 数构建.

初等超越函数

  • 指数函数和三角函数使用Taylor级数、参数加倍的稳定递归,以及函数关系.
  • 对数和反三角函数使用Taylor级数以及函数关系.

数学常数

  • 低于一定规模的常数的值在计算后就缓存.
  • 二进位分裂被用来对常数计算进行细分.
  • Pi 使用 Chudnovsky 公式计算.
  • E 通过它的级数展开进行计算.
  • Catalan 通过广义超几何和进行计算.

特殊函数

  • 对机器精度,大部分特殊函数使用 Mathematica 所导出的有理极小极大近似. 下面的注释主要应用到任意精确度.
  • 一般地,对于多项式和超几何函数,正交多项式采用稳定的递归公式.
  • Gamma 使用递归、函数方程和 Binet 渐进公式.
  • 不完全 gamma 和 beta 函数使用超几何级数及连分式.
  • PolyGamma 使用 Euler-Maclaurin 和式、函数方程和递归.
  • PolyLog 使用 Euler-Maclaurin 和式、不完全gamma函数的展开、数值积分和 Hurwitz zeta 函数的一种函数方程.
  • Zeta 及其相关函数使用 Euler-Maclaurin 和式以及函数方程. 在临界区附近也使用 Riemann Siegel 公式.
  • StieltjesGamma 使用用 Keiper 算法,该算法基于一个zeta函数的积分表示的数值积分和使用 Bernoulli 数进行交错级数求和.
  • 误差函数使用不完全 gamma 函数和超几何函数进行求值.
  • 与指数积分相关的函数全部使用不完全 gamma 函数进行求值.
  • 逆误差函数使用二分法搜索和高阶的广义 Newton 法.
  • 贝塞尔函数使用级数和渐进展开式. 对于整数次,有些也使用稳定向前递归格式.
  • 超几何函数使用函数方程、稳定的递推关系、级数展开、渐进级数和帕德逼近式. 有时也使用 NSumNIntegrate 的方法.
  • ProductLog 使用始于有理近似和渐进展开的高阶 Newton 法.
  • 椭圆积分使用递减高斯变换来求值.
  • 椭圆 theta 函数使用级数项的递归计算和模变换的级数和.
  • 其它椭圆函数主要使用代数几何平均数方法.
  • Mathieu 函数使用傅立叶级数. Mathieu 特征函数使用广义的 Blanch-牛顿法.

数值积分

  • NIntegrate 使用符号预处理来解决函数对称性问题,将分段函数扩展至各情形,将由不等式设定的区域分解为单元.
  • 如果直接给出了 的设置,NIntegrate 缺省使用 Method->"QuasiMonteCarlo".
  • :基于Kronrod点计算的带误差估计的自适应Gaussian积分.
  • :非自适应双指数积分.
  • :基本梯形法.
  • ::用来实现包括三角函数和Bessel函数的积分的变换.
  • :自适应 Genz-Malik 算法.
  • :非自适应蒙特卡洛方法.
  • :非自适应 Halton-Hammersley-Wozniakowski 算法.

数值的和与乘积

  • 如果比率测试比不为1,则使用Wynn epsilon算法求解一系列部分和或部分积.

数值微分方程

  • 对于普通的微分方程,NDSolve 默认使用一种 LSODA 方法,在非刚性Adams方法与刚性Gear反向微分方法之间切换.
  • 对线性边值问题使用 Gelfand-Lokutsiyevskii 追赶法.
  • 微分代数方程使用IDA,它基于重复 BDF 的和牛顿迭代法的.
  • 的偏微分方程(PDE),使用直线方法.
  • NDSolve 支持显式 Method 的设置,涵盖了文献中的许多已知的方法.
  • NDSolve 及其相关函数的代码的代码约有1400页.

近似方程求解和优化

  • 多项式求根的实现基于 Jenkins-Trau b算法.
  • 对于稀疏线性系统, SolveNSolve 使用一些有效的数值方法,这些方法主要基于带 Markowitz 乘积的 Gauss 因数分解(约250页代码).
  • 对代数方程组,NSolve 首先使用一个有效的单项式排序计算出一个数值的 Grobner 基,然后使用特征值方法来确定根的数值解.
  • FindRoot 使用了减幅 Newton 法,正割法和 Brent 方法.
  • 通过 Method->Automatic 的设置和两个初始值,FindMinimum 使用 Brent 的主轴方法. 通过对每个变量赋以一初始值,FindMinimum 使用 BFGS 形式的拟 Newton 法,对于大型的系统具有有限的内存变体.
  • 如果极小化函数是一个平方式的和,FindMinimum 使用 Levenberg-Marquardt方法(Method->"LevenbergMarquardt").
  • LinearProgramming 使用单纯形法和修正单纯形法,且当 Method->"InteriorPoint" 时,使用原有对偶内点法.
  • 对于线性情形,NMinimizeNMaximize 使用与 LinearProgramming 相同的方法. 对于非线性情形,尤其是当出现整数变量时,则使用 Nelder-Mead 方法,辅以差分演化.

数据处理

  • Fourier 使用结合长度素因子分解的FFT算法. 当素数因子很大时,则使用快速卷积方法来保持 的渐进复杂度.
  • 对于实数输入,Fourier 使用一个实变换方法.
  • ListConvolveListCorrelate 尽可能使用 FFT 算法. 对于准确的整数输入,则使用二元分割将问题简化为大整数乘法.
  • Fit 使用的是奇异值分解. FindFit 对于线性最小二乘情形使用相同的方法,对于非线性最小二乘情形使用 Levenberg-Marquardt 方法,其它时候使用一般的 FindMinimum 方法.
  • CellularAutomaton 通常使用数元截割的位包装并行运作. 对于基本规则,并行操作使用的是最优布尔函数,而对于许多极权规则,使用的是适时编译位包装表. 在二维时,对于运行于 Moore 邻域和无限背景状态时的双色静态规则,则尽可能使用稀疏位包装数组,只更新激活状态的集群.

近似数值线性代数

  • 机器精度矩阵通常被转化为一个特殊的内部表示来进行处理.
  • 涉及到模式规则的 SparseArray 使用柱形代数分解来找到连接的数组元件. 稀疏矩阵使用压缩稀疏行格式被内部存储,被推广至张量任意秩.
  • 对于密集数组,扩展至任意精度的 LAPACK 算法在适当时被使用.
  • BLAS 技术被用于特别机器结构的优化.
  • 对于稀疏矩阵,LinearSolve 使用 UMFPACK 多面直接求解法, 当 Method->"Krylov" 时使用 Krylov 迭代法,并且由一个不完整的LU分解预处理. 对于高精度数,它使用自适应迭代改进法. EigenvaluesEigenvectors 使用 ARPACK Arnoldi 方法.
  • MatrixExp 使用变量序的帕德逼近,使用 Paterson-Stockmeyer 或 Krylov 子空间近似方法进行有理矩阵函数的计算.

准确数值线性代数

  • Modulus->n 时,则使用模 Gaussian 消元法.
  • Det 使用模方法和行变换,通过使用中国剰余定理构造出结果.
  • Eigenvalues 通过对特征多项式进行插值来实现.
  • MatrixExp 使用 Putzer 方法或者 Jordan 分解.

代数和微积分

多项式处理

  • 对于单变量多项式,Factor 使用一种 Cantor-Zassenhaus 算法的变形按模分解一个素数,然后使用Hensel上升重组法在整数域构造因子.
  • 在代数数域上进行因式分解时先找到有理数域上的一个素元,然后使用Trager算法来实现.
  • 对多变量多项式,Factor 通过用适当的整数选择替换除一个变量外的所有变量,然后分解所得到的单变量多项式,并使用 Wang 的算法重新构造多元因数来实现.
  • 除一般多项式处理外的 Factor 的内部代码约有250页.
  • Resultant 要么使用显式子结式多项式剩余序列要么使用附有中国剰余定理的模序列.
  • Apart 要么使用帕德技术要么使用待定系数法.
  • PolynomialGCDTogether 通常使用包括 Zippel 稀疏模算法在内的模算法,但在某些情况下使用子结式多项式剩余序列.
  • 对于多变量多项式,则结合使用中国剰余定理和稀疏差值法.

符号线性代数

  • Inverse 使用了余子式展开和行变换. 主元通过寻找简单表达形式来选取.
  • 对小矩阵,Det 直接使用余子式展开,而对较大的矩阵则使用高斯消元法.
  • MatrixExp 首先找到特征值然后使用 Putzer 方法.
  • 各种函数的零点测试通过在随机数值已代入变量后使用符号变换和基于区间的数值近似来实现.

准确方程求解与化简

  • 对线性方程使用高斯消元法和其它一些线性代数方法.
  • 表示代数数的 Root 对象常常使用有效的数值方法来分隔开和处理. 当 ExactRootIsolation->True 时,对于实根,Root使用基于 Descartes 符号法则的一个算法的连分式,而对于复根则使用 Collins-Krandick 算法.
  • 对于单一的多项式方程,Solve 使用四阶之内的显式公式,并试图使用 FactorDecompose 化简多项式,和识别割圆以及其它特殊多项式.
  • 对多项式方程组, Solve 构造一个 Gröbner 基.
  • 对非多项式方程, Solve 试图改变变量并增加多项式条件.
  • Solve 及其相关函数的代码约有500页.
  • 对于多项式方程组,在实数域上 Reduce 使用柱形代数分解,在复数域上使用 Gröbner 基的方法.
  • 对于代数函数,Reduce 构造等价的纯粹多项式系统. 对于超越函数,Reduce 产生由超越条件组成的多项式方程组,然后使用函数关系和逆图像信息数据库将其化简. 对于分段函数,Reduce 进行符号式扩展来构造一个连续方程组的集合.
  • 对于单变量超越方程,Reduce 用超越 Root 对象来表示解集. 对于实数域上的指对数函数方程,Reduce 使用一种准确的指对数根隔离算法. 对于有界实数或复数域上的解析函数方程,Reduce 使用有效数值方法. 对于初等函数,根的数量和位置都采用区间算术方法被充分验证. 对于非初等函数,根的数量的验证取决于数值积分的正确性,根的位置的验证取决于由 Mathematica 的有效算术所提供的准确性估计的正确性.
  • CylindricalDecomposition 使用 Collins-Hong 算法并对导向性良好的集合结合使用 Brown-McCallum 投影,对其它集合结合使用 Hong 投影. CAD 的构造是通过 Strzebonski 的基于系统学的方法,使用由准确代数数计算支持的验证后的数字. 对于0维方程组则使用 Gröbner 基的方法.
  • GenericCylindricalDecomposition 使用一种 CAD 算法的简化版本,它使用的是较简单的投影算符,并且只构造有理数采样点的单元.
  • 对于丢番图方程组,Reduce 使用 Hermite 正规形式对线性方程进行求解,使用 Contejean-Devie 方法对线性不等式进行求解. 对于单变量多项式方程,它使用一种改良的 Cucker-Koiran-Smale 方法,而对于二元二次方程,对于椭圆,它使用 Hardy-Muskat-Williams 方法,对于 Pell 及其它情形它使用经典的技术.Reduce 囊括了用于大约25个丢番图方程类别的专门方法,包括用于 Thue 方程的Tzanakis-de Weger 算法.
  • 对于素数模量,Reduce 对线性方程采用线性代数,对于多项式方程在素数域上采用 Gröbner 基. 对于复数模量,则在整数域上使用 Hermite 正规形式和 Gröbner 基.
  • Resolve 使用的方法主要源自 Reduce 的方法的一个优化子集.
  • Reduce 及其相关函数使用大约350页的 Mathematica 代码以及1400页C代码.

准确优化

  • 对于线性情形,MinimizeMaximize 使用准确的线性编程方法. 对于多项式,它们使用的是柱形代数分解. 对于封闭和有界盒框的解析情形,它们使用的方法基于 Lagrange 乘数.
  • 对于整数变量的有界线性情形,MinimizeMaximize 使用分支定界法进行整数线性编程,而预处理格化简完成.
  • 分段函数被符号性扩展,其中每一段函数被当作一个单独的优化问题来处理.

化简

  • FullSimplify 自动使用约40种一般代数变换以及大约400种特殊数学函数的法则.
  • 广义超几何函数大约使用了70页的 Mathematica 变换法则进行化简. 这些函数是 Mathematica 中许多微积分运算的基础.
  • FunctionExpand 使用广义高斯算法来展开含有 的有理数倍参数的三角函数.
  • 如果指定变量是实数,多项式的约束使用柱代数分解的方法来处理,而线性约束由单纯形算法或 Loos-Weispfenning 线性量词消去法处理. 对于严格的多项式不等式,则使用 Strzebonski 的通用 CAD 算法.
  • 如果多项式中包含方程,则采用 Gröbner 基方法.
  • 对于非代数方程,则要使用关系数据库从它们的定义域中确定值域. 只要值域是半代数集合,则使用面向多项式的算法.
  • 对整数函数,则以 Mathematica 法则的形式使用几百个数论的定理.
  • 分段函数使用一种基于分段可分配性的递归步骤来处理.

微分和积分

  • 微分使用缓存来避免重复计算局部结果.
  • 对于不定积分,只要被积函数和积分能被初等函数、指数积分函数、多对数及其相关函数表示,则使用广义 Risch 算法.
  • 对于其它不定积分,则使用带模式匹配的启发式化简.
  • Mathematica 中的算法囊括了诸如 Gradshteyn-Ryzhik 之类标准参考书中的所有不定积分.
  • 不包含奇点的定积分主要通过求不定积分的界来实现.
  • 许多其它的定积分使用了 Marichev-Adamchik Mellin 变换方法来实现. 其结果最初常常表示由 Meijer G 函数表出,从而可以使用 Slater 定理转换为超几何函数然后进行化简.
  • 对于由不等式界定的多维区域上的积分,则是通过递归分解成不相交的柱形或三角单元来计算得到.
  • Integrate 使用了约500页 Mathematica 代码和600页C代码.

微分方程

  • 常系数线性方程组使用矩阵指数的方法求解.
  • 解能表示为初等函数及其积分的变系数二阶线性方程使用 Kovacic 算法求解.
  • 高阶线性方程通过 Abramov 和 Bronstein 算法求解.
  • 系数为有理函数的线性方程通过 Mellin 变换以特殊函数的形式求解. 系数更为一般的方程尽可能使用变量变换进行化简.
  • 解能表示为有理函数、系数为有理函数的线性方程组使用 Abramov-Bronstein 消元法求解.
  • 非线性方程尽可能通过对称化简技巧求解. 对一阶方程采用古典方法,而对二阶方程和方程组则使用积分因子和 Bocharov 方法. Abel 方程通过计算不变量来确定等价类别的方法求解.
  • 分段方程通常通过分解为一系列边值问题来求解.
  • Mathematica 中的算法囊括了诸如 Kamke 之类标准参考书中的几乎所有普通微分方程.
  • 对于线性或伪线性偏微分方程,使用的是变量分离或对称化简.
  • 对于一阶非线性偏微分方程,完整积分的计算通过 Legendre、Euler 及其它变换进行化简得到.
  • 对于微分代数方程,使用一种基于核心幂零分解对奇点部分进行隔离的方法.
  • 高阶微分方程的分解方法使用来自于 Bronstein 和 van Hoeij.
  • DSolve 使用了约300页 Mathematica 代码和200页C代码.

和与乘积

  • 多项式级数使用 Bernoulli 和 Euler 多项式求和.
  • 对于有理、超几何、 有理及其它类型的不确定、有限及无限求和使用的是专门的算法,这包括了以 广义超几何函数的形式返回答案的 Adamchik 算法.
  • 含有多重伽马函数的级数使用积分表示求和.
  • 狄利克雷及其相关级数使用模式匹配来求和.
  • 对于无穷级数,要进行 d'Alembert 和 Raabe 收敛性检验.
  • Mathematica 中的算法囊括了诸如 Gradshteyn Ryzhik 之类的标准参考书中90%以上的求和方法.
  • 乘法既使用多项式、有理、 有理、超几何、周期及其它类别的专门算法,也使用模式匹配实现.
  • SumProduct 使用了大约100页的 Mathematica 代码.

级数和极限

  • Series 通过递归对带参数级数展开的函数进行级数展开实现.
  • 极限通过级数和使用其它方法求得.
  • 极限和级数的假设使用嵌入于 RefineSimplify 中的一种一般目的评估与假设机制来处理.

递归方程

  • RSolve 使用矩阵幂来求解常系数线性方程组.
  • 解能以超几何项给出的多项式系数线性方程使用 van Hoeij 算法求解.
  • 解能以有理函数的形式给出的有理函数系数的线性方程组使用 Abramov-Bronstein 消元法求解.
  • 非线性方程通过变量变换、Göktaş 对称化简法或三角幂法求解.
  • Mathematica 中的算法囊括了所有数学文献中曾讨论过的大部分普通微分方程、 微分方程和函数微分方程.
  • 对于代数差方程,使用一种基于核心幂零分解对奇点部分进行隔离的方法.

输出和接口

图形

  • 三维图形渲染的优化在可能之处使用硬件加速实现.
  • 三维渲染程序采用两种不同的方法多边形排序. 对于不包括透明度的图形场景,使用一种硬件加速深度缓冲器. 否则,渲染程序使用二进制空间分割树从任何角度进行多边形的分裂和排序. BSP 树的创建较慢,并且不是硬件加速,但它提供了支持多边形的最一般的能力.
  • 笔记本中的图形应用于内核图形基元的 MakeBoxes 中的排版规则的结果. MakeBoxes 通常保留着内核图形的结构.
  • 图形可以被 Mathematica 计算. 默认情况下,它们通常会计算其内核表示,尽管其它计算规则可能通过超载 MakeExpression 来实现.
  • 笔记本使用一种自定义的与平台无关的位图图像格式. 这种格式用于位图单元和对输出的图形外进行观缓存.
  • 对于支持图形反锯齿的系统,前端选择性地使用反锯齿,以确保二维图形的最佳渲染. 三维图形根据 Preferences 对话框的设置均匀的反锯齿.

可视化

  • 在第6版中,涉及返回非数字值的函数的警告信息在默认情况下为 Off. 这些信息包括 , .
  • 绘图函数包括几个最先进的几何算法,并且特别强调视觉质量.
  • 排除选项利用了高度精密的符号处理. 当带有 Exclusions 选项的绘图函数首次使用时,系统需要加载排除包,这会导致轻微的延迟.
  • 排除功能通过点和曲线周围的数值抵消来处理跳跃和奇点. 在某些情况下可能会出现不想要的差距. 使用 Exclusions->None 可以避免这种缺陷.
  • ColorFunction 被用于曲线时(例如在 PlotParametricPlot 中),非常大的表达式可以创造,因为每一段都生成一个单独的颜色指令,可能会创建非常大的表达式.
  • 自适应细化纯粹基于几何性质. 对于具有 ColorFunction 的曲线,可能需要增加 PlotPoints 数量得到平滑的色彩过渡.
  • MeshFunctions 使用数值方法通过检查运算符号来确定切削值,所以像 AbsBoole 函数不能被用来推动网格的构造.
  • 网格线或轮廓线是几何图形的一个组成部分,而不是覆盖层. 因此,大量的网格线或轮廓线将产生大量相应于 GraphicsComplex 的多边形.
  • ContourPlot中,首先应用 MaxRecursion 的值确定主要特征,然后使用第二递归阶段理顺轮廓曲线. 请注意的是, MaxRecursion->n 的值可能产生高达 个递归层.
  • ContourPlot3D 可以识别代数函数并执行一个符号分析,以确定所有的奇点. 在某些情况下, MaxRecursion 的默认值可能不足以解决所有沿奇点的细节. 在这种情况下要增大 MaxRecursion.
  • ContourLabels 以使标签之间的最小距离最大化的方式放置. 文字风格和文字大小在确定最佳位置时不予考虑.
  • 对于不规则的数据, ListPlot3D 构造一个 Delaunay 三角. 对于大型的坐标值,可能会放弃一些点. 缩放的数据将改善结果.
  • ListSurfacePlot3D 是一个重建的函数,它试图找到一个尽可能接近数据的表面. 采样值低的区域将导致表面上有洞的出现.
  • ListSurfacePlot3D 中的数据点用于构造寻找零级表面的距离函数. 原始点并不是最终结果的一部分.

前端

  • 前端使用 MathLink 同时实现与内核的通信以及它内部不同成分之间的通信.
  • 前端中所有菜单项和函数通过使用 Mathematica 表达式指定.
  • 配置文件和优先选择文件使用 Mathematica 语言格式.
  • 文档在 Mathematica 的笔记本中编写. 然后经特殊的 Mathematica 程序处理,建立最终的文档笔记本和在线文档网站及其它有关 Mathematica 的内容,如语法着色的信息数据库和使用信息.
  • 通过计算完成后的内核查询,前端保持有关用户变量的语法着色信息. 当几个计算排队时,查询可能不会在每一次计算后发生. 查询总是会发生在队列中的最后计算之后.
  • 许多前端的嵌入对话框以 Mathematica 笔记本的形式实现.

笔记本

  • 笔记本被表示为 Mathematica 表达式.
  • 笔记本文件以 Mathematica 注释的形式包括了隐藏的附加信息概要. 这些信息使得有效随机存取成为可能.
  • 笔记本的附加存储是为了尽量减少数据重写和尽可能对已写入的数据移出.
  • 平台无关的双缓冲被默认用来使窗体内容更新时闪烁次数最少.
  • 自动滚屏使用一个控制理论机制来优化光滑度和可控性.
  • 所有字符都使用 Unicode 值在内部和在文件中表示. 许多编码映射表被列入支持系统的接口和使用其它编码的第三方软件的通信.
  • 当复制文本到剪贴板时,许多技术特点和所有私用空间字符都使用详细的的长名字编码,而不是利用其 Unicode 值,以改善软件对这些字符的可读性,因为这些字符可能无法通过这些软件正确呈现. 所有字母字符都以 Unicode 的形式编码,与系统的本地化语言无关.
  • 拼写检查通过使用算法和一个包括 Mathematica 所用标准英语、技术术语和数学用字的10万字的英文字典实现. 拼写校正通过使用文本、语音、数据和键盘距离等实现.
  • 断字通过使用 Liang 断字算法和英语断字的标准 TAdjustmentBox[E, BoxBaselineShift -> 0.5, BoxMargins -> {{-0.3, 0}, {0, 0}}]X 模式来完成.

动态计算

  • 前端与与之通信的每个内核建立3个独特的链接. 一个链接用于由用户发起的定期计算,而其他两个链接用于更新 Dynamic 对象的值.
  • 当前端格式化一个 Dynamic 对象时,它将该计算发给内核. 内核注册了依存关系表中所有用于 Dynamic 计算的变量.
  • 当内核中的变量发生变化时,内核向前端发出信息使任何依存于该变量的 Dynamic 对象失效,然后从附属表中去除该依存关系的信息.
  • 在需要时,前端只向内核发送无效的 Dynamic 对象,以便更新笔记本窗口. 例如,Dynamic 对象已滚动到屏幕外或已经被其它不会刷新的窗口所隐藏.
  • 不是所有的 Dynamic 计算都被前端发送至内核. 前端自动确定一个计算是否只需通过前端内的小型计算器完成.
  • 如果 Dynamic 计算发生在一个正常的计算中,内核会暂停正常计算,以便处理 Dynamic 计算. 对于暂停内核计算的机制与用于中断内核和计算子集的机制是相同的.

MathLink

  • MathLink 是能放在任何基于通信和流的传输媒质上层的表示层协议.
  • 当一个连接两端确实是兼容的计算机系统时,MathLink 将使用一种压缩格式对数据进行编码.
  • MathLink 能够像 Mathematica 表达式一样传输出诸如中断的数据块.
  • 如果可能,MathLink 使用动态链接共享库来实现.

表达式的标准化

  • 前端使用一个有向无环图来表示标准表达式的盒框结构.
  • 盒框使用运算优先分析算法的一种二维推广来解释.
  • 图形和排版都使用相同格式的语言来实现,这使它们能够无缝地协同工作.
  • 增量分析算法用来使结构最小化和显示更新.
  • 字符间距和定位通过字体数据和运算表来确定.
  • 贯穿于表达式始终的线性中断的全局优化使用基于与 中所使用的文本排版方法类似的方法.
  • 在输入过程中将建立线性中断以使表达式的微小变化几乎不会引起大范围的重新标准化,如果输入需要跳转,一个椭圆形光标会立即出现以引导我们的视线.
  • 非常大的输出截断基于输出盒框表示的字节数. 一些类别的盒框,例如用来表示图形的盒框,不包括在字节数中.
  • 表达式的标准化使用几千页的C代码.
New to Mathematica? Find your learning path »
Have a question? Ask support »