数学建模社区-数学中国

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

作者: woshiwangxiao    时间: 2012-6-12 16:53
标题: maple基础
" c6 |. l! q9 _9 T
第一章  Maple基础
1 W6 w7 f5 V# y- Y0 {3 y
5 E9 E- N$ b* J4 B# x1 初识计算机代数系统Maple
0 y3 R' y# h7 R  Q5 S: t/ P0 v1.1 Maple简说
7 t/ h) p! j* c$ B1980年9月, 加拿大Waterloo大学的符号计算机研究小组成立, 开始了符号计算在计算机上实现的研究项目, 数学软件Maple是这个项目的产品. 目前, 这仍是一个正在研究的项目. ! s2 B5 \0 y( p; x
Maple的第一个商业版本是1985年出版的. 随后几经更新, 到1992年, Windows系统下的Maple 2面世后, Maple被广泛地使用, 得到越来越多的用户. 特别是1994年, Maple 3出版后, 兴起了Maple热. 1996年初, Maple 4问世, 1998年初, Maple 5正式发行. 目前广泛流行的是Maple 7以及2002年5月面市的Maple 8.
3 c+ w/ H: h2 |4 ~0 t+ E. uMaple是一个具有强大符号运算能力、数值计算能力、图形处理能力的交互式计算机代数系统(Computer Algebra System). 它可以借助键盘和显示器代替原来的笔和纸进行各种科学计算、数学推理、猜想的证明以及智能化文字处理. ! O6 }; A' X" B. f6 R- [* o! j
Maple这个超强数学工具不仅适合数学家、物理学家、工程师, 还适合化学家、生物学家和社会学家, 总之, 它适合于所有需要科学计算的人.
; S( V1 p. B6 a# {9 q1.2 Maple结构
3 l7 I! A- c% \+ B/ O  ^; N0 [% H: R2 D% CMaple软件主要由三个部分组成: 用户界面(Iris)、代数运算器(Kernel)、外部函数库(External library). 用户界面和代数运算器是用C语言写成的, 只占整个软件的一小部分, 当系统启动时, 即被装入, 主要负责输入命令和算式的初步处理、显示结果、函数图象的显示等. 代数运算器负责输入的编译、基本的代数运算(如有理数运算、初等代数运算等)以及内存的管理. Maple的大部分数学函数和过程是用Maple自身的语言写成的, 存于外部函数库中. 当一个函数被调用时, 在多数情况下, Maple会自动将该函数的过程调入内存, 一些不常用的函数才需要用户自己调入, 如线性代数包、统计包等, 这使得Maple在资源的利用上具有很大的优势, 只有最有用的东西才留驻内存, 这保证了Maple可以在较小内存的计算机上正常运行. 用户可以查看Maple的非内存函数的源程序, 也可以将自己编的函数、过程加到Maple的程序库中, 或建立自己的函数库. + d' s- v! ]1 k0 w! y; S3 Y, p& i. l
1.3 Maple输入输出方式2 k1 K6 G0 X% M1 }' ^
为了满足不同用户的需要, Maple可以更换输入输出格式: 从菜单“Options | Input Display和Out Display下可以选择所需的输入输出格式.
  a3 u) X/ O% Y: H$ O! M6 cMaple 7有2种输入方式: Maple语言(Maple Notation)和标准数学记法(Standard Math Notation). Maple语言是一种结构良好、方便实用的内建高级语言, 它的语法和Pascal或C有一定程度的相似, 但有很大差别. 它支持多种数据操作命令, 如函数、序列、集合、列表、数组、表, 还包含许多数据操作命令, 如类型检验、选择、组合等. 标准数学记法就是我们常用的数学语言. ; `# P4 n- p; b( b, ]
启动Maple, 会出现新建文档中的“[>”提示符, 这是Maple中可执行块的标志, 在“>”后即可输入命令, 结束用“;”(显示输出结果)或者“:”(不显示输出结果). 但是, 值得注意的是, 并不是说Maple的每一行只能执行一句命令, 而是在一个完整的可执行块中健入回车之后, Maple会执行当前执行块中所有命令(可以是若干条命令或者是一段程序). 如果要输入的命令很长, 不能在一行输完, 可以换行输入, 此时换行命令用“shift+Enter”组合键, 而在最后一行加入结束标志“;”或“:”, 也可在非末行尾加符号“\”完成. 7 o3 P2 `/ I7 @) }5 L8 i
Maple 7有4种输出方式: Maple语言、格式化文本(Character Notation)、固定格式记法(Typeset Notation)、标准数学记法(Standard Math Notation). 通常采用标准数学记法. - M( v( h$ N1 i# E) }/ r
Maple会认识一些输入的变量名称, 如希腊字母等. 为了使用方便, 现将希腊字母表罗列如下,输入时只需录入相应的英文,要输入大写希腊字母, 只需把英文首字母大写:   2 d; y5 @- d% j
3 W. p1 G$ ^5 Q, w- S* I
( K& ?: z: X8 W" Y1 t: c2 c6 D
! g7 t9 m/ l+ u6 D& v- p& A( q

6 K" f% N5 b4 e5 w) q ! w; {7 e! }/ X

3 V  ~9 ^9 S+ [, {- M6 ? / A9 z  C- e4 k5 S1 T" f+ J# {: C
: x: S& M2 t2 L# W6 z. _' H/ J
- u# m# w% }3 L- E! @
, h' X5 g- W! r# u2 g0 v

( H7 M  h) z- Y, K, ~
4 }1 @2 ]  {; v0 X
* d( Y' b0 t7 P3 W9 aalpha        beta        gamma        delta        epsilon        zeta        eta        theta        iota        kappa        lambda        mu5 ~; \1 v9 J1 x
! `9 k& D) p( F; m( T- x
) f( S; s. d% K( i- e5 `0 n
- W- W2 K- {, J

' n2 d. k' r& R5 `- [$ N* w / U/ ?7 ]+ u9 [  U

. r& Y. I) e0 J0 r: d
$ V8 _6 [% G7 O5 Z  h7 Z
# a6 _. J9 {/ Q8 H6 K, w
- E% P# \: K  O6 g/ U+ J" E $ U* s1 O4 u" b9 K( C7 v! d& h( M

2 }8 ?5 Q* t& S9 S# P0 e6 j . Z+ F6 u+ L1 @4 P6 d4 w

6 Q, [/ P. Z; m( Anu        xi        omicron        pi        rho        sigma        tau        upsilon        phi        chi        psi        omega% k  a! V4 i2 D: A1 y
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:6 ]8 L% ~( |! G' K6 \# N
> for i to 10 do
2 p: e% a4 ?7 j7 Y3 i9 Dprintf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));7 w6 @, M8 ~# \
od;' ^% ~# _3 o% H: d( x( y9 k* Z2 k
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
5 K" U" u% v) g2 _' H$ T7 J+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:
* _  e7 }" [; Q1 M> for i to 10 do
7 h5 j. w- T% M$ d* n3 Z0 D9 hprintf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));
- q% A. [9 O% Q( e+ i6 a# w" |. zod;  o# Q2 A3 s1 c8 N
i=+1 and i^(1/2)=+1.000! u6 \; [: ?5 ?  K1 X( c
i=+2 and i^(1/2)=+1.4146 J6 q6 Z5 m5 K6 {/ H
i=+3 and i^(1/2)=+1.7320 E7 a; i' R, j# ^3 a7 W6 \
i=+4 and i^(1/2)=+2.000) }) ?( }0 m3 q1 s, c+ K
i=+5 and i^(1/2)=+2.236
( G# D( Z# s2 X0 C2 }! gi=+6 and i^(1/2)=+2.449
% G0 z: g6 }, H: D& |i=+7 and i^(1/2)=+2.646: O# e4 s% f* M3 N# v! U
i=+8 and i^(1/2)=+2.828
! }  ^, Y: F" @$ z7 R9 f" Vi=+9 and i^(1/2)=+3.000
5 G. N4 B' K4 M/ k$ ~8 Ii=+10 and i^(1/2)=+3.162
8 V! u9 J6 @( y  @; }. e4 u! p再看下例:将输入的两个数字用特殊形式打印:
) F) y! r  }! s> niceP:=proc(x,y)8 A8 \. q8 `4 A( ]2 B0 F" L
printf("value of x=%6.4f, value of y=%6.4f",x,y);
( r  i  S. c, E& e  @2 lend proc;7 I) l& G8 B, p2 ?* u

. F: y' m9 p3 w5 M> niceP(2.4,2002.204);
! O: s7 K& O( p7 F% vvalue of x=2.4000, value of y=2002.2040* e- v6 q- b0 ]! Y( u/ x
1.4 Maple联机帮助$ K0 Z3 ~! R7 y
学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用. : D2 j& n! J0 Q- r, e6 E9 L
在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可.
; E9 X* M7 |+ m( A3 v, M# c; U2  Maple的基本运算
" E- W. i: z' v! a2.1 数值计算问题
. q! C. \7 `' C# I2 c3 O$ B算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”.
8 q3 A2 @; q2 [2 V$ \在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之,  是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数. & i6 S  Z8 T# a# T" J, H, z
Maple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算. 3 \8 y, ?8 |% y) F0 f+ X0 q
但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明. ' i* q! E7 y1 c  c0 Y
第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:   
- a' o$ a8 M  e$ o> 3!!!;
7 x; h9 c4 U5 p, }2 _9 R9 L& r2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) U( u5 ?1 n' |) `; M& V
上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?
# e7 R, s2 c+ f* i/ G! d为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式
9 }( h( ^9 N5 E3 @ 7 M5 v+ C8 U6 Q4 S3 ~
可得:  , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:   
' Q  }0 I) n$ |4 q- `0 K
; G) \5 q" }% f: X! k. `( f2 |这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性. & T* _, C% F* o5 N  g
另一个例子则想说明Maple计算的局限性:   : r* A0 V- a: x" I4 w( T5 N# i* M
  , i  a  Z2 O0 @% L- d! q
Maple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:   
5 x" @: q; m' _+ F4 h
8 @: f/ t- R  j6 P) U& A显然这是错误的. 这一点可以从代数的角度予以分析. ' M( b/ K+ }' J) _5 J
不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果.
* j! o8 w- O1 D另一方面, 设 , 则 , 即:
* `4 W( F+ f) L; |4 ~
* k' r/ I* Z% O9 k! m- a显然 有6个结果, -2、2是其实数结果. 0 _( T* L5 i% @/ }6 y" b, ^2 z3 Y
这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性. - k1 X7 w3 l) b0 i8 Y) M2 G% b
尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的.
1 K' [. h7 L1 t* r) p0 j2.1.1 有理数运算. H- W2 u6 q: Z$ I! ^& g
作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20).
8 t: B8 b# p" W# R> 12!+(7*8^2)-12345/125;, L  m( C3 k! I# I

% J- ^! u: |' W6 V8 f> 123456789/987654321;( e8 B' }) N' i  z
8 T7 `( E5 z, {. c. g& c
> evalf(%);$ t5 t9 n# ]5 j( k, s# @, S9 S

; X7 T5 M. y" N/ S> 10!; 100*100+1000+10+1; (100+100)*100-9;
5 l; f( U5 T# W6 r3 Q) {
5 N* d6 v/ n2 n- A: ]! J + |. O7 X! K) n; o

  I/ P% G& i. P& J) v3 m) N6 O> big_number:=3^(3^3);2 G% S7 m2 {  z5 ~, l
; Z* [2 _) ?4 ~0 O- i
> length(%);9 M6 R+ a8 i% v: ^
8 C4 n0 T% {8 k" b( ~& q9 P
上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:   5 l# ^. q& Y; d3 r
    1)整数的余(irem)/商(iquo)( {6 Y! _1 ]3 [/ g, L& u: I
命令格式:   5 Q, I3 o4 K- y8 f  a, `! t
irem(m,n);        #求m除以n的余数  J: G/ h. Q$ n9 v1 S
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q
( }* j9 `+ C9 U2 iiquo(m,n);        #求m除以n的商数
% Z# @4 n7 ?  A/ Z- [( W) Giquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r
& J: B) K3 O( L% E8 j/ X: d# I其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
. ~& p4 c6 d: ~+ F" b! g% W> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
5 F1 e$ e. c: G+ L! A  o
0 l: G9 o4 D* W1 c' r2 T> q; #显示q  h- o2 K9 p$ e% H( J

# k/ e5 s  G3 j  I6 N) u: [> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r
' ~& g2 ]( }+ W # J6 ^5 I* F* e! m3 D, [' F! w4 V
> r; #显示r
4 ?3 u  u# \9 S6 B) g4 J7 O  ] 6 }, z& |& Z* V- h
> irem(x,3);2 x0 O$ g: [* Q! Z6 R
* w" z5 j. z: Z: K$ T
2)素数判别(isprime)
6 h, Z" g5 L6 {- h' d+ o$ p& M素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n); ! F  }6 R! k$ A: o6 O4 o2 h5 Z
    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
+ H- w9 q6 b& h5 H# b9 j7 S> isprime(2^(2^4)+1);
- x5 j4 `2 h: S7 B$ O
2 H$ v) W+ P& f0 a: F> isprime(2^(2^5)+1);
+ ?3 n" g; p5 i+ z5 A' `) J3 l 7 T8 m: V* \$ q( k1 c  [
上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多.
- U, Q/ n  w  Q" L4 r# [, C3) 确定第i个素数(ithprime)/ T) c1 X2 [- x% x
若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);   
$ y+ p5 U; [- h; [* ]' j> ithprime(2002);7 Z) e1 Q) x7 O& }

' I# l* m( c1 A( F> ithprime(10000);
+ Z# }) a) J8 E( o, b8 w+ o( f& `# f7 B + Q- j; i6 d' s' Y! e8 z. W
4) 确定下一个较大(nextprime)/较小(prevprime)素数
5 j( F4 ^4 W# G; H6 l9 O当n为整数时,判断比n稍大或稍小的素数的命令格式为:     x9 Z& v  m. d& g- }4 X
nextprime(n);  
/ \! l0 x  J& aprevprime(n); 4 @/ {6 S) E) x+ w! l# p( F
> nextprime(2002);, s+ {" \: O" N
; x5 F, q4 W( @3 v
> prevprime(2002);
* B8 U4 G6 R$ O- d9 {$ O5 l& k
- _) U( S+ i+ v- M0 {& J5 q* D5) 一组数的最大值(max)/最小值(min)
2 M) s: r/ E0 M; a( n8 i7 ?命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值& C* J5 b- q/ b6 @4 D
             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值
5 ~9 \" T4 O% H9 T0 k> max(1/5,ln(3),9/17,-infinity);
3 Y9 Y/ s. r( D' h 4 `0 i! i: D) ]
> min(x+1,x+2,y);; P# D8 S4 A! C
- S! M( E% P8 U6 N) h6 D, G# U
6)模运算(mod/modp/mods)* z4 r0 |$ V8 I9 ]$ N9 k
命令格式:  e mod m;    # 表达式e对m的整数的模运算
0 U* X- c0 t$ Z: h# Gmodp(e,m);  # e对正数m的模运算
5 A  W3 s- k- w7 D/ Imods(e,m);  # e对m负对称数(即 -m)的模运算
, ~1 H4 L  V" @`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价$ J+ a. K; k, w' ]& O0 G( w# z
值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/. : D& Z) x, U) {6 Q
> 2002 mod 101;
! l* y  M, T$ F9 c) c6 y" F$ s
2 L: O% j0 x/ n2 I& @  t! r> modp(2002,101);
/ l; i" a" @: e! \ # j* a" j3 K$ h3 o! X( D3 E' N, u7 m$ u
> mods(49,100);
2 X' N) B) |/ `3 i5 @
7 b: l3 Q/ h# o4 F) @- g> mods(51,100);% u: ]+ D! y, E$ h1 Q8 V5 R2 y

/ Y' G' P+ @8 m2 J> 2^101 mod 2002;  # 同 2 &^101 mod 2002;
8 E5 M2 r. q+ T1 ]+ N: q" D5 y4 s
8 s  o; X1 V" v  |9 S" z* V7)随机数生成器(rand)& j: o7 T5 v& G; ~" E5 g: u
命令格式:   ' f5 _. y1 _/ R
rand( );    #随机返回一个12位数字的非负整数
6 ?6 P% }6 h8 r( w; Lrand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数7 j9 a! _! Z/ d# m0 S, N0 G
> rand();0 Q" Z+ B! Z1 ^3 S3 A. G5 D

8 V# J' n' v( d: M: b; }0 K8 G> myproc:=rand(1..2002):) L9 z  A" U. A- m
> myproc();
0 {" l, B3 P6 p9 j+ y2 A
7 w! W0 g! d. U# l> myproc();) R  a4 s2 v$ T
& n* Q1 L( U7 Y' U/ z4 G# ~
    注意, rand(n)是rand(0..n-1)的简写形式.
" ]7 u% D9 e& g2.1.2 复数运算
: ?' V8 f( t; e- J& x) ~复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:   
, m1 ?' j# K- d1 K: Q7 e> complex_number:=(1+2*I)*(3+4*I);8 l( J7 Y! T( j! m/ i  k4 ?& Z
/ m) r8 v# E9 A- _
> Re(%);Im(%%);conjugate(%%%);argument(complex_number);& z- ]/ W) R% z  m  y
  s, E$ u2 }6 i- _

2 w9 g9 b9 n6 j# R$ W% g" K! k6 T
  q8 S5 _% m8 k4 D7 i2 \5 f
+ w- l  f6 J+ z: x7 n值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%. - h% h- F1 M4 `$ `4 x9 E8 p9 \
为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:   & D0 }8 G+ ^; B: ^
1) 绝对值函数
2 ~. t8 ^8 h# {% g& m命令格式: abs(expr);  
1 J# z+ G  n; f. T当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.
2 q) K& B3 \4 m! W, P, P, c$ x> abs(-2002);    #常数的绝对值, ~" I. c1 }- @1 C4 s- p* M7 h
  C# i5 u' b; m
> abs(1+2*I);   #复数的模9 _& Z# c# I- h

" i) |3 P/ w5 |> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值: @/ Y% x; ]: Q( q: z; a" H
) n5 [4 v/ R" y5 B2 d# d( d
> abs(2*x-5);   #函数表达式的绝对值
# }$ _* t- K. O5 v1 h, G+ u
  F/ d4 a; k% ?3 P$ H2)复数的幅角函数8 M% n* O: n4 f' Z1 ?
命令格式:   argument(x);  #返回复数x的幅角的主值
2 O% r2 R& u8 J0 R' R+ p# Y> argument(6+11*I);  y2 E& n' D) j/ G  F
3 [5 k0 Z1 A- t' s, j; Q
> argument(exp(4*Pi/3*I));4 L: O. w1 K% L3 j2 X" N. e1 \: p
( d2 T: u/ @; f. i* R0 y
3)共轭复数
4 _, q3 B# i$ A. Z" z命令格式:   conjugate(x);  #返回x的共轭复数
6 b# Q- @7 y: ^- L> conjugate(6+8*I);9 @- U; n) F8 Z; B
6 s0 i  ~. a& U+ D: e8 w
> conjugate(exp(4*Pi/3*I));
5 [5 x# Y) m; p" ]7 \$ F
) @/ B) }: O! Z) @' E0 a2.1.3 数的进制转换$ G0 L+ X) U8 G
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可.
3 W) p8 L9 D$ k! ^命令格式:   convert(expr, form, arg3, ...);    - U; n- T" J5 \  O- f9 ~2 ?- V
其中, expr为任意表达式, form为一名称, arg3, ... 可选项. 4 H) {- `9 y% X& X3 B: h, {1 H
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述.
! z4 K3 P5 c/ {" ]) M* d+ ?) S    1)基数之间的转换9 q9 u5 n0 o- n. j
命令格式:   1 R+ u; H& E# m! w) m) z
convert(n, base, beta);      #将基数为10的数n转换为基数为beta的数
- I* j. c) E5 t4 G    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数
. f& A+ A* z& h> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
- a2 }6 f! [1 T$ a
" L5 j, L2 v& f> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数
* ^% d: M% d$ V; m& j5 }8 m
. w" l3 [. t/ _> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
7 m+ G" p: O, ~% |9 C3 z. Q " s& @; m! U% A& _, }
    2)转换为二进制形式
" J1 l2 A3 w% Z命令格式: convert(n, binary);
' D" W: A% u+ M9 w" j( q其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂. 1 b1 c0 \% K& D2 Z2 N; k0 u
> convert(2002,binary);   
+ N8 F0 @# k: ~  I* I
$ j. E7 G) I8 ~* {> convert(-1999,binary); % T% X. F" ~/ N( R7 t) G% {

1 A2 a7 e5 Y% m3 c; v' O2 _$ n> convert(1999.7,binary); + [+ x" z$ X0 e3 R+ P+ l: J9 \
" {/ q2 O1 T" o  ~6 ^+ @  X; g+ B
3)转换为十进制形式
& v# q3 @; p( g0 z其它数值转换为十进制的命令格式为:   
! t* I, |) u6 Q' W" f/ [convert(n, decimal, binary);   #将一个2进制数n转换为10进制数
( X' b! S4 s) F& d    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数- T* b3 L/ @! p
    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数
: f1 {2 Y2 w0 I* z7 d> convert(11111010010, decimal, binary);      ?( F$ o" @* B* e" ]

: n8 W+ R& d/ x2 E3 g> convert(-1234, decimal, octal);           3 T0 o, J8 {2 V" a& \) ~. o

- O) V! Z9 K7 w/ x> convert("2A.C", decimal, hex);          , E8 e& s+ E9 n- r
2 y4 P- e; {" W0 q: g
4) 转换为16进制数
, i: L1 x0 J/ Z+ U将自然数n转换为16进制数的命令格式为: convert(n, hex);   
8 _. m8 w& p2 @. Y( ^> convert(2002,hex);  convert(1999,hex);
8 A% `% M, D, `7 t; y, ]/ ] + R/ @( n1 F; {6 A' R  V; b
8 U1 O# [9 D2 @+ M7 I  `" Y
5)转换为浮点数' x( E; u. [5 |+ N# R
命令格式: convert(expr, float);6 f* {( P4 `$ r6 R- b' U' j3 F( B
注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用. 4 \- F; ?; y$ C) T3 P8 p3 Z
> convert(1999/2002,float);
8 \0 A, \% ~/ J4 F: M' f ! ^) r/ N# q1 p3 ?0 Y+ ^: a
> convert(Pi,float);
1 O# Y, K# a; \0 o1 G  D5 j
: t  G( B+ R4 `6 Z- E2.2 初等数学
! ]5 m. A! R9 f6 c% O. v0 e    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识.   z3 f2 \6 K# S, }% a
2.2.1 常用函数
, @1 P+ C5 D2 x1 k  i7 N作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:   
. w# W+ a  y) k# J指数函数: exp; t2 ^$ X) i6 l/ v1 e
一般对数: log[a]
4 `/ u: f# o. p0 V* M% ^0 h$ b" h自然函数: ln
; F0 B1 `( Z3 g. W% [常用对数: log10
/ h7 T3 M+ h9 u7 Y, k( o1 U6 n* S/ b平方根: sqrt. q* k; o1 S+ o( X- {- ]
绝对值: abs
& G9 V% k7 r  ?8 C三角函数: sin、cos、tan、sec、csc、cot
9 ]8 h( L! f" B$ K# L反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot
! u2 w' |* g$ L2 \双曲函数: sinh、cosh、tanh、sech、csch、coth
- V, q  p% X4 v& U反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth9 Y' h5 R: J. ^4 S2 ]
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY. e$ w  c: {) }% `" u9 Z  f
Gamma函数: GAMMA$ R% ^1 Y' F9 \
误差函数: erf
1 D3 D# }* q3 ]4 P6 h7 _1 E函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能.
1 w4 i7 G  g; S( k% g* ]1) 确定乘积和不确定乘积
& z/ S: O% Z" P) [& u8 L. D命令格式: product(f,k);  
; w; U/ L) a* B! I7 wproduct(f,k=m..n);  : Z; n+ p& N. `; G; P  p+ p
product(f,k=alpha);
0 Y$ E+ C7 ?9 m  }0 h2 {product(f,k=expr);
% q6 C* g+ P8 j; \其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式. 5 a  O9 o% V" y% Z0 J( o+ ?4 M
> product(k^2,k=1..10);   #计算 关于1..10的连乘+ [. h# A8 U1 x* \7 p$ g+ F, Z
3 ^+ a5 m' O% q0 J
> product(k^2,k);         #计算 的不确定乘积6 `% q: N) c; {* b

# P: T  n! L  Q8 b9 Q3 G6 E8 }3 [> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘
! X) f) [' o1 Q( u3 s+ u
1 w+ K! H( Z5 S' d> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘( p- V' |' q/ y
7 B: U9 v) S: [' {$ |1 c) m
> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式
: P) v# x% f9 B9 W  X0 b9 W - e5 p4 E/ C' w& R7 g& S" A
> product(k,k=RootOf(x^3-2));     #计算 的三个根的乘积1 O4 F: ]0 h8 Y* E( m3 A: H
, [1 r* {( {  x4 m) S4 P
    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:   
, y4 f8 K" Z1 p> product(x+k,k=0..n-1);( A, I5 K7 `  j1 T, M  w4 o$ S
) X0 t2 r5 a; W: D$ t
如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:   
8 T& J6 V$ d5 L) |3 W> mul(x+k,k=0..3);1 h6 v7 f+ R  e: r3 g7 d
: U  Z% Y1 ^$ r, x
2)指数函数! ?# L; r9 P  z! Q1 T1 v; V, E
计算指数函数exp关于x的表达式的命令格式为: exp(x); 1 c  z# _' Z8 N
> exp(1);, W9 S$ x6 b1 ?# B
. f* R6 g0 @% \, i# g# p& L% ~
> evalf(%);
8 t; A+ [' M! O% ]  {
& ^$ v& ?/ j1 n' Q# X3 B7 E4 @> exp(1.29+2*I);
. g; S0 @7 ?' M0 j+ B7 o
  [# s8 D, Z) l& t9 W5 ?> evalc(exp(x+I*y));
# I: E7 v9 W2 Q/ e) Y6 v 1 x; l! i( m* G; \  N
3)确定求和与不确定求和sum" F. L# |+ x- @
命令格式: sum(f,k);  7 k# h/ Y' X$ U6 x4 b
sum(f,k=m..n);  
9 q, X3 O3 S0 N4 R$ L+ vsum(f,k=alpha); ! a/ i0 Q1 g, D2 B8 n: E0 F
sum(f,k=expr);- g7 P3 r9 n5 X
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式. ! h7 G3 Q' p8 f8 W
> Sum(k^2,k=1..n)=sum(k^2,k=1..n);
  k6 M" u+ }! M& d9 n) [! a" [ % E* ?* v% k+ I' @1 c. `8 a5 N$ E5 B
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);
) U8 V. p$ @! o  K0 R7 `- n
. w  p, D' d3 @' ?3 J" `& l> Sum(k^4,k=1..n)=sum(k^4,k=1..n);
& A2 e+ u' o2 ~: D, w6 T
3 d. m8 }& L+ z> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);, {4 \; b( i8 I: ~

1 Q2 K9 y1 Z+ v' Q, e7 S> sum(a[k]*x[k],k=0..n);
! D# T& u7 Y0 T; V' ?3 S
9 X' I/ k' b. \' I5 b> Sum(k/(k+1),k)=sum(k/(k+1),k);& [$ O+ r$ X. K/ Z, L# W

' G5 {0 A) e# d* S. m> sum(k/(k+1),k=RootOf(x^2-3));
! `, ^& E$ Z# _" x, l) j
2 V; E$ B/ \2 b4 }sum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的. 2 L' b" a9 E: M' E( j2 R: Y" B
> Sum('k','k'=0..n)=sum('k','k'=0..n);
' l5 D5 p5 U4 k' ?3 A ) `. g$ A+ }' R- _6 ^3 t0 n9 O" ?
如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:   , d) D- C* ?" S7 _4 u/ r
> add(k,k=1..100);% E2 {( K5 w/ x
8 T( z1 ^0 q/ d( x
尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令.
& |* _. _! w6 e( Y) b+ i4 _, ~. i另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性. # y0 ~1 I) t6 \% r
3)三角函数/双曲函数5 ]. I% N+ f& ]" b5 _7 f) B
命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);
. F6 V: T0 W7 r% l, j6 w          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);
7 x+ I2 D( f& c: Y# s! J其中, x为任意表达式. $ r) f- F, X7 M9 Z
值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.+ P! @1 Z- L+ }7 s% M! f
> Sin(Pi)=sin(Pi);
% t/ U5 F3 H3 j3 S' G6 n % j) t" U$ Z, ?! t! y$ F
> coth(1.9+2.1*I);
9 s" L7 d- n/ q0 c
1 \& S; o* j' X1 x> expand(sin(x+y));     #展开表达式
6 ?$ T  K/ z, o. q8 s/ [
% C+ m. X8 F* s; Z> combine(%);        #合并表达式
& c7 K: B3 _& G0 d ; C' H, l7 [% w  U  q
> convert(sin(7*Pi/60),'radical');
/ F9 v9 Q. E# l/ H- z  K 9 X5 Y5 I3 R9 J2 q5 C# [
> evalf(%);4 X- h/ P+ q. p  I  L- K9 t5 R7 a

! S6 d8 \' H; {, B0 I6 _但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.
( d3 e+ }& j' E5 {" P4)反三角函数/反双曲函数
$ z4 P# e! c0 ~) s$ K命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);  `1 f2 w" x/ G2 z. O
     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);   
- `' Q3 S+ F! o3 Q5 oarctan(y,x);
1 l2 |! Y' w% n7 n" r* K, `其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算.
* _3 F0 e( q$ ^1 k' h4 z算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.
( u+ X4 w! }6 d% B2 y. a( g, T! V# i7 V> arcsinh(1);  k5 D1 j" O1 R; {* u
/ C0 H4 p: M. m8 _6 D. m0 ]
> cos(arcsin(x));4 @/ I( Q: D/ |8 i! l* G
1 g( _: ^0 n4 h3 K1 J( p. D
> arcsin(1.9+2.1*I);
+ i0 s( |7 k( v8 z5 Z* u, g+ t& P9 O 9 G! i* R+ \- `. x; g( s3 m
5)对数函数; X1 S. y+ w% \$ _
命令格式: ln(x);           #自然对数
: N, A, r" T0 I9 ^8 k; m1 llog[a](x);        #一般对数' n1 ~! w$ i0 o' O6 Q8 R( g
log10(x);        #常用对数
) `( A6 R& A5 c6 i3 _: F* t3 p一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:   4 Q) Q$ y2 }6 P; F" P7 T
  (其中,  )4 x5 k8 y& m; M. h
> ln(2002.0);* F" M$ x% ~) T- V  t- [! ~
  {- J, F4 P% }1 }( o
> ln(3+4*I);
, y  U5 f' _9 {8 A0 E" E5 o . `3 [& o. z0 t
> evalc(%);    # 求出上式的实部、虚部4 h) T0 A6 u/ V4 f1 X
! Z: b& ]) }" H) I, X/ s4 L
> log10(1000000);
  U7 }: P* E1 ?1 [7 A( o( n+ z
% Y7 Y2 D2 T+ r( f. f3 G1 I8 ]> simplify(%);   #化简上式% P! W4 ~7 |1 c

( s5 u6 L$ @3 j# k" J2.2.2 函数的定义9 Y4 ^7 |! }. Z& d" D
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:   ! m/ x: ?* Q: k4 ]- n7 J/ o
> f(x):=a*x^2+b*x+c;2 J- Y/ V/ E( a' a. c9 O/ O/ X+ d

2 {( G* R% ~: J: y8 G可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:   ; s0 i! c) m7 |2 t, @
> f(x),f(0),f(1/a);& P% K, F1 }$ R5 @
6 E  b( x5 b! _2 R; J2 J% V
由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:   
4 w% c, {- n* j& l* j> print(f);
$ v) i1 p. D' _9 T* O; x 3 i* C. f7 Y7 Q$ R
事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式.
# a2 p/ B1 S: m/ r( [4 t4 |在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):   , G  a8 U% f5 d2 [
> f:=x->a*x^2+b*x+c;
5 m0 F( f" P) |' A9 ^2 j7 D
0 K1 t1 e8 \/ V; |1 ]. `) _+ _, d( Z+ N> f(x),f(0),f(1/a);
# O' r1 h2 E) o% x, r8 ~* _9 s % B* }2 ^8 r& h( k+ t0 P. ]7 ^
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
/ e) _, Q7 X3 |3 ?9 N! a8 l/ ?> f:=(x,y)->x^2+y^2;
3 n; X6 H% u- O  B% f4 o
, P2 v3 q+ J" y. ]> f(1,2);7 J! k' U3 j7 ?

1 \9 J* J: R$ m> f:=(x,y)->a*x*y*exp(x^2+y^2);2 U- p( `8 V; v8 j5 @! `& I

, ^2 l% Y' V( _4 o综上所述, 箭头操作符定义函数的方式一般为:   * d1 r+ O9 l5 I: N. N1 S
一元函数: 参数->函数表达式
; i; L. H6 \* N; F, E1 n4 T多多函数: (参数序列)->函数表达式
- A3 ~& E& `* |/ i无参数函数也许不好理解, 但可以用来定义常函数:   
% X. _/ L1 u* t0 B: t" h% ?> E:=()->exp(1);! l3 {# x1 W8 u

) f0 p+ f& u  Z9 a' L4 c0 L/ G# m3 n> E();
& ~6 ]8 z% P* E% f' j! h' d
7 B2 q0 N* }: L/ J6 S> E(x);
% N$ d$ Y* o$ ?( X$ X / G0 r! k) S6 e$ y) U
另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数. ! O6 a" R# B! {* ?6 r- c) @1 H
定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);         
$ s2 }9 H, b) |: v. ^! d) T定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);     
1 t* j1 [, _% k5 k% Y0 }> f:=unapply(x^4+x^3+x^2+x+1,x);, J0 }# q+ Q) \* t" y, q# d! r

+ N7 J# t" _6 q- j- B> f(4);2 X' V4 v! i' B8 i
' h7 }0 I5 h* e9 r' e# j
> f:=unapply(x*y/(x^2+y^2),x,y);
7 j8 L1 q: Q/ K# J
5 W8 ?& h" \* E  }1 y* w: d> f(1,1);
( X0 v4 s2 |3 D. r* g 3 ~$ t1 x0 I% s( _7 ^
借助函数piecewise可以生成简单分段函数:0 k; s: Y9 y! e  E  R# l$ x
> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);
- j7 x5 U. V- C" j( @
, S. ?" Q2 P% d7 J3 s+ J清除函数的定义用命令unassign.
8 z' `! X7 k* B1 m# x> unassign(f);
/ T  q8 A6 k* I7 v2 S* `> f(1,1);8 Z" S- L8 H0 [: u/ d5 G* i

, L6 }  P* u6 e  @; i/ F% i除此之外, 还可以通过程序设计方式定义函数(参见第6章).
( T9 K/ |" J3 H; ^6 r0 F7 O7 b定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:
' k: C/ d' I% K; gop(expr);          & \; C% S# n% t- b. {+ U! L
op(i, expr);         # @1 k1 J1 A, V* |
op(i .. j, expr);        v! Y! J  O6 V
nops(expr);# b+ M, E: N1 N3 \" p9 _1 p
如果函数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的类型. * a2 A2 }" J9 M; C# r
命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.
3 C* o/ h& n) N% t" Y" i命令op(expr); 等价于op(1..nops(expr), expr);
; G7 m% F6 A, g! I特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...)); 5 P0 `8 q, Z& J; X
而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和. 2 r* n* I( w5 p3 H* s7 [8 w
> expr:=6+cos(x)+sin(x)*cos(x)^2;& G1 z. q6 f& U1 G2 W( @
6 D+ G/ Y. k; m4 B/ T2 N
> op(expr);+ V* z) ~, b# {2 p
: Q* h4 H4 O5 l
> nops(expr);
) `$ p6 ]* F* p2 f  z2 A/ ?/ t . I. N( f( N% O% G) e
> p:=x^2*y+3*x^3*z+2;
% s0 J  n& ~% X' U/ P8 ?
5 a/ H3 \$ j2 h3 t> op(1,p);8 ?6 _0 w, t1 ]% E

8 L7 M+ t# v2 Z! Q, D, u( N> op(1..nops(p),p);
7 s; K$ |- X/ j7 d& J" x/ T9 h7 q
( g! J# [+ f- W" G+ |. T> op(op(2,p));
5 r5 A8 B- C* `
  C; Y% @! T* _! v5 K3 L1 r2 x2 r> u:=[1,4,9];6 A& J( J3 l; G) f: h) J
% y# V. r. V7 I6 w1 _3 {( I
> op(0,u);
" v; r7 Q1 a8 w: {9 t
0 \/ |5 A8 D% d. {. G6 x& d& g' p> s:=series(sin(x),x=1,3);
* O3 _/ q9 d1 K7 [
, D* Y4 I7 M% i0 R> op(0,s);- m* c& Z/ f2 d7 M3 j$ X
       
: }: c( c# p6 q; Z1 M> nops(s);
& D. v5 _1 O7 Q: J8 h- {, W, Y
5 g2 ~+ ^+ y, f/ Q/ b. p8 O) f下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:+ Y8 ]( J8 ]4 b5 K' j
> op(x*y*z);9 e  l$ @) r7 j7 V$ Q

4 x- D+ I9 W5 D. B0 V> op(x*y*z+1);- X2 N) L1 K9 [3 O) y, d% i: r3 N

# v9 ?3 S& T# A* d. Y& W( n2.2.3 Maple中的常量与变量名* g7 B& @6 B6 `0 s! \4 v
为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:   
' P0 v7 ?. x$ p> constants;3 L1 M6 [1 j- S. B6 R* I
# ^' V8 e- Z1 t2 l1 }1 h
为了方便使用, 现将上述常数的具体含义列示如下:   0 b8 G0 |) F. _
常    数        名 称        近似值# I( @( U, }$ ?  [4 j
圆周率
2 ]# k/ F5 j7 w# p& pPi        3.14159265350 Y' @3 J4 R; |$ E& `% N
Catalan常数
' K' V* X0 F& S) o: A' k6 f- QCatalan        0.91596559424 d' y( _7 |" g2 g9 x$ W
Euler-Mascheroni常数
7 _/ b5 a+ P  N; Ngamma        0.5772156649
, E2 h4 h- I' r7 y; @  A% R: Q
+ P( r  d* e# B1 dinfinity       
: a7 [9 b1 J- p6 H0 q. W+ N0 y+ H4 k$ k! K/ m, M0 x
需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取.
; N( \$ t1 t/ `" q+ |# {% A: z6 \在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”.
; V0 e. r" a% L值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名. ; c% q2 B3 W) ?  E
在Maple中有一些保留字不可以被用作变量名:   
* t; ]3 p- i3 ~; nby      do      done     elif     else     end        fi        for      - }) Z1 _4 H( {, r; n
from    if       in       local     od     option    options     proc         
( E$ v1 g) Q0 O6 w$ ^9 _3 W+ Bquit    read     save     stop     then     to        while      D' o& c& ~3 Y1 {' l
Maple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名.
' T! z4 \2 S* x% @" l, C3 Q另外一个值得注意的是在Maple中三种类型引号的不同作用:   
- r8 g& y  h* A5 @' G$ e" j! B; B`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;   
/ R5 n$ K9 T7 [$ Y'  ':   界定一个暂时不求值的表达式;    2 C! g# s! F. m* ^0 V1 p8 D
"  ":   界定一个字符串, 它不能被赋值. ( F# N/ t- S$ r
2.2.4 函数类型转换           : Q& y4 v: Q! o( S, Z3 j
函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:    y- t' ~8 L& h2 k9 j$ G: L! i7 P/ Q
    convert(expr, form);        #把数学式expr转换成form的形式1 B( ~* j1 e$ H& Y8 p! ~3 b
convert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos8 h7 A: @8 H" L, x+ X: ?# U
convert指令所提供的三角函数、指数与函数的转换共有exp等7种:   
4 F8 T, R# n1 ], S& C(1) exp: 将三角函数转换成指数
3 F6 ^2 g6 N* M: U: L* ^(2) expln: 把数学式转换成指数与对数
4 Y1 X9 y2 [/ \: k# R(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式7 {2 [  A5 ?6 H
(4) ln: 将反三角函数转换成对数" l* P) |  s3 ^
(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式! B2 v" f3 m2 p% p( [7 d0 |3 b! j5 v
(6) tan: 将三角函数转换成tan的形式; J% E: u# I0 f( Q2 Y. P: R  x
(7) trig: 将指数函数转换成三角函数与对数函数/ D% i; h" P7 E  K) W( J0 {
> convert(sinh(x),exp);   #将sinh(x)转换成exp类型
, h4 M* i7 e" l6 K4 k # r+ K( v8 J6 L: A9 |) H
> convert(cos(x)*sinh(y),exp);
/ K& V3 ^2 `, W  V
8 I1 N7 ^2 l0 f" c6 N: N8 {> convert(cos(x)*sinh(y),exp,y);. O0 s1 n, S: G( ~  z6 D
2 G" Y1 y  c4 |0 H- N; b
> convert(exp(x)*exp(x^(-2)),trig);6 N* [  ~, d: k7 m- l2 \0 J
% n! {8 n  M/ K+ }" R& E  H" q
> convert(arcsinh(x)*cos(x),expln);" d' B: v9 }. S# i$ f
$ }: e. M1 e& f. W: i/ c
> convert(cot(x)+sinh(x),expsincos);
% ?' |# j  l4 d0 G2 g ) r! ^0 {* j0 |1 k# m% p3 s. i
> convert(arctanh(x),ln);
) v+ s* h4 ]4 C 6 Z2 M5 o3 m& T# g
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:   
' O  j; E. d6 N. d> with(codegen):
2 t: s/ ~+ W. v% b; [/ M> p:=4*x^4+3*x^3+2*x^2-x;, i5 t, i  O1 d' A/ ~5 o# p
1 m" P8 }7 s. v( R" M
> cost(p);3 F' U% m8 z: A, q( _4 ?0 P
, A6 l! w. \# M8 B) ~1 @* B6 L+ [
> convert(p,'horner');  #将展开的表达式转换成嵌套形式- I) c+ F& T0 \/ [
3 v5 B% h# ~: D. u5 F
> cost(%);
: o% z  E+ j3 ]3 F8 I7 `) ]4 ]
8 k1 y# N" p& u4 ]2 _同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量. 0 G3 a# x$ u8 z9 k
> (1+x+x^2+x^3)/p;
+ k6 I8 z$ V( w0 T2 u
! Z! o& m/ L/ `* x7 r" q> cost(%);1 u9 l; I) b2 A$ |; k
5 Z  v  d+ E: i4 H; m1 x; B4 U6 Y
> convert(%%,'confrac',x);
/ A% R, x) R# S$ Q0 P, z   w/ c7 Q( l( l& }& z
> cost(%);4 ]. p4 O( ^$ M, ?) t& i9 \
% W3 d2 N: K0 p, K
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式.
. V% Y1 T  L3 w4 X# T' l> convert(%%, 'parfrac',x);! U& L) }( B8 F  @5 ]
2 `: ^' }* k9 M+ ^; d  q
> cost(%);1 k. J. h4 Z( X

5 O% q4 }3 [% b1 J$ a& c3 {而把分数转换成连分数的方法为:9 ?5 Y0 U! m% T" _. y+ J  n
> with(numtheory):  U9 D' l6 j* @. v7 }# M
> cfrac(339/284);( Q) K3 w0 s" [+ V9 G# J) J

* Q  _8 h7 j/ q6 D9 u, L2.2.5 函数的映射—map指令
8 V/ k8 O' T: `9 a  h' ~在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:
# H0 P0 t: g, {; Smap(f, expr);      #将函数f映射到expr的每个操作数3 A! U- v2 X: F) r! s
map(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量8 o* E# S& [5 s( E# E3 {% `3 m
map(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量
7 ]8 @9 Z' l3 p9 k* n6 x" E8 p9 Dmap2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为
. ^9 o/ r) p" {/ Q第3个自变量…, an为第n+1个自变量来映射函数f
1 D! D  F' X5 H/ Y! C% C> map(f,x1+x2+x3+x4,a1,a2,a3,a4);
- [6 {" f5 g" a3 f7 m- x9 J# t , s. Q7 X' t! S
> f:=x->sqrt(x)+x^2;  j3 T* k5 `; l. u

  X8 _+ E8 M8 O: z3 ?9 |  J; b, J* l> map(f,[a,b,c]);
$ k) j+ I$ L7 ^, L7 r$ B- |" O 6 T2 N1 \! `% k( n
> map(h, [a,b,c],x,y);
5 T- D7 P8 U0 g6 O
: [, [6 o: c' h+ G> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);( t6 |% B& b- u: X
- Z' N5 M" y6 V% D* Q" K
> map(x->convert(x,exp),[sin(x),cos(x)]);8 Z( e( a# q; {5 D1 i# Z' z1 e
3 W$ v5 }# \2 M# f
上式的映射关系可通过下式理解:5 l; [7 ^& I; Y5 D+ Z
> [convert(sin(x),exp),convert(cos(x),exp)];
$ ^+ H9 R, U4 c$ ] * J1 \7 X8 J8 k! c2 h+ }6 \$ f2 z- C
> restart: 8 ^5 U8 z1 p0 \: v6 b  ]
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);2 G2 n! L% u* s+ ?2 _$ L
$ p* ^/ H. H! {5 l' X3 \% L8 T$ w
> map2(max,k,[a,b,c,d]); : d6 w/ H! B+ i( y. @0 L
3 H* l. ]# y, I, h
再看下面示例:   
! j! O7 V8 j0 R8 k9 L' [> L:=[seq(i,i=1..10)];
7 Z9 w4 M! W2 P3 W 2 N; ^* B9 d/ I9 H/ y4 X" e5 P
> nops(L);% I' x, p1 I! @5 a! N# ~

0 b# t' _! E3 w8 K. _$ J> sqr:=(x)->x^2;9 g( E- x" ^  Z

$ b6 v: n& j9 X+ ~$ y> map(sqr,L);4 J0 n. L& ~" m  X8 ?2 v4 n. v

. ^4 w- s! |% X" q# C+ K> map((x)->x+1,L);! U3 c4 u, I  v/ I. L- W* X, L6 l" f

5 O6 A2 `3 v% ?0 c1 `1 _( V> map(f,L);
& s( \" y5 d6 _ 8 w  w0 y; ~  C# J2 e
> map(f,{a,b,c});( j- W- }0 h; h! e$ e7 p$ h4 U
) U. c, n2 ^  u& y
> map(sqr,x+y*z);
& d& U( c: m  \  B7 t9 D& P 2 d5 y. ^, W" D- I2 _6 m
> M:=linalg[matrix](3,3,(i,j)->i+j);/ t' K' |( a8 _1 U8 h; N3 }

/ Q4 ^. d% q, t2 x> map((x)->1/x,M);
8 Z# s6 l/ u& Y/ ]; r: C 7 ?5 ]! O7 {' Z9 Q4 P6 t4 X2 d
3 求 值
( M- b  g2 ~! k+ k0 ~3.1 赋值5 p5 T0 N* i- ]7 \
在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子.
- u  ]! u% {5 n7 h, y: d. L> p:=9*x^3-37*x^2+47*x-19;
' F7 I1 {% |2 Y& e4 n8 H ; N1 k1 e6 T2 }' V5 N
> roots(p);
# j' j; c, j& K
6 q8 S/ L. M% N- f9 D0 T) [( y> subs(x=19/9,p);
0 F* A- @1 R/ r * |$ V1 p1 r7 `% H
在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量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;”这样的简单语句即可验证. $ c( i, f, ~  L. O3 r  q
3.2 变量代换* p6 M5 Z  \4 P* f
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:   * @1 \+ ~; K* e) S0 g) p% J
subs ( var = repacedment, expression);- d; N" s! g. J: B, l' W' }
调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement. 8 O' K; A  f  b- [2 g' h( V7 m
> f:=x^2+exp(x^3)-8;0 u4 j, }0 e9 R+ X

% b* n+ U$ ]5 \. c: g2 D1 Y7 }, D; H> subs(x=1,f);
- T$ C, }% U8 G0 L ! [" g+ s2 l/ q) m
> subs(x=0,cos(x)*(sin(x)+x^2+5));
. Q8 d; \# ~# N! _# Y+ S6 J' I $ U7 N* \- ~8 c. }( ~
    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:   " |; P8 h2 S& R
> evalf(%);* O7 t6 C! R1 b' s* r2 {9 U

0 l/ g( {# I. f  D5 ]4 a$ n% [! u变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:   
1 ?$ N  i5 d, @: z! L: W( bsubs (var1 = repacedment1, var2 = repacedment2, expression)
0 m3 ^0 z: B) y) l( s* j6 f调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:   
2 e6 B! g5 G8 }. G; ysubs ( {var1 = repacedment1, var2 = repacedment2 }, expression)! L9 c6 w" X0 }
下面通过例子说明这几种形式的替换.
1 B2 S8 {) t5 @> subs(x=y,y=z,x^2*y);              (顺序替换)% z5 h$ ~5 s) s
6 [& @7 ~* q6 Q- q
> subs({x=y,y=z},x^2*y);            (同步替换)
8 k) \/ i: C. r: R! t* Q6 b
( |! m% \, r2 O" }" b& E8 `> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)/ i; o' E% z5 ~
7 u( `) j5 ]6 q
> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)
# E0 ?8 Y+ i1 O0 M" M* S' f
) e) u4 o+ {! c! j1 y+ N8 H> subs({p=q,q=p},f(p,q));             (互  换); a( j$ z: u; j

6 S- t; D( X' \, n& L( v& F/ o3.3 假设机制
- M- z- X0 L6 oMaple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点. 6 W$ `! j0 J/ Y- {6 l+ Z$ n
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);- ]3 j' x- h5 J
函数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);”也不会产生矛盾. & M8 T& I' V9 e7 _
> Int(exp(-s*t),t=0..infinity);
% E1 ]5 F# k# K( i8 y+ P
6 N: E7 f1 n) d5 ]' q# e; ~: M> value(%);0 K/ f' T2 v# T2 X" |# @
Definite integration: Can't determine if the integral is convergent.$ d% ]6 {4 C- ?8 G
Need to know the sign of --> s
3 ~2 o+ v( g( }) G! p  k/ FWill now try indefinite integration and then take limits.
) x& M. S. ^& |2 s) \# j3 w
7 D6 X4 u/ K/ k( h: y> assume(s>0);
' S+ z9 n" \7 y: v> Int(exp(-s*t),t=0..infinity);
0 @* B  v6 _( U; I) l & U/ p" E7 p+ x2 Q# M  y8 h
> value(%);
: }1 x3 y; ?0 q8 Z" k % q+ b7 v3 O! {6 o% P
3.4 求值规则
! i% z' v  ~% d4 M在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:   2 g: h  \5 [( `$ j7 h
> x:=y;
+ e0 T- a4 p# x0 B4 Y& K% E# n% m ( \9 W2 e& H' k& {0 w
> y:=z;
+ r- a4 Z9 F1 s0 I$ P
% `# {9 Z7 T! l+ h& f, I+ m> z:=3;* P( y1 D' n: r: T( Y
2 m/ B% S% z2 T' X5 e4 [! Y
> x;
5 P5 s2 m+ v. o/ ^ 4 a& D5 H/ m; Y: P$ g3 _% g
> y;
6 M. Z& s- R$ `. m7 B, v  l
/ {. r; _0 \$ t% d/ y" y> x:='x';
0 Q3 v- B. N4 L* V8 G8 U" b
8 N: O" |6 u% p( |( e/ o* W> x;9 P5 k3 l' G5 L/ Q$ O; V

+ d( ^2 o" j. c; C8 m  d5 ~> y;
, G  K" T' Q- E& d+ X9 \+ C " L5 C8 W$ ]$ n; t$ g' Z9 E4 |5 m
对于不同的问题, Maple设计了不同的求值命令. 现分述如下:   
( T. W1 k" L4 J1) 对表达式求值
/ v0 \2 X# m1 O6 U! Y% X" p) P8 w命令格式: eval(e, x=a);  #求表达式e在x=a处的值; B* `, r8 x: b1 _2 X3 ^2 h5 K
             eval(e, eqns); #对方程或方程组eqns求值, J7 u6 \$ [9 U9 y  j  p
             eval(e);      #表达式e求值到上面两层4 S) {* O( O* a% r3 x9 B( \8 j
             eval(x,n);    #给出求值名称的第n层求值
8 V, n' l( L0 e0 m* J/ D% C/ I> p:=x^5+x^4+x^3+x^2+x+73;
: e: R* ]2 D, j
# |+ Q& \0 F& i- ]> eval(p,x=7);
6 S. V+ k) i/ t# h6 s: s8 H
+ N8 L' y2 M& c> P:=exp(y)+x*y+exp(x);
" T) T/ Y. B+ X" F8 \
% @, N/ C% b; U0 W> eval(P,[x=2,y=3]);- \/ Z; r. i% c8 l6 g
  p8 O; g+ \5 I) K" n& R* o8 Z( f9 Y
    当表达式在异常点处求值时, eval会给一个错误消息. 如下:   3 H( V$ a9 W5 h+ ^& B
> eval(sin(x)/x,x=0);1 E  @. Z' h/ r: G& R
Error, numeric exception: division by zero1 B+ i/ E1 d) u' q9 ~7 y: m; A
    下面再看使用eval进行全层求值或者对名称几层求值的示例:   
6 Y8 A; i- T- e0 d> a:=b: b:=c: c:=x+1:* B( {& y6 g* ]. E3 G
> a;              #默认的全层递归求值. V! }5 o$ @  u! B
( H3 b4 h3 A! \+ g- Y* a
> eval(a);        #强制全层递归求值* K0 n" X. V7 l6 P* Y. p. `, u# _
$ ~' y3 q' G  t; [
> eval(a,1);       #对a一层求值
1 Y- J0 P0 A. ?! d6 T$ p' @7 l; d
' b$ p7 L( ^7 B> eval(a,2);       #对a二层求值) r. m- ^  d. a

- j+ A3 E: g+ S6 P> eval(a,3);       #对a三层求值
/ p, n! N4 @6 `+ k' | # }! a1 [* E6 g0 w7 o! f
> eval(a,4);       #对a四层求值
' f" y- m# c' l6 Y 5 c. E5 N6 v' W' Y3 p+ i( c
    2) 在代数数(或者函数)域求值7 g% T5 _0 C# F& _7 d0 l0 {
命令格式: evala(expr);       # 对表达式或者未求值函数求值
2 A" q" M8 S  \9 Y9 [) `9 s             evala(expr,opts);   #求值时可加选项(opts)3 c# K4 ?7 J, @; [4 G
所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式. ) `3 N- Q# j9 S! g7 u9 h
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:   # M; ~9 z( s* Q: J2 V8 u7 q3 d
> alpha:=RootOf(x^2-3,x);  B9 p; F3 T) h/ ?

# b" A: u# Q5 d* }> simplify(alpha^2);
$ a1 y$ K& g! A2 `
. u! ~4 ]- B9 m  o7 d" W在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:  H! i. M# m3 e" A/ v3 [
> alias(alpha=RootOf(x^2-2)):
+ v  I4 v# ~8 Z# A> evala(factor(x^2-2,alpha),lenstra);
2 K) K8 \, ]! L+ U0 F5 |  [$ Z 6 D( H3 T  ~3 U' x$ ]1 Q
> evala(quo(x^2-x+3,x-alpha,x,'r')); 3 X3 x' O% [- }

! ]+ M! F4 ^5 ~! E/ I> r;
: O) S/ {  u) Y0 l 1 ~1 H/ S: r; f
> simplify(%);' ~) @4 \# }$ j& K, @: b, M
. x' L6 k, {4 a" x
3) 在复数域上符号求值
$ o( U8 M' d3 K% ]2 ^  ]5 ]操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
3 Y+ y8 j, a2 C! hevalc(expr);   
8 z1 Q9 |8 X! ^2 H& V8 v' N5 _evalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
0 q1 O; H) ~3 ?4 ^> evalc(sin(6+8*I));
1 Y( P$ L0 m9 ~  y$ V8 m) M : B& B8 E7 R6 \6 B0 _
> evalc(f(exp(alpha+x*I)));
9 `- b: G! h) {6 j
% s$ j6 T+ q9 A# T& Q> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));
* v( c: u/ f9 Y2 x
1 A5 n4 _0 g) F& k7 M4) 使用浮点算法求值+ t6 ~7 g* s. ^# m" ?
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);       l& ~3 P, D" \9 u
> evalf(Pi,50);    8 I; j4 {7 W5 F( J7 N6 D

8 Z: V$ l+ \7 @- |0 d> evalf(sin(3+4*I));   7 c- f: [$ `2 x$ Q& h& U; `

" V8 c% E5 r' V2 b$ s> evalf(int(sin(x)/x,x=0..1),20);
) c- U8 ?& M( N( ?* b* G5 F/ u9 k
! O0 ^/ Z9 |- C; P% D, t$ P5) 对惰性函数求值
! Y) h2 @" O* F8 r  i/ T把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);   ( Q( a$ f% N" [4 v  j
> F:=Int(exp(x),x);8 Z  G/ Y7 u9 |! R3 Y- Z
6 R& q3 q6 U( j0 r5 _
> value(%);4 D7 o+ S2 @* s8 u5 w

0 r- `- f, G9 n$ A7 H. E5 I9 k> f:=Limit(sin(x)/x,x=0);
) E5 C9 l1 h; _' ?
5 [7 m5 a  L+ p1 ]! @0 ~> value(%);
3 R# E- c4 u2 C2 D9 b
% L0 k3 O+ ~, |另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:   . Y0 z# k3 l2 ?
> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);* e+ M) g" X& @( {0 ]
5 A- f. M# i  ^. x) R8 x6 B
4 数据结构
, p+ I+ u1 f* I2 lMaple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
, Q( I; m, Q! a4.1 数据类型查询
9 s1 |2 s- r: U# [) u& S% }  c在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为: ! L9 L& S/ x" H. r  w; m
whattype(expr)        # 查询expr的数据类型" ]6 c" i2 M# P% |
type(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false( J8 u* t# e# `2 W
> whattype(12);
5 p7 I1 n2 o  G% u ) E) b# F' E# w
> whattype(Pi);
& A( x# |! Q8 T& o) u# n
( A( e  {# l& k, v% X> type(1.1,fraction);
9 |+ ^! Z* }. u. M
/ i0 Z+ v/ {3 j6 {9 q> whattype(1.1);
  E0 G* O. r8 j  x
) r3 m+ \1 [, `; J( z% q3 p+ U/ C1 O4.2 序列, 列表和集合
2 l; N( |- P% Q! c& C) v6 D4.2.1 序列
+ x8 ?7 {9 r; [& R* p所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:   
* o/ G) y8 x8 ^! U+ x5 v- H> s:=1,4,9,16,25;( w7 @4 I# U+ ]7 d0 v
8 E  M5 h  e. ~' b+ c+ w1 Q
> t:=sin,com,tan,cot;# f; W: _# S) f% U9 z3 e1 e0 Z

6 R# p# r0 q: z6 z! I- f' L1 s一个序列也可以由若干个序列复合而成, 如:   
& i3 w0 t: l, d3 b> s:=1,(4,9,16),25;
& e9 V% O8 P+ F# [0 `$ y0 C# `% P
% W0 ]  W$ }/ ^> s,s;
6 o7 X3 ~( e3 Z( v5 G% V. L
# ~7 v( F1 q' w而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:   
7 v& @0 i: N, P  w9 O/ g> max(s);
6 z8 D2 Z/ w. R# H * y, d$ Z( r* i" w
> min(s,0,s);
. I. o, G) @- Z- ?# G, A9 L  \# P
& T; x$ a- T$ |* G值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中. % K2 g$ H" @7 y, q, ]% z8 Q$ R8 h
> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;$ `& {6 C3 O% r, \6 @
  a# g- U) M1 _& z
> op(s);. }8 ?( M4 l: H! K( M" J
Error, wrong number (or type) of parameters in function op/ x3 F% w4 n% l  M! s- W! p0 H% g% a
> nops(s);2 {4 \  p  }2 n& M! C
Error, wrong number (or type) of parameters in function nops$ ?, ^4 R1 A+ F7 R: K. I
> op([s]);& P' ~4 @" }1 @' p/ {

1 f1 p6 M- a% m. {- B> nops([stuff]);( t0 Y* u8 C% b7 x2 o

- J. M. k9 a4 c+ N# d# `) i1 E函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:   $ Q9 l: W, x3 |; ]+ o8 N
seq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)% i5 ^! M6 V) ]/ a: d0 U" H4 w
seq(f(i), i=expr);  # 生成一个f映射expr操作数的序列4 @" x1 g# @, T7 }2 N
seq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列
( Q: n5 P" t4 M6 s. d( @9 m6 C> seq(i^2,i=1..10);% T8 o8 |+ b% A' q7 M

  \! S, C7 w3 I> seq(ithprime(i),i=1..20);
3 [, w3 u9 [/ j# y- u! R, K% ? ( ]8 q; e9 A8 F4 s
> seq(i^3,i=x+y+z);
$ K0 W6 J  \5 {: b7 T/ n, ^! D5 K6 e$ y" E % J8 J+ b2 i2 p  d9 t# \+ m
> seq(D(f),f=[sin,cos,tan,cot]);
3 R( i6 A/ d/ V+ \5 U" I$ ? - G9 g$ F$ t  ]4 j6 d
> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));' S0 O5 t( D) g
1 y3 W7 \1 P( d8 P# i( o
获得一个序列中的特定元素选用操作符[  ], 如:   
4 e, L& T7 Y1 H1 J1 o> seq(ithprime(i),i=1..20);
1 ^. g, G. \; F7 ]  ^
6 N5 {  {* W8 Y> %[6],%[17];6 V' Z# w2 x9 g9 H

+ ^% e# s4 T5 P  C8 c0 D4.2.2 列表5 z. l4 z( Y6 `. L' F) G
列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:   3 @" K/ N7 F' o2 ~/ b
> l:=[x,1,1-z,x];) \- H3 q4 b, A4 L1 _

; J9 h- i; i( t) O> whattype(%);
0 \& `6 \/ j" [
. C, E+ g9 _% Q7 H+ k空列表定义为[ ].
5 a9 I3 I% B" g/ _7 t8 C但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:   
, j' i% v( I5 S8 P& i> L:=[1,2,3,4];
7 r4 i, j: a" \1 }: L
- J" U. N/ F% g, s" I2 x, G- z> M:=[2,3,4,1];% Y1 v% z; o, K' l+ G4 h& l1 [
' w0 T6 q. B) k" F4 ~# @7 n% t7 O
4.2.3 集合% }0 ]4 _8 K$ c9 ?- ]
集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合.
7 a7 W5 g5 T4 ^% O( q! ?9 g> s:={x,1,1-z,x};& D: b: _2 T1 ^5 N' i

: G& y; V& z5 V4 F0 x6 R! w' Q> whattype(%);
; s. C; D& Z6 H- g6 x5 M
- K- I; ~( l( Z( n  \# B  }空集定义为{ }.   c' Y% H' P9 m/ j5 {& e
函数nop返回列表或集合的元素数, 而op则可返回其第I个元素. , J/ @+ y. }) U0 T0 |
> op(1,s);
$ Y% {; a9 p* i0 ^, k+ F9 Z
, M5 [1 c7 U' k* S: E> s[1];
( ]2 b1 ~5 K4 d% r: z& y* C+ E6 s
$ j$ P+ e& Q# R; D' F7 l4 e> op(1..3,s);/ _) `0 {5 ?% h# d& R
! g' E' ]) J( Y# y9 W4 A
> s[1..3];
+ B  y  z3 i0 A) t5 q
3 ~5 q5 @, D  _3 Z# T( |函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false. $ O9 w% C, t, H/ z) l" l+ N
> member(1+x,s);/ j0 S4 Z! ~" Z  f$ E4 z. B4 x

% B' }$ u8 ^  Y2 B& m: y3 y可以通过下述方法在列表中增减元素:   
! e: Z! `# E$ o0 N9 q2 y> t:=[op(s),x];
' [$ o8 I! C5 [! A + q& r  y" h- [' r$ U0 O: a
> u:=[s[1..5],s[7..nops(s)]];4 d& a, T* d" j" ~* G
! L. L; @5 @8 |
Maple中集合的基本运算有交(intersect)、并(union)、差(minus):   ( s2 {: T$ q5 @: \; d; l/ z
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};7 t7 Z, R% z) v# g: U
9 k' N% o  ~' s' q; `! Y% o; X: s

! i" B# j& U0 `2 }7 F> A intersect B;
- q" y7 `6 T2 L6 T2 [# P
& J7 H. x* ^$ \1 |> A union B; 1 C0 V$ T, k3 i
% m, z; Y% w- E4 O0 A* d
> A minus B;
2 ?. Z6 K- A  l8 G 3 ?1 l3 e1 z) b" ?3 O
4.3 数组和表
. b& j: |- B. v) P. K6 ]) g在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令.
2 `( n% H$ m' r$ ]' V* H8 x0 c0 P    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的. - r& m$ g3 X' P# L, ]* f/ n) X
> A:=array(1..4);
# o. U" t" k6 u. p% w7 Q
' a! n5 E: h( s$ k6 J4 G% S> for i from 1 to 4 do A[i]:=i: od:
, F3 r& ^- d1 F" b> eval(A);2 i) ?. l5 |7 L3 x
; t5 y- p0 l: ^1 F7 F3 a6 b
> type(A,array);7 t6 O; X+ r3 {5 P

/ |. G( i8 K5 J; x. d/ H> type(A,list);2 h* h; v5 e3 d7 [3 p

6 q# \! S& o( Q+ d> T:=table();
5 n# ?1 @* \, S" i
& Y) P- I4 X. w! x( E> T[1]:= 1;
" j: w9 V" ~) M# I
: H2 R- X  h" y/ o) ]% B> T[5]:= 5;9 ]8 h6 }+ [  B/ D
! p; \6 A2 K" P- n+ E: I5 B5 ~/ e
> T[3]:= 3;9 d; ?0 W9 J% C: q% b
7 v* Y0 Z0 y+ R+ t7 l. E  G
> T[sam]:=sally;
1 y; v  B% ~( Q% b0 ] 6 f  ~3 A# t  `: g" k4 S
> T[Pi]:=exp(1);
. \* o1 k5 X5 l! m1 T
2 K' @' O! L1 G8 U. R! c$ J> x:='x';
7 S8 g, @' n! z6 j! `* n4 j ; S5 k' _& q3 [; ^& r5 {0 w0 ?: e
> T[(1+x+x^3)*sin(x)] := 0;
" o& O" d" ?6 n8 h
2 X: i' A+ S+ @: h5 h2 Z' U; ^! J> eval(T);
! i, G$ Q& w+ E3 z4 C4 c
5 N. k+ e8 {' L) D6 f4 e> T[3]:='T[3]';, E2 f) \! I9 \- R

4 T) B5 y) J! H9 g# O* {> eval(T);0 C4 y  B) b* t) `1 E

1 S) \2 j& M. K% o# Z, I8 B6 e4.4 其他数据结构
& k1 C" z# X7 I( @串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来. 3 H' T) M3 R- [" w2 T
索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立. + e3 s4 Y8 h0 A$ g+ x, h. Q& M
> x:=T[3];
# G" R- N/ w( n3 N . t7 \. Z2 Y  R4 C( A
> eval(T);0 m; E+ S0 j6 j; A
( @) K8 n3 ^' {5 z+ M/ z
> T[5]:=y;
) ~) Q5 ?' T& @; ~4 f" q 5 M7 k9 n) u. B0 @  X
> eval(T);' B$ J3 ?2 |( L, L

  m8 y* v2 B& Y) {由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.     % |% [9 I/ F8 O2 \
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数. " q; @5 F9 G0 }
4.5 数据类型转换和合并6 ^: X. L% s6 x7 H8 b: i% X
convert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:   
$ t- F" D7 d2 o1 I* ]6 `> L:=[1,2,3,4];
* a- c6 {6 a2 W! z& l, W8 W: L
' D2 X4 `+ t, d% b- f> type(L,list);  \$ h! G# G+ P: t5 y. Q/ E7 a. z

  j3 ]8 N4 f: U) D% r> A:=convert(L,array);1 r( E# U$ a8 l5 n  ]
0 \" E; f! B) n3 L
> type(A,list);" z# d5 o1 Q7 {7 c" |% S1 M$ ~
! ]- l& n% R, r5 s) U
> type(A,array);
/ \+ E0 A0 A; E, O! E2 ]+ a 4 ]3 t8 F% f7 ?
另一个有用的函数zip则可把两个列表或向量合并:   
( j1 D# s2 h8 D+ d: ~3 f>L:=[seq(i,i=1..10)];
6 l! i/ D7 w7 Q
- }  m' ~. ~& A- b$ ?> Sqr:=(x)->x^2;
/ l) R! g5 V+ h+ I9 h # F( L5 U5 ]/ n: O) B
> M:=map(sqr,L);
) j' t0 x4 L7 p; \- p
8 T2 A1 C% a+ K) Z7 d: y> LM:=zip((x,y)->[x,y],L,M);: c2 ?) g8 l3 R' |
  R4 J$ N* S- p& t
> map(op,LM);' i$ k" A- O3 R/ G' w7 R/ Z
2 q' ?7 \6 @& ~3 E( g
5 Maple高级输入与输出操作
( z( k# N) w: GMaple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里.
! ]% d0 M" e% u5.1 写入文件. ?6 M1 K, C( o7 s% p4 y; W
5.1.1 将数值数据写入到一个文件6 Q) B* Q, ]$ b2 \# W; y+ T8 z
如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令.
8 G9 ]- l$ v9 P* s若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);& o7 I6 K! {. |  y! \3 K! ?
> with(linalg):- L) u. R5 \+ Y1 l- r
> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);/ y8 W: z$ I- ^" |; k5 x% k2 L8 {7 A

$ _& O& n, E6 b; R> writedata("e:\\filename.txt",M);! ~4 d$ g+ w! O( {1 y( {
而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);
5 ]3 X# _; j5 `8 W$ r> W:=matrix(2,2,[1,2,3,4]);
# I0 i: M( w/ j0 W/ M# Q * }; `! V% E- K+ O& ]9 P
> writedata[APPEND]("e:\\filename.txt",W);7 k  F+ I9 m0 Y- B3 L- A& e; o
需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.8 x; `4 b: ^) l, R" ^
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);" Z, ~- g- F/ P
> writedata[APPEND]("e:\\filename.txt",W); 5 j) ]; \3 O9 w
> writedata('terminal',M);& q/ _1 |7 `5 a/ K1 S+ r0 _) \6 S
1                   2                   3           5 ~( ]$ B* j8 _9 ~$ t- C/ ~
4                   5                   6           
: E4 j6 |- \2 g. q* y' ]7                   8                   9    6 ]" F5 h2 q2 K) h" L
5.1.2 将Maple语句写入一个文件
8 A- F* b' n0 E# y如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:
9 j  n9 I2 A3 M4 |- `save name, "filename";4 W+ j5 t- G- Q; s8 T7 L8 O7 |) S5 e
save name1, name2, …, "filename";
: ]5 i- Y8 r6 n9 I, `- m# C$ ^若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.6 f  ^( _& o( @- \
> myfunc:=(k,n)->sum(x^k/k!,x=1..n);4 i7 E7 O  r# |+ {7 j
# d1 r8 W& S2 b; `- }
> myresult:=myfunc(6,8);4 N) \0 d" A1 I, U

, W2 n4 U2 X8 r0 M7 `- J% [> save myfunc,myresult,"e:\\test.m";% ~3 R( K* X5 a* k; G' w9 F
调用已存m文件用命令read. 试看下述实验:* k( Z1 ]: J8 S' d; X
> restart:3 Z6 O1 l, B" e$ J0 r0 e
> myfunc(6,8);! t1 A* B: [' o2 F" k& S6 l, T* z
& I' C; ~4 E: K- g, s
> read "e:\\test.m";
& T9 m& G* ]& e3 D( G8 N> myfunc(6,8);6 m# o- g" j, d9 j8 `/ A# Q

9 E, B7 u9 h( k+ I4 Q% E> myresult;) o9 [3 d7 v% c+ d! L
' w7 [$ t, M# n  o/ c
    而存为txt文件时则将整个语句存为一个文件:; t9 x2 Q; ?2 T7 I8 `) c" b
> save myfunc,myresult,"e:\\test.txt";1 Q) }8 K! _2 e( a2 l3 o
> restart: read"e:\\test.txt";
! q, ?9 T. z2 K7 Q+ |% z
' F+ o& }$ O( Q' ^, h( R9 k/ H + a- g% p5 H$ W/ X
5.2 读取文件
- i8 d! ]/ h5 G+ @: [) L# x; t" D在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.
7 P# O7 C8 h# H0 I; {) I" g5.2.1 读取数值数据" a! Y" L' k: y9 L3 v8 m3 K6 S9 Z
如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.
6 {8 J( I) Y: @; D! A从filename文件里读取n行数据时使用命令: readdata("filename",n);- _' Y5 S; [; x7 j! F6 o/ R! l) r
以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);
% a# J+ k* i) X& k' @> readdata("e:\\filename.txt",3);' T  ^5 U+ z8 N$ s
- N7 z' Q# U) s2 o4 o
    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:
) t: I3 ]! o1 Q# z& R4 u, T0 F> readdata("e:\\filename.txt",[integer,float,float]);
: X8 p2 S1 K+ O! l$ d/ _ ! W" [: Z8 _9 P! d0 j9 f
下面再看一个运用大量的实验数据在Maple环境绘图的实验:
% P0 B: r( l$ Q5 J- G: p, y> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:
  i( ?6 o+ F! R% {  X> writedata("e:\\data.txt",evalf(mypts));5 _" B) g: f' O$ R( a5 \, ?
> dots:=readdata("e:\\data.txt",100):
/ L9 w5 C' s$ q- s' O> nops(dots);0 N4 d8 c0 A- B. b8 z2 T

0 X  C7 s/ J  Z& [) v> dots[1..4];8 V% g% j. h; Y& J3 `

: W. J0 v: g3 g) ?> plot(dots,style=line);
; {' U8 D( T6 S4 l( ^/ @ * s9 l2 j6 D  G
5.2.2 读取Maple的指令' W9 F5 F2 V  A' Y$ n
在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:
# U8 f: o7 C& d/ yread "filename";
  D/ }/ m9 h0 v% y如下例:
; a) a6 n0 o% |( v- B6 v) E1 @6 X> reatart:
! I; Q; j6 [) M4 s& N5 S2 B$ F> myfunc:=(a::list)->add(i,i=a);$ f6 ~+ K% Y( D% J
9 G6 z9 }/ b0 y. |0 B- \
> avg:=(a::list)->myfunc(a)/nops(a);
0 i3 F4 P- H" [3 R1 c' N: W 5 t  {- C0 I! w& T& M* J
> save myfunc,avg,"e:\\function.m";3 n" k% W! v% X
> restart:
* k. z4 z5 e4 A9 \- r! V> read "e:\\function.m";2 z. g7 F0 n/ W" V
> myfunc([1,2,3,4,5,6,7,8,9]);
" Q3 `! N: q* C9 w, u8 g+ _, N/ n9 O ; c: r! o5 \% r& n
> avg([1,2,3,4,5,6,7,8,9]);
2 M, }6 x/ A8 H7 m+ x3 h
4 r1 t) s3 V! t$ n4 }8 i5.3 与其它程序语言的连接9 U" o/ V  V9 N1 P& u5 I' X
5.3.1 转换成FORTRAN或C语言
7 t# p+ F7 C2 p2 R; n" J2 L调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:# b0 s2 j( ]# i' |
> with(codegen,fortran):5 t; L9 P2 n" y% h
f:= 1-2*x+3*x^2-2*x^3+x^4;
0 T$ [% V* Q/ L% Z% y5 D
8 D) o& o8 |$ S$ H$ d> fortran(%);
$ `0 z; l. F: y# q      t0 = 1-2*x+3*x**2-2*x**3+x**4( j9 o, _/ `' R
> fortran(f,optimized);
; [( n3 h" K5 |/ B7 g; P& F      t2 = x**2
* K* A( K8 y3 x% A      t6 = t2**27 E" e4 F4 j5 z1 C7 I, u- E7 W
      t7 = 1-2*x+3*t2-2*t2*x+t6
" v. A  V% r5 a- S8 `' q$ l> fortran(convert(f,horner,x));3 X5 N% f4 _2 d) J' X$ |: R
      t0 = 1+(-2+(3+(-2+x)*x)*x)*x% z$ _) B4 H. ?
而codegen程序包中的C命令可以把Maple结果转换成C语言格式:* T5 J; T( r/ u" E/ r
> with(codegen,C):/ ]% K0 B0 I1 H- n& F
f:=1-x/2+3*x^2-x^3+x^4;/ k" f" N4 C/ \7 M! Y! a

- @3 y2 M  I- Q3 x  B> C(f);
$ ~/ V9 O* Z5 U( Q      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;# \% \, y! Q9 d3 A
> C(f,optimized);2 W9 E4 j! `/ F# o6 }6 N, z# B
      t2 = x*x;
1 k" k9 A, A3 |5 s, [5 e      t5 = t2*t2;' w7 y( F2 O  M$ F, c
      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
; n) q" C; k9 noptimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.
2 \. p; K5 F$ c0 `5.3.2 生成LATEX; y6 F1 j6 I3 _; ?" a3 A# P2 G
Maple可以把它的表达式转换成LATEX, 使用latex命令即可:& E! K: N) S6 _: m5 f
> latex(x^2+y^2=z^2);- J" }7 H4 g& V! E
{x}^{2}+{y}^{2}={z}^{2}
' R+ m; K2 h. O* i    还可以将转换结果存为一个文件(LatexFile):& p9 L8 D* K2 m: u
> latex(x^2 + y^2 = z^2, LatexFile);1 ?& Y' C# E$ h
    再如下例:
3 N' G$ m' _$ x> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));6 N8 B/ ^* q  m0 {
\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)) B( ?8 `+ ^+ N- y

# S2 h9 c! K" u# x% a
作者: 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年!! ]4 Q+ I2 _1 H4 O: i

0 |5 c. L; r% {4 k# a$ ?2 B# Q2 A' e: n3 J4 c

作者: wangbutian    时间: 2012-6-14 11:53
正如2楼所言,弄成一个word文档阅读起来也好些,不是吗?
作者: 边缘d无奈    时间: 2012-7-24 20:38
顶一下~~~~~~~~~~
作者: 独守一座空城    时间: 2015-9-15 15:25
lz这样看很累人的啊。建议换成一个文档形式的。4 \3 J, t& f; D( r+ \1 Z( U





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