数学建模社区-数学中国

标题: maple基础 [打印本页]

作者: woshiwangxiao    时间: 2012-6-12 16:53
标题: maple基础

, J9 \. L  X, i" V! c& ]. t0 A第一章  Maple基础8 P) T! O% g, s- W" e; C
! j- c: o7 s" \' h" g
1 初识计算机代数系统Maple
) ]- Z- l: U; O) x+ G1 X/ S1.1 Maple简说! z. o  I5 Y- p" m# B2 ^
1980年9月, 加拿大Waterloo大学的符号计算机研究小组成立, 开始了符号计算在计算机上实现的研究项目, 数学软件Maple是这个项目的产品. 目前, 这仍是一个正在研究的项目.
! C3 Z( r: {7 OMaple的第一个商业版本是1985年出版的. 随后几经更新, 到1992年, Windows系统下的Maple 2面世后, Maple被广泛地使用, 得到越来越多的用户. 特别是1994年, Maple 3出版后, 兴起了Maple热. 1996年初, Maple 4问世, 1998年初, Maple 5正式发行. 目前广泛流行的是Maple 7以及2002年5月面市的Maple 8.
  k0 H/ m' Y6 b7 ^0 U* [7 uMaple是一个具有强大符号运算能力、数值计算能力、图形处理能力的交互式计算机代数系统(Computer Algebra System). 它可以借助键盘和显示器代替原来的笔和纸进行各种科学计算、数学推理、猜想的证明以及智能化文字处理. ( Q# r& Y: [2 r+ A* {# J
Maple这个超强数学工具不仅适合数学家、物理学家、工程师, 还适合化学家、生物学家和社会学家, 总之, 它适合于所有需要科学计算的人.
7 {5 t0 Z! _% C! G) _1.2 Maple结构$ g" y, F; L) Y& C! x" Q
Maple软件主要由三个部分组成: 用户界面(Iris)、代数运算器(Kernel)、外部函数库(External library). 用户界面和代数运算器是用C语言写成的, 只占整个软件的一小部分, 当系统启动时, 即被装入, 主要负责输入命令和算式的初步处理、显示结果、函数图象的显示等. 代数运算器负责输入的编译、基本的代数运算(如有理数运算、初等代数运算等)以及内存的管理. Maple的大部分数学函数和过程是用Maple自身的语言写成的, 存于外部函数库中. 当一个函数被调用时, 在多数情况下, Maple会自动将该函数的过程调入内存, 一些不常用的函数才需要用户自己调入, 如线性代数包、统计包等, 这使得Maple在资源的利用上具有很大的优势, 只有最有用的东西才留驻内存, 这保证了Maple可以在较小内存的计算机上正常运行. 用户可以查看Maple的非内存函数的源程序, 也可以将自己编的函数、过程加到Maple的程序库中, 或建立自己的函数库.
& j" I; \; K% h1 i0 ~1.3 Maple输入输出方式1 ^# I# i1 A) ?1 N) }* P
为了满足不同用户的需要, Maple可以更换输入输出格式: 从菜单“Options | Input Display和Out Display下可以选择所需的输入输出格式.
, i9 e2 L6 K4 k# P4 ?& kMaple 7有2种输入方式: Maple语言(Maple Notation)和标准数学记法(Standard Math Notation). Maple语言是一种结构良好、方便实用的内建高级语言, 它的语法和Pascal或C有一定程度的相似, 但有很大差别. 它支持多种数据操作命令, 如函数、序列、集合、列表、数组、表, 还包含许多数据操作命令, 如类型检验、选择、组合等. 标准数学记法就是我们常用的数学语言.
" t* L% j4 `) X3 B3 g4 Z8 {启动Maple, 会出现新建文档中的“[>”提示符, 这是Maple中可执行块的标志, 在“>”后即可输入命令, 结束用“;”(显示输出结果)或者“:”(不显示输出结果). 但是, 值得注意的是, 并不是说Maple的每一行只能执行一句命令, 而是在一个完整的可执行块中健入回车之后, Maple会执行当前执行块中所有命令(可以是若干条命令或者是一段程序). 如果要输入的命令很长, 不能在一行输完, 可以换行输入, 此时换行命令用“shift+Enter”组合键, 而在最后一行加入结束标志“;”或“:”, 也可在非末行尾加符号“\”完成. / L& m* u& |7 e5 F
Maple 7有4种输出方式: Maple语言、格式化文本(Character Notation)、固定格式记法(Typeset Notation)、标准数学记法(Standard Math Notation). 通常采用标准数学记法.
9 M* t3 K4 F9 l0 L+ |Maple会认识一些输入的变量名称, 如希腊字母等. 为了使用方便, 现将希腊字母表罗列如下,输入时只需录入相应的英文,要输入大写希腊字母, 只需把英文首字母大写:   
. j  H' v0 W, @
8 |( x, f! l, a1 n* R$ X! x
. K" N* A5 @6 q
. g) D  l; c' X! |" H' n. ~
3 x# v+ u, \% u$ m
, }: c( k6 S  q* m( ^
& ]$ z& O# B9 G& H4 Z
9 ^3 C) X& b  d4 e 8 S+ D  [+ v0 U
6 y8 H$ y! ^& d/ s6 b/ m
8 U4 t. Y7 ~4 u- b) m' X

, v% H* O% J$ |2 o# ^; ^
- c0 ?- |! k) V5 a9 C$ y& t9 ~2 L+ C5 ]$ |+ S0 |
alpha        beta        gamma        delta        epsilon        zeta        eta        theta        iota        kappa        lambda        mu
$ |/ r' i6 N1 M0 V6 d9 ^# o: D . I$ Z& D) N  R
! B  _) i1 i' J' `+ e% J1 \# j: p& V

, ]  O( Z- j- F- u" p
) {4 h" C, B& q# t" A- J' } ' K& R: m5 ~* ~7 N. N0 f7 F6 P/ `8 Y
* W$ f1 v/ U3 W* z4 p. p* T4 i! n

/ e8 P: ^  _2 \( R9 V
* ^. [9 z# L6 W& G" H ; {; l  o# l, V0 O5 i
: \2 G' `7 z8 Q; ^$ m8 ?4 {! h8 F

- o* @( Z, X/ f8 l
9 ^; |* m& ?% B0 Y1 Q3 J8 k0 k* f8 z# g5 m5 _) V  U7 n7 D
nu        xi        omicron        pi        rho        sigma        tau        upsilon        phi        chi        psi        omega' I+ g/ ^( J& m5 M. |
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:  j! G8 M* Y# k3 n  I5 H1 ]
> for i to 10 do 7 q% x# z& P* c1 a. E
printf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));, |9 J6 u( N5 P
od;3 P7 y5 s- ^8 z: P" F
i=+1 and i^(1/2)=+1.000i=+2 and i^(1/2)=+1.414i=+3 and i^(1/2)=+1.732i=+4 and i^(1/2)=+2.000i=+5 and i^(1/2)=+2.236i=+6 and i^(1/2)=+2.449i=+7 and i^(1/2)=+2.646i=+8 and i^(1/2)=+2.828i=+9 and i^(1/2)=+3.000i=+10 and i^(1/2)=+3.162* e7 g* a4 W% N) ~  m; R) l0 u0 a
+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:6 W4 Z( {  f* O0 c' A+ @
> for i to 10 do . H3 m$ b' ~) C8 Z, u% ~
printf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));: z6 j- o# t) }& r0 V
od;2 Y* w' l2 w' `" r! Q+ C/ X
i=+1 and i^(1/2)=+1.000- r8 ~3 i: \3 [4 h" g* a
i=+2 and i^(1/2)=+1.414
8 {% }7 U, A0 e- Y2 Q4 t) |i=+3 and i^(1/2)=+1.7324 Q  }! f( A: w1 f/ \& d! y' o6 H
i=+4 and i^(1/2)=+2.000
6 [( i8 f) C3 {" @7 ~i=+5 and i^(1/2)=+2.236/ J' s# R1 `. {4 E# g- [2 n) `
i=+6 and i^(1/2)=+2.449
6 \; z. g* u, S4 \: Ai=+7 and i^(1/2)=+2.646
2 N1 j2 T+ T& S8 qi=+8 and i^(1/2)=+2.828
5 u" k4 [! t$ z9 z1 M8 C5 J) Q( D; Zi=+9 and i^(1/2)=+3.000  e2 K6 F. r, v/ G, T( I
i=+10 and i^(1/2)=+3.162! j# t1 h9 ?2 z: D2 U2 L" e
再看下例:将输入的两个数字用特殊形式打印:
6 j! ~# z( g, s0 b6 L! |/ o> niceP:=proc(x,y)
" w- q1 Q0 L- v. j' S1 k. Fprintf("value of x=%6.4f, value of y=%6.4f",x,y);; k, p" P5 |8 t* a; Z/ r
end proc;
% u$ p6 _! `, f 3 ]  E; ~/ \1 c8 |2 n% K
> niceP(2.4,2002.204);* _0 b5 Z9 p8 z* I5 c8 A0 q8 d- h
value of x=2.4000, value of y=2002.20406 c3 l# m' k# m6 [+ C
1.4 Maple联机帮助
: y0 L3 S$ t0 K+ u- @4 c* P学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用.
- U3 u7 l; d8 y9 W% `/ S' g在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可. 7 m) ~! t( p  P
2  Maple的基本运算6 Y, i' r# s; l! |1 b' q
2.1 数值计算问题* H$ Y& f5 t% g9 y
算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”. + Z7 o) z+ Q6 ^9 _9 Q
在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之,  是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数.
0 E2 W% [- h. A9 T1 P4 vMaple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算.
0 P% d8 n2 H% r5 ]& x但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
5 m& q  X7 f$ y1 c6 o0 i: ?3 c7 A第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:   # r4 s$ |' E) E2 F, F
> 3!!!;
1 P6 R1 R5 k" V# Z6 t/ {. k  O; z3 I2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
" C' K" y  O- O; z8 O$ E上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?
, V3 E; ^# I8 V6 E, `为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式) }% q7 R; ~& ^% L5 R" E1 e

2 m/ h, g2 z& _) ~4 \* Y3 M. d可得:  , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:   ) D: q2 p# a" f" E7 K  ~; s
0 H6 F, z+ \2 F- a2 }) p
这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性.
( {0 h+ m& ?, J4 U另一个例子则想说明Maple计算的局限性:   $ q/ G% C& U. h( t
  
2 w/ T3 y  T9 rMaple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:   ) |& O) s, W, `% l- R% R7 T
' Z- t4 a# I& o' D3 |$ m. U
显然这是错误的. 这一点可以从代数的角度予以分析.
9 D& |1 `) g  s& ~: e- P4 t不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果.
  P( u: l& F9 N  l1 K另一方面, 设 , 则 , 即:
6 T4 f+ s/ a6 C( z- e * y& C5 v& o8 ^4 s2 W9 }9 g
显然 有6个结果, -2、2是其实数结果.
' T4 U( B- e( k( f( F, B2 [/ s3 U这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性. ! j5 p8 K; A4 e5 A* _$ e/ W
尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的.
! A/ f/ d+ j6 y7 M1 ~2.1.1 有理数运算
% l* S# g: v% ^" J$ w作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20). - d% y- y6 G2 g. \4 r
> 12!+(7*8^2)-12345/125;4 }1 `2 F! E" X8 _- V  y: f2 @
7 z+ K- S1 e& V' q/ n
> 123456789/987654321;- t* \) G- L2 X, @  t
* X. A: e3 k1 x  |4 `. K; J4 \: H& V
> evalf(%);: H' y+ R9 }: _) U5 L1 T4 U8 R
7 e: N/ @1 h* Z$ G
> 10!; 100*100+1000+10+1; (100+100)*100-9;
+ R8 i# v/ ?0 V
: p) b" r2 ]& q& x7 M. J/ H0 x3 g
0 |& z3 E5 ]5 s- C# M# k4 ` 0 J' h: U: Y0 ~4 q
> big_number:=3^(3^3);
( m2 I  _% V' t, h4 l/ _$ F
- q* A" k. B, V' c1 D% y5 K> length(%);/ Q6 A4 g0 C6 _; A6 @: X1 a

5 C5 E3 e/ \) U( c3 R上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:   & ?9 p) w5 b) P# X, O; \! H  ^
    1)整数的余(irem)/商(iquo)# S) U8 \2 Q5 W
命令格式:   
4 |' _- z$ `: Xirem(m,n);        #求m除以n的余数& A1 g, t7 ^" S3 ?  I! |% j9 h
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q
; w4 u! |4 J: w; ?4 }iquo(m,n);        #求m除以n的商数( `6 t: q* i" K. T! K
iquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r9 c. L+ C+ Z- ^  t: @
其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
$ z4 y9 s. l3 ^% Q> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q% C0 U4 N  H3 P/ E! v! |/ s5 r0 w
2 F! Q- Q2 V3 v) e6 D" q) {
> q; #显示q
* n8 R, O6 F* k7 d# ~1 j) k0 [4 ?: D & [* `& n! ?. V- ]5 I2 I/ X, ^4 O
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r
: v) Z2 q" w1 g$ V# Z 1 `' |0 K: y* f. ~' E
> r; #显示r
& L. [5 l/ x) G2 k - W: K2 o2 F! }+ K& F# p! ^
> irem(x,3);
1 h% b9 A3 q- S+ z6 V5 B. t
# B7 v- L, u  D: P2)素数判别(isprime)
  F3 z& j5 u. n8 a/ b2 i' v素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n); 2 d5 v" c/ w5 I- j% i
    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
1 l, Z4 G  D1 K" @" V# b> isprime(2^(2^4)+1);' G; ^! b/ J! J$ B  p* B* v0 [
" c+ d3 e2 b  U
> isprime(2^(2^5)+1);
: Z$ l7 s# P0 c1 @ 0 q; F0 }0 N& [$ j# @4 {) b) F  j
上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多.   `9 c$ K& p, A6 W1 J
3) 确定第i个素数(ithprime)
* h& i4 r2 J, X  M3 g& t若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);    . g9 d/ b. X1 C1 Q  Y: B
> ithprime(2002);
0 Q* t* w* O; A7 [! u& Q' _
# \# U. S8 H5 i) E> ithprime(10000);
2 ~$ A3 H, O) _" U. W9 [' O
! z; v2 {3 m0 ?( l) T4 i- S' I4) 确定下一个较大(nextprime)/较小(prevprime)素数( Y1 G) H6 @6 h  g6 ]5 b  N$ V; M
当n为整数时,判断比n稍大或稍小的素数的命令格式为:   
! r  M7 ]7 z; q9 x( J1 rnextprime(n);  ; \* ~1 N/ Q; S5 |' L1 x- J- s
prevprime(n);
* \! {1 f" S/ Y> nextprime(2002);
! Z: p1 @3 S" S, { : A& r2 a( t3 h6 |: t
> prevprime(2002);
7 y" g) L1 U3 k2 E
8 a3 `  K3 Z; x0 i5) 一组数的最大值(max)/最小值(min)9 d# Q6 G$ z/ ?6 V& ]0 f! a/ p2 {
命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值
6 {* U# D. _* B9 L. z             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值
7 m4 z; w9 L4 u+ a' u) j8 X> max(1/5,ln(3),9/17,-infinity);7 W  u$ `! }0 g8 w' {$ ?8 }

" D5 z6 ?2 t& k( q- C& e% p# S> min(x+1,x+2,y);
& j7 t4 H3 i& `9 I2 m( t/ Z
3 f+ z/ S' t6 E- _+ f8 K6)模运算(mod/modp/mods)' _6 L+ `" l; N. W/ Q/ M
命令格式:  e mod m;    # 表达式e对m的整数的模运算
* o1 ~; h: ]5 y, Nmodp(e,m);  # e对正数m的模运算: g3 q+ m) |/ P9 u* i4 G( S
mods(e,m);  # e对m负对称数(即 -m)的模运算' C' b' \4 y: v& y3 C4 b7 Z
`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价) T1 R5 r+ b3 Q" x9 P0 ~
值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/.
, V/ `6 J8 i. I; y) [; V> 2002 mod 101;
: w) O2 `8 G1 k$ R9 K2 F
& g  o- U0 y0 ^* U# @> modp(2002,101);5 [9 ^0 m* f; J2 z8 I- H( q2 Y
1 @  a/ e5 `$ W3 u
> mods(49,100);: p0 F5 t( ?2 T$ `" l8 n: ]
. Z/ c' w5 ?% ~5 b5 Y
> mods(51,100);
2 U8 o: y* z4 |) g  s0 |! Z: k + ]6 O4 f! Z7 {) ^- ?8 Z& R
> 2^101 mod 2002;  # 同 2 &^101 mod 2002;
/ t" l. F" g# I% p1 S, M1 D
- Y  ^- j& y% H! v. e, N. [7)随机数生成器(rand)2 O9 B, z* U0 z, g+ G! q. F: h
命令格式:   
4 P5 d5 x- h, f2 yrand( );    #随机返回一个12位数字的非负整数& b; b1 b2 R" I% X3 j3 V# {
rand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数
9 f) y) U6 M; ^9 `. K" R9 d> rand();* Q- C5 r& N0 k  ^5 y' L
1 c/ f8 J  t& i( Y3 z
> myproc:=rand(1..2002):
2 R5 ~: O3 q/ z' @" N> myproc();
0 ?5 |4 X5 N! w* ]
, H/ f8 f* p, T/ V6 `; Y% k9 D> myproc();
' G" a0 k% O! G+ c# p# k
2 M* ?' o5 l" V7 G+ F, A! D    注意, rand(n)是rand(0..n-1)的简写形式.
$ V5 m" |0 k+ i7 A! L, c2.1.2 复数运算0 X  n0 K  N& D! B" E
复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:     I" r2 E) u: V" C* G7 J8 q4 _" k
> complex_number:=(1+2*I)*(3+4*I);
, q/ S! R- v: g! x! Q7 g ( h; V$ {5 Z. a- c1 I
> Re(%);Im(%%);conjugate(%%%);argument(complex_number);" V8 T) a" X/ K8 J& s

2 W- @/ K9 q' ]4 J! u& s5 l $ }! t+ ~+ o0 e" |" Z9 f; i  o
8 d( o6 i. A/ T

9 c- D' N' R* n7 n  Q/ L值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%.
( ^1 |' D1 H3 C! x$ [为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:   
- z+ e- q( T$ i4 G" V, S2 @$ Z1) 绝对值函数' ?* N% w( F# Q8 d
命令格式: abs(expr);  
6 [5 h+ B% d4 r/ V5 ?2 F当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.' ~, G" L4 G) B  z: e" p
> abs(-2002);    #常数的绝对值
# R# n" h' }( C9 o7 h 3 V4 C' l9 v* v# _
> abs(1+2*I);   #复数的模
5 p' v  G" d0 b' U
' J3 y0 n" F& N: \6 A> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值
( Y' K6 B4 h+ c1 U4 [: T$ j( a3 W ; s' s* h2 ]2 s' Q! a& [
> abs(2*x-5);   #函数表达式的绝对值1 u$ Y# r1 M+ g, i9 z+ q4 A

- ]# M6 P6 r9 J- i6 ?2)复数的幅角函数/ X$ S* g8 r4 q  A3 |
命令格式:   argument(x);  #返回复数x的幅角的主值# K7 Z% a% g7 U
> argument(6+11*I);' C6 m& I1 t) O: ?# U- V

  W- j0 R2 O8 {, `> argument(exp(4*Pi/3*I));
! y5 ]1 X, i+ g   w; [2 Q* }; k1 M2 `8 z0 m0 G" r* N
3)共轭复数. N% `; d9 B  G; V- {
命令格式:   conjugate(x);  #返回x的共轭复数
9 Z$ p# f8 x9 U% `% J1 S> conjugate(6+8*I);6 N: v5 Q- w/ d. }9 b

+ |3 j6 `8 I. O; D( ]4 _7 M' {2 |- P> conjugate(exp(4*Pi/3*I));# S$ M0 `2 h& I2 l  t3 B
9 P) ~1 o- ~1 O
2.1.3 数的进制转换! x7 B7 L/ b+ {. e& }
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可. ! N. M, g5 n$ G5 U  t
命令格式:   convert(expr, form, arg3, ...);   
. M0 a$ Y* j0 Z8 q0 p8 T) {  z其中, expr为任意表达式, form为一名称, arg3, ... 可选项. 4 @+ Y' w8 X) _* `9 p
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述.
& b1 B# t! a/ ~2 ?    1)基数之间的转换- N+ w, s# x2 j" @. ~9 B
命令格式:   
- K# j2 G7 T$ A4 k$ K. Rconvert(n, base, beta);      #将基数为10的数n转换为基数为beta的数# b* q+ S1 t* w1 c# U" u0 T3 [. C
    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数& J: v: P( v: D8 {3 }3 m2 {
> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
* ?9 x. H7 ?9 z3 _+ ?7 p+ F7 W! h
9 Y2 q' o# Q7 l/ B! L> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数
% A! z% L( p* O6 k/ ~" Z( J 8 j0 o; _4 `! c+ H8 z9 ?# D9 ]
> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
% \" N6 [  {$ F1 @5 R 9 T: O/ I1 E  Q5 }6 W
    2)转换为二进制形式3 I0 n! R0 H4 B0 P+ Y* c6 K
命令格式: convert(n, binary);# }/ h) G  D6 S6 ?$ x4 h% W3 T
其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂.
( Y7 Q' o9 C* g4 `/ \> convert(2002,binary);   
7 x1 W" V9 ~# m4 W" _& G . x: ?5 a1 K; q% ~, p
> convert(-1999,binary); 6 W" X! i/ f1 K* z; T6 U$ h

9 I" P' [  g0 ~  C1 q> convert(1999.7,binary);
, T9 b0 L# H: \- ]" P  [( r2 ^ 9 H+ [- c& h, H& J+ o
3)转换为十进制形式
! F1 W) c# x5 U! G8 Y其它数值转换为十进制的命令格式为:   ; x1 V& H+ E, g$ J$ t3 M5 Z) x1 X
convert(n, decimal, binary);   #将一个2进制数n转换为10进制数& U6 c% i0 l9 g$ o3 O/ k- _
    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数% ~7 |" i; h  S1 _/ \. s7 `
    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数
6 o8 M" G5 B# }> convert(11111010010, decimal, binary);   
' P( a* ~, a) V
5 r3 I5 @( b8 R3 {: r> convert(-1234, decimal, octal);           
. @* R' t! Q7 _# o ! w- z4 f8 Q3 X
> convert("2A.C", decimal, hex);         
: j" B% Z5 f' v# L) M5 V! y  c
+ n) t4 d- @; }- g4) 转换为16进制数
5 e" t4 k! B7 C- c4 O" e将自然数n转换为16进制数的命令格式为: convert(n, hex);   : U' \4 b% \6 K8 A2 N
> convert(2002,hex);  convert(1999,hex);4 H% z/ h% K  c% v8 w" K$ `
: w" V  j% E4 F0 A  t9 ]( k1 j
* V& f( C2 x- n% c
5)转换为浮点数
; e8 V3 v: E% X! F  u" A命令格式: convert(expr, float);3 \3 d9 G4 N; H- N) K/ |* t" O; N
注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用.
2 |+ m3 ?# _8 w0 D' y2 m8 m3 n> convert(1999/2002,float);
9 e) ~: h! _6 D7 k
' M2 b. n: p8 u* H> convert(Pi,float);. a& F+ s* L. T' _& e1 y
' l+ {! S: f( M6 T; X+ ?
2.2 初等数学& }2 a& r; y- K2 O
    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识.
; N" S5 j! y9 I! h4 n8 X2.2.1 常用函数
$ s0 _9 k5 G4 m$ A4 `3 m" ~  A6 q作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:   
' R: ]8 U  H2 P& L4 X" l$ u指数函数: exp
1 j0 e3 {/ C6 b; [一般对数: log[a]
9 G; y# Y' M5 z1 F- K自然函数: ln
$ t, {; G! ^0 V" h7 p: Q常用对数: log10
2 w1 F- Q2 }8 Y平方根: sqrt1 k9 X2 ]. k$ |! e" c
绝对值: abs
" z9 t3 Y) _# J三角函数: sin、cos、tan、sec、csc、cot7 d) y8 H  y2 S: ?. X1 |8 z
反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot
2 Z; @; n- ~8 O  Q+ M+ Z双曲函数: sinh、cosh、tanh、sech、csch、coth. g. }3 B2 ~& x7 C# ]
反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth; C  W: y+ o' e
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY
6 J& E" @; d1 F; v6 \) u3 f, OGamma函数: GAMMA  h0 [% V3 V# J& |5 v0 X% d0 e3 u
误差函数: erf
) l: ~( [: M8 J- D/ Y2 j/ H函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能.
7 i$ E; e% V/ s, F' Z+ S1) 确定乘积和不确定乘积8 \3 e; \& l$ k- w2 p+ j* G9 b
命令格式: product(f,k);  " @% X  m, V' z
product(f,k=m..n);  / L# h$ }6 ~" [- `* C
product(f,k=alpha);
( P9 {0 G* s2 |+ `product(f,k=expr);& ]# s0 g* p. s; v
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式.
3 X- O* B0 z: d. X& }2 f  X% r> product(k^2,k=1..10);   #计算 关于1..10的连乘
# P6 i- R' S1 U) W6 b+ G1 M ; G4 s1 J- I* u2 @
> product(k^2,k);         #计算 的不确定乘积
' Q0 s& n' D+ g4 W% T( R
0 l* h+ V& d7 U. i> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘: D& P/ T. |0 t: Q; L8 q
4 }3 E# i, [& ?5 X- H% a
> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘* i, h" o$ e) K" f% X8 k* B
* ?% ^. _% R: s* }$ `
> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式1 R1 ?' M/ g  F

5 B& L% \: \$ R2 ]0 @5 O> product(k,k=RootOf(x^3-2));     #计算 的三个根的乘积: e; z* |6 R1 f
9 X5 U0 L1 W* _
    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:   
8 }4 s! r5 r" j> product(x+k,k=0..n-1);
  l: l9 ^, H8 F% ^/ A 1 U5 Y4 `+ C+ N7 n! ]. a
如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:   ( R- b4 h0 y* {1 _3 i: H% Q
> mul(x+k,k=0..3);* Q. h3 v* L# e8 {/ n# |0 y

" }$ \- J: i) X3 ?# |2)指数函数
7 {) g% s: Y8 T3 U! k3 g% Q计算指数函数exp关于x的表达式的命令格式为: exp(x);
. O( u& ^/ a6 U2 w% `8 Z/ g> exp(1);
3 b. W# Y9 x1 ?+ T- M
# U" F6 I# A$ ]7 W% s# @. l7 |> evalf(%);& k. K& V! g+ \
( F) _* a9 F/ X. r' w
> exp(1.29+2*I);2 s) n. A0 B& y
8 ~$ r& B, k" O* F* |
> evalc(exp(x+I*y));" Y/ Z; Q) C. w
+ l: j4 v$ c: e' G) \. ^: O! S  ^) m
3)确定求和与不确定求和sum
- ]% E9 J( P- z" f1 B2 Q: [命令格式: sum(f,k);  
1 u7 h( \# h# N7 i* Hsum(f,k=m..n);  
) y1 z1 ?5 f$ X- i; z5 T1 a1 U' `sum(f,k=alpha);
4 x# _# w9 t' J7 C& Isum(f,k=expr);& M7 m8 w' n9 o1 h3 f% q1 C
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式.
1 L+ l; D1 C4 e; D> Sum(k^2,k=1..n)=sum(k^2,k=1..n);
8 |% Q; Y& _$ l
, B( J! q+ p; a$ @+ P" k> Sum(k^3,k=1..n)=sum(k^3,k=1..n);
1 J# T; F2 d9 o% x  `  Y8 C1 h
+ v3 G1 ]2 Z! B9 l> Sum(k^4,k=1..n)=sum(k^4,k=1..n);
( o9 H+ o: A; m- v3 d+ i
8 R' A! R. A5 V- v6 j1 e> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);# X7 u/ y, n. v8 T3 \/ s$ H. M
& F% L7 \2 @5 a1 w5 [
> sum(a[k]*x[k],k=0..n);
& u  A$ C  D: }% Y1 k
3 Q- S( M1 B1 f* b5 M> Sum(k/(k+1),k)=sum(k/(k+1),k);" J9 R8 z. Y. s" g8 V+ [" ?

/ n( T/ N3 s5 L8 }- v" I3 U> sum(k/(k+1),k=RootOf(x^2-3));
+ D' @$ y4 U5 k" G2 R; Z" Y2 a$ s ' q1 B/ m8 k5 D
sum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的. % g3 P: g3 @4 U% c$ a
> Sum('k','k'=0..n)=sum('k','k'=0..n);% U0 q3 _& |! Z" @4 C  w! j# W
8 ^. f! Z! H' b6 v8 @' x/ @
如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:   8 z/ O; {+ @3 C- R: v5 K! T! G/ I7 Q
> add(k,k=1..100);! @4 b& |& B3 x" C
* E: p& i. W+ i5 H. d# Q: r9 F
尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令. 5 `, Y: P! S3 [% k+ r! Z! X0 ^- h! ?3 A
另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性.
6 q/ p, M$ ]/ L/ o4 _  o3)三角函数/双曲函数
2 _1 ~3 L* T- [命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);+ [4 K0 k& q5 V' o0 x" w
          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);
4 P: G% m' ]/ p# T其中, x为任意表达式. 9 Y$ S/ A9 }  ~
值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.( J/ `% z- s8 }+ D0 e5 A
> Sin(Pi)=sin(Pi);
" H1 [6 r. b+ J" x5 M, _  a5 Y
' q% O, S0 ~' t  H/ h. @: R  u> coth(1.9+2.1*I);
2 b; E2 a% l; d+ W- }6 F( | 9 @" a& Z. k' A5 `9 j3 N& k2 E
> expand(sin(x+y));     #展开表达式
# K" ~6 p/ F2 E* n. t) \* _
" r" f* W* R2 T9 C- L+ B> combine(%);        #合并表达式5 l& |6 A2 Z% S7 P# ^
& }9 s# \6 d/ Y0 j) K
> convert(sin(7*Pi/60),'radical');8 k" E; `' g* C
4 Q- L( [; w8 e0 {  L" V
> evalf(%);* ?' S) m5 |# \4 i

: V5 R% j  A9 p/ R# q但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.8 J! n6 k+ V1 c1 a5 r8 M; F
4)反三角函数/反双曲函数
3 N+ f+ l1 g9 n" o5 F7 u: H命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);; {$ E6 F. J. Y$ v$ t2 o
     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);   
* t4 F2 K( z4 ~) Y' darctan(y,x);3 s: l3 u: @! v% {" Z
其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算. 2 ~% T3 {- e: y0 ^3 O
算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.
* A* w" ]4 i) ^* q" g> arcsinh(1);
2 {- T" z6 o4 i" v 8 k. ?* p0 B9 ~1 n
> cos(arcsin(x));
9 _# w) O8 A, o; i9 P 7 z9 y8 {$ }7 n6 ?- }: a( h
> arcsin(1.9+2.1*I);7 x7 c- b# k) L! V' a" K6 [

& K- M, v+ G1 h3 e4 N: s4 t0 G5)对数函数
5 ]. P* V5 F7 \2 G7 a  ~0 r- F命令格式: ln(x);           #自然对数
' l9 N) t* S" ^# ?9 n0 |) Rlog[a](x);        #一般对数
, P$ n$ c4 Z6 |( glog10(x);        #常用对数* m) k8 y. g& C- Q: B# u
一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:   9 _/ s$ K/ P* a, i2 F
  (其中,  )' V0 A: E4 S* J% a2 {
> ln(2002.0);
+ {1 I. A% V4 L7 Y3 S
& e: w$ o% k$ D  j; |> ln(3+4*I);8 T: J9 l7 E4 O/ a  }' Y
  R5 `% M" t# D
> evalc(%);    # 求出上式的实部、虚部" X4 L5 c! E: c, H4 p: P
8 M- l+ R# e4 ?; o
> log10(1000000);
0 q1 @/ ?# F: ]5 s, _ 4 i4 E7 o5 ?2 t  a7 @$ \( Z
> simplify(%);   #化简上式
" Q% ]  j2 Y( W; ~. @* Q' i0 q- } 6 n- V0 r* L' c" d
2.2.2 函数的定义
" h& m6 O2 e9 f8 P5 |) S% [Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:   
1 q( \0 ]- [0 U' T- ^& w> f(x):=a*x^2+b*x+c;
: P0 r# b* |3 }8 k0 z) W
( p7 D1 o4 X1 r( a0 u可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:   
/ b8 X7 }/ h) B6 ]> f(x),f(0),f(1/a);5 O# S/ A0 i& `( ~1 P2 v' m

, q( H3 |. Z) U由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:   
; |8 F" U5 i0 ?. F' M# v6 H, {> print(f);; n% N0 a$ y' b( B+ a

4 C0 O& `+ D! `事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式.   e6 O) j; t& g  g7 ~0 E
在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):   
# P$ V+ I* e6 z/ X! @9 a2 ^" d2 q6 r* \> f:=x->a*x^2+b*x+c;
2 [. h% I& F. i+ W, ^ 3 T6 N, Z  k# p6 i! k+ v9 @" {- U+ T
> f(x),f(0),f(1/a);
& Y/ `! d/ N2 ]! A0 N; w+ Z6 Z 7 D5 X- W# Y& G' }" Z3 A
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
1 i1 ]- }, r. ^6 G> f:=(x,y)->x^2+y^2;5 ~0 G5 X& C, e# ~
$ d# I" y3 t: C  _  @
> f(1,2);
, w0 R4 B! L* ]0 d8 O
: }6 M0 p+ O4 G8 h+ a> f:=(x,y)->a*x*y*exp(x^2+y^2);
, s7 Q) k" h/ F& O 3 Y1 ^5 }6 b1 J2 A  X. B
综上所述, 箭头操作符定义函数的方式一般为:   
5 v2 j  s/ p6 G/ J% [一元函数: 参数->函数表达式8 \2 X+ ?+ L" }# _
多多函数: (参数序列)->函数表达式
* B+ y  \4 I3 {  U% ?# H无参数函数也许不好理解, 但可以用来定义常函数:   3 S9 {; U6 s# A3 ^1 f
> E:=()->exp(1);  s6 ]) c- H) z# k
  M# g8 [% o, x
> E();
3 U9 I, S( B( h: F( Z # A, u+ }  N) q. [# W7 U2 Z8 h6 w4 h# B
> E(x);; W6 N( x, c" M3 ?5 ^3 R; O

( a/ S" E  t  h0 P0 E另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数.
2 _5 W: m8 c+ [6 ]  D定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);          . f' U5 P7 e: k3 Z, `1 k: r( A
定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);     
! l; u3 I, Z4 y" P9 _> f:=unapply(x^4+x^3+x^2+x+1,x);+ Q  J2 N* Z) f% q/ X5 h5 k

; \, P3 u" i/ L) a+ T> f(4);# v0 y. Z3 ]  S8 Y( T8 g" H9 z9 [; ?

% ]* ~; e! u+ D# F7 X: ]- X> f:=unapply(x*y/(x^2+y^2),x,y);/ U* h5 H8 D0 i: ?$ `5 v
7 P2 K: q  \' B( f: t
> f(1,1);
7 c7 P) H4 _: _4 j9 e+ H6 u
9 ]0 a$ R& ~7 C- h8 `借助函数piecewise可以生成简单分段函数:
3 L, `9 L, s! ^7 j$ [> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);) a% G) H3 i$ L) v% @
& Y- L( O' |9 u, y
清除函数的定义用命令unassign.
" ~2 s0 k" {4 I: `> unassign(f);
% x9 w9 I* U0 S# l7 J; g> f(1,1);
0 s; }) W4 L; k 6 M- m: [. U5 `9 y$ t5 q5 I: Q' O
除此之外, 还可以通过程序设计方式定义函数(参见第6章).
9 ?2 w$ _3 v; A7 t; Q0 M. e1 J8 r定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:* F) w( d4 O# }' Q7 K- g5 h
op(expr);         
+ d' M& P( N; l: g% W6 Lop(i, expr);         5 L6 c; L  a, F4 ]0 a3 f
op(i .. j, expr);      . H* [' z% D5 P! c( ?  A" F( z
nops(expr);
+ v# e1 ]$ S) n* o( a如果函数op中的参数i是正整数,则op取出expr里第i个操作数, 如果i是负整数, 则其结果为op(nops(expr)+i+1, expr); 而i=0的情形较为复杂, 当expr为函数时, op(0, expr)返回函数名, 当expr为级数时, 返回级数的展开点(x-x0), 其它数据类型, op(0, expr)返回expr的类型. 3 v% ]+ z) L2 `0 g' E# a0 M
命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.
; R, B5 T; D0 }; m命令op(expr); 等价于op(1..nops(expr), expr); # e0 N6 f; I! ~4 {
特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
# h5 }% f# _2 N而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和. , o4 e; y: V+ W* m& m9 T
> expr:=6+cos(x)+sin(x)*cos(x)^2;5 i7 V5 @( S/ a3 o7 o7 ~& z
/ ^( a, `3 A* h( A
> op(expr);
8 f  U2 r5 h) P! X
" q( E1 L- P9 Q2 N. h> nops(expr);3 r2 i0 q5 v" i1 c% R* }% L* n9 r

( z" J& W+ {3 [) |> p:=x^2*y+3*x^3*z+2;
$ f' L+ `& f- U  x* o
% C. p7 e+ p0 o> op(1,p);! Q4 U/ D. f& x- I% N

# P3 U( E( Y/ `# M5 h3 O> op(1..nops(p),p);) |: }, g9 ?' G7 E
9 U$ S4 K+ \# J
> op(op(2,p));9 f6 p5 l- X% H- ]2 a$ u

( I4 a  r" A( `; e0 J> u:=[1,4,9];& q( E) L# c+ b* w

8 c2 M, b( z+ o; z> op(0,u);
4 h4 g& C4 _! C! e- e( h% c0 _7 E ; Q4 W) n' P) E( d! m
> s:=series(sin(x),x=1,3);( H* I* ^* j/ W* b6 ~' i8 r+ ^

2 o0 Z8 L' r, X> op(0,s);4 E4 F7 ^& Q' a  a: J
        ' t" A: t1 {$ z% m
> nops(s);9 E9 n# z  X6 s+ V- a0 u

7 V; O# B9 P5 X7 o下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:
' \* V4 l- K- q: c> op(x*y*z);
2 g$ r; `& Z: a& v1 G6 ~# m( i
- }* ~% W5 n; z8 x0 T> op(x*y*z+1);
9 Y0 R1 Q, i; z8 Q 5 z/ h0 m/ L# M; n. O
2.2.3 Maple中的常量与变量名
2 Y- d+ @8 H& e4 y# y为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:   5 C# g6 z% q3 q  M: J  ]) e
> constants;# }& t) C0 B. r

9 G; l  p, ~' e& v1 R5 c为了方便使用, 现将上述常数的具体含义列示如下:   
. _) u, x, e3 j+ K: W) }1 w. S8 n" p常    数        名 称        近似值
9 J- P5 y2 J$ ^7 g  r( \7 J1 I  V$ W3 T圆周率 0 R- Z0 _6 t* J
Pi        3.1415926535' M1 o1 |& x) i3 x( O5 a, ]
Catalan常数
5 Y" r& w* H. OCatalan        0.9159655942
: s1 y. J3 h# @. {Euler-Mascheroni常数
2 r  H5 E1 l, \# Mgamma        0.5772156649
3 f; d) i; t! F4 K, I; x3 m# }
. V) E( O. O4 Q# f8 L. Oinfinity       
' i5 ?8 w; c0 j! M  ], w' I* ~
' Q* S3 p5 J2 L# U! t- |需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取. 6 r7 k8 W0 C5 _2 @. V; i; x% D! D
在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”. 9 Y$ x: N/ P! }3 \1 }
值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名.
0 B; `8 m& P5 w; y2 j0 d  Y0 s8 t在Maple中有一些保留字不可以被用作变量名:   
7 O/ X$ f' `" E8 ^2 v! y- z' _" Sby      do      done     elif     else     end        fi        for      
- V' ^% k8 k. ]. Y; [2 \0 f4 ufrom    if       in       local     od     option    options     proc         - w6 R# F- [* I" G1 j
quit    read     save     stop     then     to        while      D
; C1 H+ V" J8 }4 J7 P1 T9 sMaple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名.
8 a6 `; a* P: \- x0 ^0 A另外一个值得注意的是在Maple中三种类型引号的不同作用:   
( P! n2 s7 {/ C7 ~, h6 N`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;   
7 ?/ A$ V4 S- s! a* }'  ':   界定一个暂时不求值的表达式;   
! f: F- y" J) G# m& F' X" v"  ":   界定一个字符串, 它不能被赋值.
  r& q1 _- B: d% x2.2.4 函数类型转换           
, u6 h) j$ M  ^" c. o函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:  
) t4 j) l' J6 \    convert(expr, form);        #把数学式expr转换成form的形式7 X* x% h) F$ Y* [
convert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos
+ i/ k$ Y: ^8 K9 ?  Oconvert指令所提供的三角函数、指数与函数的转换共有exp等7种:   4 Z: }1 R+ P) q. U5 j
(1) exp: 将三角函数转换成指数
& J) M* V$ {8 N# c& a6 [* x7 X(2) expln: 把数学式转换成指数与对数. {5 G. T4 q* C( v1 h9 Z
(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式
; w- x& P2 a, H. a(4) ln: 将反三角函数转换成对数8 P0 N4 E3 |  Z2 E& g( T; K& q
(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式& P) R% k8 t! o* r6 e* q7 d1 m
(6) tan: 将三角函数转换成tan的形式
2 g) s$ U0 ~4 t+ F7 x(7) trig: 将指数函数转换成三角函数与对数函数$ h+ v3 G" E* J" {
> convert(sinh(x),exp);   #将sinh(x)转换成exp类型
* [0 E/ p) U& O, B 9 A9 I' P5 F7 W5 c7 H# J
> convert(cos(x)*sinh(y),exp);
  ^3 }8 O, r/ j
  T1 ]0 M; S" a' g& y% p6 a> convert(cos(x)*sinh(y),exp,y);
4 v) z$ J3 X3 R0 @- V ' Q" l$ c; `) |
> convert(exp(x)*exp(x^(-2)),trig);
! t% _! x( S0 O/ c) Y, T' [
) I* l6 Z9 E- W) w" l> convert(arcsinh(x)*cos(x),expln);
1 R7 q6 o# x5 X4 |, k! q 9 h4 T  e  d# D! l
> convert(cot(x)+sinh(x),expsincos);
* [" i# Q2 Q/ c, u) g7 D2 N) C
; y. l4 W9 \1 P+ X9 ]" A> convert(arctanh(x),ln);
8 T2 E* {$ C6 F: H0 |8 ~ # I6 B* W. R- ~  W( U1 Q, f4 Y
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:   " Z- p4 t' o) ?/ g
> with(codegen):
2 O6 [  G( T6 Y, c$ i5 v3 T> p:=4*x^4+3*x^3+2*x^2-x;
- y: d0 B) m( h5 _) l * m' p4 N9 `8 e+ N
> cost(p);5 g, O7 f% T, n0 @- H* [, f

$ y' T$ _0 f; n. X. {4 t4 M. d> convert(p,'horner');  #将展开的表达式转换成嵌套形式
9 J9 t' g  |8 z0 I8 g% c7 X. Z: h ) U2 o8 ^$ ]$ ]5 S& V
> cost(%);. U, B2 V- t# K3 v( a

  N) F; K! v6 C同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量.
% A; `1 Q* ?- ^+ }8 d1 w5 i> (1+x+x^2+x^3)/p;
0 |$ V  Y2 Z5 ~4 z7 W
# o3 x! |0 F& g/ C1 E" E; a/ i  U> cost(%);
2 W* Q& W6 H  u4 V# t  Q; ~
$ z) T, T1 {0 ~/ d- J7 O; T% X> convert(%%,'confrac',x);
" f* H. o- V$ {# [2 X: @5 l; N8 h  V- ~
/ q. S6 F7 x/ P* Y& |> cost(%);
; U0 q, l) d) v, ]0 c5 G5 s 3 e2 E' }0 x% w$ F7 C1 G$ [3 @9 Q7 j
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式.
# x# ^: P# I. v' P' k0 m> convert(%%, 'parfrac',x);
3 r& T6 X8 g2 I2 w
- u8 b) ?7 m2 q1 x> cost(%);
8 b! h$ ^" ~5 q- ?. m) L 9 h+ \. e" z: c, k' C8 s9 x2 U
而把分数转换成连分数的方法为:
- \0 h$ F' w3 E* B  U> with(numtheory):
/ }- R0 _3 B( [% c" @2 O# e  n; E> cfrac(339/284);* Z! }/ Z; @4 O) k. C6 X+ u5 A4 W

) b8 u1 T9 J: ?) W+ ?, J2.2.5 函数的映射—map指令
- O5 k) t# v# f3 ]) s  E在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:& w1 D) ?% B4 L" y! E
map(f, expr);      #将函数f映射到expr的每个操作数
$ N& c: l1 y+ G! G3 C9 wmap(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量
( n7 U1 s2 T9 b+ @& J8 L4 `' c! ~/ fmap(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量. D' Q. j  B+ l6 u8 Z  U: D0 P
map2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为
/ B0 N/ ^: w5 J, _* A第3个自变量…, an为第n+1个自变量来映射函数f
0 ~6 K1 L) w/ L1 T$ V1 D) s/ M> map(f,x1+x2+x3+x4,a1,a2,a3,a4);: m$ K) M" r$ v# K8 P

6 ]2 v  ~8 C+ `& Z5 u$ S; j  S* C- F> f:=x->sqrt(x)+x^2;, c8 o% _6 ~' W( T" W0 a; H) V

3 C0 S5 P$ Q' g& I: H> map(f,[a,b,c]);+ g( Z$ @: q( I( |/ ^6 C
/ Y" y* M9 a5 A' A  V
> map(h, [a,b,c],x,y);   Z) g. B5 ^7 y) t

& s4 C" n  a; K" V  H# a, @5 I" V> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);
5 @1 p4 a7 V3 ^5 a  b
  X$ T/ n9 J! y* o# o> map(x->convert(x,exp),[sin(x),cos(x)]);: G# l% p- W3 r
% Q8 G7 ?( C( ~" Z. ]& k6 x  A, `
上式的映射关系可通过下式理解:5 Y3 l6 w1 Y: d
> [convert(sin(x),exp),convert(cos(x),exp)];- g5 I; J. Z' {1 U
  Q$ z* N9 p4 I  L1 D0 d% N6 M; H2 ?' Y
> restart: 6 B; j" d+ b! \2 h0 B7 D! P" ]
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);
1 r+ {$ X3 `, x! { 8 A, q6 p3 g# o) S) g
> map2(max,k,[a,b,c,d]); / \( @8 t+ m5 w( J5 V
& Z  H# ~+ r  R* Q7 r* U1 X
再看下面示例:   & b; v3 ^9 I% _  C: q- Q6 f+ B$ i6 @8 V5 T+ c
> L:=[seq(i,i=1..10)];" f* e- n$ M7 L  w4 W

  S) i5 {$ c+ N; N> nops(L);
- d/ f2 v6 \. P; z& x: I5 L
. E- W$ B$ r% K- |3 e* K# s> sqr:=(x)->x^2;/ {% M2 D/ A$ K. J  ^% m9 T; {  w
' T3 \" P# R2 P) H6 ~& P
> map(sqr,L);# k4 B. j4 N, l. O
8 `. M+ @' m4 ]( E
> map((x)->x+1,L);6 e# g6 [  B; R1 ^

; r  j- C* I1 v+ c+ j  `1 \> map(f,L);
- F; ?! N/ n$ @; U0 `0 p, H) D
& G: L% W: H9 v% C( _" ]> map(f,{a,b,c});
8 u0 {! t; n4 a7 N; a
, W8 r3 u! u) w# p) L5 T- D> map(sqr,x+y*z);! N! R/ b- d5 q5 T7 e2 ]  o
# n5 G$ N; o# H7 j- R
> M:=linalg[matrix](3,3,(i,j)->i+j);
& f* P7 n9 q$ {2 I! M; u( j
0 F7 z/ _8 B  D' A> map((x)->1/x,M);& x, g! [8 A  j' x( N7 {5 W

0 Y! Z! P( W# F, J$ }. B, I3 求 值: X9 k8 o" b" p8 z' t/ v2 m5 O
3.1 赋值5 Q( Y& l; o1 a& G4 S
在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子.
/ p% K! T% ?% F& K4 Z> p:=9*x^3-37*x^2+47*x-19;
9 `+ \, `; |, `- B' l / {' a; D& x5 z% F  D
> roots(p);$ t* E% I8 O4 t- l; R

3 r$ i. E1 ]8 D/ y1 t- q4 B/ G* P> subs(x=19/9,p);
* a, c! b" {% ~6 _7 A/ F8 Q8 O! Y 8 `) t# Z) q5 a( G
在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量p和多项式9x3-37x2+47x-19相关联, 在此之后, 每当Maple遇到变量p时就取与之唯一关联的“值”, 比如随后的语句roots(p)就被理解为roots(9x3-37x2+47x-19)了, 而变量x还没被赋值, 只有符号“x”, 通过subs语句得到将p所关联的多项式中的所有x都替换成19/9后的结果, 这正是我们在数学中常用的方法—变量替换, 但此时无论x还是p的值仍未改变, 通过“> x; p;”这样的简单语句即可验证.
; q$ b( a: n5 V) u3.2 变量代换9 \2 q) S4 w! f8 u; p
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:   ) v  V1 H! O- F3 n' z$ P) {! M
subs ( var = repacedment, expression);
7 N+ l' G: d0 ]' {调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement.
2 b" `" Y+ E& N' N! Q> f:=x^2+exp(x^3)-8;! L  p3 }) _8 p% D2 j) ?

* H7 t8 T6 F, i% ~> subs(x=1,f);
+ H/ X* q/ j: Z$ M8 M+ B# a  O- D- f
* r: J  e' ~' e  X+ v> subs(x=0,cos(x)*(sin(x)+x^2+5));
7 Z) T- h9 |  J% r' z4 ]
# p& x+ q/ ?( h8 k8 W    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:   
, m/ X& p. ]; q+ n4 Z, A> evalf(%);
) M& L, ]7 V, V+ C8 i' c   [' h. R/ _  u) P$ c  ?
变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:   
1 Q5 l' E7 U$ `& r. x3 d8 gsubs (var1 = repacedment1, var2 = repacedment2, expression)' w8 |" u3 V# |; C+ ^
调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:   
8 `  e) q: @; T5 T' Q; I: }7 Qsubs ( {var1 = repacedment1, var2 = repacedment2 }, expression)0 W: F; l6 k! |4 U2 \. J0 i
下面通过例子说明这几种形式的替换. & U: I5 H' ~; m
> subs(x=y,y=z,x^2*y);              (顺序替换)
$ e: Q" S4 P- w7 |& u $ r7 _# K' w4 I+ [* v  O8 |2 ]9 D0 u
> subs({x=y,y=z},x^2*y);            (同步替换). p* f) z% G: ~, O+ [

1 t* W1 `* H# f! g# |! Y> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)
2 O. t+ P  H# G & \1 F6 f: ]/ j5 C# I5 x4 I- Q
> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)# X' ~* S9 @% ], B) j
8 y5 H" K( S9 D2 b
> subs({p=q,q=p},f(p,q));             (互  换)
7 C6 K2 P5 L. L4 _2 n$ A$ e2 u  _
" q: J! B0 s/ o2 r" ^3.3 假设机制
& b/ p* h! `( S& VMaple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点. 3 C3 z# A" G+ y2 W9 ~/ N
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);; c" m2 h% z: P  C
函数assume界定了变量与变量之间的关系式属性. assume最普遍的用法是assume(a>0), 该语句假设符号a为一个正实常数; 若假定某一符号c为常数,使用命令assume(c,constant); 另一方面, assume可以带多对参数或多个关系式. 当给定多个参数时, 所有假定均同时生效. 例如, 要定义a<b<c, 可以用assume(a<b, b<c); 同样地, 要定义0<x<1, 可以用assume(0<x,x<1). 当assume对x作出假定时, 以前所有对x的假定都将被删除. 这就允许在Maple中先写“assume(x>0);”后再写“assume(x<0);”也不会产生矛盾.
7 r; b! t# e+ S% @. ?' F> Int(exp(-s*t),t=0..infinity);
  T( D' e7 Y. J2 Z# H+ _ ' k6 n6 Q  `) e$ N8 l
> value(%);9 \. _+ `$ O0 p7 P9 _
Definite integration: Can't determine if the integral is convergent.  ^4 ^! M# {) \: c- X; h" u3 ]
Need to know the sign of --> s: R0 G: u3 A+ ~! |
Will now try indefinite integration and then take limits.& M! b  G0 b& E. n
& \4 v3 }6 \8 t: V5 F" |
> assume(s>0);
3 [5 I7 ?, J" m1 ~5 d> Int(exp(-s*t),t=0..infinity);' @5 i9 R9 T! [
( w0 m- J  ]# A( S% C. K$ w1 _
> value(%);
) O7 B2 d+ L& c) H  d- n& F. T . c) K& u. j( j$ Q8 ]
3.4 求值规则' n( c) j+ W# P- g
在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:   
7 Z% x* c6 R! N& J" e4 Y" j$ e> x:=y;: F, w; R' T2 R. L0 @, a
; L9 a! j+ s/ m3 n' \& v
> y:=z;% ^5 j3 M1 r7 Q
, P7 U" f+ h8 w
> z:=3;3 s2 B# t) q5 K1 S  W
5 o; Z$ `& \6 c+ ]6 p$ Q; w
> x;
( n- i+ a) z' z5 a3 H- P
) T0 u' D2 L  o, f2 m( q> y;
1 Z8 O/ w! a, ^
) N. w/ R& i& H* p1 h, q> x:='x';
- L- z, G8 r6 s; s: h5 Q0 c
/ n: H. j3 ?& u1 u3 p; l' c> x;
2 j- O6 s0 p% I8 d+ J: [6 ^ ; T$ r  G. g/ u" ~, s$ ?5 b7 f
> y;& d2 ?: W- x, S
1 x; m: O$ ^1 K  o. E3 s: H
对于不同的问题, Maple设计了不同的求值命令. 现分述如下:   % \4 c7 n6 y8 p
1) 对表达式求值7 T$ a5 [8 o% R
命令格式: eval(e, x=a);  #求表达式e在x=a处的值
4 B2 C! ]+ P5 K  p# Q& K             eval(e, eqns); #对方程或方程组eqns求值
8 D' n; ]; h# c/ w0 Y             eval(e);      #表达式e求值到上面两层9 W  t) B2 \) R* [' {/ R/ [
             eval(x,n);    #给出求值名称的第n层求值
1 B. o/ ?7 r! z3 r5 p' z> p:=x^5+x^4+x^3+x^2+x+73;' E9 u* K# ?2 m, m5 v& L

' ?6 A9 r! N: u2 b2 r: Z> eval(p,x=7);
( v7 U/ R& T+ X& x) Q) o
' U& H- N) v5 Q, R5 H1 i> P:=exp(y)+x*y+exp(x);
$ y- D6 f' N. P' J
; x, d. F0 m. g- ~& L: K6 W$ r> eval(P,[x=2,y=3]);
" v( y. @% P1 S% ~& I 3 J( H6 j# b0 \) M# ]
    当表达式在异常点处求值时, eval会给一个错误消息. 如下:   
* V6 }$ j% [( Y2 H> eval(sin(x)/x,x=0);6 d: M6 @% \( R  ~  h) q) f, g* n
Error, numeric exception: division by zero
5 V) B4 e5 a* ]    下面再看使用eval进行全层求值或者对名称几层求值的示例:   9 k) }- d+ b% d9 w
> a:=b: b:=c: c:=x+1:
( ^' r6 o# H7 E) C1 r! }> a;              #默认的全层递归求值/ i/ T: Z& E$ q1 Y

. i  G6 I3 l7 @) U  Q/ {> eval(a);        #强制全层递归求值
* b0 i4 \* C+ V1 N: J) i
# K0 x4 y2 j' D. |. Y> eval(a,1);       #对a一层求值& f: q% F/ h; X# }
& N; l9 I$ o$ X6 k! {4 y" T( i
> eval(a,2);       #对a二层求值/ `2 ]) _( n. O) f) H
' A( e  Q7 \1 g$ A1 _; B$ j5 k
> eval(a,3);       #对a三层求值& ?# p1 ^( P. U7 e. y$ [' G' {1 [
! z% ~$ N' A" O- X. q# B
> eval(a,4);       #对a四层求值5 o& z7 h' {! ~+ U6 L
6 K3 _4 W! R/ D1 Y  I! }8 _
    2) 在代数数(或者函数)域求值
+ F& j4 Z/ D" g" ~' O# c3 d命令格式: evala(expr);       # 对表达式或者未求值函数求值+ N/ z' ~) B% I/ y* O
             evala(expr,opts);   #求值时可加选项(opts)' o$ W8 f0 Z4 B$ ]9 D
所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式. & l! c2 {- _% L* D
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:   7 p( ?- d* v# @- u- k
> alpha:=RootOf(x^2-3,x);
3 ]& v9 e( p$ ^& `/ j- C; L3 A 0 u# c% L; s- [% L4 W6 e4 |4 @
> simplify(alpha^2);7 h; o* F' C+ Y( x) L
% {' r7 W& ^- G' W# h) `. u- r+ @
在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:
% [9 l7 L5 O7 A; Z9 I' W4 H> alias(alpha=RootOf(x^2-2)):0 i+ u; v. G# ?6 [5 }9 T. j
> evala(factor(x^2-2,alpha),lenstra);
4 i* C" Y9 q; T3 W$ ~4 c
/ {2 |; `* B# L; |> evala(quo(x^2-x+3,x-alpha,x,'r'));
9 L/ W8 A  U5 c1 D) V6 |
5 L/ N! C- [5 l( [' P1 J) }> r;
% s& L5 j2 `' J7 Z / V, o9 E$ ?/ F9 t; p, ?8 o* t2 s
> simplify(%);  ]  f) |% J; p# d# |* _- o
, r+ a/ u0 @: c
3) 在复数域上符号求值
) H* q% m7 d5 Y( j+ X0 ^/ {操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:$ u3 H1 z  V: q
evalc(expr);   
3 A6 v, @7 w3 U% `' a% pevalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
9 _2 o% P6 I" i. E> evalc(sin(6+8*I));- r$ B5 Q3 B& U3 [6 z, y
9 f+ w: N* S/ A4 {
> evalc(f(exp(alpha+x*I)));! ]0 l3 E1 I2 M3 S; a8 I& F9 R
  R) n3 y: X! ~) p3 o( }
> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));/ v) c/ g  z5 B- Z5 C2 y  r, f) {
- q7 T' p, M* A! q+ Z
4) 使用浮点算法求值% X3 L# K' P$ O* j- M
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);     
# F5 c! R9 Q, q% B( b> evalf(Pi,50);   
9 V) s; M  p0 z- Z3 s9 K8 | ' i! Z  s8 c; J0 [7 J" d  G+ K
> evalf(sin(3+4*I));   * o1 o6 i5 e: M& U4 Y
8 p+ H7 n5 K% g$ x+ @* Q0 N/ b' d" K
> evalf(int(sin(x)/x,x=0..1),20);
2 B4 G3 c2 s1 {
% t4 R4 k& \& f& S5) 对惰性函数求值
/ L; C) u; T( M, }! |把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);   ! k$ P9 }- y9 W$ I! {7 n% T
> F:=Int(exp(x),x);4 o! O/ n, `: Q$ e( X7 b

8 y9 J- Y( @$ ^, T> value(%);
( h  a6 w; E+ b- a
) J, q8 j, h4 d( `> f:=Limit(sin(x)/x,x=0);
+ z; B! U# g  c# g) D7 u & P- y- p+ B! P$ u. a- O6 G2 M
> value(%);
. ?8 F# u2 d3 H# M
) I" q, b; ^% t4 Y3 ^! Z另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:   1 Q4 J" n( h/ L, r4 D* j
> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);
( u( u) C. @3 X: n( ~* [ / [) M' U7 o( l- s# H4 C
4 数据结构  e! a4 c0 U$ R! |6 n/ A  ?1 l5 Z
Maple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
$ Y  e+ k8 X, l. B6 P6 G0 Q4 n' O4.1 数据类型查询7 ^% I$ h$ @- X& f: U& o& U
在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为:
. \- B, z2 h$ [0 q' q* b- hwhattype(expr)        # 查询expr的数据类型
$ Q. N: K7 E; v/ V: x. @4 m" \  e: ztype(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false, X) d7 f0 z9 G1 Q" J
> whattype(12);
9 G0 Q& A" T7 L0 m 7 G9 l3 L1 _! G
> whattype(Pi);
6 h+ h5 Z" w% P ! t- [* A+ N, n+ }5 i# p) n9 j
> type(1.1,fraction);
: k! ]* {/ |) K: |- B! M
, o1 R! ~# g' d5 q% \( Z> whattype(1.1);
) f9 x# A& p7 s) ` 9 N; w% i5 J6 \6 {; H7 Y
4.2 序列, 列表和集合. E9 _9 |/ J  J6 w. @; Q& V4 M
4.2.1 序列
* T" ]5 h: {2 b所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:   
# {% F7 W4 h) @. K) ?( y/ ]0 C) m> s:=1,4,9,16,25;( u+ v" D8 z' v# |$ \
% H% W7 A! _" E* x- J4 }: Z
> t:=sin,com,tan,cot;
% T) ~& m9 h' o) `8 E) _: D 0 c6 Z9 y8 b8 Y% [2 y: g
一个序列也可以由若干个序列复合而成, 如:   
: H- }  y, R* g1 x, w0 D" u, u3 ]9 Y> s:=1,(4,9,16),25;$ Z2 \9 D6 \  E; C9 @

4 w1 l5 e2 e  I1 d> s,s;
" M0 X6 Y( K: X / P4 I% @7 R' Y1 v
而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:   ' N- J9 R6 g0 P  ?) i
> max(s);5 N& e% y5 T0 a) ~" R) {

0 _. \" f& Z3 L$ |2 y5 o> min(s,0,s);
3 q0 w( @6 h7 F  h6 J" {8 Q ) r- ?: ]6 C+ u2 D, l) z* S+ f$ U
值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中.
6 G1 ]5 n* Z; b) g- W! r> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;0 q( F! b* u# K  j, D4 i" r' ]
& d* z4 s& G) `$ u3 v
> op(s);
9 L, k& A  H: R4 c& F0 {Error, wrong number (or type) of parameters in function op: O8 P% }- N* q! D6 d
> nops(s);
, q4 M. j. F* \, y8 S$ BError, wrong number (or type) of parameters in function nops
9 q5 }; g3 @: h" ?> op([s]);
+ W  L% P; G2 W" I. a, ?1 y 1 c' U. b/ k: C; F) J
> nops([stuff]);- p' f4 p+ T* E+ d

& `: c: W: d' V  W- V函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:   % w3 Q7 u( w* b9 b, H; h
seq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)7 p$ ~+ I4 o, w4 Y8 m
seq(f(i), i=expr);  # 生成一个f映射expr操作数的序列
& P0 G3 O- C- P! dseq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列: ?+ _/ L  {9 p8 h
> seq(i^2,i=1..10);9 x2 i) q( }1 x/ |# o
; k1 E6 u' n) g3 S
> seq(ithprime(i),i=1..20);
$ `4 W0 V6 p, m4 z$ W0 s
; t$ |# _0 N. P& L! d8 F- ]> seq(i^3,i=x+y+z);
$ m5 r* ]; E3 u3 s1 \0 x& q
# s3 r2 h, z  I. m3 K: R3 n% I> seq(D(f),f=[sin,cos,tan,cot]);
2 Z5 U& f* T  ?% C7 Q2 z8 W  F 8 x9 r' c1 x  f9 R
> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));
& r, F4 S/ Z0 N4 z: B* I1 C5 g6 ~ ( C5 `. O! o& W3 T$ b7 p5 N- ^' g
获得一个序列中的特定元素选用操作符[  ], 如:   
- g+ P4 C: T( Z; c3 }2 j> seq(ithprime(i),i=1..20);
  g: Q* h3 |- S; p3 `3 h2 D
7 d% i9 d* B1 h8 _9 S3 r" D0 n9 z7 A> %[6],%[17];
: I9 L' ~) s+ z- \2 j2 N
  Y5 X& ^9 _# T* y7 Q# U& _4.2.2 列表9 Y; Y: [2 q4 N- E1 j4 T' V9 \
列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:   1 i3 M6 O2 v8 v3 ]$ \- B
> l:=[x,1,1-z,x];
2 C, y% d) L& O1 ` % Z' h1 _: o  b/ G% H1 |! o# q
> whattype(%);. N$ a. U3 r0 C
- K2 O2 N1 f3 x. s9 B
空列表定义为[ ].
" ?6 [4 R* U6 R但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:   " f4 V# p, D' s: E
> L:=[1,2,3,4];* o2 G" u3 O2 C6 [6 V9 F
# f5 m/ e) ?" y( g, i8 f$ v' O: J
> M:=[2,3,4,1];
9 g/ ^0 a4 r( U0 V) i! X* Y* \' T( k
7 ~: t  C8 f8 e4 T) q/ N' J4.2.3 集合
) f$ G: p+ V& J" {; R5 w$ l集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合.
' }8 u/ |& b. ]4 \2 {4 @2 {> s:={x,1,1-z,x};
7 ^0 t. t& j5 W3 |6 d: M
! f5 u" A' P! Q& C% i0 F+ i" ^# P> whattype(%);
+ h% z6 g% I+ q( V
  M1 l2 z7 p7 D) X' d& D空集定义为{ }.
2 h* s5 C: e0 |  u函数nop返回列表或集合的元素数, 而op则可返回其第I个元素.
  [6 d: x4 i  |) e$ p! _/ x- F  y1 ?1 A> op(1,s);5 V7 B5 \6 A2 E0 ~4 _/ P
) V) I. V) a; g6 L6 \* j0 z, z
> s[1];: h9 d0 |8 T& I& M
* T" {* n8 {6 x0 E# |# p! K4 o2 p
> op(1..3,s);5 D' P0 m8 n& q/ v; {

1 t+ F; j: Q+ [+ M9 A> s[1..3];
0 p; F1 y1 q2 g, V0 |& M& F
: c! v9 E0 t' |) X8 |5 z函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false.
6 X5 ?3 \, D2 n* Q3 [2 S6 ~> member(1+x,s);
: ^5 S2 v4 E" Z7 x% s 7 f1 x4 D  a6 F, w$ q  A/ }, R
可以通过下述方法在列表中增减元素:   
8 Z5 t# [! M' S0 i9 N$ [> t:=[op(s),x];
. |* T+ [/ R8 G6 n
! o! k$ \- y" W- ^> u:=[s[1..5],s[7..nops(s)]];
7 A. z$ G2 h! v$ G% K $ `8 o* S* V% W; J
Maple中集合的基本运算有交(intersect)、并(union)、差(minus):   9 e. Q6 |' o, y8 J0 I
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};
0 N7 A% e: B. H% ]. o ( U2 i7 j9 N$ g  e

- f, M) J# m1 U: N! z, T> A intersect B;
  x! ~8 U& @1 H
1 o# J& \: A' N; Q7 V> A union B;
0 H4 J0 A$ C6 f5 b# h / S0 |( d) m: j$ A) ~. r
> A minus B;6 R/ B" D! h' Y; j2 B2 |% Q4 \
! M- V5 Q) K9 J) l: D: b- P0 H
4.3 数组和表
% O: `4 O% j2 t# [! G在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令.
2 C' |4 X; o& W4 i    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的. * i$ d. g7 P3 i4 }' @! t
> A:=array(1..4);
3 L0 f5 C$ V5 r3 L
9 r6 d6 z5 T! R4 K! D> for i from 1 to 4 do A[i]:=i: od:. _0 C# l" k/ i4 f1 ~* M$ _8 u' H
> eval(A);) X& e8 Y9 v, |
+ S& }0 I/ g) Z0 V5 p/ y
> type(A,array);
' @0 V8 o% T; k/ m 4 K+ S  ^2 K8 x
> type(A,list);
7 A" \, V+ j+ i$ T) f5 s
/ a( x. J* B  d& _: ?! o& \> T:=table();
1 ^4 z/ X) @9 `+ Z
7 r- ^; j0 r& n9 G8 x% x9 g6 q> T[1]:= 1;
9 N2 F  B$ Z5 j% n4 D2 h. k
& i* V9 E. ~7 k0 `7 W> T[5]:= 5;$ e$ W$ N% B$ c" z0 ~

8 n0 u4 D2 y2 X> T[3]:= 3;
5 Q& Y0 j. f1 w" R! k7 X9 }; P ' E& J5 `' `8 M) L% ?/ H
> T[sam]:=sally;
5 e" R: K# X. x1 A
- G& n$ K- t. ~  F* t> T[Pi]:=exp(1);, w* h% X, Q/ r1 V  G1 _2 j8 ]

( ^  U" A) Y. K  b3 Z1 `+ W> x:='x';
: d5 t% x: U( X, J0 l' Z, R; [3 Q- z
+ G( _- V8 X. d: k% b) B2 g> T[(1+x+x^3)*sin(x)] := 0;! `, q1 T- `/ M: u5 g" {6 H# _/ w

& Y- G' g- J& j> eval(T);
$ l% W* i. m% Y; |  O
$ A  b4 ?0 e; t8 C  I> T[3]:='T[3]';/ h9 Y; \1 M& |6 f
, w9 G0 N# J+ A0 a) `
> eval(T);; Y) q6 c  K$ d) T( g/ O3 ?
7 ~' x& Z0 D, o: ]7 M
4.4 其他数据结构9 t9 w3 o, F  {9 x. ]* A/ N  `
串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来.
& ?# Q) G# c/ K1 V+ Y: v索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立. $ @3 X' [# T8 W5 s9 ^% M  n2 K- m
> x:=T[3];- f5 V* e1 {- K
8 Q; S6 G, ^2 ]
> eval(T);4 q) h: |4 {5 g4 b/ [; v9 X
! h. X. v" \0 S4 A( X9 i+ @' x* w
> T[5]:=y;
/ m  `9 j* l+ _8 i + E5 S* I1 r: R8 h0 P
> eval(T);
# z: v7 P5 l! s! d
" w4 _( \1 ]8 k, t' j& I由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.     2 t/ G6 Y: Y9 V- u* I
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数.   `) D/ |- T/ R; w5 R5 ]% k3 [
4.5 数据类型转换和合并6 B5 h# x  s( e& n6 E
convert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:   
* h* P0 x8 d. ?> L:=[1,2,3,4];* N) K1 E+ t" ?& C8 B
$ z4 K7 X6 F: t/ F
> type(L,list);6 y, r, x- z. Z: q- H+ n1 e
5 \7 b- n9 Q: \$ B0 O: X. G
> A:=convert(L,array);
. p# J  h6 m8 G$ `& k# a% Q $ A) w3 d4 B& _. O. T9 c* F
> type(A,list);" n2 s7 N2 y! G* t( s3 g! i
, z  W) n+ A1 P
> type(A,array);
; J8 _# h8 T9 [0 \* w# @! D
! x! V9 ]% F! p+ x另一个有用的函数zip则可把两个列表或向量合并:     t: ]5 `! @9 p  H/ ~
>L:=[seq(i,i=1..10)];( i( ^) W( x! e. \: R
; x. P) j8 p9 \- v0 Q. x7 X: g* X
> Sqr:=(x)->x^2;
" K8 @/ P5 o6 w! q0 b" A
' Y% q8 }& R, t" q8 g+ A  K) E, i> M:=map(sqr,L);
8 }5 c% B8 z6 X5 V - r, I/ ]$ Y/ P# U" V
> LM:=zip((x,y)->[x,y],L,M);
, Q6 j% E1 y* O - D( ]% G- V9 }( J9 P! F1 q( D, u
> map(op,LM);0 h( l) l. Y, m! c
* ~8 C& q5 t, p
5 Maple高级输入与输出操作
; U9 m  K7 t* E4 z( DMaple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里.
! O: k- q0 }) L# i5.1 写入文件0 D; `: e5 r% T. d+ C. [
5.1.1 将数值数据写入到一个文件
' T9 M% z, I% p2 j  z& V如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令.
& S/ |6 K, I2 j' @# r" z7 Y若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);
8 K* U! O% l: k5 ^> with(linalg):& l; Y3 F  `2 Y9 T  P+ V3 \) z
> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);2 t9 A: d$ _( J# q( V- g* m8 O
1 N( W' ?1 w( r4 T: p% R2 `
> writedata("e:\\filename.txt",M);
% I+ Q' r/ i( x+ n! g而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);
0 q1 Q2 H2 t" t% q* k> W:=matrix(2,2,[1,2,3,4]);
: G5 \2 e3 a; p) U9 J
, {! N3 D/ d/ w2 p' _> writedata[APPEND]("e:\\filename.txt",W);
, M- S4 R  |4 H: E6 Y需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.
$ a, l; z3 p( `  j4 x5 b另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);* H4 C/ y- n  r9 Y! g
> writedata[APPEND]("e:\\filename.txt",W);   s. g2 Y/ V2 U, o7 {
> writedata('terminal',M);2 Z5 k5 i7 E* M3 ^: ^. |
1                   2                   3           
2 b7 F8 o) w, y7 Q% y! l4                   5                   6           
8 m6 A: T# j7 U  F9 Y  ?6 D7                   8                   9    ( R1 ^5 k. a0 x, ^! {
5.1.2 将Maple语句写入一个文件
: r* F9 Q- z- h" m如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:- `* }2 B7 Y3 [* }- [% o# ]0 Z
save name, "filename";
: o' u0 Z$ d: O4 F3 Z) [7 f$ Asave name1, name2, …, "filename";. e, t) O, H( c' a8 m! d8 f) K
若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.
; g, d3 @1 C( n0 x6 o> myfunc:=(k,n)->sum(x^k/k!,x=1..n);+ R0 ]3 G, c- p, R! B5 y( a

/ E, _. \* H2 g+ H& R2 L* {> myresult:=myfunc(6,8);
- k+ K3 _$ [$ b6 y7 |5 g+ l) d
. o) v- ^, ~; }> save myfunc,myresult,"e:\\test.m";
0 `% V5 n7 n: I' b0 E! ]+ v调用已存m文件用命令read. 试看下述实验:
8 Q8 M/ V5 t* D1 s9 ]> restart:$ w/ B2 h2 u( c0 j
> myfunc(6,8);
) S# @0 y+ a" ~: j* O: N7 P ) o( g( v4 O. }  \
> read "e:\\test.m";
+ a, |- @& ?* a. F4 t. m! u> myfunc(6,8);
/ ?' G& I7 j: i0 ]5 |" h
0 J- u) w, K4 Z" c- c6 G> myresult;
% P) f9 a, @0 b; [* [# E. D
0 m2 {& p! @1 R2 }    而存为txt文件时则将整个语句存为一个文件:
/ N4 b2 D% Z) E> save myfunc,myresult,"e:\\test.txt";
& Y8 a: {' E& G/ X> restart: read"e:\\test.txt";
6 W* m* k$ x) |9 S& V7 u
) N  T  h4 ]$ i  Q2 s7 L0 x 1 o" e6 c! @# K+ l5 ?5 R
5.2 读取文件2 ~: x8 Y+ o' p/ m; |/ m
在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.1 ]- e) e* R% N: n
5.2.1 读取数值数据
9 w1 A' K2 o2 a1 Z+ b7 e如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.# Z* C0 l* n5 L1 d7 o& M
从filename文件里读取n行数据时使用命令: readdata("filename",n);& _' }$ t' R' b9 _1 w- r
以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);  y7 s" o; N3 j
> readdata("e:\\filename.txt",3);
6 }( L; A* C! |$ _  A+ J+ k% z : Y+ B# w& ?, ]' s8 r/ _/ {
    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:, r2 x' \( Y6 w9 P7 \
> readdata("e:\\filename.txt",[integer,float,float]);- J% ?% L. a6 s. x- P9 l

  H1 g2 }, r) c: x% r6 j5 F4 ]下面再看一个运用大量的实验数据在Maple环境绘图的实验:
: l: h: C# F" G> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:; k: T/ W+ L5 ]6 A# J1 F
> writedata("e:\\data.txt",evalf(mypts));
. S4 s* k7 h2 O4 |* L+ Q( x> dots:=readdata("e:\\data.txt",100):/ Z3 c( e2 f! }" N1 j+ b
> nops(dots);' Y7 G* m: {3 T- A+ G
* g% g) T: d" d9 u6 v' z& M  A* [+ y
> dots[1..4];
8 D8 C! n# H, y; M
0 j& n; f, \3 }( _) x> plot(dots,style=line);( `- B# P! t% @. j4 {
4 I1 c( q* z" \: }* P5 N
5.2.2 读取Maple的指令
7 W+ W1 K% B6 }% R在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:
1 L& b$ O& o6 F% s. O; Vread "filename";8 r# g, n8 ?( I1 A1 g9 w
如下例:+ F$ `- G. f  i
> reatart:
+ F2 k( ~( C- h> myfunc:=(a::list)->add(i,i=a);/ P8 T( A% J: |% g( L
8 Y3 g% m; H% ?- p
> avg:=(a::list)->myfunc(a)/nops(a);
; p) R$ ?- w2 L ' G0 U9 ~. l; F, x8 ?( |! N
> save myfunc,avg,"e:\\function.m";2 P- B; M; t% [5 d
> restart:
2 g1 n- h# S  M4 ?% o* G( ]> read "e:\\function.m";2 g! S% {' m, Z2 n; |( l% k  e
> myfunc([1,2,3,4,5,6,7,8,9]);. E* q' P+ Z& b8 `2 ]

1 v6 h) U" `& {0 |8 @> avg([1,2,3,4,5,6,7,8,9]);3 u3 C; c* r: P) u
5 O0 l# ]$ O$ o" v, ]
5.3 与其它程序语言的连接
8 B: c  H, p! s* {% w) {& K5.3.1 转换成FORTRAN或C语言
$ k4 U9 b3 t# o2 |9 N调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:
* G/ m- H- R9 E4 e* Z. b> with(codegen,fortran):. K1 f1 k0 q5 b
f:= 1-2*x+3*x^2-2*x^3+x^4;
( O" @. Z# J( Q7 E7 w 8 E; T$ G5 A) U( ?! H
> fortran(%);: {1 o/ U4 a9 Z" K  Z
      t0 = 1-2*x+3*x**2-2*x**3+x**42 A; L6 J9 O& J
> fortran(f,optimized);
% p9 Q% w+ a+ n      t2 = x**2$ b, ]1 L& P* U) q6 f
      t6 = t2**2* y: t, W# z/ T( ?$ |* _: f! V2 J9 R
      t7 = 1-2*x+3*t2-2*t2*x+t6) h8 Q3 }2 |2 W( ?. d
> fortran(convert(f,horner,x));
6 q( I. }, `. G; J/ d% {: P* C      t0 = 1+(-2+(3+(-2+x)*x)*x)*x" S- h7 a) e: `7 X) k, p
而codegen程序包中的C命令可以把Maple结果转换成C语言格式:& B* P/ b6 z- A8 d
> with(codegen,C):
  |9 e6 e1 a0 U/ @9 z6 b! i1 pf:=1-x/2+3*x^2-x^3+x^4;
( D2 i3 O5 P( y7 m& F/ }; S5 ` ! j  N; T$ ]% K) J2 [$ d* B
> C(f);
4 b9 h% Y# m( H, J" A* U      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;
2 A& C/ C& u$ k2 L0 L. C( N2 Z> C(f,optimized);. k) }8 E! Z+ W! i: {# m7 _
      t2 = x*x;! ~, A& B+ f9 \
      t5 = t2*t2;1 g" R" {0 G' ~1 F1 n
      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
( C' [/ Q4 `1 H9 Y# b/ @, Noptimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.
6 L2 u& m3 ]3 ?# Z2 O5.3.2 生成LATEX
8 O0 X5 `+ }- G, E8 SMaple可以把它的表达式转换成LATEX, 使用latex命令即可:* }0 ?9 T& h  z. r7 O
> latex(x^2+y^2=z^2);
% X; f5 `* B2 {# S: D  w! v6 j# a{x}^{2}+{y}^{2}={z}^{2}6 C5 G& P2 v0 W/ E8 h0 j
    还可以将转换结果存为一个文件(LatexFile):' M  T3 Y0 o, A* w" A5 B
> latex(x^2 + y^2 = z^2, LatexFile);7 _  ?0 O$ f$ B) s, G4 R! a$ v
    再如下例:
- a  {7 F0 L9 N; `5 _> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));- ~  p9 n$ z- b, o3 u
\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)
- _2 e% J' `* C* M7 }( f' v$ K3 x+ {+ J+ R0 o

作者: darker50    时间: 2012-6-12 17:24
   lz这样看很累人的啊。建议换成一个文档形式的。
作者: wssl103050    时间: 2012-6-12 19:03

作者: wssl103050    时间: 2012-6-12 22:31

作者: yunbuhuiku    时间: 2012-6-14 05:22
听说女人如衣服,兄弟如手足。回想起来,我竟然七手八脚的裸奔了20年!+ J0 u( K, J" s4 s& P# [
) b  ?+ k( H1 h$ e- o3 s* N% G2 T

. V; u& t" Y& h8 q9 _
作者: wangbutian    时间: 2012-6-14 11:53
正如2楼所言,弄成一个word文档阅读起来也好些,不是吗?
作者: 边缘d无奈    时间: 2012-7-24 20:38
顶一下~~~~~~~~~~
作者: 独守一座空城    时间: 2015-9-15 15:25
lz这样看很累人的啊。建议换成一个文档形式的。
0 N; l( P( z2 M& o




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5