2010年4月27日星期二

编程语言与科学计算 - 篇二

从现在的行文看,还会有篇三的,因为一下子内容还写不完全不的内容。
那么本篇就先侧重在Maxima这个CAS上了。
也不打算代替手册或教程什么的,只是去提及一些有关要点吧。

词汇表

这部分是简单的中英对照,以方便下面内容的阅读。
先列在前面也是写这些内容方便来着,
由于词汇在之后都会对照提及,所以在之后会移除这部分。

factor因数
expand
simpliy
solve
plot
reduce
rectform
ODE常微分方程

(下面是手册中关于Maxima内置功能对数学领域的分类)
Polynomial多项式
Constant常数
Logarithm对数
Trigonometric三角函数
Elliptic Functions椭圆函数
Limit极限
Differentiation微分
Integration积分
Equation方程
Differential Equation微分方程
Numerical数值的
Array数组
Matrix矩阵
Affine仿射
Tensor张量
Series级数
Number Theory数论
Symmetries对称性
Group群

Maxima
http://maxima.sourceforge.net/

说明
Maxima是历史悠久CAS的Macsyma维护至今的开源版本。它是一个用LISP编写的计算机代数系统,可以精确地进行符号运算。这不同于数值计算软件中强调的高性能,以及通过计算的累计来逼近数值。因为此篇的内容是想关注数学方法与数学模型的运用,选择Maxima来使用是一个简明而有效的手段。

安装
因为Debian是个人比较喜欢的发行版,其包管理功能可以为应用安装带来很大的方便。所以为了减少在一些方面不必要的麻烦,这里选择了最新的Ubuntu版本作为实验环境。
最基本的一步是安装maxima包,然后便可在终端下交互使用了。由于目前Ubuntu9.10的打包问题,该包其实无法正常使用。一个简单的方法去 http://packages.debian.org/sid/maxima 下载符合硬件架构的包来安装。
可选的GUI有wxMaxima和Lyx。前者以在界面的菜单中列出了常用的命令,以提供方便和减少门槛。后者是一个LaTex排版软件,支持用不同的数学后端来对可视化编辑中表达式进行运算和显示。其他较简单的一些GUI前端也有一些,也可作为对打开字符界面的终端的一个代替。
本篇的选择是iMaxima,是Emacs的一个模式。它可以自动用Tex对Maxima的输出进行处理来生成美观的公式图像,也提供若干编辑器上的增强。需要安装的包有emacs23, texlive, texlive-math-extra, maxima, maxima-emacs。
然后在.emacs中插入
(autoload 'imaxima "imaxima" "Frontend of Maxima CAS" t)
(autoload 'imath "imath" "Interactive Math mode" t)
(autoload 'imath-mode "imath" "Interactive Math mode" t)
(setq imaxima-fnt-size "Large")
(setq imaxima-use-maxima-mode-flag t)
其中最后一行是让imaxima模式中也有maxima模式在编辑方面功能,不过其实这部分内容就是照搬imaxima的网站上简单安装使用的说明啦。
配置好后进入Emacs输入M-x imaxima [ret]便可运行,也可直接执行
emacs -f imaxima

额,还有个XMaxima忘说了,也是图形前端。然后,如果在Windows下的话,下载官网的安装包后,里面包含了Maxima/WxMaxima/XMaxima了,其实也很好用的。


使用方法
在Maxima的文档页,即 http://maxima.sourceforge.net/documentation.html,提供了使用手册和若干篇中英文的教程,很适合对照着来学习和使用。而本帖中对Maxima的使用也将以此为参照,并结合一些个人的实际体验。
同时,在下面的内容中,打算依照对基本的数学知识点的展开来安排,并想侧重在体会数学工具的应用上。
另一份值得参考的中文Wiki是 http://wiki.ubuntu.org.cn/Maxima,人气还行。
接下来将列出一些较基本的概念和用法,不过更推荐去实际尝试和使用。

基本使用
Maxima是通常是通过交互方式使用(也可编写成脚本再用batch装载,库则通过load),直接在命令行中输入表达式交互执行。
分号(;)表示语句结束,之后输入回车Maxima便会对表达式计算并显示。用"$"则执行但不显示。
单引号(')前缀用来阻操作符被求值,而两个单引号('')则相反是noun到verb的过程(可以用在函数定义中对符号进行运算)。
ev(expr, arg_1, ..., arg_n)
用来为表达式附加操作/标志/条件,也可略写成逗号表达式的形式
"%"用来表示上一个计算结果,等价于"%o3"(数字不一定是3啦)。而"%e/%i/%pi"是三个常用的常量,注意它们代表精确值哦。
quit();
用来退出,中断运算则是按键control-C。

联机帮助
describe("sin");
用来在线查询手册内容,也可用"? sin"。"?? sin"则是名称部分匹配(特别是用在只记得部分函数名称的时候)。
example(append);
这个用来显示示例,参数非函数名的话要加双引号。空参数则显示示例列表。
通过这两个命令,就可以用来查询别的指令的意思了。
比如:apropos查询Maxima内置的名称,demo调用演示文件。
注释用 /* 和 */ 包围。

操作符与表达式
操作符是用来连接符号构成表达式的,常见的如"+""-""*""/""**""^"算数操作符。
x:%pi
":"是赋值操作符,用于执行计算并关联值与符号(变量)。
F(x,y):=cos(y)-sin(x)
":="用于函数定义,函数有自变量。
=和#是表示相等和不等的关系操作符,也可用其他不等符号如"<""<="。
还有很多操作符是以函数的形式提供的,如"sqrt""abs""mod""floor""round"...。
从Lisp的角度说其他形式的操作符也是用list表示出函数形式的直观表达,它们在Maxima内部仍以list来处理并可转换表示法。

符号与数|Symbol&Number
上面说过,Maxima表达式等价于几个多层List,而Maxima的运算也是针对表达式而不是针对数的:
(%i1)1/3;
(%o1)
1
-
3
其中分数根号%pi什么的都会计算结果的一个部分。
如果需要显示小数形式的结果的话,可以:
%,numer;
float(%);
(","是"ev"函数的简写)
"numer"标志和"float"函数/标志用于将将结果转换为浮点数。
而转换为高精度浮点数则用"bfloat"函数来进行,其位数由全局变量"fpprec"决定。
注意,直接输入浮点数也将在内部以二进制形式处理,其值并不等于高精度浮点数。
如果要Tex格式输出用于排版文档的话,可用tex函数。
表达的式中出现的字母也是符号的意思,在计算时可能有赋值或指定性质也仍可能只是一般的符号。而赋值操作会让一个符号表示了计算得到数或符号表达式。
对"f(x):=x^2;"可以使用"f(2);"来求某值对应的函数值。


绘制图形|polt
这个功能用来绘制函数图形的,比较直观来着。执行
(%i1) plot2d (sin(x), [x, -%pi, %pi])$
(%i2) plot3d (2^(-u^2 + v^2), [u, -3, 3], [v, -2, 2])$
Maxima就会去调用gnuplot来显示了。
其中最重要的参数是,被绘制的函数,以及绘制的坐标各轴(至少是提供自变量)的范围。
函数参数也可以通过名称传递事先定义的函数或一组函数构成的列表,而且可以是分段函数。
更可以使用discrete/parametric形式表示被绘制图形。
控制绘图也可跟其他许多参数,可能用到的有:
"[grid,30,30]" 网格
"[nticks,29]"
"[logx]"/"[logy]" 使用对数尺度
"[box,true]" 边框
每个参数都构造成列表的形式传递,单原子列表传递参数名或者将参数作为列表中的剩余原子。
比如:
(%i1) plot2d (exp(3*s), [s, -2, 2], [logy])$

也有"gnuplot_"开头的一组参数,用来作传递向gnuplot的命令。
绘图还有contour_plot绘制登高图线函数,以及"load(draw)$"后可以使用的绘图包提供的Maxima-Gnuplot界面。

化简|Simplify
这是通过对表达式的等价变换,得到我们需要的形式,或者用来手工帮助Maxima处理复杂的表达式。
被化简的可以是带符号的表达式,也可以就是单独一个数。
一些简单的化简(也是运算啦)Maxima是会默认进行的。
下面列了一些会用到的化简类的函数(先暂且考虑实数域吧):
"%,x=5/z;" 替换表达式中符号,功能同subst函数。
"sublis"则可以用来把一组解代入某个表达式。
"factor" 因式分解
"expand" 分解多项式
"ratsimp" 有理数化简(通常是通分,逆操作为"partfrac")
"radcan"(=radicals+canonical)化简log/e/根式
"trigsimp"(=simplify trigonomtric)化简三角函数
"logcontract"(=contract logarithms)合并log
三角(Trigonometric)方面的还有"trigexpand"和"trigreduce"
还有"rootscontract"和其他一些,手册中有分类的完整列表。
多项式除法用"divide"函数

方程|Equation
solve([x+y+z=5,3*x-5*y=10,y+2*z=3],[x,y,z]);
solve(x^2-5*x+6 =0,x);

solve用来求方程或方程组的解,结果将会表示出所有符合等式(表达式则"=0")的解(结果中的变量用%r加数字表示)。
也可用allroots函数数值方法求根的近似值。
这里的原理用到矩阵变换来着。关于微分方程,见下面一节。
其他可能用到的:
"linsolve"(=solve linear system)解线性方程组
"algsys"(=solve algebraic system)解多项式方程组
"eliminate"(=eliminate variable)从方程组中消除变量
"find_root"用二分法查找一个根
差分方程用"solve_rec"

微积分|Calculus
先来求极限,导数,和求积分的简单示例:
limit( (2*x+1)/(3*x+2), x,inf );
diff(cos(x),x);
integrate(x/(1+x^3),x);
integrate(1/x^2, x, 1, inf);

这里被运算的是表达式,函数或等式会对等号两边都执行运算,可以使用预先定义的符号。
符号f(x)和f是不同的符号来着,前者会表示符号的依赖关系。
如果仅仅是用来表示而不计算,可以用单引号"'",常用于写微分方程。
"diff(expr,x_1,n_1,...,x_m,n_m)"参数中可跟多个符号来一次求导和在符号后使用数次参数表示求导次数.
"limit"极限有"plus""minus"两个方向。
又涉及了几个常量:"%phi" 黄金分割,"inf" 无穷大,"minf" 无穷小,"infinity"复数无穷,"%c"/"%k1""%k2"是一阶和二阶的积分常数。
有时也可用Romberg函数数值方法来求近似积分。
求解常微分方程,例如
ode2('diff(y,x)+3*x*y = sin(x)/x, y,x)
ode2可以用来求一阶和二阶的ode。
初值用到ic1和ic2函数,而二阶的边界用bc2函数。
depends函数用来表示函数间的依赖,相当于一种抽象的函数关系,会对求导产生影响。
另一种用到的高阶微分方程解法是运用"Laplace"拉普拉斯变换函数(用到"delta")。
通常是直接使用desolve函数,它即是用Laplace变换来解线性微分方程
这里还涉及"del(x)"是解释微分中dx的写法,"atvalue(expr,x_1=a_1,c);"用于建立边界值。
使用"assume(x>0)$"可以给表达式中的符号指定范围,一些运算在不同范围或者特定值上会有不同的意义。
有时积分要用"changevar"用一个符号来代替部分表达式。

级数|Series
首先是求和和求积,即∑,∏这两个符号:
sum (a[i], i, 1, 7);
sum (1/3^i, i, 1, inf),simpsum;
product (i^2, i, 1, n);
求1..100的和就是"sum(i,i,1,100);"了
"simpsum"标志则用于对结果化简,例如使用等差数列求和公式。
也有些其他的标志:
sumexpand: true$
cauchysum: true$

然后,来将表达式展开为泰勒级数:
taylor (cos(x) - sec(x), x, 0, 5);
"taylor (expr, x, a, n)"是将自变量是"x"的表达式"expr"在点"a"处展开(显示出的部分)到"(x - a)^n"。
要输入泰勒级数的话可用"trunc",然后输入一个展开式的片段。
或者展开:
niceindices(powerseries(%e^x, x, 0));

这里有个有趣的例子:
taylor(%e^x, x, 0, 5);
plot2d([trunc(%), %e^x], [x,-5,5]);
很直观来着。

线性代数|Linear Algebra
这里主要是来进行矩阵(Matrix)的表示和计算:
A:matrix([1,2],[3,4]);
B:matrix([1,1],[1,1]);
A + B ;
A . B ;
A^^-1 ;
determinant(matrix([a,b],[c,d]))
"matrix"是按行来表示矩阵的。
矩阵的运算符表示为"+"".""^^",其中"A^^-1"等价于"invert(A)"求逆矩阵。
其中"determinant"是用来求行列式。还有"transpose" 求转置,"eigenvalues" 特征值,"eigenvectors" 特征向量。
取矩阵的部分可以这样
row(A,2);
col(A,2);
A[2,3];
要取子式的话,可以用"minor"函数。
其他可能用到的有:"ident" 单位矩阵,"adjoint" 伴随矩阵,"echelon" 梯形矩阵,"charpoly" 特征多项式。"rank"什么的就是字面的意思啦。
矩阵可使用"genmatrix"由一个lambda表达式创建其元素。
也有些附带的包提供的函数,比如"mattrace"。
稀疏矩阵的话。。。

曲线积分|Line integral
这个涉及多重积分,其实也是微积分的一部分。因为没有直接的函数,就分开说了。
参见 http://maxima.sourceforge.net/docs/tutorial/en/gaertner-tutorial-revision/Pages/lineint0001.htm
这篇从原理上说,就是把"[x = cos(t), y = sin(t), z = sin(t)]"代入,类似于手工操作。
代入操作使用"sublis"函数。
简单的表示就是:
lineIntegral(fn, path, param, p0, p1) :=
block ( [substitutedFn, x, xx],
substitutedFn: sublis(path, fn),
x : ev (substitutedFn, diff),
xx: subst(1, diff(param), x),
integrate(xx, param, p0, p1)
)$

lineIntegral(x^2*y*diff(x) + y*z*diff(y) + z*x*diff(z),
[x = cos(t), y = sin(t), z = sin(t)],
t, 0, 2*%pi);


集合|Set
创建用"set();",然后也有好些用于集合的函数,
这里就不展开说了。
...

复数|Complex
复数域和实数上一些函数会得到不同的结果。
首先是"%i^2=-1"然后就可以来写:
1 + 2*%i;
实部和虚部用"realpart"和"imagpart"得到。
"gfactor"是复数域的因式分解。
"domain : complex$" 保留"x^2"
"declare(z,complex)"
"rectform" 转换为"a + b %i"形式

补遗|Others
length 返回一个数量,对不同类型的值有不同意义。
at 用于假定符号的值
declare定义符号的类型,会影响符号在表达式中的作用。
block 一个有局部作用域的语句序列,可以用"go(tag)"。
kill 清除符号,可以"kill(all);"
分段函数可以用"if"语句表示
流程控制见"Programming"分类
列表是Maxima内置结构,也有些对应的操作函数。
"map""lambda"等用于函数编程。
用"to_lisp()"和"(to-maxima)"可以在Lisp与Maxima的语法表示法间切换。
也可用":lisp"命令后Lisp语句,用|$%o1|引用输出。
一些有趣的例子:
block([fpprec:100],bfloat(%pi));

Fib[0] : 0;
Fib[1] : 1;
Fib[n] := Fib[n-1] + Fib[n-2];

block([w:0], for i:1 thru 10 do (w:w+i^2),w) ;
(取自xmaxima的介绍文件)


声明和推论|Declarations and Inferences
这是涉及数学概念上的推算。
参见 http://docs.huihoo.com/homepage/shredderyin/maxima.html
用到的函数有:"assume","facts","maybe","is","forget","declare"。
可以给变量指定范围,也可以给函数指定奇偶性。

统计|Statistics
虽然不如R在这方面功能丰富,不过有个包叫"descriptive"提供了相关的基本功能。
使用前要先"load (descriptive)$",然后就可以求均值方差什么的了。
详见手册上对此包的说明。

概念|Concept
复制自维基百科,只是个片段的东西来着。
微积分基础
函数
数列
级数
初等函数
极限
无穷小量
收敛数列
收敛性
夹挤定理
连续
一致连续
间断点
▲一元微分
导数
不定积分
高阶导数
介值定理
中值定理
泰勒公式
求导法则
乘法定则
除法定则
倒数定则
链式法则
洛必达法则
导数列表
导数的函数应用
单调性
极值
驻点
拐点
凹凸性
曲率
▲一元积分
积分的定义
黎曼积分
达布积分
勒贝格积分
积分表
求积分的技巧
换元积分法
分部积分法
三角换元法
降次积分法
部分分式积分法
定积分
牛顿-莱布尼茨公式
广义积分
判别法
柯西判别法
阿贝尔判别法
狄里克雷判别法
主值
柯西主值
β函数
Γ函数
数值积分
牛顿-寇次公式
辛普森积分法
▲多元微积分
多元函数微分
多元函数
偏导数
隐函数
全微分
方向导数
梯度
泰勒公式
拉格朗日乘数
多元函数积分
多重积分
广义多重积分
路径积分
曲面积分
格林公式
高斯公式
斯托克斯公式
散度和旋度
▲微分方程
常微分方程
分离变数法
积分因子
欧拉方法
柯西-欧拉方程
伯努利微分方程
克莱罗方程
全微分方程
线性微分方程
差分方程
拉普拉斯变换法
偏微分方程
拉普拉斯方程
▲微积分的应用
微积分的几何应用
平面图形的面积
平面曲线的切线和弧长
平面曲线的曲率
旋转体的体积
旋转曲面的面积
曲面的切平面和法线
空间曲线的切线和法平面
微积分的物理应用
运动的位移、加速度
力所做的功
物质的质量
静力矩、惯性矩和重心
微积分的经济应用
边际
弹性、交叉弹性
收益流的现值和将来值
成本分析、净资产分析


数学建模|Model
下一篇再说这个吧

……|...
...

Links
这个是补充,更重要的列在上面了
http://www.math.harvard.edu/computing/maxima/ [推荐]
http://cadadr.org/maxima/faq.html [推荐]
http://math-blog.com/2007/06/04/a-10-minute-tutorial-for-solving-math-problems-with-maxima/
http://maxima.sourceforge.net/docs/tutorial/en/gaertner-tutorial-revision/Contents.htm

没有评论: