数学建模社区-数学中国

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

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

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

! u8 z3 ^3 N3 t' n+ f$ c5 C : o% O' R( Q* j- V! \* C

7 v& a: X. k& X( S* L
/ Z( n+ X3 L. \2 B* ^/ b * A/ B# t+ y* U1 Q

& @, v9 x6 R9 J' V/ ` 8 r/ l: V3 m  C& C1 F& z( g
9 ~* \' m4 ]2 x
& T3 u0 Z6 t9 N, r7 y; v

1 T2 y( t7 @! z; U0 s" ^ 7 p2 C) [* \3 w# o$ B
$ U2 k9 `8 Q( \- w" f

2 ?1 P( A, l8 H9 Malpha        beta        gamma        delta        epsilon        zeta        eta        theta        iota        kappa        lambda        mu! r% J) L2 P# ~$ l( z- f
9 }8 U( j; d) j1 D" g, [
* `8 K2 ^* q, H8 }  s

0 l: {( f) n/ V' _/ R ! P* ^# s2 m& Z$ ~- j6 k* Y4 }
9 `- z, u+ i  f) }

- Y( y- k" H) x2 Y! L- y6 D ' x) L3 H; E1 H! X5 A

' T9 _6 J1 W6 m( j, H) d
$ O5 T5 I- T7 a7 J7 T
/ ^5 `/ k* ]( ]' ]7 n' K
2 z& u8 L' `9 q
0 D- u, e8 U: R+ z0 Q
7 i0 P# E9 ^5 m  b* enu        xi        omicron        pi        rho        sigma        tau        upsilon        phi        chi        psi        omega4 Q2 U  w' O7 z
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:
  X2 b9 O6 O/ Y4 A" s' b> for i to 10 do
" ?0 h+ r$ `- N+ ?/ aprintf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));. m; [, X" f/ Q; _% B6 }: e
od;* U0 Y8 C- I$ O+ c' \$ K2 D
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/ W" U) q0 R. V
+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:/ N9 G( b6 ?! Y% A# Z
> for i to 10 do 1 {: R6 j9 \) w, ]/ ]
printf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));& n/ T* g! p9 n: G- B
od;  x, W1 _6 H1 r( g* }9 ~. j+ H
i=+1 and i^(1/2)=+1.000% E) h1 [8 w& b( t" M" [
i=+2 and i^(1/2)=+1.4146 J* K. Q/ `$ y" `; k
i=+3 and i^(1/2)=+1.732
9 h" t" u. L2 W$ Oi=+4 and i^(1/2)=+2.000" r! ?6 j# V8 t) p- t+ g
i=+5 and i^(1/2)=+2.236
2 f2 l* p/ }% T2 H, Ci=+6 and i^(1/2)=+2.449" e$ v& {3 x) H2 ~: C! j, D
i=+7 and i^(1/2)=+2.6468 B- r! m& z! S; P8 z: g5 A
i=+8 and i^(1/2)=+2.828; @. l& i; T7 \8 a* L* t) K  Q& D
i=+9 and i^(1/2)=+3.000) i* K  V8 S6 D0 j$ z3 B5 {
i=+10 and i^(1/2)=+3.162
$ J$ Y: Z, P; h: s再看下例:将输入的两个数字用特殊形式打印:
) \0 a$ s5 p; h! R& S> niceP:=proc(x,y)* E; t+ ]& v2 u* ]. P" m
printf("value of x=%6.4f, value of y=%6.4f",x,y);
2 W; b8 X% C$ \- s* s9 {end proc;
, [; T0 Z2 S6 b2 Q5 w7 c
" U" d2 s4 `( q% N/ D3 T( P+ t> niceP(2.4,2002.204);2 X" V: W* ~+ A/ a5 `
value of x=2.4000, value of y=2002.2040
3 w# V7 S: Q! W$ V2 K' W" @1.4 Maple联机帮助  q5 \7 u1 T% k, S: c
学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用.
* Z6 m% @/ C! a8 i! n在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可.
7 I4 o9 W" I6 R) P/ }2  Maple的基本运算3 V+ _- D5 v" h& m8 |5 U# M
2.1 数值计算问题
! x; ^4 Y1 T& {: f3 p1 z3 e算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”. 3 e8 ^' c8 O% `: K  Z' c2 H
在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之,  是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数. & i7 ~0 ?8 Z& t4 Y- N1 e+ _
Maple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算.
5 e2 v; ]( M- Z* ]) l0 f9 V但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
: U9 {2 G: M7 ^. T1 {3 T) u第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:   $ j2 y& P9 y' ^4 j% t' D
> 3!!!;
0 l/ i+ Z7 o: u/ t2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
3 J2 p7 j( F& I# ?上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?' N2 q+ R1 W) S8 e) @3 E" ]/ L
为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式8 s( v9 ?- N8 c  R( W8 N! N

; c3 S3 l- Y' K9 u, B' U9 n可得:  , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:   " G% u: d# q9 U
+ S& @; Q+ Y4 @+ b5 f
这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性. 3 }( y: P& A( T
另一个例子则想说明Maple计算的局限性:   
# F4 K6 ?; `+ p+ }) W6 P  
% g, s: D% ?2 N& \3 T  GMaple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:   
) j5 x* w5 K6 E. j4 k
. a$ y" J1 o+ {9 M. ~, w( M' y显然这是错误的. 这一点可以从代数的角度予以分析. 8 ^7 h% \, l1 U- l2 B
不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果.
* Q9 p( P7 p* y; p另一方面, 设 , 则 , 即:, h$ \  R1 M2 ^- j/ {

- f" B9 G+ y( h9 a8 v/ y显然 有6个结果, -2、2是其实数结果.
3 z8 d+ R# Z/ U( r这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性.
1 I1 G! E& }/ _9 J' |% i: V/ x尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的. 0 w. W2 a: {+ m% |
2.1.1 有理数运算0 m5 n* p* y! k+ W" n, F% Y0 G
作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20).
+ a( q: ?, p7 p8 @4 o3 A6 _( f> 12!+(7*8^2)-12345/125;8 \( |+ L$ d( }6 @0 X0 K

% \0 Q% G9 e; b) _% E, U> 123456789/987654321;
& ?$ v5 E! C) `. ?! j, S
* A9 t$ G  k& Z' y> evalf(%);
  s% V. l6 ~  D" O, s" L4 [
" n0 f5 O6 A( P7 }4 `8 ]> 10!; 100*100+1000+10+1; (100+100)*100-9;* b# q' D0 b% U  E9 w
7 b; K. u% S; Y' t0 x
, A/ }, Q% {7 p

/ `7 V4 T' }: b- t( m> big_number:=3^(3^3);
2 Q9 J9 e! ^# T) M% U 2 g! n) f2 @5 b" b
> length(%);) K3 T) o  S4 @
, [' }: u/ P- P; Q( H
上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:   3 q0 h& H# }; c; u
    1)整数的余(irem)/商(iquo)$ f( d& n) ~. Q9 x/ v
命令格式:   
& b2 ^! }, ]9 M6 J: k/ L5 v) Jirem(m,n);        #求m除以n的余数  n1 |1 S. r1 X% l! b% p$ j
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q
" j2 r: z2 C* f6 a  d& ciquo(m,n);        #求m除以n的商数
! J: g1 M" k1 M4 |# |7 oiquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r
1 V) G# x0 Z- ^0 b* Z其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
" W6 H$ @' A8 m5 r) e+ U> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
) a8 s* e3 l1 i4 \1 Z . S: h6 r/ W3 i1 l" P. C, K
> q; #显示q; [, y) y( s7 H! R1 k
& [, W) p; k  u8 W* w% H9 L
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r
8 O; e4 w, R+ @" t2 H
/ w  _; b7 |+ r0 O> r; #显示r
! V2 P2 A2 V/ m2 J
1 f: Z2 a' j9 t5 w, x> irem(x,3);" H2 a7 N* Z) W  t& N& m
6 E/ {/ G! T; N  Z0 v. S
2)素数判别(isprime)
2 h# ]& m3 Y! ]. D) K4 V& K素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n); , |+ o0 x; T* j
    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
/ d( x( \# O2 p; H: U4 E- U1 S> isprime(2^(2^4)+1);; O# B+ Y1 _2 Z( ^& t* O8 ^4 q: X

3 Q/ R, f  K4 P* }3 T1 Z8 e5 F3 A> isprime(2^(2^5)+1);1 F$ m1 T0 ]7 U1 j9 s6 i- P

4 w( h# J+ M# F, \5 W上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多.
( k/ X/ T8 y8 k0 Y) x3) 确定第i个素数(ithprime), C2 [* n1 \0 U9 o: S% D) u! K
若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);   
$ z1 U: M0 r  b3 X- [> ithprime(2002);
% L7 X3 A' I9 I7 I1 ?7 D6 a
" y5 m! q' v  A' `) ?> ithprime(10000);/ U9 ?9 A7 N1 {* l3 R8 R/ K% d
9 t8 X2 ^( V* G. G
4) 确定下一个较大(nextprime)/较小(prevprime)素数% y6 a4 b9 }# s" B
当n为整数时,判断比n稍大或稍小的素数的命令格式为:   5 l9 z% C4 |" `( M  R7 L. K; S
nextprime(n);  
# E5 t4 t) V" Z8 \prevprime(n); 2 [5 l! j. q) ~& U) u9 |' M" ~
> nextprime(2002);
/ o( O0 m! D( p) v
0 N# U3 F; M& y. n! p> prevprime(2002);" T+ l/ W; _( H0 b

; ~+ d9 W: w9 s5 ]5) 一组数的最大值(max)/最小值(min)& |0 ]1 `8 X  L2 \1 e
命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值
1 B  G" R5 T/ e( _+ ?; H  G8 e             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值
% U& H* p+ h# A  @1 |% D9 @8 C' K> max(1/5,ln(3),9/17,-infinity);
3 r) K. J1 D( i' M) k# P  U8 u4 J
4 Y" U6 A5 a2 \* Y  o! H> min(x+1,x+2,y);
6 ~2 T7 }3 ]) F
' U: M' J- P0 S9 z. g# M' U3 K; C6)模运算(mod/modp/mods)
+ v6 D: t8 W8 j7 A8 l' N命令格式:  e mod m;    # 表达式e对m的整数的模运算
$ O# _4 y1 M3 E6 s  R. S( Tmodp(e,m);  # e对正数m的模运算
/ o3 k" x: H+ n# ~, E2 F6 \0 n# fmods(e,m);  # e对m负对称数(即 -m)的模运算( s  }; P' e2 C+ T; u. g9 K- H
`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价
1 x: P+ `7 d- k值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/.
+ n" l( {9 D5 v. M2 Q) `> 2002 mod 101;
( d  x& b! g& c/ ]5 O
$ y1 s0 U2 w! u' D3 w. a4 }' ~> modp(2002,101);( o8 k7 s0 n0 i# Y0 ~

, g8 D4 E; ^! [1 {> mods(49,100);  K$ c/ u  m0 [. o3 X' V
# {4 |4 l1 r: \# M9 F0 }- u
> mods(51,100);0 K" ~; G3 F& [: F6 B: R) y
9 X2 w; O1 }( n: c0 K' m  I
> 2^101 mod 2002;  # 同 2 &^101 mod 2002;( s) f& v' m" i, s0 A9 w" F
+ S1 \4 I' M- v- Q
7)随机数生成器(rand); G1 P8 c% O3 V1 P- }5 f
命令格式:   
+ V' t6 z. e' c5 }rand( );    #随机返回一个12位数字的非负整数
$ U; @! W' [: j, p: H: Frand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数
2 Y" e2 `$ _6 ]9 F4 }" e6 j0 m! n! L) U> rand();$ i# h) |& O/ e$ `' G" T; [
+ K  ~  C/ ?$ _
> myproc:=rand(1..2002):
! `6 {& j# m& g! U4 E6 o% f+ |> myproc();
$ a6 u( f; @. t) F* A
. L2 n1 s* L) n# o> myproc();
% w1 v- o: Y# ~& @0 h
( h( Y) z( r6 X) }8 l/ a0 A    注意, rand(n)是rand(0..n-1)的简写形式./ B, p6 g) E  V$ a6 [6 n8 g
2.1.2 复数运算4 i5 T' J. Q$ H3 h5 o+ u+ X
复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:   
* z  I. W! m& |; B, y> complex_number:=(1+2*I)*(3+4*I);
4 D6 v- I" f9 u3 x
6 g7 g5 V! e1 c> Re(%);Im(%%);conjugate(%%%);argument(complex_number);
# B0 V& |" T/ ^$ x. [7 N" W- }% X- P * u. Z  d0 F1 Y- ~$ p6 {+ ?
. z4 I/ }1 ^1 @# K3 b% ]
3 R. s% F- {# Z0 r

- ~7 y# ^, h' }2 E& h3 t值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%. 5 P4 n# T& l8 K# j& ?
为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:   7 }7 ], H! ~1 ^8 S9 d
1) 绝对值函数# @( S: v0 f3 e2 ^
命令格式: abs(expr);  
6 f; k- v, s" q: B当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.9 X2 T' O: A$ ^1 t3 l
> abs(-2002);    #常数的绝对值
; {% R. z; w( f2 y5 k
) }( J7 n3 y1 T9 K> abs(1+2*I);   #复数的模4 f. P5 L8 ^9 R8 }+ K( r, s" \. Z+ w
$ Q2 m# `2 ^& t* L) ^! R! o# \
> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值
( u2 |* Y; h. ^. O3 a  R, T , c5 i7 H0 a: V/ c! z+ t# J
> abs(2*x-5);   #函数表达式的绝对值
: b1 a: \4 @) e4 ?6 z1 X! w 6 K9 }9 e6 M+ _: o) n
2)复数的幅角函数" r' \! Y) ]: P3 u7 I
命令格式:   argument(x);  #返回复数x的幅角的主值* d! X$ z/ E2 T* n% [& ~
> argument(6+11*I);2 Z3 W' u3 m- Z+ w" e3 Q
+ E& V; R; C9 I
> argument(exp(4*Pi/3*I));
! b$ g9 {$ m0 o7 l, X
0 ?5 N* X% t' X3 {9 I3)共轭复数
" y! l: W. Z2 V& Z2 e命令格式:   conjugate(x);  #返回x的共轭复数
" _9 C; |" A+ s! H% s2 a3 n+ t> conjugate(6+8*I);: _- T3 m( G( B- g0 M

# \0 ?' N2 ^7 |/ h3 ?5 b> conjugate(exp(4*Pi/3*I));0 G9 Z/ k# N; Z( _
: l- A  A5 l1 Z/ a2 @/ @
2.1.3 数的进制转换4 ?' q& M! a( I+ `, W
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可. ! d; H- ^) V- k/ ?$ k4 R
命令格式:   convert(expr, form, arg3, ...);    ! k/ V) }4 T& `$ |
其中, expr为任意表达式, form为一名称, arg3, ... 可选项.
2 u0 ]( u" W5 B3 t1 b7 ]下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述. 5 u$ M3 Y' g: |: c8 `
    1)基数之间的转换6 g6 S2 p, e6 L4 R) {! Y( a
命令格式:   1 `& e' k/ p& q- O
convert(n, base, beta);      #将基数为10的数n转换为基数为beta的数6 J# b* r( K5 g5 m3 Y0 V
    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数
& R/ L; w& b3 I1 P> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
) X8 n1 r, m/ Z + ?0 H" i! C* Q# ?8 s3 |
> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数
( g; G3 s' |; l) I + \' p3 }9 V: ?/ q1 l
> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
* y- u; X# f/ ^- C. @7 O0 L; a' j/ { 2 G% U. b( L* v2 M
    2)转换为二进制形式
9 ], R6 A6 {; ~. S* i命令格式: convert(n, binary);3 T  w# ]' d8 A# M; ]5 ~
其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂.
( M. h, T3 M6 Z: `' h; O6 M0 [# |, p> convert(2002,binary);   & J: s2 {0 w. n. o9 j6 ?
6 ^2 P% h2 q& Y1 ^" B
> convert(-1999,binary); 0 P/ p& \4 o0 T/ `
( f1 r9 ?9 {$ E" e* ?
> convert(1999.7,binary);
% M7 Z' n7 o3 M& O, M - P* a9 d* ^9 D  J
3)转换为十进制形式
( t6 y  L; T9 B4 N) S4 F其它数值转换为十进制的命令格式为:   
: I, r8 G4 Z$ M$ o' q) H$ Fconvert(n, decimal, binary);   #将一个2进制数n转换为10进制数
0 r0 l( s3 D, D7 J8 l6 O    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数
0 X* b% n- S: I7 Q" j0 n* c    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数
% H! _; N" _+ ]; |  U> convert(11111010010, decimal, binary);    7 E6 I( E% d  I3 \; K

. r2 }7 Q( c$ e* Q> convert(-1234, decimal, octal);           7 C7 d$ K9 J# V6 I& o

' S9 h. v& v8 |, G. X% A# c> convert("2A.C", decimal, hex);          7 W% O2 X9 ~6 A  P3 c& G! s
: O4 a& h( v3 S* b( W
4) 转换为16进制数- Q0 n5 v# T$ _# r5 h
将自然数n转换为16进制数的命令格式为: convert(n, hex);   % t. T; @+ ^. Y* D
> convert(2002,hex);  convert(1999,hex);/ K; H1 m' _. d4 D
2 a' u( v; |" U( X

* X: _" p! x% t. k7 `4 f5)转换为浮点数
/ ?, w- U: M. u0 i7 r+ \0 i( W. ?4 z命令格式: convert(expr, float);6 A/ U6 r$ o( Y& C
注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用.
! C% w* H0 q1 v8 g! m> convert(1999/2002,float);
( @0 D# q% H/ K2 U ' U" e( J* n* `1 t& f
> convert(Pi,float);
. J9 ?+ S# H1 {5 D4 K3 p1 C , ]/ q  W8 I( J% L
2.2 初等数学6 L; i+ c4 u5 ?* [9 Z3 m
    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识. % h$ o/ G8 Z6 _, M# {0 a
2.2.1 常用函数: q- }, }$ B  D6 D6 S  J7 x
作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:   * P5 c" I" C9 X$ R9 i; Y; t" T- @4 k
指数函数: exp
% n0 x3 f7 z2 P- B! v一般对数: log[a]% u8 f; x" E+ T. D
自然函数: ln
8 W. B2 H! K5 p4 ]' u7 S4 S2 x常用对数: log10
' |) C0 L0 `/ K$ B平方根: sqrt0 V- ~; d1 p" e4 [. l1 f" E2 V2 e
绝对值: abs6 Z9 Y( I# ]9 z( a: S% ^. Q
三角函数: sin、cos、tan、sec、csc、cot1 |7 Q! e0 R: ^; m9 f6 l! J
反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot+ M7 ]) U% g$ K6 J
双曲函数: sinh、cosh、tanh、sech、csch、coth% e- S3 o& F. d: w' x
反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth& @! g" |: y; U0 @& M7 a( n: g$ W
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY. |3 s9 N. @2 N$ T, F/ e
Gamma函数: GAMMA
' A8 w1 U+ s- p误差函数: erf$ B) a. N( d) J
函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能.
% n) F8 m: s9 ^, y. ?1) 确定乘积和不确定乘积
5 _# P$ T8 i& M0 q  |# c' w( ]3 |命令格式: product(f,k);  & C- e% z9 _9 U
product(f,k=m..n);  
% |- Y) e" J/ T. B) d" Zproduct(f,k=alpha);
/ G& a$ ~( i! m# H6 s% a5 [product(f,k=expr);3 m  P1 T' }, ?
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式.
( ?4 d1 E/ a2 g1 V3 M2 U4 {> product(k^2,k=1..10);   #计算 关于1..10的连乘9 \! s, c2 D( A6 i

' ?3 V* F0 U) k> product(k^2,k);         #计算 的不确定乘积
7 e9 d" d/ H8 w" X* P
( J) Q! G3 H, J, j* U> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘0 c& o8 C+ f* k) N- U
1 e6 [- `0 b5 _6 q
> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘! X. U* B+ f0 U
% I8 d" C- j' n* L# R: t9 ~& ?8 s
> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式
5 m" W& O% [' l" q+ \ 0 W7 |% Y- r, P
> product(k,k=RootOf(x^3-2));     #计算 的三个根的乘积
/ R  A# |0 q- A) z& X3 ^- c% a $ K$ r7 Z3 W# x; [. k
    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:   
4 T$ y1 V' j" P* k2 W> product(x+k,k=0..n-1);9 V# N( @8 P. W: q; ^! t& e2 f
$ v' @# F. g! d& F1 G% O. G* r
如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:   
! }4 g! p* a" a4 R> mul(x+k,k=0..3);
; W/ p' G( T: E) X# v # x( L, Q2 R5 r" b- u; y  t2 P
2)指数函数4 B, D7 {6 p7 T5 p( N) H7 C  @
计算指数函数exp关于x的表达式的命令格式为: exp(x);
* }) E% H0 E& C; W- {& a> exp(1);* h; @8 K# o4 j1 H7 E
( P) s/ }/ H8 v3 H
> evalf(%);. s3 [. S  w$ _( s
8 R' M  h, Z6 _' z% \( G" Z. ~# _' |
> exp(1.29+2*I);
- `. Y7 A5 N% f0 }# m- O% q* h , D2 u. E* \% t2 }+ K5 k
> evalc(exp(x+I*y));4 {0 `! {/ [- q8 q; ^( Y6 E& l
6 \1 Y1 q& [& V) y6 M0 B  K
3)确定求和与不确定求和sum
5 ?7 w0 o+ A/ `, z命令格式: sum(f,k);  $ ?! [: [! ?0 ^9 _5 F2 E" S
sum(f,k=m..n);  
& n: V2 K& n& L% ssum(f,k=alpha); / H" w% v* d# |) a# P& p; n
sum(f,k=expr);  O1 _- K6 {: @8 ~$ Q  o3 S
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式.
) W0 {; l; R0 i" H; Q5 w2 P> Sum(k^2,k=1..n)=sum(k^2,k=1..n);
  ~( [( a- m# @ . W; l4 v! R. D6 {7 ~5 T3 P
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);
7 U7 g- Z# P  G0 l4 r
* o7 i8 Q/ @3 q0 }. P4 l# E& x6 v> Sum(k^4,k=1..n)=sum(k^4,k=1..n);0 \+ E7 b$ Z6 z. h" o
; }* h+ A0 S5 K/ H& ^! r5 x
> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);6 u$ W8 e6 _7 `( c9 |
2 Q* p2 ~: A: `9 G
> sum(a[k]*x[k],k=0..n);
+ y1 |0 E% b! ?4 ~, \& L" c/ v : d  P! j; s3 O2 g3 P! `5 A& k
> Sum(k/(k+1),k)=sum(k/(k+1),k);
" C' O) _. V3 T- K3 Z 3 O5 N" ^; r! S- @2 H
> sum(k/(k+1),k=RootOf(x^2-3));+ p: u6 y. B$ S
* @2 R) P( h8 b, i/ o7 b
sum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的. : A4 g: r$ _  _; H
> Sum('k','k'=0..n)=sum('k','k'=0..n);7 A# z/ }: w) W2 ?

) y9 V. q5 [& T. k4 h. l. T3 s如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:   , U& w3 k  i  @7 t4 t
> add(k,k=1..100);9 C* w. X. c+ t, Q

7 D3 L; E2 Z& w' |( h尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令.
2 x9 X& \6 r1 y. x9 N% y另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性. 8 o2 N7 y" I9 g+ K% a) i1 I
3)三角函数/双曲函数8 S. \) j- e  w( u9 z. X
命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);" t! [4 I' C9 l- q2 {
          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);! h/ _" s; m7 p% \* c1 c9 O
其中, x为任意表达式.
+ i/ y+ D# j2 N+ `值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.
& Q  u" X2 w# n" l> Sin(Pi)=sin(Pi);
& d7 [$ P$ I2 f ) `  v* _1 e8 d" C$ Z# A/ G
> coth(1.9+2.1*I);6 _1 \( S5 r$ T8 F( W" w

" Q  E3 m/ R, k* ?2 O, g> expand(sin(x+y));     #展开表达式# l, _, I7 K3 p; K2 x
0 L, l2 D9 s+ K: @
> combine(%);        #合并表达式
  k" h5 g/ m. N# e' ^: E' u , {9 \/ p- ?3 u$ t  d7 [' J5 B
> convert(sin(7*Pi/60),'radical');
1 g- \2 Z  U) |7 A' g
! v( u+ T( B) _, r( _/ ?$ o# J4 ^> evalf(%);
9 z8 U4 k# G% i9 \) F6 P0 h   h  `) u3 ?3 m; V: h4 C# q
但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.! d& y- ?+ R) z1 ~9 K/ f
4)反三角函数/反双曲函数
, K+ t9 K8 G! S% G) a命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);( _- H7 j2 [& H! S' t
     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);   " V$ P/ ?! c' U* X3 z
arctan(y,x);# n0 F, r& O' m9 K$ i6 `( ^
其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算. ( v2 j3 X+ b& w9 b8 i$ ^5 ?
算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.. P7 o) i0 R8 Z- {5 Q0 r* U
> arcsinh(1);% a+ {9 V; d2 R2 `7 t2 {$ I

5 y2 j. E  J1 n/ A3 R1 \' f> cos(arcsin(x));
) l; ~/ U7 S/ Z6 P
; @+ h3 X+ |# _0 i> arcsin(1.9+2.1*I);1 u. g( ?; H; ^0 M$ M
1 k9 T3 K2 ^: q5 L& k
5)对数函数0 K* b: h5 @: k7 ?3 V  C! \
命令格式: ln(x);           #自然对数: I: w0 k5 C. ?7 g3 e/ b
log[a](x);        #一般对数( Z  j- ?! v3 H, n. H# Y: u
log10(x);        #常用对数' E" C! [" N# C$ \; D
一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:   
) [& g6 I+ K* T6 p  (其中,  )
. I  F9 I- T7 q& u& l- n> ln(2002.0);- F% I7 h3 s; T0 w( ~8 M" v

3 {; ]9 }/ Y" `& @9 d" m> ln(3+4*I);
5 A! x# s+ w, [% f9 H $ X( a; l' \/ o3 D  [8 K9 o3 S
> evalc(%);    # 求出上式的实部、虚部
) i2 d5 m- [, D% F2 b* m- Z
4 t8 O9 F2 _' m( t" d6 b> log10(1000000);- y/ L2 Z5 q1 z: u1 R1 ~
6 S" u( R# K' t
> simplify(%);   #化简上式4 D0 j9 W; l. T# f5 K& s

& o% f# s1 Z! ]2.2.2 函数的定义  F: _7 l4 A/ w# H7 e
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:   9 c' b8 X0 j, W1 a& X
> f(x):=a*x^2+b*x+c;
6 N7 J" x8 ?) W( {- n( k( y$ i
! ^% h" W( v: Y可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:   
. B" R; G- m. N( g2 P> f(x),f(0),f(1/a);
# `; Y6 v* z# o3 s9 v/ G 9 ?& |' I/ w. N1 I5 \
由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:   7 a7 F. D" f5 J
> print(f);
" l# T" \, K. p$ w: i 5 `1 D+ v8 D" Q  n- M( Y+ s
事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式. ( [0 T5 ]# Q; c5 q! N/ c  [) o- j
在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):   5 Y2 i( C- F8 {( M# q7 \8 r
> f:=x->a*x^2+b*x+c;
# e2 B- h, U& D4 c: a
1 c; a9 Q  D' h& |5 s> f(x),f(0),f(1/a);4 U  H0 u' V$ ]- G6 f6 L, I
# I; S/ ~9 B* }
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
4 K/ {0 Q: e7 k, W7 S( P> f:=(x,y)->x^2+y^2;, |2 Q. W; M) [% z4 c
/ o. Z- [  `$ I7 \4 i( L! Q8 y# ]
> f(1,2);
- r3 W3 [( c' x/ P% Q% l. z
' f4 x1 x3 ?  s! b5 [# n/ _) I> f:=(x,y)->a*x*y*exp(x^2+y^2);1 o- n; j8 g/ C& F
5 v! _9 e5 z+ j  h% B( Z
综上所述, 箭头操作符定义函数的方式一般为:   
6 U7 F  a6 S# p1 W3 v0 O! b" O: ]一元函数: 参数->函数表达式
9 C, M& _$ K0 Q! |多多函数: (参数序列)->函数表达式
- j1 K" i4 K, A/ V/ ~7 }无参数函数也许不好理解, 但可以用来定义常函数:   
- t- T$ p7 X4 R+ N9 [2 C& @( W, m' O> E:=()->exp(1);
- A1 }+ {  [5 y . ~/ C$ \/ J5 M; A6 g  [/ S
> E();
. ?9 e. {8 N! e9 K: N% n
- K9 W' }- \" J& C0 h> E(x);- a5 s4 B7 \, r: M4 X: @  {  a

8 ~9 J: N# Y, P+ F另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数. * ~/ S' f, I" K: _0 N& _
定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);         
5 ]; p9 W5 ^5 q3 B4 u5 x3 `' u; E定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);     3 |) G( u9 d! B$ E
> f:=unapply(x^4+x^3+x^2+x+1,x);& z# C5 ^% w7 E1 S

! \  k; ?1 K  Z/ v9 {( G5 O6 A> f(4);
: F2 D! Y/ Q% R. k7 ~1 _' U
2 u8 b9 y. h  X% `> f:=unapply(x*y/(x^2+y^2),x,y);
, S7 e' C6 l$ O- m; H: T" c
% z& y  F3 O! Y+ p% P9 z+ [> f(1,1);
- n/ _% X0 }: x) f. q% M; e. G% l
+ b' i2 X, W* o- A6 K" z0 {( c借助函数piecewise可以生成简单分段函数:( W1 r- Z! J* G5 }* ?4 \4 u
> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);4 ^/ B9 t/ z, I7 S5 F3 Z

+ j2 S2 N: E) i9 z  ]' }& p清除函数的定义用命令unassign.
3 M: s' g7 _( ~> unassign(f);, r" j% Y) K8 K/ Z) d- _
> f(1,1);4 v- t0 k1 u0 z: _. @6 C
# k$ a  ?7 Q: [! ?( {
除此之外, 还可以通过程序设计方式定义函数(参见第6章). 1 e  P5 L) T& R; U  Q
定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:
4 l. f; g6 b( f- ]4 top(expr);          ( F4 ?* S" L. h: F
op(i, expr);         / I: q( ?1 _6 h# t, U0 U( S
op(i .. j, expr);      # b9 v1 @! d) E: U
nops(expr);
) b" q  D4 Y5 R- B8 j3 E! S4 t如果函数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的类型. , a% t7 ^% Q8 U1 |$ k
命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上., O7 Z) K! f; a: z
命令op(expr); 等价于op(1..nops(expr), expr); % `' o7 g8 C* e7 G0 z% K
特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
% @/ d, h# c' X. S. f+ M+ C6 `) u而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和.
& d0 u9 e0 Y* ^- H& n> expr:=6+cos(x)+sin(x)*cos(x)^2;# }* }: Y% e* s+ g, |8 w/ N  I

/ y; _; U, s( q  }2 e6 W> op(expr);+ |4 k! L1 I. t( O9 m0 i& E$ f5 U

: R2 B! c& u! I# T9 X6 }/ \/ U, l, ~> nops(expr);
& a4 N' p* b8 {/ s# Y/ a - r0 {; z6 s3 u4 K9 e, X1 Z
> p:=x^2*y+3*x^3*z+2;
9 c1 z  m; |% h# A" }, G
" J) j/ v; K3 \6 q' P> op(1,p);
: _$ V3 u8 P% \5 I2 v ) [7 E. X  Y4 {9 E& o) J
> op(1..nops(p),p);; B: m0 W; c# z' Y8 G, U, x
: i0 c: y& X. E. Z1 P0 ?7 q0 E
> op(op(2,p));  f+ N& G! E" Q1 u! R& {

2 ~  H( T) A6 b/ h> u:=[1,4,9];
6 T) V& j% \0 p2 C5 [
% c' l$ G+ X1 Z5 N) @& c> op(0,u);! r$ D+ S6 \- x; A( }& ]- \2 |6 g

& s  m9 e1 e2 C2 o8 K2 M> s:=series(sin(x),x=1,3);
: l. B5 O: C5 L; J2 W
6 u+ ^- V4 ~+ L! k' H> op(0,s);7 x0 k% g! {% B
        3 ~. w$ z$ j) |3 T! h" u6 d- c
> nops(s);
: G" Q9 U" ?0 }# X: E
  |& w6 W; O) h% |; J1 |. k下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:3 c+ y3 d/ e7 C5 A; X+ m1 z
> op(x*y*z);3 x( ~1 I4 W" q, ?, T
5 Z. O' r$ U' n1 ^5 w$ N/ p3 q
> op(x*y*z+1);
0 J0 B8 T4 J8 D1 C+ _) J 4 z1 H) r: ^& x' E  B1 t1 ]' }
2.2.3 Maple中的常量与变量名
  K( m5 W8 a/ n. h- O4 e+ R为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:   
! f2 Q/ X  c, v> constants;4 K# F3 K# R4 D; d  e
5 N! T- m6 o! C
为了方便使用, 现将上述常数的具体含义列示如下:   ) \7 |5 v) h  W
常    数        名 称        近似值$ ?1 {  h) ^  h/ M! c! R
圆周率
5 G$ `4 C# h& x9 Y2 i3 zPi        3.1415926535
9 l( j3 f% K2 u  B# B3 _+ CCatalan常数
6 E: Z+ j$ M4 I# n/ ECatalan        0.91596559422 Z1 D! J- e3 Z) w) C
Euler-Mascheroni常数 3 ]8 N( G. T1 v) T# X! w! ~) ~
gamma        0.5772156649
8 K  j7 M8 N! s
. e+ P& t/ O, O& ?8 `! a: o% Sinfinity       
+ s4 s6 O5 E, U2 U- }8 T. t& s) U- g: ~$ g/ K9 O, B
需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取.
3 j8 }2 S: R+ T, E% @在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”. . W: K8 d3 _9 n! L& {6 a% o/ c% a
值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名.
# Y2 r4 N, f3 U$ b! m: h& a1 [4 X在Maple中有一些保留字不可以被用作变量名:   
; @7 h# E4 f# Z* }  Aby      do      done     elif     else     end        fi        for      
% D4 r! c+ l2 [" }4 ofrom    if       in       local     od     option    options     proc         
9 D+ H/ \* w  |0 _7 vquit    read     save     stop     then     to        while      D
4 g9 |: b8 Z" s% rMaple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名. ( e; n/ K) f7 K6 n6 C  [' d
另外一个值得注意的是在Maple中三种类型引号的不同作用:   
" |/ {  X" C" O0 r: B8 P8 ]`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;   
$ v( S1 m0 g5 ?: Q+ ['  ':   界定一个暂时不求值的表达式;   
/ Y  ~2 M: N  Y- [/ A. W"  ":   界定一个字符串, 它不能被赋值. " W* u' i$ }+ H  u0 H6 r
2.2.4 函数类型转换           
) `) }2 ]% P( G+ n- d函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:  - w& W! F& w4 C1 o; M
    convert(expr, form);        #把数学式expr转换成form的形式( O7 g- V& X% |" \
convert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos* w+ i$ l( v+ I+ ?1 O; |
convert指令所提供的三角函数、指数与函数的转换共有exp等7种:   
* B4 d: ?! T$ e2 Q8 g( W7 U(1) exp: 将三角函数转换成指数
4 R6 d, a9 D5 p) A$ N1 L# t0 z- B(2) expln: 把数学式转换成指数与对数! t/ P: B+ ?! V
(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式
5 F" p( p& Q6 _  q; M(4) ln: 将反三角函数转换成对数
4 h7 k& m) K% @% R4 A% M, t3 [: l(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式
, n0 ?5 t9 ~4 U" m4 l0 r(6) tan: 将三角函数转换成tan的形式! e) X7 z3 v7 ]' Q; }) H
(7) trig: 将指数函数转换成三角函数与对数函数
$ @+ ]( L1 e# Z6 W> convert(sinh(x),exp);   #将sinh(x)转换成exp类型$ @, d+ k# E4 Y; R9 a

" G% f' N& S- Q6 S* [> convert(cos(x)*sinh(y),exp);
2 N; Z+ ?( D% @. m3 V
0 V  }1 c9 [' A> convert(cos(x)*sinh(y),exp,y);
5 H0 p# A" K% ~
5 D. V9 t" G6 t5 d) E. `, z/ {  ]> convert(exp(x)*exp(x^(-2)),trig);
8 z; N9 O& i  F) O; D $ H/ |: k* y1 m( P1 H8 L, ?1 [! z
> convert(arcsinh(x)*cos(x),expln);9 s6 k( e  H* h' z' P; U
* }) I* i! i4 D
> convert(cot(x)+sinh(x),expsincos);
/ W2 v! t3 A9 k2 ?7 z( k
& ]2 y$ p7 i$ D4 H2 T0 ^( H> convert(arctanh(x),ln);
) _0 {+ y" |: A$ b & o$ ]* D% ?5 A
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:   
0 H4 F: i& X  ~' B> with(codegen):
9 m! n( J. A7 x* z& X+ F> p:=4*x^4+3*x^3+2*x^2-x;
. m% L, z5 b* U' a" p& y) W0 J
3 W& Z2 o. m- L: _& M& T$ k: ~9 m> cost(p);* h$ X( s- T3 B  _
! e* K. h6 v& f/ S
> convert(p,'horner');  #将展开的表达式转换成嵌套形式
/ ~# O; j8 a: i 3 D& o, X4 k3 V  h: _! k% P
> cost(%);$ v- ^% p( {- y. [
! S( S/ T! B* n! u4 p- ^" B7 |
同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量. / T8 C  X& Q/ X
> (1+x+x^2+x^3)/p;
8 n1 P; c5 U% ^# H
6 W: V: G9 N# d: v- [7 J4 q, O) p$ ^> cost(%);
5 U  C- q" n3 b, ]& X . b: g4 z, o7 G9 m6 ~& t+ `
> convert(%%,'confrac',x);. P; P# \2 Y: y3 j4 D( x6 F

$ B) C/ C% y1 a" ~> cost(%);
$ o/ o$ s: i" c! ?* ^ + {& M5 G  Y- v6 b4 V3 M
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式.
4 ^: F$ [3 D, o) [> convert(%%, 'parfrac',x);: j6 n1 R9 R+ A- W2 i# \0 x" S
2 E6 Y' r, S, @# e
> cost(%);
! q/ ^! A( L3 r# Q' o
+ R6 l) f/ }; R2 U4 u, Z8 x; G( a而把分数转换成连分数的方法为:
1 ^# T. x0 q1 }6 W' n8 Q6 j; O> with(numtheory):& O4 s; z, Z4 K! e2 ~
> cfrac(339/284);
8 j; b$ Y4 C% a' @7 m " a4 ^$ S" p( ]6 c; y. B+ B  K
2.2.5 函数的映射—map指令& _$ _4 a: Z3 \, f
在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:+ _$ a6 h/ l* H! w  X
map(f, expr);      #将函数f映射到expr的每个操作数8 [2 {6 H- Q2 ?  F4 e4 A  l
map(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量
& k7 P1 k3 B6 Bmap(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量7 y; I+ K( u6 R+ k. _# O5 v: H7 C  l
map2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为
8 ^5 O- t7 g4 s3 w' S第3个自变量…, an为第n+1个自变量来映射函数f
+ ^- k/ F# @' a> map(f,x1+x2+x3+x4,a1,a2,a3,a4);+ t  P. k8 c# g
9 R: ~$ ]/ G4 K! K
> f:=x->sqrt(x)+x^2;# x" v1 w: S) x+ j& h, u
7 g( v2 }8 c( K: q' k, r
> map(f,[a,b,c]);
- G$ C* b+ q9 l! i. b
" s" {$ v" g, C% J2 K> map(h, [a,b,c],x,y); / B( O' b3 w: [4 W
" }2 L: E. c4 ~1 X( w) o
> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);5 K' X: k( B: w2 s* c  g, O

5 x4 Z! t- u8 a) u, u) B% Q> map(x->convert(x,exp),[sin(x),cos(x)]);9 u  n, i/ t# Y3 q* n

3 H; S5 j5 p. Y+ E9 C: }上式的映射关系可通过下式理解:
( J# H0 I/ ~# A- D7 l; d> [convert(sin(x),exp),convert(cos(x),exp)];" C& w2 R+ J" }
) w: u, Q/ p4 N6 {. P
> restart: 4 r9 H2 n7 t' Z
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);
" C% ~; ?  Z3 Z ' B; J- b" d- I# a/ f7 B
> map2(max,k,[a,b,c,d]); - \1 ]1 h3 E7 v# R9 c* R  \

8 Y3 [4 w6 @3 c  m' v4 u: J8 k% {再看下面示例:   
% d' ~, Y  Y( Q' m) e8 S: @6 j3 f> L:=[seq(i,i=1..10)];& X9 @8 y; X6 b0 [; J
0 E# M" V' a  C
> nops(L);% d0 B- L* H& ^, k* ~2 ~$ s

4 w8 C% Z  m6 b6 q> sqr:=(x)->x^2;$ r8 s  g, G6 k
" ]+ p. Y4 I2 b: G' v4 U
> map(sqr,L);
, a! @1 b+ V0 N9 f  u) P$ U, Q* y* K' U
* \3 Y( T2 M: Q* f) ]) N> map((x)->x+1,L);
6 m+ b9 m+ I' n' k & `, m" y; e, u
> map(f,L);% @) \6 B: Z' y" r
" U% g( }' H: ?+ K+ ~1 M9 N" I! H3 q
> map(f,{a,b,c});& v# Q, y6 C& t/ ?9 _) i
. \5 i; w5 w$ B3 V0 q; v0 t+ j
> map(sqr,x+y*z);
8 \4 o7 \  G* [. a * @/ u: w3 V& ~1 r
> M:=linalg[matrix](3,3,(i,j)->i+j);1 C' j$ h4 E$ i+ o
5 {1 Z: t# K) W& P
> map((x)->1/x,M);
5 H9 X" t/ {' X' }- f* ^; v
9 @; Z8 Z2 e$ i7 \0 s3 求 值
/ |% q/ o8 e, \7 k1 R, ^, f, ^6 J3.1 赋值
* S4 W, ~; }- k! @# T7 q/ n. Z/ l! K在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子. 7 x! c& ~# P/ K: T: i
> p:=9*x^3-37*x^2+47*x-19;: G- L- Z- D: y0 \) ~5 l& b

; `* B5 Y9 t* l. w* c& `2 w# w" I- A> roots(p);& F! F# E' A; J) L9 ]( l+ J2 F& k
1 U7 y4 ?; e- d" s: W
> subs(x=19/9,p);+ @/ I& K$ d8 R% L3 e  D. |% R$ E

* a$ [8 R( ?+ Q* L5 w7 U/ |8 ?* Y在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量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/ B1 Q2 o" N: O4 ]# w- S1 Q3.2 变量代换% C) \0 l# l2 H# t. I$ {( x- w
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:   
$ u- B8 Q; r$ w: X+ Wsubs ( var = repacedment, expression);
: _0 T& a+ P6 @! ^调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement.
0 B% h7 J1 r- p7 \- M4 z5 q> f:=x^2+exp(x^3)-8;
2 k1 |: Z9 T! e" f# Z0 v
% H; W2 s- @4 s5 y/ h2 f0 J> subs(x=1,f);3 t3 [9 }+ K& ~9 e" L$ {

( x! S, Y2 o& o6 X7 ^0 D> subs(x=0,cos(x)*(sin(x)+x^2+5));
3 h6 T9 m/ G& \6 e* |
) d2 [6 G" S8 m* e7 R5 u* [    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:   
0 Q2 w; T. B* I) \  l> evalf(%);
) L! U5 }4 S, ?  h; l& s
! U  d, x" N5 ?: K8 B变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:   & h% T5 k% T1 ]$ I! r; k" N7 y  i
subs (var1 = repacedment1, var2 = repacedment2, expression); `) v1 D! ^! u7 j6 j3 ~- q, c
调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:   ) |# j: V( ?! Y+ n( b
subs ( {var1 = repacedment1, var2 = repacedment2 }, expression)# W0 k  R2 t4 k0 }1 A
下面通过例子说明这几种形式的替换.
" U! I4 R/ y: V  F8 r$ e> subs(x=y,y=z,x^2*y);              (顺序替换)2 Z' c# [! H3 D; a0 D3 d- H
  a5 x; A/ s3 @; p0 Z: ]
> subs({x=y,y=z},x^2*y);            (同步替换)8 v4 Q1 b  I5 o$ }( k
. h1 B' D; r; G0 t$ Z( u, ~  k
> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)! o$ h& ?0 R" y
+ q& M3 |8 d5 R) P! f4 J* o0 l; r: M* Y5 z
> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)& c' [! X( H' D! j5 [

; L- g7 n- k; m* @> subs({p=q,q=p},f(p,q));             (互  换)
8 }; k2 V& `# ` 7 ?  |  P! N  V, z
3.3 假设机制; ]; n7 R8 Q: Y& {4 V- G
Maple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点. * i4 g' ~. w# Q4 Y- ~
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);
# s: {9 F) ~1 Z& A8 K( V% d函数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);”也不会产生矛盾.
. O' G/ \9 n" D+ v  W2 M> Int(exp(-s*t),t=0..infinity);
- {" V' O$ Q; e + s: v  W9 a4 _9 G) G1 q' Q. M
> value(%);
3 O, y, u; _9 W7 O% oDefinite integration: Can't determine if the integral is convergent.
- b. n! i) F+ d/ E+ F' RNeed to know the sign of --> s
: c$ O  q- ?. h0 }Will now try indefinite integration and then take limits.
* E, n/ L- h4 |. N: i
" y/ o/ }; K5 H( R' u> assume(s>0);
% _/ @8 b5 h: _> Int(exp(-s*t),t=0..infinity);+ B6 ^* S; t+ Z* w1 X( Y# k- ^

) w/ f* W, E2 a> value(%);
7 W! F* y" G. B2 o $ K' v4 ?, \$ Z4 a2 O9 L
3.4 求值规则
/ E  V/ M: X- l' S' A5 e. n在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:   
; W* ^8 C. v+ D3 [8 \+ b> x:=y;
' I! [" u+ u. z! M  t
2 V7 _  q  |. r" s8 k: P> y:=z;
* l8 A7 i; n1 ~( r4 W- Y 2 V4 P8 o6 p5 o( p& T- C
> z:=3;* {1 ]' R. M! L9 c

7 \- y( T/ v+ ~0 j, E/ o> x;
/ d, {: d. e1 o1 w
  I& u9 Z/ s: j; D. `$ T# r> y;6 h' i7 t" r$ y' g/ g5 m! }
0 f, k5 M; J" V$ S8 i; c
> x:='x';4 Q- W( p7 P2 L8 h# L0 a% u' U
( x' F, G9 Z# o, Z7 `3 o
> x;
6 {, i7 [. @- [/ F4 |  f
& ?3 P. ~5 B& i9 o> y;
" Y' Q& R2 F0 c1 y
0 J. s  T9 x4 Z% [5 M6 p) O& R对于不同的问题, Maple设计了不同的求值命令. 现分述如下:   
+ b; S1 `3 \) G% n: O4 V" _1) 对表达式求值" ]" }6 k7 O  i
命令格式: eval(e, x=a);  #求表达式e在x=a处的值0 y3 \# E6 n6 Y  N
             eval(e, eqns); #对方程或方程组eqns求值
* i" K: L4 N6 R$ z  E             eval(e);      #表达式e求值到上面两层
. c2 ?" F$ w- h             eval(x,n);    #给出求值名称的第n层求值
) A0 i- O# G% d> p:=x^5+x^4+x^3+x^2+x+73;5 H3 A. n; e, D: n% j" Q4 y

+ Z0 d0 Z' D# n+ _1 C" {( u$ _: G> eval(p,x=7);
  w2 I& F" s7 m , ]+ S3 v* |$ M6 \5 q
> P:=exp(y)+x*y+exp(x);- _+ m- I; l- t" i8 ?

0 d, h8 V. ]% K# y> eval(P,[x=2,y=3]);
! D6 e3 ]% V) N$ B5 m
- [8 t8 H. T% N- x: x0 @5 g1 o    当表达式在异常点处求值时, eval会给一个错误消息. 如下:   4 y: k+ P# C3 [. |& g& }2 L* D
> eval(sin(x)/x,x=0);* Z4 j" s1 G& G7 k6 M
Error, numeric exception: division by zero- C, Y& V; K/ f# j- G
    下面再看使用eval进行全层求值或者对名称几层求值的示例:   : ?" J9 `* ~7 U) j/ ^. Z
> a:=b: b:=c: c:=x+1:% p* Q4 F" Y+ b! }' \  q4 u
> a;              #默认的全层递归求值
5 t6 u* Q# t0 V& Z
" `* Z6 n, {/ m0 J* E( J> eval(a);        #强制全层递归求值1 o* o6 M: o0 e! ?
2 g, ]  J# c: u5 k, Q6 Q" l9 n% ~
> eval(a,1);       #对a一层求值
* g  H, i+ w3 e9 G8 ^) |- w" `
- f; ]1 K* E; w> eval(a,2);       #对a二层求值# G+ n& _; n1 o  i, h* _
/ I3 @( c$ A2 \' b1 l
> eval(a,3);       #对a三层求值
8 q. z+ ~' J0 I8 G # y% U; O% V: [* y* z
> eval(a,4);       #对a四层求值/ {$ ^* Z; ^+ @
# R1 V" z* L8 _/ T
    2) 在代数数(或者函数)域求值& [* Y: [1 _$ z5 M! n: ?! U
命令格式: evala(expr);       # 对表达式或者未求值函数求值
- |0 H* C6 z$ z: X4 r. w& _             evala(expr,opts);   #求值时可加选项(opts)
# {) W2 `, M( M. p+ n$ I" H所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式. 8 c7 ?8 r; j1 I( R, Z% J
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:     C8 o0 w3 M* O/ V2 H
> alpha:=RootOf(x^2-3,x);8 o( q4 N9 r0 D
; H6 E; k% q- J% c/ J/ a
> simplify(alpha^2);# w# q, F9 o% d; C7 i. L) G# I6 |

. `' O; r) l  W, t- j" E9 v在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:
2 i2 r+ w2 j, P5 U/ z/ B> alias(alpha=RootOf(x^2-2)):1 i8 v3 c8 R, [+ O
> evala(factor(x^2-2,alpha),lenstra);
9 D; L% M' R9 V0 g  f
0 y# K$ J' @6 I2 X- c' D7 M( o> evala(quo(x^2-x+3,x-alpha,x,'r')); , D0 J7 a9 O9 ?$ O) ]$ J

1 C$ b4 F3 ?; D6 J/ `. d> r;+ x# @; F' I: s6 F# o4 w' q
! g$ Q" [/ I9 e" i( f; @$ L) S
> simplify(%);
) r. b( k" O1 ^6 \/ J: W $ c+ w9 c# J8 T5 L- o6 [
3) 在复数域上符号求值+ `/ g1 g* t# n6 w4 a2 P) O
操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
9 j/ F" n/ Q5 H! \/ Uevalc(expr);   : M# G7 [; r: K+ V, z' x
evalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
5 p! _6 C  ~+ d. S% z: o> evalc(sin(6+8*I));! O$ b4 Y+ x  M& S  U$ n4 j# a, f- M) A

; i) B$ J5 }# P; u- Y' J> evalc(f(exp(alpha+x*I)));' R2 i% p3 h% E  B6 W# g

8 X! M- @- i5 h- f/ q) O> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));
. v' i" x6 j- O% R ; D& P* V9 Y% X5 h  h# K
4) 使用浮点算法求值( s' A. g5 I" [  ^1 x% L* }, V
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);     6 ?# ^' r" f6 Q
> evalf(Pi,50);   
' N5 f: V5 `# z 5 g9 e* ^5 r% R, S7 v" S( h5 i
> evalf(sin(3+4*I));   ; Q2 s' X! a8 K  [* {, r3 M- e' Y

; Q0 e0 K6 S  z/ K5 F$ X> evalf(int(sin(x)/x,x=0..1),20);
( h* f* J+ f2 Y2 ?, ?! l6 V : N# e: y! [, ]0 ~
5) 对惰性函数求值7 S! I  B! e7 @* e- n
把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);   4 ?& ~4 ]) p7 ?/ w. l. o1 Q$ ?
> F:=Int(exp(x),x);
& _: u+ P9 W5 _$ @& T8 N3 I: _, q
. C2 _" W' D5 r3 ]; s- t" W> value(%);
' l8 x! M: l% T  \  J% `* _. Q
& M2 f- ?, z7 b8 y> f:=Limit(sin(x)/x,x=0);8 V; O* V# _8 M( W4 D
$ A: U- c' C# W
> value(%);5 ?' v; X+ E; _

* w3 `, q/ o) N另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:   ; g* X, f) p- N: C" o
> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);2 u9 V; }/ M6 W( m/ C9 B
3 t" F/ G2 b8 b9 Y
4 数据结构
5 A+ [, ^6 i4 h" }4 f1 A) tMaple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
0 D" m3 B; ^& ~4 t. \" s- O4.1 数据类型查询
! Y! l3 D& q/ q在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为:
& r/ p+ D, r  }- A3 _' q1 ^) mwhattype(expr)        # 查询expr的数据类型% W/ T- r/ r+ C  S
type(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false
& C0 o; @) B9 Q6 m+ @> whattype(12);) w& @# |( V9 ]3 b7 w& h

! R. N, a3 U' K. p  a> whattype(Pi);# I" k. r" X+ y% |3 O. F, \

' x! [' U  m* K- J7 V> type(1.1,fraction);- D2 Y' E2 k  k
& m9 F  S$ c3 `  i9 }$ X- P- ]# d
> whattype(1.1);5 @1 }5 v! B- s+ X
1 i, [/ k& u/ S" \
4.2 序列, 列表和集合2 `+ ?, |- @9 y) X
4.2.1 序列
# @" i" f& G/ L$ {7 `. d9 D0 m# c* V所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:   0 u" _. h" ~7 X- [- [- ]
> s:=1,4,9,16,25;
6 K% g8 {% ?, U2 i/ V9 |
. z. L, b  L4 H* E> t:=sin,com,tan,cot;
/ g0 m* g7 N4 X; B# q9 F 7 B) o: Y9 N, K! L: C- k) ~
一个序列也可以由若干个序列复合而成, 如:   
% l) f& d* u1 F- e' z5 S6 X! b> s:=1,(4,9,16),25;
* ^5 k1 @0 g6 E% C2 G& b, l
% T9 k) Y2 I8 C; C+ H> s,s;
6 q( W7 F, J8 c( o$ I; V# h& v 1 V' N# S5 P5 Y3 H) }" y! L
而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:   7 b% g6 r; F6 \0 m8 r+ ]
> max(s);# t, Q' a' }0 A7 M6 Q

$ O4 s  M( C- H% `! Q  D> min(s,0,s);
5 a. t# H; e2 t1 i' u# G* c& q% a! c
& \/ p) d( X. K" F" j2 `2 i4 V" z值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中. 2 W7 W) ^9 O+ i: M
> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;, W2 Z7 R: G8 V# u# X7 P6 {

) v0 \) Z$ ?# s' B2 B6 Q+ q. m" ^2 x$ W> op(s);/ F2 w) l9 A( |- o* T
Error, wrong number (or type) of parameters in function op
# E/ A/ ~/ C  e! P7 \: W+ E! L3 [> nops(s);
4 O8 V  ^9 ^3 Z" IError, wrong number (or type) of parameters in function nops0 M8 C' D, t  G. m* y$ n
> op([s]);
. D+ R# K. |0 x1 h 3 n) R/ m& m0 t2 e% @' E
> nops([stuff]);. m* O: U! B( a1 Y

9 T( S5 D' |7 y1 Z. @; D函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:   
" p& i0 G+ g; ~8 I. lseq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)+ s; B8 ^8 p: w$ R1 A  X
seq(f(i), i=expr);  # 生成一个f映射expr操作数的序列/ P# K5 `' a+ V7 ^: }
seq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列
# d+ ?( s1 ]: V* s$ B3 ~: O> seq(i^2,i=1..10);% l. a3 g; e  g* I. X
# l: P6 O$ g3 |+ ]; I# s
> seq(ithprime(i),i=1..20);
7 b( `$ _$ V) a, \/ J / {8 ^! z8 ~+ I. k* k9 ?
> seq(i^3,i=x+y+z);
3 U1 [# Z* w4 r7 K) @9 L- ]
$ C' C+ u7 s7 j# l0 \3 k: U> seq(D(f),f=[sin,cos,tan,cot]);) t6 I. Y2 o1 o. x' B- E  a

5 k; P# N  V7 W! @/ e# ~. X- x0 c$ P> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));
6 w, R% v& E- F) l- h# A: Q . p9 Q2 {8 l6 s" c
获得一个序列中的特定元素选用操作符[  ], 如:   ! I) U+ B/ R: Z/ B
> seq(ithprime(i),i=1..20);. M. C* ~6 g+ ]1 r$ q1 r+ ^

- [6 \( u* T, H- u; e+ n: }> %[6],%[17];
, ], t  U! B( m( _/ @5 G# g; R# w0 p . _6 e$ E+ F! x& U1 d2 |3 {6 V
4.2.2 列表
% N, o& Q5 q8 }! W3 x列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:   
+ \0 C' s& @5 }: o$ }. v  x! p> l:=[x,1,1-z,x];
; A0 W9 k" H4 R) o & X' g! n& Y- b$ B
> whattype(%);9 w' s% {/ J* S. D% c

$ b# [4 {# o( z$ V6 l0 }空列表定义为[ ]. - u4 [( l, \) y" C
但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:   
$ y8 z' Z* \$ w* W> L:=[1,2,3,4];
6 A1 r- r4 H; E, f) w
7 K9 i% V9 h" Z1 Z9 m% ~> M:=[2,3,4,1];
# x% Y3 F9 M0 V3 h- D & U% o6 q; X7 Q2 G5 e/ n$ U
4.2.3 集合! P8 W$ P( I" i4 P5 B
集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合. # f# W4 K& g0 S$ R6 |5 X8 o2 J
> s:={x,1,1-z,x};0 D* S. P( t" @4 J7 {6 ~( M

- O( }* [: D& H( E0 q$ C- w> whattype(%);4 O' c9 x) ?0 y0 T: V5 {6 S* N

# j/ q( B2 l8 S; p空集定义为{ }. / M5 F( U  c+ V( a+ M: E
函数nop返回列表或集合的元素数, 而op则可返回其第I个元素. ; i- E" L) M# v7 S) v4 j7 j& ]2 ^1 O- }
> op(1,s);; O  w4 G  ]5 l9 v1 V# o( N5 {. j
6 L9 T, l. p1 ?( ~6 J
> s[1];
! S/ G1 h) a6 r+ M
$ i9 l- }  \' f. h( [  B. t> op(1..3,s);1 i' _0 u. y7 m" Z7 Y; ]
1 B% }, y* c" o) B! ]
> s[1..3];
+ T. V* b9 M' C# `! D- ?
* u- Q5 W: w6 f+ V* V( i函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false.
5 P. w3 c% g, a4 d8 E+ ]; Y> member(1+x,s);/ b/ j$ r$ Y" ^$ b# R1 g

- ~' D. E- c: }5 O" z( U1 V$ m可以通过下述方法在列表中增减元素:   
7 ?1 w, V  f4 h8 f& j> t:=[op(s),x];- E: P3 h8 `- \5 S0 |6 f

8 v! ~# C/ s5 m  O6 ^> u:=[s[1..5],s[7..nops(s)]];" p- v9 Y( D& ?& Y3 |& J1 q+ F3 Z

+ \8 j$ [* A! x% K* v; h' {Maple中集合的基本运算有交(intersect)、并(union)、差(minus):   ; K& e. j4 n8 r3 }8 Z+ v/ N
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};
) u/ R) q! Z& p& N! x+ q3 C: P * Z6 G* u( S1 ?! {0 ]

) ^! s4 |+ x* ^> A intersect B;
# a. s/ i3 J7 r! o8 x# W5 b
+ K# F( Q7 w; k. S1 w> A union B; ! e4 M2 x* A" D. ?7 z
5 b" v8 {2 t5 l& n6 m: h
> A minus B;
8 Y* I) O* J! V9 U / a- k+ y7 P2 w" N  M, \2 v) Q1 K
4.3 数组和表
: f# e( o( X/ R2 J5 |: F' G在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令.
' A3 `; {6 V! f# I* T- H- V: [    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的.   w/ H1 c$ l7 P. f8 O& N1 H
> A:=array(1..4);
5 Z7 T* c3 e- i" R 8 u) F1 g. U+ q
> for i from 1 to 4 do A[i]:=i: od:
. T; ]! G7 u* t4 C9 G; D> eval(A);: v, b- y4 D* s4 z+ g$ u
# [( |1 E4 c+ Z
> type(A,array);. }7 N) g* z8 ~* P! O8 V) [

- v3 r4 I8 d8 k$ i. ^4 ]> type(A,list);2 a: T* h& g- ]  p

" i* h/ w  O; k/ N% Y> T:=table();" U2 u4 n4 u' ~; o

, R9 q: @. |% B- h6 p4 O> T[1]:= 1;. Z3 T: [' u1 |+ ]/ b
) P  d: W: n/ Z+ G! v5 G8 o
> T[5]:= 5;( w6 o4 T$ d0 C( H, K

+ {$ m2 e% K. r2 ~+ t& ?> T[3]:= 3;
# S3 M# {0 x( [; ^3 h* E
- q, O+ W& |: i) Y> T[sam]:=sally;% ^8 P, E5 X# j- y$ g( P

( \  }; }" K$ f0 g, B> T[Pi]:=exp(1);  |# |# r0 N- Y: m$ ]' e

% K8 j) |3 t; i& c- A2 v$ w> x:='x';
: [4 X( @% o( |9 g* c. C1 W 8 R$ R3 }7 f* b% `
> T[(1+x+x^3)*sin(x)] := 0;
" R; q1 F# S* }! Z+ R 2 e& o& n& }/ S
> eval(T);
: h# z" [" [4 J& F' y- Y5 A
# i* m$ G; h, y1 V: Z( _% T' X/ G2 V> T[3]:='T[3]';
2 G7 k4 Z* P. x" D  B# p # n/ W  a2 k. q: b! c+ k
> eval(T);( y# I$ c; n" n$ ^
. S/ R8 T$ J7 E
4.4 其他数据结构  e' l# g" D3 I4 y# x- Z+ ~
串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来.
, d0 r% J" s2 s1 ^! R* n索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立.
5 }: O* m. p! M' H, ~. w> x:=T[3];
9 M6 x# X) H0 p) E) D6 M " A% [9 h5 K$ t& \
> eval(T);$ }; ?; T" {3 ]/ U7 C5 p$ G) @
! L" J9 P. m' R  B6 G2 ]
> T[5]:=y;6 C( f% S! P2 ]% ?4 g4 G9 d
. M/ J1 V7 a# @" ^. {- c4 x
> eval(T);/ Z/ l& C; D( }% i9 `

# Y" E8 X4 w* j/ s7 D由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.     & X. k3 O" H4 a6 C% y
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数. , h. D' D5 U3 Z7 ?
4.5 数据类型转换和合并, _) X1 b( ]) L
convert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:   $ j5 w- ~' |2 r" T- ?
> L:=[1,2,3,4];
& d* ^0 d) F  A: q0 K- v 9 ^, H1 ?1 A1 a# R: n
> type(L,list);: o0 s1 z, e% e- `$ |

0 x3 M+ e6 F- x0 t> A:=convert(L,array);
  ?; T7 U! a" Z4 k( T1 P ( I6 j; b( F8 I( q" _
> type(A,list);, w0 c- @5 {) P2 ?9 i$ k

  ~( m# }( g, E3 N! r> type(A,array);5 I" E% g- `' ^* K$ D$ @+ A% ]

1 O( ]/ W5 k; D. U另一个有用的函数zip则可把两个列表或向量合并:   ' r! i5 F. T9 ~& e1 Q& t
>L:=[seq(i,i=1..10)];% M& X" {0 j: _5 k3 K7 z5 B
, i0 {$ y/ Z. ^; K' L% F) d
> Sqr:=(x)->x^2;
7 \0 I! n: I7 {; l
2 {& H) K3 i0 ]! T+ \> M:=map(sqr,L);
) t( ~& H7 n8 [! m% f
$ Q! {% j0 T! a6 ?* M1 j8 q* w9 e  y> LM:=zip((x,y)->[x,y],L,M);
9 @# [9 `! G( A9 b
7 ?  A! U7 |  F0 _0 F8 E) p> map(op,LM);/ B3 D3 f6 L. u6 ~3 r9 `
% u% v6 ?  K9 e  ~: |6 f% j3 |
5 Maple高级输入与输出操作
; o' P  f3 S8 ]" vMaple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里. 2 _+ u6 G8 U+ T% h
5.1 写入文件
. J8 s2 G/ s' b5.1.1 将数值数据写入到一个文件: q9 c7 q$ c5 Y0 \& |- _0 O0 H* ]
如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令. 9 {4 ~0 a$ T, q6 d" v
若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);
0 j2 H7 e- B7 h* n* c" {$ g5 y8 z7 h> with(linalg):
3 Z, A* T6 e) Q' f! x> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);. }/ K, j: c( F3 Z

2 I% J% [. s3 g' f> writedata("e:\\filename.txt",M);
& v! d: \( t/ r" @而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);
% ^1 Y2 k  Y4 ~7 ~$ k- j( H! @> W:=matrix(2,2,[1,2,3,4]);
4 D/ o6 A, V4 ?% R* j+ ^
+ P& q3 [% f7 ]9 p; J/ u( F$ ~7 O+ ^> writedata[APPEND]("e:\\filename.txt",W);
* k. Q- a. _8 [7 I! [) {需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.6 Q+ \, l/ ~& d- p  a
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);" D4 }: W! H* u- @
> writedata[APPEND]("e:\\filename.txt",W);
7 u7 U/ |. o  L  H, |8 F> writedata('terminal',M);
. ~) `1 R8 G6 P7 j5 A1                   2                   3           # g; B$ o9 {8 e! _9 ?+ ?
4                   5                   6           
6 H2 m9 k; I* N! B) W& z7                   8                   9   
2 @2 |! i$ C- p$ q$ s2 h8 H" `& E5.1.2 将Maple语句写入一个文件! x+ F  e& T$ V1 J0 o# h7 Y  G
如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:
' _' u7 k3 O4 \" `& @- b" |) ^save name, "filename";. d8 d0 M- H, l1 N; W
save name1, name2, …, "filename";4 Z7 i$ i. x8 I- E% ~
若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.4 q, r9 b% X' W: _! M" i
> myfunc:=(k,n)->sum(x^k/k!,x=1..n);) C3 Q% }- M; T+ D/ X

# V* l# C1 e' m* k1 r6 e8 D6 o> myresult:=myfunc(6,8);
/ G5 I# I, g* }( n
0 r5 P) h' k# }, `- I9 F> save myfunc,myresult,"e:\\test.m";
$ l4 B; M$ Y% |调用已存m文件用命令read. 试看下述实验:
' p2 j) i$ a7 Y9 c> restart:
$ A. o3 z6 J) B0 X1 ]> myfunc(6,8);
! E" D& O5 x7 u& c! h0 { ) k; N( _; e+ o6 A
> read "e:\\test.m";
0 H  w% V( W8 z' v$ Q' b) j- a8 D> myfunc(6,8);
" z1 z* F7 ?- }) r/ A 3 Q: _( F9 h! e: c( y* @0 H
> myresult;
% U" q( O' b) K- y1 y , M5 a1 ]+ a4 O( x; E+ P" r# l/ h
    而存为txt文件时则将整个语句存为一个文件:
7 }( f' r4 G; Z% E3 W> save myfunc,myresult,"e:\\test.txt";8 H: ^" s( t, h; {. S7 Z
> restart: read"e:\\test.txt";: U1 o# k+ I4 X' [
7 P1 m1 G/ C5 ~4 T) h
% b( t# s; v( f9 P$ S6 }% b
5.2 读取文件! n2 H0 s  S8 k4 K4 V
在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令., B4 O" ~- K+ U5 R0 z
5.2.1 读取数值数据7 g0 D! P+ b$ F+ _% g
如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.
. `: w3 o! _4 ~0 c) x, k. _从filename文件里读取n行数据时使用命令: readdata("filename",n);
1 {6 n- a: ?6 ^9 o" U以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);- u+ P5 \5 X4 W9 T+ o
> readdata("e:\\filename.txt",3);
( m& i) h7 ]0 e
9 z% \! W' g! X3 _    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:& U6 P, {5 b7 g- q: R
> readdata("e:\\filename.txt",[integer,float,float]);5 I% e% a( m9 E# y
, r  O; s" B: c9 @+ P/ e& P( u
下面再看一个运用大量的实验数据在Maple环境绘图的实验:4 r: Z# N) R* V! a/ q1 n0 ~" |7 j
> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:. g" Z8 e. S, |( d( g
> writedata("e:\\data.txt",evalf(mypts));
  ^/ R5 W/ I* z2 X  i4 J/ E- T" C> dots:=readdata("e:\\data.txt",100):/ G0 L2 v. o+ Z" L
> nops(dots);) x  ?0 V1 n% i7 Z. ?- |

# c) Z5 Z# g( g# s, V> dots[1..4];
4 {" H) e' B8 `* T  w
$ D! q& q, D5 X4 c6 X2 C! t> plot(dots,style=line);
# k. a+ @( @& [1 D8 c2 s: t( l
  o$ K) w: K; h+ I! ~5.2.2 读取Maple的指令
+ Y1 h5 B7 z$ y0 u+ o在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:
8 t% [$ |% s' f" f% L( sread "filename";; I( \6 W* E6 U& M0 ~
如下例:
. L1 q+ X# J7 {6 i( }$ D! x. ~> reatart:
' o6 _4 [6 a- S  g- F) X> myfunc:=(a::list)->add(i,i=a);
' |, H  `, n* y' ?9 w & t8 f" ?. ?7 Z4 Q9 C4 E
> avg:=(a::list)->myfunc(a)/nops(a);3 r. T, S( `, l7 l8 k

0 p+ f9 K- P" C> save myfunc,avg,"e:\\function.m";
) I; e( x) ]: s- p9 s> restart:& g" q9 @( ~/ i& W
> read "e:\\function.m";
9 \, J- B& V; k% ~, a( }> myfunc([1,2,3,4,5,6,7,8,9]);
$ j9 o/ z3 c6 g. U& G 8 c6 I4 }3 |* e' z. y6 B, X8 l
> avg([1,2,3,4,5,6,7,8,9]);, q( s2 `: @4 B/ z! e2 s: X- Z9 h) f- x

; R8 s! \7 L" Q  I4 V5.3 与其它程序语言的连接
  u6 V/ C+ c+ D  y* }6 q5.3.1 转换成FORTRAN或C语言+ r! w% S& Y/ K$ B# \. C6 u0 g" J
调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:3 x! C4 z+ ]/ _% H. f, |6 [
> with(codegen,fortran):" a6 j( p) |3 R& B* b. M
f:= 1-2*x+3*x^2-2*x^3+x^4;
1 v  V" I$ y+ h- \0 ` . V4 [: U& h- f& W" {2 ]$ \
> fortran(%);
2 v* e6 T2 T. l; {/ k& Q) q, A      t0 = 1-2*x+3*x**2-2*x**3+x**4/ V; ^2 B+ K1 I; h5 }& T
> fortran(f,optimized);
+ s- b- E7 Z( |& g      t2 = x**2
5 W4 J) Q  U0 t0 p) n: {3 B      t6 = t2**28 ?( B) u6 i  J  p2 @. z
      t7 = 1-2*x+3*t2-2*t2*x+t6
( q; D) [, @% s4 I) s> fortran(convert(f,horner,x));
, b) v/ C7 _6 P. G      t0 = 1+(-2+(3+(-2+x)*x)*x)*x, F# v5 g& e7 u" i
而codegen程序包中的C命令可以把Maple结果转换成C语言格式:6 w8 Y$ q4 X. M, I. X
> with(codegen,C):" o4 {3 X7 y; U; ]4 y. |6 F
f:=1-x/2+3*x^2-x^3+x^4;/ F$ X/ h$ B7 _1 N. i3 H# m& k
8 N% e% ^+ D" u3 Y" C
> C(f);
+ {4 ?$ e9 N% v# |1 b& {" b4 u      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;5 }; F7 H; i5 |7 n1 h0 F2 {
> C(f,optimized);
; j7 {7 Q  ?, y2 J      t2 = x*x;
# P- b, ]/ Q* ?6 y9 {      t5 = t2*t2;7 x2 e2 j0 r6 X/ _
      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
, \+ w: n' ~! o" |: Noptimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.1 O0 \$ n0 r0 N. K+ K3 p! X
5.3.2 生成LATEX* @9 g% O% o5 x8 p7 f8 @
Maple可以把它的表达式转换成LATEX, 使用latex命令即可:! B) ^3 {! k3 N; M
> latex(x^2+y^2=z^2);
. A4 C: n: b6 p6 a- g! H{x}^{2}+{y}^{2}={z}^{2}' Z4 z) N& j: G' e
    还可以将转换结果存为一个文件(LatexFile):' b8 J+ Z# a* h; P/ E# `4 w6 o
> latex(x^2 + y^2 = z^2, LatexFile);: p& X& k9 A$ \4 t, X, x
    再如下例:
8 t, `! p5 Y9 T4 `3 }. }3 S> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));
2 ^- K% O. r2 i9 c6 _4 f\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)4 ?' h! G/ V- O& r
3 Q, G' A( G3 F. p, V

作者: 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年!0 |5 I' s9 t6 |7 h3 @" {% L
' m' i' A* N! @

" i/ F+ Y; g( x6 [7 o
作者: wangbutian    时间: 2012-6-14 11:53
正如2楼所言,弄成一个word文档阅读起来也好些,不是吗?
作者: 边缘d无奈    时间: 2012-7-24 20:38
顶一下~~~~~~~~~~
作者: 独守一座空城    时间: 2015-9-15 15:25
lz这样看很累人的啊。建议换成一个文档形式的。4 O$ ?2 h, V2 }2 f  F& D





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