数学建模社区-数学中国

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

作者: woshiwangxiao    时间: 2012-6-12 16:53
标题: maple基础
% {6 r& A: \3 {
第一章  Maple基础  w8 f) \; j) M4 C/ X
! [4 J( O% A( d5 J
1 初识计算机代数系统Maple
+ z7 G9 _+ S( t1.1 Maple简说) F# J8 _  x& t& k+ A  K
1980年9月, 加拿大Waterloo大学的符号计算机研究小组成立, 开始了符号计算在计算机上实现的研究项目, 数学软件Maple是这个项目的产品. 目前, 这仍是一个正在研究的项目. . X4 [: Z6 {8 B, K. o1 B
Maple的第一个商业版本是1985年出版的. 随后几经更新, 到1992年, Windows系统下的Maple 2面世后, Maple被广泛地使用, 得到越来越多的用户. 特别是1994年, Maple 3出版后, 兴起了Maple热. 1996年初, Maple 4问世, 1998年初, Maple 5正式发行. 目前广泛流行的是Maple 7以及2002年5月面市的Maple 8.
+ d# D8 i' @+ r/ x. G- V) K2 pMaple是一个具有强大符号运算能力、数值计算能力、图形处理能力的交互式计算机代数系统(Computer Algebra System). 它可以借助键盘和显示器代替原来的笔和纸进行各种科学计算、数学推理、猜想的证明以及智能化文字处理. $ o$ y* @8 U4 m& L4 a
Maple这个超强数学工具不仅适合数学家、物理学家、工程师, 还适合化学家、生物学家和社会学家, 总之, 它适合于所有需要科学计算的人.
' D0 D. [- x5 p3 E- [7 X, W( X1.2 Maple结构( B5 F! m% Y) W* K3 p: O
Maple软件主要由三个部分组成: 用户界面(Iris)、代数运算器(Kernel)、外部函数库(External library). 用户界面和代数运算器是用C语言写成的, 只占整个软件的一小部分, 当系统启动时, 即被装入, 主要负责输入命令和算式的初步处理、显示结果、函数图象的显示等. 代数运算器负责输入的编译、基本的代数运算(如有理数运算、初等代数运算等)以及内存的管理. Maple的大部分数学函数和过程是用Maple自身的语言写成的, 存于外部函数库中. 当一个函数被调用时, 在多数情况下, Maple会自动将该函数的过程调入内存, 一些不常用的函数才需要用户自己调入, 如线性代数包、统计包等, 这使得Maple在资源的利用上具有很大的优势, 只有最有用的东西才留驻内存, 这保证了Maple可以在较小内存的计算机上正常运行. 用户可以查看Maple的非内存函数的源程序, 也可以将自己编的函数、过程加到Maple的程序库中, 或建立自己的函数库.
6 K5 [  e- g7 w9 J# @1.3 Maple输入输出方式# f5 Q3 ~$ X) s2 W0 w# p( h, C! p9 E
为了满足不同用户的需要, Maple可以更换输入输出格式: 从菜单“Options | Input Display和Out Display下可以选择所需的输入输出格式.
" f2 y9 u5 f: p  o4 X- AMaple 7有2种输入方式: Maple语言(Maple Notation)和标准数学记法(Standard Math Notation). Maple语言是一种结构良好、方便实用的内建高级语言, 它的语法和Pascal或C有一定程度的相似, 但有很大差别. 它支持多种数据操作命令, 如函数、序列、集合、列表、数组、表, 还包含许多数据操作命令, 如类型检验、选择、组合等. 标准数学记法就是我们常用的数学语言.
  b+ g+ c8 W$ P5 ?启动Maple, 会出现新建文档中的“[>”提示符, 这是Maple中可执行块的标志, 在“>”后即可输入命令, 结束用“;”(显示输出结果)或者“:”(不显示输出结果). 但是, 值得注意的是, 并不是说Maple的每一行只能执行一句命令, 而是在一个完整的可执行块中健入回车之后, Maple会执行当前执行块中所有命令(可以是若干条命令或者是一段程序). 如果要输入的命令很长, 不能在一行输完, 可以换行输入, 此时换行命令用“shift+Enter”组合键, 而在最后一行加入结束标志“;”或“:”, 也可在非末行尾加符号“\”完成.
! x* G5 f0 a8 Y3 w* oMaple 7有4种输出方式: Maple语言、格式化文本(Character Notation)、固定格式记法(Typeset Notation)、标准数学记法(Standard Math Notation). 通常采用标准数学记法.
( j) _  M5 o% ~Maple会认识一些输入的变量名称, 如希腊字母等. 为了使用方便, 现将希腊字母表罗列如下,输入时只需录入相应的英文,要输入大写希腊字母, 只需把英文首字母大写:   
3 y1 ^* c, H1 [2 j/ D& l" N6 m   ^) m& ^6 v6 s8 o

8 S9 S$ k% {9 @" X  w5 g( c  Q
0 Z4 |) a) Y& ]7 W
! n8 q  P$ s( N1 n; R ' F3 W. x( G3 g0 m6 C4 Q

3 U# D: e. t; X# u$ ~4 W  f
+ Y5 A* P4 G4 ]  p
% z3 h$ y) T# a! F7 |  b ; Z2 e# R. q1 \$ G! Y

/ n- Y7 v7 C. u* c
' D( a, R& w. U3 N0 g 0 ?) J+ m6 A$ H% d9 v1 y2 {$ d6 @
6 Y$ b4 ^3 U, |# O0 v
alpha        beta        gamma        delta        epsilon        zeta        eta        theta        iota        kappa        lambda        mu
  T% X( ^3 j: U4 w ' s7 ~: P3 A- A2 E
3 d) z. a2 I6 R* [2 O

4 I7 @/ U- g: d( p( p
1 s/ [9 @7 h7 t1 f , R7 m$ B2 b: H( K' D6 e

- k8 p, }) i: ^2 d$ H , |0 m& i1 @: m5 Q( E. h

3 a) E* I4 ^6 |' O8 P/ I& ~/ m
/ J! Y# x- u  U7 I3 W4 y8 ]
- o  o$ ~$ }$ ?0 j& R* Q4 {( J* | ( q! Y/ E! W9 e8 j* X* p0 a( t
. i& o9 W7 L/ @! {5 p$ X( V4 |
& k1 }$ e7 ^: I! x
nu        xi        omicron        pi        rho        sigma        tau        upsilon        phi        chi        psi        omega% N  b! g+ s! X3 g$ F+ M! G) \4 q5 l
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:
5 s# K9 A/ n3 n6 w> for i to 10 do ' ~: e# J8 K3 Y  m( C" O% E7 k
printf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));4 V7 E; p& q( A* D* X! p
od;
) z$ L, ~2 f0 W) [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.1629 Y/ B/ S( y3 W' [$ k
+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:$ U& U& u, N% G; W, y2 b
> for i to 10 do
$ Z1 o& R7 B+ `$ {4 G5 Nprintf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));
/ C5 R+ ?& c7 m, ^/ u  j+ L' Yod;
* P2 x4 a/ U: z. k9 ~i=+1 and i^(1/2)=+1.000
2 ~7 |/ K+ Z% [8 O0 f* Vi=+2 and i^(1/2)=+1.414
$ n( b1 G5 C3 Z! D$ c7 E  Y+ `i=+3 and i^(1/2)=+1.732
( E: T. V) R' j0 T1 j+ }i=+4 and i^(1/2)=+2.000+ U8 Z' B3 Q; Q
i=+5 and i^(1/2)=+2.236
( q+ F5 ~; f+ ?% Y2 Pi=+6 and i^(1/2)=+2.449, x" o3 a. P  b; l
i=+7 and i^(1/2)=+2.646
3 _* f* C; J; E8 d5 fi=+8 and i^(1/2)=+2.828
2 f; L5 b  P. w% F6 _( w7 _' Ei=+9 and i^(1/2)=+3.0006 k& K# {/ t& E) L/ n/ F9 x
i=+10 and i^(1/2)=+3.162
; P1 c* K3 n) @+ R" F8 `4 [; y再看下例:将输入的两个数字用特殊形式打印:
$ j: m/ E7 B7 p) H9 f. h: U> niceP:=proc(x,y)
' B% S! ~+ S$ ?$ U8 [printf("value of x=%6.4f, value of y=%6.4f",x,y);
/ Z' U) x" S; ?, V7 ?; e6 q  _/ Qend proc;
( l) I# z- _' P" L - w: ]0 k) @! e$ c4 y
> niceP(2.4,2002.204);
4 N8 Z5 `9 m* Mvalue of x=2.4000, value of y=2002.2040# `5 p. y" b' I# P  X
1.4 Maple联机帮助
) d$ r% \0 h% q- A( X" T: j: P1 i学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用. " C; i% d0 m0 ~
在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可.
& C# A2 S0 p7 L5 d2  Maple的基本运算
# z2 E1 q& v( Y2.1 数值计算问题4 ^" b1 h( v/ k% g
算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”.
- V% J! {0 F( S3 ]: {) s8 z在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之,  是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数. : R8 ?' o* M# t# O! d7 `
Maple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算. 5 c% @1 q2 E% \4 P
但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
0 s/ J7 Y; K! k+ z第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:   
: Q! \5 b8 _6 l: A. a, W& Z4 G> 3!!!;' e# a( n( o3 B! Z) B
2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000# g+ I+ _8 s: o% ~5 s6 o5 ]% K+ c
上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?
9 ~/ ~$ i+ v' s3 a1 L8 Z! y* c为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式
9 f) S" a; f2 q+ d9 h , \* g4 I$ A) n+ y
可得:  , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:   
1 a2 P; G$ I- V& @1 O
& z3 k/ t! ^! A这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性.
3 N- u( r& Y) j" m3 O% D5 A另一个例子则想说明Maple计算的局限性:   ! U: V$ W3 @  A) E5 v
  
. r( ], v6 ?* p* V6 J) m. QMaple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:   ; Z4 Y! |! D! a
( ?( @) n6 a3 _
显然这是错误的. 这一点可以从代数的角度予以分析.   L2 k  H1 {- o8 ~
不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果. , \( F! K7 t) ^3 Y, C/ [
另一方面, 设 , 则 , 即:
% z. x. G/ i3 u% Z/ j
3 T$ j3 X1 C9 Q$ o: K显然 有6个结果, -2、2是其实数结果. + N5 H- U  j  s# \; I& C
这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性.
: D7 S& }8 J- ?5 x尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的. $ P6 n6 H6 U( Y' k
2.1.1 有理数运算
8 M- Z7 v4 j! w3 L作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20).
. J! F6 [1 c! z8 Y& Y> 12!+(7*8^2)-12345/125;
5 P: B$ T5 X' o5 O. G' H
) F# w; T; A% R* Y9 `> 123456789/987654321;
1 F% N- ]( H( n8 }" t! v1 p
& Q% s' T4 Y2 r7 ^8 v. b> evalf(%);
. A$ _! y% w+ t3 z
* r0 i& [/ g2 h7 S, o> 10!; 100*100+1000+10+1; (100+100)*100-9;
5 u5 V! J1 ^9 U! s. Y: i2 J, p- [ ( {: d/ G4 H6 u' O7 @. a
# T+ i: w, o3 k' k# |6 ^: L

5 y/ g% \& q2 _- ~7 K> big_number:=3^(3^3);. n, ~  ^; k' ?
$ Y2 H( b6 H: e, [2 d
> length(%);6 O& n" H* D$ t$ F7 v
; u, S) N/ t# O; M
上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:   
' Y8 j- I& y% W/ w' {    1)整数的余(irem)/商(iquo)/ T. `. R% C0 ~3 @: b
命令格式:   
% s. y+ I- r. M$ Y2 f" J  f9 C7 airem(m,n);        #求m除以n的余数2 A9 r; V- r) Z2 Q' f% p
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q5 u# v4 y- U8 T9 M- |2 P
iquo(m,n);        #求m除以n的商数
, [; A$ Z* S, E: O8 riquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r8 D% {  Y% r2 U* ~% }3 e) {
其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
! T0 h* u7 g' ~; N, J> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
9 T$ c" ?+ r, g7 K9 [ - u% B/ k, Z4 u
> q; #显示q
' B; ^+ k6 |/ Q6 z1 j- b6 ~ + K0 |$ M7 p  \9 f8 D& f! T( ^
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r4 \. H1 O: H8 G# w( q8 r0 H

2 c3 q7 ?9 F) M$ c* \> r; #显示r
7 z! j8 @/ w8 d9 ^* _2 F , H) a& {; l1 e/ O/ h% r* E
> irem(x,3);& d" N7 G7 g3 @* V1 j: {
: Z3 ^) o( P1 a; e# V
2)素数判别(isprime)9 K; M5 H4 D/ A; z: y& \
素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n); 9 x) U+ W/ Q$ A1 X3 ]
    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
* p  c/ u/ |* W> isprime(2^(2^4)+1);
- s# @0 [- q! ?" R& x3 X
, j- P/ [+ c6 {; @2 Y: f> isprime(2^(2^5)+1);
' ~# u3 ~: Q% ]- u  a7 W
' G3 `% D" H, b7 P1 C上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多. . m0 {( B, V+ p3 a  Z( h- q! n
3) 确定第i个素数(ithprime), D5 Y5 N) ?6 N$ B
若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);    ; w; G5 G4 e: Z6 U: p7 ]
> ithprime(2002);
. X1 E+ s1 t3 M: y' ?3 M 5 G- [. u! `0 e: q
> ithprime(10000);
/ |7 o* q6 i0 _! A) p1 i1 C6 a $ B% L  `/ l" N, L/ ~  K
4) 确定下一个较大(nextprime)/较小(prevprime)素数9 I  G2 [; ?* u6 j5 J2 b: i8 ]
当n为整数时,判断比n稍大或稍小的素数的命令格式为:   
. P( Z3 B" d6 a, e. Knextprime(n);  
, b2 `  g9 D4 I1 `. w' pprevprime(n);   Z* M1 H$ V6 ]3 |3 f2 }
> nextprime(2002);
+ X' k' S( C2 D2 Q# h6 E 6 ]. v5 F  K4 H) S, z' V
> prevprime(2002);
- y0 Y' Z- [' X
# _6 l  j. p9 H* p* V5) 一组数的最大值(max)/最小值(min). _' i5 G! ?, Q8 h  G8 M
命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值
7 k  {# c+ Y1 ^1 H: f% j$ K  E5 l             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值. x! U( i6 F, J
> max(1/5,ln(3),9/17,-infinity);
+ n3 D3 z$ V& a' H: P- E ; O. y+ H5 v2 y  w2 x. {
> min(x+1,x+2,y);3 u, P8 |, Q, p6 _0 U
0 c: F% ?  P8 e1 \& q
6)模运算(mod/modp/mods)
% [- b  z% j: y: s命令格式:  e mod m;    # 表达式e对m的整数的模运算
) n. Q8 P- R1 v2 V/ m0 Ymodp(e,m);  # e对正数m的模运算
2 |: v; _# e7 Q  J$ w" b  E+ z+ [mods(e,m);  # e对m负对称数(即 -m)的模运算
2 r: w) G0 U2 u! v; U`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价
" P+ m! i( a2 W' ]5 X+ W值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/.
! F5 }* p8 f) [1 g> 2002 mod 101;
/ U! O% {8 j/ V
* g, ]1 o6 D- P3 l1 G> modp(2002,101);# A- m. {# R6 l0 T, U: z# X4 y. A

% |! c6 G- J3 q# m$ l& Y> mods(49,100);6 m! I, U$ M* \. ~* G

! _6 ^+ {! P* _" @+ e$ U> mods(51,100);2 S/ O5 o# p+ I

0 `! q) M7 Z5 L. k> 2^101 mod 2002;  # 同 2 &^101 mod 2002;3 q7 S/ B5 R( J

4 ?8 I. ?" l" Y* G7)随机数生成器(rand)5 T$ K1 L+ M7 c4 b( p  o
命令格式:   $ v: J* {! ?  m3 L8 U& \
rand( );    #随机返回一个12位数字的非负整数
1 V4 i2 I& h) Y+ H$ K+ s! [rand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数
& L3 K" W. f3 |! g3 W) F> rand();. L8 |' @' t$ y

7 b) @) N( o' f> myproc:=rand(1..2002):
3 n7 T- J1 p9 i- w. m> myproc();
* \5 t2 M) o: s, B
2 ]7 j8 X2 b, }+ |  [: N! `9 M> myproc();
9 q1 c/ z8 i: P& j2 i' C; {7 B8 [ & ]3 T6 F" {6 \0 p1 Q
    注意, rand(n)是rand(0..n-1)的简写形式.  _6 `5 A! L% h. G- Q$ r
2.1.2 复数运算9 Y6 O6 u+ H7 m: b, W& X4 v+ J
复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:   - y  v% d0 O- x5 S, h) v
> complex_number:=(1+2*I)*(3+4*I);
5 g; ~; f) D# J- @6 i + B' x, B0 {: @# s/ _! ^8 |! G  O
> Re(%);Im(%%);conjugate(%%%);argument(complex_number);4 J7 x8 [' o- r

1 g! t/ r$ ~/ S  @ / k7 c0 x3 I$ K8 s4 h
" a* C. x0 q4 ?; q' f3 p) O9 {2 D

6 J7 v6 x( R( q: R* M值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%. 4 x- }# {. m1 y" i
为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:   
" X5 i# w  \* b* l; V1) 绝对值函数
- }' Y! u- W" y命令格式: abs(expr);  
# M& P3 r  G& E( {8 v' M当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.
; v( ~7 o# h) K5 E> abs(-2002);    #常数的绝对值9 n1 S/ ~) G0 T

$ w. X  k$ Q9 r3 F2 b% I; ?> abs(1+2*I);   #复数的模
) H. s8 w0 t" I8 @6 Z3 q / G, O- A* s* t, \6 c3 d0 B
> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值
5 N6 Z! ?9 ], l7 M' t" a
0 A! _3 i5 r+ r> abs(2*x-5);   #函数表达式的绝对值  W5 {( U% ]" i( z

% K+ |9 ?4 V  v- p$ z# M0 T9 @. F2)复数的幅角函数2 a3 Q8 q: P" @! W
命令格式:   argument(x);  #返回复数x的幅角的主值$ Z: R$ a) n, }! u
> argument(6+11*I);
+ m; j. T- P" v$ ^% i6 c8 J . S  E7 l6 p  a- x$ o
> argument(exp(4*Pi/3*I));+ S  R* }7 @0 Q! w' z; F

0 O4 |/ d2 Y1 y: e6 L8 y) h- V3)共轭复数
- f; W: V0 D# q2 i9 ?命令格式:   conjugate(x);  #返回x的共轭复数+ u. b: d9 Q5 m" B5 v1 e/ h: Q$ @
> conjugate(6+8*I);# p/ A  i+ {  i9 D" T* n( [

' \; j/ U& W' m* m; W> conjugate(exp(4*Pi/3*I));
( b" U+ H3 g( b  y! `: O # r3 M  B) ~: }; K+ d
2.1.3 数的进制转换
9 f$ w( c5 [4 b3 v- v! `数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可.
0 L/ w6 A; J* P. h命令格式:   convert(expr, form, arg3, ...);    3 O) a4 o8 R' U* T
其中, expr为任意表达式, form为一名称, arg3, ... 可选项. 5 g# O0 f, M" \9 I1 p) b) t/ z
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述.
9 u: f. ?/ G8 k    1)基数之间的转换) k" C; ?" y( ]! P8 D: n3 d7 G
命令格式:   0 s- j# l1 M/ s# Q- j
convert(n, base, beta);      #将基数为10的数n转换为基数为beta的数
9 Y2 L# d9 B# ~7 {! Z- I: E    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数
( t6 N. l; r. ~$ b+ _> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
3 }7 u* |: w$ J: i
, m  `) ~+ X8 y4 o* X  a4 n> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数
7 O2 e( |/ [2 N2 [
8 d' c) ^5 t% Y> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
" R. H* F! O6 g1 q
. J( ?; ?% c+ R: {) v    2)转换为二进制形式2 s8 ~3 ^& }; A4 ?$ ]) }: c
命令格式: convert(n, binary);
6 ~, c: P- C, U其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂. 3 S* K4 C4 i: o" j+ G
> convert(2002,binary);   8 b8 c+ M- C5 _; g+ V
" W8 a5 f4 Z. ?( K0 W
> convert(-1999,binary);
6 x. @' J4 l" R6 ? ; u0 X0 o9 p) K6 g5 Z* p9 W
> convert(1999.7,binary);
! Q. q4 C8 i' |# \/ v8 @
$ C: j; M# X  n3)转换为十进制形式
; V- r1 ?; Q3 w; s. F0 [其它数值转换为十进制的命令格式为:   
" t4 ^9 s2 Q9 C+ Sconvert(n, decimal, binary);   #将一个2进制数n转换为10进制数6 T: W9 q' h) \1 u
    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数
+ M- |* {) S4 `$ y( x. {- H    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数" X. N# W1 @8 n' v
> convert(11111010010, decimal, binary);    8 f4 x; _& d: A7 M5 V
: _+ V6 ?5 `/ N. P3 W
> convert(-1234, decimal, octal);           
: w; w* S0 b; M) n( z: z
- G" _; T8 n. Y> convert("2A.C", decimal, hex);          $ I2 M6 m- a$ g. J" d, n; M! X
0 {& y1 a# R1 l
4) 转换为16进制数2 W' y6 Y! R$ q$ m" }
将自然数n转换为16进制数的命令格式为: convert(n, hex);   
+ c8 O3 x' O8 O> convert(2002,hex);  convert(1999,hex);
( m+ `4 B/ A- ?$ ^
3 L0 O6 `8 ~1 s7 n
/ J$ w( y5 J$ I+ n9 s- h( I5)转换为浮点数, T6 V' E: C. E$ V% T+ A3 L( j
命令格式: convert(expr, float);
$ i7 _& q( x$ i$ X+ }注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用.
% T1 ?. d6 C! |> convert(1999/2002,float);
3 }, ]/ o' R# r% ]) `
7 [4 F+ M3 {/ ^6 l> convert(Pi,float);
3 K  @% A1 E5 g' J, U+ L( a 3 R- g. f- v. l# K
2.2 初等数学
, H- Y; c6 w' t0 x    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识.
$ N4 p4 H. w5 o4 [* i* ]# E7 Z2.2.1 常用函数/ L+ p$ J0 c3 f% \+ O3 P/ F0 O
作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:   - K! D1 ?4 T+ j$ `3 P
指数函数: exp
. Q! Q6 M  Y0 S7 _一般对数: log[a]
* n; L) U/ S' m( c; ]1 {自然函数: ln
7 l9 m: ?6 t0 |7 w: Q常用对数: log10
+ q" o3 T& R! j" m: k/ w平方根: sqrt/ P$ C  h* [1 A8 h* Q3 H- R
绝对值: abs, j5 j' \8 W# K; ?$ _3 _
三角函数: sin、cos、tan、sec、csc、cot
4 w" t3 B8 R6 V5 }反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot+ A3 y& B: ]+ P* l7 u5 k5 y
双曲函数: sinh、cosh、tanh、sech、csch、coth* q" U+ p# ]- {8 n+ s- t6 L" H3 s
反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth( z8 m0 |6 o+ o$ @
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY
2 t% i! }2 X' G& ^: bGamma函数: GAMMA2 T$ I8 h# S* Q; V5 [8 e. r
误差函数: erf2 z. t9 ]6 Z; p7 s8 U
函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能. , o. ]" p! R5 i& y
1) 确定乘积和不确定乘积
* B: N% Z9 x! f) T命令格式: product(f,k);  1 @0 J0 J6 H( f. ^" d/ H5 v
product(f,k=m..n);  * Q" W# q/ L1 n
product(f,k=alpha); - T# I; O7 h# m5 b. e) M' w' g: f
product(f,k=expr);  }6 v. t' y4 ?* p: f$ P0 f
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式. / k' j% P9 t: U, r. M' l
> product(k^2,k=1..10);   #计算 关于1..10的连乘
2 M/ `9 W! {3 f1 z+ V% W & _' r6 F  K( x8 h' k' |
> product(k^2,k);         #计算 的不确定乘积: P' e- w9 O$ g3 ^
( p% ^6 \5 M" J1 U+ F' k
> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘, c- m4 B6 h6 n9 Y' B

8 [5 I7 v9 D" G# \) t+ d> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘2 d4 f/ n3 A) _1 m. K, i

; `* j* w4 t1 l9 _8 c7 k> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式4 N3 H  F" Z3 I0 D! x; G4 B
# F! o3 o6 u- n4 k* d
> product(k,k=RootOf(x^3-2));     #计算 的三个根的乘积
# C( O0 m$ i- [2 p, r
+ d. o. R: U% _5 A0 X    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:   
( j; F# W- L$ `1 Y5 t8 Z# w: M+ {> product(x+k,k=0..n-1);
% P: g5 \3 l% A7 q4 a) L
2 M/ v/ [7 n* }& |0 d" s- s; Z3 I如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:   
4 U) j: z0 e3 n0 m/ t> mul(x+k,k=0..3);
8 f5 t1 g* e( H6 a) h
3 D$ ^: ^; _; e5 d4 i2)指数函数
! G% V. a$ K( ^4 u: w0 J计算指数函数exp关于x的表达式的命令格式为: exp(x);
) L5 o6 a7 Q- R0 z> exp(1);( s& M& t4 @3 w

' `' |3 ^7 b) |( B& i> evalf(%);* ^; }% W* M  [! U* a* H

/ h$ J/ P2 D# G> exp(1.29+2*I);
6 o, s3 C- R+ |" _5 l- [* \0 i
/ e/ r- Y2 O5 L, g: s( a2 c> evalc(exp(x+I*y));9 C' Z5 g! Q6 N3 Y" C
& O9 X# \. q# s: q* \: I, `
3)确定求和与不确定求和sum
) O3 r8 o9 w2 u, o3 Z命令格式: sum(f,k);  
; I/ E# ~9 _# D& D8 U% R; rsum(f,k=m..n);  
" f4 @! ~% w4 ^/ b$ t8 Xsum(f,k=alpha);
& [' I: J5 e1 ?& e* wsum(f,k=expr);$ H% A/ q0 w: V, I0 _
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式.
, e6 Z/ q7 g# ]8 Z" W7 H% f> Sum(k^2,k=1..n)=sum(k^2,k=1..n);
# v9 B+ G& Q6 h: V+ `) Y * P6 l; C/ Z+ B. v$ j% L
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);, _8 Q4 j- d8 P! n

# D9 n: t' s+ J# M$ x7 e6 f' L> Sum(k^4,k=1..n)=sum(k^4,k=1..n);
, M8 O8 E' x  x% l9 ^6 A6 s 4 l+ q" T* \2 Q* {6 ?
> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);0 B6 Q* `, Z& q2 e5 ~2 M. ~
  ~: ?! o  L8 p
> sum(a[k]*x[k],k=0..n);0 |: w" Y, z# M; p+ _' B" G* g( g

/ f( f* r6 h1 A' k& e$ q5 V8 `> Sum(k/(k+1),k)=sum(k/(k+1),k);( V* A, `% [. H2 z) }( z; C; h$ x

, u" q( A7 s- }- C# c& j> sum(k/(k+1),k=RootOf(x^2-3));
$ F3 h/ \% o9 Z5 h ' ^- ^1 ~- b9 M
sum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的.
8 C: \' k& x5 _2 v' G> Sum('k','k'=0..n)=sum('k','k'=0..n);
3 Y- d* @' h3 ~2 J 5 A. K; d+ K. N; B! h/ O0 n( m
如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:   
5 f1 ~0 a9 E! A1 O$ q5 u> add(k,k=1..100);% P2 K( _' q) c5 l# p

* r9 J0 i0 h: W% C. i2 ]尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令.
% n! ~8 [5 x- p. D/ O另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性.
0 o+ q/ t- K1 e8 |3)三角函数/双曲函数' _, C: U( I; c  n% @) t
命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);1 e( K/ B9 ~. s7 y* Z  m$ G
          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);3 C/ Y( q: G7 u( L' ^: J7 Y
其中, x为任意表达式. " o7 z7 K: u5 Z+ [! {
值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert./ d/ K5 ?3 N1 j. H/ K3 {" T
> Sin(Pi)=sin(Pi);
% \% _4 P( o( F7 U' W 2 T+ ]# o% }# o( @. c  ]; l6 Q
> coth(1.9+2.1*I);
5 w. {" N# q+ Q1 K1 L 7 L2 G) X: |8 u/ {* ^* i7 Z5 |; @+ ^
> expand(sin(x+y));     #展开表达式
$ }9 j2 t$ c6 M, G# E! y: A + @9 `' d1 }$ L/ Q. ^) V- o
> combine(%);        #合并表达式
7 Y8 w2 v2 F2 V$ ] # f# m2 @2 q( f0 l
> convert(sin(7*Pi/60),'radical');* s9 u* N! n& E! j  k

  E2 D- O, A9 W" t> evalf(%);
: |* c2 B, M# k* _2 h 7 Z& E* z  q7 ?2 t
但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力., r+ _: {& R* \) }+ a* o. u, L4 g/ `8 p
4)反三角函数/反双曲函数5 `& H4 d9 d# Q  X9 o  z4 l$ d
命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);
6 L* b8 ?! [& v$ J/ y* _" @2 o4 c     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);   
' i# K! U8 m# L( g* ~$ l( O* barctan(y,x);
; O' D# X1 {6 E8 a/ v! q' Q其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算.
  U' n* I& I8 F: h" q  w算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.
, w4 P9 P$ P9 V; q5 M" d> arcsinh(1);" X, w+ N1 ~+ b. \/ x; H% n
0 w& @: i4 Y# c& A
> cos(arcsin(x));
$ @1 G% m1 P( _6 g9 T+ u8 v* d ) ^% @* w, f* x3 ]) ~0 x
> arcsin(1.9+2.1*I);6 b+ n- V! x+ P" p" N% C6 Y
+ P8 C5 _: d' b/ W$ h5 e
5)对数函数
; \$ v" M/ {- ?; D命令格式: ln(x);           #自然对数7 o' ?3 B- _7 G, q; j/ T! u( `
log[a](x);        #一般对数  `; P1 K; X6 k5 e+ H
log10(x);        #常用对数+ e- F6 }3 T" s
一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:   * f( l# o4 `% P( l% S3 B
  (其中,  )
# H- W( H2 R' F( H' W) G> ln(2002.0);# }3 R* @: v( I( [" e7 f3 e2 ?

7 ^; q( h) w" a; q% P* C" o+ u> ln(3+4*I);
& B' k; f2 |/ T6 h& A0 H$ Z1 h5 _ 9 A' w( T  p7 D9 E( C
> evalc(%);    # 求出上式的实部、虚部
' s$ J; k2 p) G9 q) l
3 p# T' _( b: o- e) p7 _. D> log10(1000000);
0 F, O3 J4 i$ q
0 H  X2 d- j% b7 |) ]" p: S$ }5 c" `> simplify(%);   #化简上式
5 N; f: [5 e" x. e8 q, I. C( e& ?
) j  f4 M! G. b+ |' N2.2.2 函数的定义5 c, X9 P( C8 b
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:   0 L. o; X/ C; b4 R9 k& c
> f(x):=a*x^2+b*x+c;$ @  y& C4 }$ T% ?

1 F$ X2 m3 D8 v3 z: D/ L" p. o* b. J! y可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:   
4 ]; n) \0 n/ ~. U> f(x),f(0),f(1/a);
+ ?6 |# C6 `/ S- }* ~4 I8 k% h2 V& F
/ E# f+ t( l1 L由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:   8 A  z( R& a/ A* N, Q3 a/ F5 `. ~6 q
> print(f);8 a3 s! y$ T4 f+ W

. \! r2 T# U% s% m事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式. 4 a+ B. ~: Q8 O
在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):   2 P: I7 B+ E( V& K
> f:=x->a*x^2+b*x+c;
* o. g" C; Q: a; C* n
5 c6 D! [& `4 y5 E2 v> f(x),f(0),f(1/a);. Z/ j* v  N" M, q) u' T

1 F3 t5 M6 y% m6 B, _多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
1 c5 r+ S# g! A& Y$ \> f:=(x,y)->x^2+y^2;
% P2 Z- p# t6 x) \; @! Z0 @ 0 `: C6 R; ~. g) w' G
> f(1,2);
! q, r( C/ h, N9 c$ D* H
* l0 _! ^, X$ M: `! ~) F> f:=(x,y)->a*x*y*exp(x^2+y^2);
4 X0 |: D5 X9 D1 C* [+ X" f
7 U  v5 R4 k/ f( T0 y: j9 n9 f综上所述, 箭头操作符定义函数的方式一般为:   
- K4 ~& p, L  R一元函数: 参数->函数表达式
* _+ ?$ O: o5 V8 _3 F  x7 T- T多多函数: (参数序列)->函数表达式
/ i* }$ r$ M/ \  i. Y+ r* B  _无参数函数也许不好理解, 但可以用来定义常函数:   $ p) D. e# A0 m% E3 L' ?8 p& V
> E:=()->exp(1);+ z. f0 T8 H0 s% e# |
- K: p- g5 x  y0 y1 L; j( k. m/ \
> E();+ z5 P, R* g; t" O0 D" n
4 T; e3 `  A  Q# p2 a6 j6 e
> E(x);
: I) T$ V+ U+ j5 v. ], ^5 z, E
6 u" `6 G3 O; {' _. }0 ]; w另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数. + f$ }4 k# L  i' k# v" G
定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);          - j2 h+ E: L( H  V
定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);     6 n& ]( T& P  A/ ]% Z, {, w9 s
> f:=unapply(x^4+x^3+x^2+x+1,x);8 N5 f( i8 p- C. S" u

7 I7 q: u! b+ r) Q. S> f(4);2 o/ Z/ a) _# c: s/ g; @6 h4 t

" O. Z7 m3 i8 G3 K5 R4 v" [> f:=unapply(x*y/(x^2+y^2),x,y);9 x7 ~1 `. T; ~7 ?: u% z
+ F9 w9 W7 X3 q' s
> f(1,1);+ Y; ]4 H8 |$ f

; e9 u) n' E2 z, B借助函数piecewise可以生成简单分段函数:
2 E: C: C& P0 m3 r3 z' P5 y# s> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);$ ^2 z6 l& u7 q- M
2 k! _" x# y, Q( c
清除函数的定义用命令unassign.
/ R/ R/ l( ]. i  ]; {" f> unassign(f);; `" j, |1 _9 l8 {3 ?  C- T
> f(1,1);: D9 G4 U/ G( }; Q
/ s) N3 l/ a4 t" d9 b5 J$ `, e' ^
除此之外, 还可以通过程序设计方式定义函数(参见第6章). / b6 ?4 @: t7 I. v7 N6 u
定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:, f5 A% A3 j) k: a
op(expr);            o, b' ~* V# }/ F; P( Z  ?
op(i, expr);         + W# ]$ S# `* T# m) \  M
op(i .. j, expr);      
* i. x3 l5 P; Y+ a4 O5 @nops(expr);
" r6 P/ ~2 A- K* C; b如果函数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的类型. 9 R! F. h9 W- ]4 O) f
命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.
$ R# W$ Y2 L  ?1 I1 q* ?; u: t命令op(expr); 等价于op(1..nops(expr), expr);
# I- E, B$ p+ `: t特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
9 ]! A% U2 A- f而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和.
. |, u' b/ R2 e3 P2 c- L> expr:=6+cos(x)+sin(x)*cos(x)^2;
# E9 n2 `" C$ U: h3 [ / Z* K; b$ ^( ]7 f/ D' I% y, d8 j" }
> op(expr);! d& N4 F2 P; k( @! @* z

8 L& M6 h# U5 F& u5 c( {> nops(expr);
6 F+ ^7 L! I5 r5 {* G3 D5 O1 l# V/ e
7 m' y9 `  j5 z> p:=x^2*y+3*x^3*z+2;
4 b( ^, n& q" N3 P2 c& D* J& E * L, v& m; ^! G1 }( P
> op(1,p);8 a; |& W! W8 F9 {0 a4 ?
3 D# y9 N& X! P3 k* U0 l
> op(1..nops(p),p);" C% j' u5 l2 I) Z% _- g% b

% N& V* P9 Q3 }6 E$ `> op(op(2,p));
( n8 E5 {. i+ i* M% y 1 ?% n, s  |8 N$ S
> u:=[1,4,9];1 Z  ~/ E, x" O" ]

* c9 g" G6 l5 ^; s> op(0,u);5 C. e; h8 N1 m/ R3 Q
- Y1 s6 k: R/ E& T7 K0 ?! {; P! u2 C
> s:=series(sin(x),x=1,3);
) m/ _% O% K5 ^  Z% Z7 J 6 X  v( A5 A; W% H- S0 [
> op(0,s);
" S1 M! @1 n; M& Z0 w; `         8 }$ A) ^# I, H' e( b# g' b6 L
> nops(s);" k2 ?) j5 U8 J. n  z3 J0 E
2 x; Q5 P1 L' u: A5 l
下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:3 D. Z6 `, o  T" a2 L
> op(x*y*z);* ~- d% O5 l7 d, \* M2 s( Z$ c
2 f+ n7 V  K' M/ M! Y! a- Q
> op(x*y*z+1);9 h2 d& K2 y- \4 n3 r* u4 E
  S) ^+ Z! Z" l+ F; _: o& r
2.2.3 Maple中的常量与变量名
. b2 Z" R( N/ v2 @  a. \- z为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:   . O0 Q: l* Y# o+ l
> constants;/ @3 I0 G" r" {# h# i4 D/ H# F; m

7 R8 L, ]& y7 z5 N8 m为了方便使用, 现将上述常数的具体含义列示如下:   
8 J, c2 \1 I  L5 H# V/ T- j常    数        名 称        近似值
' F2 b; Y  r- S2 l: b8 R圆周率
% t+ B) g3 M* v% g; z# FPi        3.1415926535
0 ?, @( Z; j+ RCatalan常数 % T; U: m8 v; h( p$ S
Catalan        0.9159655942
% f2 g% i! L' l. tEuler-Mascheroni常数 ) u4 d9 @1 q" A$ q
gamma        0.5772156649! P6 v; m9 h4 v0 K4 @7 @( V

% B) q( h, N' f: c+ O7 W* N( R6 xinfinity       
3 L2 G: ?: ?" z7 C( p# D1 G7 v. [: @5 n
需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取. $ d! H$ M% C, O$ }
在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”. 3 b1 H: @7 V/ H1 ~  d
值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名. / o  Y) L/ p" M2 h
在Maple中有一些保留字不可以被用作变量名:   : c; C; a( k" `6 @8 b  {
by      do      done     elif     else     end        fi        for      . ~- c' _: }- @1 \! e, ?
from    if       in       local     od     option    options     proc         * j$ M* m3 H5 x5 D& p& L
quit    read     save     stop     then     to        while      D% p4 \6 M3 K2 i" K* d: h. r" p
Maple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名. ; b; P& y" ~: R" _4 X' V
另外一个值得注意的是在Maple中三种类型引号的不同作用:   5 p) n; q, h, U5 R
`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;    7 q# n' g6 K5 j+ Q2 H# I
'  ':   界定一个暂时不求值的表达式;    ' q+ S  y" ?4 Y/ u% ^3 k5 g8 T9 x
"  ":   界定一个字符串, 它不能被赋值. 9 H2 z6 J0 v+ \
2.2.4 函数类型转换           
3 G! \" ~7 ~% b4 ]函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:  
0 {0 I2 }6 P' T    convert(expr, form);        #把数学式expr转换成form的形式
7 v4 G$ b8 N, J4 Gconvert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos( J7 W9 i$ n6 o; r
convert指令所提供的三角函数、指数与函数的转换共有exp等7种:   . O8 z# q/ B- L* `( l+ a
(1) exp: 将三角函数转换成指数! T$ r% J5 ^; A  [- H- L) n8 ?# ?
(2) expln: 把数学式转换成指数与对数
; r! p- z9 {2 D4 f* x; X. q- ?- P6 q(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式) y$ n) G0 N2 W
(4) ln: 将反三角函数转换成对数- c: m8 {, u0 o" P8 \% T( y
(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式* `8 B1 z& K, i/ h# m0 U
(6) tan: 将三角函数转换成tan的形式2 K+ K  v3 U0 v# \5 p% Y- y% k
(7) trig: 将指数函数转换成三角函数与对数函数' D+ i! t7 V2 ^! f: M4 K
> convert(sinh(x),exp);   #将sinh(x)转换成exp类型
! d+ B3 Z1 J- }, j
7 m; n# y" z* H4 |8 n> convert(cos(x)*sinh(y),exp);
2 u% v  z( o& O
# o8 r: O9 b  C, Q! c> convert(cos(x)*sinh(y),exp,y);
$ n6 M: h  B) ~0 |% l
) i+ i6 Q  F, n. a8 z  @" M3 g- z> convert(exp(x)*exp(x^(-2)),trig);
/ k3 ^* V: H) F- P5 m* X, [6 M
9 A# J2 m6 w# h2 N2 n5 l; V> convert(arcsinh(x)*cos(x),expln);
$ a6 a' J* P# C4 M' `
3 d0 I$ Y9 l" A' ^: t  A* k" p3 e> convert(cot(x)+sinh(x),expsincos);, w$ g: e- E; r- k

8 c5 u: M+ ^2 g* C- z. J# v> convert(arctanh(x),ln);
. K( b. |3 ~' `( @) M" p' z# |* { ; W: s* \6 W$ S0 l  ?
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:   
. `4 y/ u2 ^4 q3 P# u- E4 }> with(codegen):' w( K# J3 [; I5 o) }2 d; K+ Q
> p:=4*x^4+3*x^3+2*x^2-x;- c1 X$ e* J- \/ F; G
4 w' j2 M5 K/ Z, G; F2 x
> cost(p);
1 A- E/ K; I% R8 s. p
) s0 [7 U; s8 G0 R> convert(p,'horner');  #将展开的表达式转换成嵌套形式- e5 a5 q  S1 L% ?) C
- B  W- r. E( p3 ^
> cost(%);
# W  v0 \2 P0 h. G+ t+ s% T
) X; M" m( J7 F5 L$ l, `同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量.
% M5 R* J  Z& `  f+ o, s( ?6 R0 P> (1+x+x^2+x^3)/p;) {$ u9 H  f. S% R: [; X

& Z! b1 N2 N! A) \( t/ S> cost(%);
: q  w, ]' v2 n( ?4 u" R$ | 3 A. j7 p! Z, V2 U' d% t- \
> convert(%%,'confrac',x);
2 W; T6 o4 o! {- J; C" f; c0 } & l, l0 k0 f% f- \" H) J8 N
> cost(%);$ b9 d8 F& I0 }& {. q

$ g* S" @! d2 P+ C  v在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式. ( n7 J$ A3 T: x! J* w$ }
> convert(%%, 'parfrac',x);
7 Z) D* r* N. {1 N8 n ) O- p) M( V# `8 D* M4 y% K3 E* q
> cost(%);
3 c. _; i; a1 [& ` / ]; t8 K' f+ V" Y! e" _
而把分数转换成连分数的方法为:# \( y2 L) ^$ H5 D- ?9 T+ _3 m
> with(numtheory):
+ T3 H/ o- q7 X  E! S' [, t3 V> cfrac(339/284);
! N# a7 M- O/ L $ _) G7 j# N% e+ B. y# c
2.2.5 函数的映射—map指令
4 q  k2 _. M$ h  o4 u4 S* G在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:; R! ?$ Y2 R) r2 K& p' a4 Z
map(f, expr);      #将函数f映射到expr的每个操作数
1 x* o, w" U) Z0 ^0 s- f% c9 Nmap(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量
0 Y0 ~4 q/ \* P2 x1 D2 _map(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量5 n" o+ s" C% s
map2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为- I7 W9 }# L- C2 G: z
第3个自变量…, an为第n+1个自变量来映射函数f
7 |% x7 k/ V5 g0 N; A1 m> map(f,x1+x2+x3+x4,a1,a2,a3,a4);% j. x5 @& T1 v/ m% R" J; W
1 E  z! |( c* Z1 K' n; n
> f:=x->sqrt(x)+x^2;7 x) k/ S, |9 `$ h6 a, a

* h# {, i' C0 |' d# k* U, @" o> map(f,[a,b,c]);1 c$ H- P# A5 `$ ]9 e! R1 C) G' |  h

$ y9 B4 P% [) l. p5 [> map(h, [a,b,c],x,y); 9 S" X* z8 `) n* H- J+ ]1 J+ n
0 o0 i' L( m" d* I$ m
> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);
! c( M: z/ y0 a$ D" w
- o8 e; R2 R$ F) w> map(x->convert(x,exp),[sin(x),cos(x)]);
/ x  V7 V+ o; h% p; b7 Y0 f 6 o; F& |9 F8 |+ z' r) `# Q) J
上式的映射关系可通过下式理解:
0 t. v0 w; A* ?' ^0 Y+ r> [convert(sin(x),exp),convert(cos(x),exp)];) \5 O. H4 K! s% y0 g* w- M
  O2 w! `; r4 Q3 ~
> restart: ! E; k+ h; o3 }9 J8 s: h! j# x! t! I
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);
  W* m- f& q' {# I( f) p
" ]" C( I6 {1 g4 w+ K8 @% B/ U> map2(max,k,[a,b,c,d]);
7 _1 K" d0 a6 F# O
# w( l& `7 u* ]7 j' {6 V1 d* t再看下面示例:   8 J4 h2 l/ W- \* k; u  N
> L:=[seq(i,i=1..10)];7 G9 d: p  \' b. H& U
, h; n$ y+ N# n' c' Y
> nops(L);
* o' H8 x7 H9 O# O
1 S& j* S/ I- o4 D2 w" c> sqr:=(x)->x^2;8 v6 p& N! x+ K
8 C% ^& D+ _/ Q( n$ o9 k% r! _  z4 P
> map(sqr,L);
4 R' m# R  C' \% E' j) ?8 s( p 2 O: r  m0 c2 |/ m% b# s
> map((x)->x+1,L);: P1 d! p! ^4 X

7 }3 _4 Y7 T: q7 V> map(f,L);6 M% ], w7 N1 l! n6 l: _2 i, x

" L7 p8 o& _* m8 h* h' ]' S> map(f,{a,b,c});
  D0 d2 X7 D" B- b: ?/ H
2 v) S- M: W1 U& K9 g1 O> map(sqr,x+y*z);
, m5 \6 h+ m* i' X 4 r+ t9 \& p0 [
> M:=linalg[matrix](3,3,(i,j)->i+j);8 W& h: A$ V/ R. I; D

$ g  j: ^0 q# I* q' q9 D8 N- `> map((x)->1/x,M);9 K. e1 F, Y: c7 x" u

3 p- w4 u' Q* W+ ^% \2 Z3 求 值9 o( J" [  x: F& e
3.1 赋值5 \+ g1 D' _  b* ]. Z. Q
在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子.   \% [/ z0 L9 }
> p:=9*x^3-37*x^2+47*x-19;
+ a, U7 I2 q4 r) g; ^% Q : `$ ~$ f) h6 u
> roots(p);
! f, Y+ s* N7 g& B8 N0 h 8 D9 S2 Z; Y% b" E2 @, b7 D9 a
> subs(x=19/9,p);
; a' ^: N% u! }0 p/ Y( k$ e0 `) U 0 y! i: L2 }5 Y) I: ]2 }
在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量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;”这样的简单语句即可验证. 8 v& l( U: ]6 o9 ]* b2 Z
3.2 变量代换2 x' L  F9 P  Y$ |6 S8 [
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:   5 [& `7 F$ [! G! \4 M
subs ( var = repacedment, expression);1 ]! G; q9 D0 `% k* R5 a
调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement. # h3 f/ k, F8 {/ W# R  i
> f:=x^2+exp(x^3)-8;" R  ?- @# ^8 t, w
# M! i0 I5 Z0 x) O* q/ [! }+ b
> subs(x=1,f);
! y# X1 F, a; B& n* ]0 O& F ( y( c  J, ^9 t% M; K
> subs(x=0,cos(x)*(sin(x)+x^2+5));& v* c5 k2 w) R; I" \
& `/ b  C% z9 E9 D" V# g% |
    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:   ( M) `: v6 t/ g; Z5 h
> evalf(%);  g! Y7 L: w, i# ~

& o1 X* G7 c4 y, a6 d4 f9 ?8 L变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:   ' s) f& V8 B2 Q
subs (var1 = repacedment1, var2 = repacedment2, expression)
& n+ C: a  R( e  V0 J  {' _调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:   
2 u+ I( m  n/ s+ Qsubs ( {var1 = repacedment1, var2 = repacedment2 }, expression)
, o, B4 ]. W7 Y7 K2 g下面通过例子说明这几种形式的替换.
& x3 Z" ]0 {) T$ |> subs(x=y,y=z,x^2*y);              (顺序替换), A7 `( I' u& \' I

& u& ?' d1 J5 r# a. l> subs({x=y,y=z},x^2*y);            (同步替换)3 _8 V& |4 E4 n. i; Y
7 F- }( a/ l+ x9 t- q- j
> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)
, O" w( w! K1 h. ?% T
! s4 v# w) D7 U" W, g/ R> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)3 r5 f% [; o6 ~: ~+ F/ Y# j

1 o, x/ P7 i9 T7 m% U> subs({p=q,q=p},f(p,q));             (互  换)
- k, J8 s. r/ m4 P9 s 4 @5 U( j' ^+ _5 b5 g( ?9 M
3.3 假设机制+ N2 P4 Y- m& l  W
Maple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点. 7 n8 [7 D8 }1 o7 z( F5 l
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);, k: U* O& O- o
函数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);”也不会产生矛盾.
: {4 ~+ }$ M: {  M. O> Int(exp(-s*t),t=0..infinity);2 C: _/ U" F5 d$ O0 D

' k4 q$ u! s! w) B6 q  Z1 u/ `' |  D% E1 J> value(%);# K* Q. q+ q9 `# C  G! B( F
Definite integration: Can't determine if the integral is convergent.
) r" u9 @! `+ d9 J9 lNeed to know the sign of --> s1 c0 s5 [0 j3 t
Will now try indefinite integration and then take limits.
3 \3 a% m* y1 O. Y 4 C3 n: g. [- b) k
> assume(s>0);
& |  N( D8 Y; e, E2 K5 z> Int(exp(-s*t),t=0..infinity);
3 ?$ r2 R4 P3 Y8 ]: }. V) x3 Q 2 q3 }) q+ Z; y$ v% p
> value(%);8 C# k& ~1 h" ~+ D; u/ h2 R
2 w2 X# v& x" |. i: z# C& r" L; v
3.4 求值规则
3 e! B4 j3 }+ b, w4 `: H, f在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:   ( w) w/ G) t3 ~5 X4 l, O% `
> x:=y;
( }5 @. n' Z; @3 j9 C ; L4 u9 J( D7 w6 a
> y:=z;; x5 i0 a  n7 p# t

8 e8 B8 C- P7 Q7 a  V> z:=3;" a0 l& J9 t/ g0 k! i

  B& r* F; e/ N% r> x;1 S" K8 d) G  u2 M/ B! H3 X, J2 f, e

4 j- L+ R2 g1 ?" E- x7 _  B> y;/ J+ m/ T% {  i+ f5 L+ x0 T
4 S+ T$ p/ G7 _" t% H% p6 ~) k
> x:='x';
3 R4 Q, z2 Y; y: u - M5 K0 Z* {$ t. ], D6 R  u( n! _4 M
> x;& d$ Z, N; L9 P8 T1 r

9 z# j& C. z$ Y6 y' H> y;
: t" H2 \+ d0 M% H& C# ^0 } + [- n4 `: G$ M% |
对于不同的问题, Maple设计了不同的求值命令. 现分述如下:   ) f( L2 }6 \9 Z: O5 \# p3 Z/ m& P
1) 对表达式求值- ^9 G% B% x" M. b5 x$ ^
命令格式: eval(e, x=a);  #求表达式e在x=a处的值; A. {, N4 c% a9 N4 J9 N6 @$ ]
             eval(e, eqns); #对方程或方程组eqns求值
, ?" q) V4 \. M/ m' P/ p/ ?" Q             eval(e);      #表达式e求值到上面两层" q* J. d0 M3 F% r3 u
             eval(x,n);    #给出求值名称的第n层求值! ?9 |& a& W  X# Q0 ]# s
> p:=x^5+x^4+x^3+x^2+x+73;8 H! x( B0 A$ [/ v8 P: B4 z+ X$ C

- w3 E" ?( g& h+ F7 m' G& ~2 \> eval(p,x=7);
- c+ e# [! L& z
3 q1 O( |9 J# I  b/ a( W' J# N> P:=exp(y)+x*y+exp(x);
6 F1 p7 c0 m' g$ p0 P4 G) v0 B; n
8 S% i3 y4 w. s9 Z$ h> eval(P,[x=2,y=3]);0 R0 d9 a/ T" n6 C4 N$ w& E
. t) d5 _9 U1 M- }- j6 |
    当表达式在异常点处求值时, eval会给一个错误消息. 如下:   
$ B" Q( o% h4 H9 t7 Q> eval(sin(x)/x,x=0);
$ Z% j8 f, F0 f- iError, numeric exception: division by zero) }3 e/ `5 }4 w( d
    下面再看使用eval进行全层求值或者对名称几层求值的示例:   & {: {9 i$ s0 U& a8 \
> a:=b: b:=c: c:=x+1:: H( P; e# B# R+ t5 o- {& L
> a;              #默认的全层递归求值0 d. w; G' a9 p! \

+ ^1 F9 o8 p. i; `% g0 Q> eval(a);        #强制全层递归求值
: b, y! ^; a( R! z% R; Z ) f/ C9 l* B3 y
> eval(a,1);       #对a一层求值: Y9 G- V' O. A
: d! u! p+ E+ W$ C# R) l4 ^' ~! t" _
> eval(a,2);       #对a二层求值
2 O* d  f5 s: T2 ^; X8 } : R5 f( }  [7 z& y, ?) R
> eval(a,3);       #对a三层求值6 Y$ R: x2 H1 U

( X3 ~7 E* C& L2 \, w9 O; b% R> eval(a,4);       #对a四层求值+ I- M& m) N0 z# h1 z

/ _9 O$ j# f5 l! h; e1 Z' E    2) 在代数数(或者函数)域求值( k. C0 I+ Z5 g& _/ {, R
命令格式: evala(expr);       # 对表达式或者未求值函数求值
& u9 ~( N- w$ J* p, O             evala(expr,opts);   #求值时可加选项(opts)! ?, X6 u6 B" L7 U' s9 I% L
所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式. 5 K- o" D* Z: e! Y! Z
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:   
7 J' x6 ^* I2 {4 g) r$ b> alpha:=RootOf(x^2-3,x);: U) \8 x" d8 D: O# ^7 h9 s" B

9 F4 a( V  l5 ]2 c> simplify(alpha^2);
/ G" C! j' q, ?9 [
2 c0 Y- [1 p2 |: V在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:; W/ h4 T/ r2 N9 Z
> alias(alpha=RootOf(x^2-2)):
; N* t. A8 U0 Z! W0 }> evala(factor(x^2-2,alpha),lenstra);9 w+ s7 C- B8 D1 K
* E- `$ z- O6 N5 E6 A
> evala(quo(x^2-x+3,x-alpha,x,'r')); & K; _2 V# W5 k$ V- y: l- i  B( G2 m
" M9 I5 v/ Q2 H( r$ G! F$ \1 V3 q
> r;6 Q6 F3 [( ?' A! s4 G( z% W1 d( }9 v

* m8 ~  o/ J5 ^' S2 K8 M> simplify(%);# k$ I) y  X7 [

7 H5 g9 W, H& R. B3) 在复数域上符号求值
" y) q) f! p4 Q0 J, K2 f操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
$ V8 {' s9 T5 v- p, M6 e3 r# Xevalc(expr);   7 \$ @6 ?4 m! W2 }, M
evalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
3 n7 t  a, b8 V> evalc(sin(6+8*I));8 N8 z1 L( O5 W7 V. s, |

3 h* P  r) g) @> evalc(f(exp(alpha+x*I)));; L8 R& @$ e1 E* q+ [% c( Z& a
+ b% ]4 V. u  I1 o; _0 Q" L; o
> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));5 L. M0 T# [7 }7 t* U! `# z8 Y

7 D" i4 H2 v% [! a6 J# B4) 使用浮点算法求值" F2 g- \0 C  _( F6 M
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);     ( f% x* F% R) l8 u0 o
> evalf(Pi,50);   
. s5 V, ~! w( L) `: p . p& c- w( ^' z& L3 z. k8 w' L
> evalf(sin(3+4*I));     F; C. W, `% p
3 O  P2 a1 j* ?' n6 ]+ a
> evalf(int(sin(x)/x,x=0..1),20);; X, ^" T$ e8 U; B% {3 Q

3 {$ v4 D7 c8 n% A, Z2 o# s2 l5) 对惰性函数求值/ L: i' A, P2 q; ]6 B1 \, t
把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);   . ^# D: _) w# |% H2 A: I3 D
> F:=Int(exp(x),x);/ U9 y. {' T4 M/ u1 b

* G2 @1 j8 }) [  M7 Y> value(%);
7 J1 g8 ~5 ]" U1 W6 n- L
# d2 j# }2 N7 l+ a9 |> f:=Limit(sin(x)/x,x=0);
& O+ c+ X+ ^( Y# u6 \" w. m
: w* J6 Y; U+ h! v, e> value(%);4 i0 K+ K1 a+ y& b7 D. X: b; ~. E

7 J- r0 _; d& ~9 L& ~8 S% K' X另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:   
+ V, ?. {& d4 J" s0 c> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);9 Q+ J0 s" `4 X) t% ?
$ L. C0 k  Y. Z
4 数据结构+ F( J: Z9 J- j6 l- I$ D
Maple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
% ]7 |) K% a$ a4.1 数据类型查询* f+ U1 y* g  y! O2 J7 H
在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为: . A+ K* E$ A# R  P+ m! C: x4 }9 ]
whattype(expr)        # 查询expr的数据类型
8 j7 V6 D) m8 Ctype(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false
* J8 [# j- i) o> whattype(12);
# Q% A; B: X+ M6 q3 ~% [   @, y0 H  x7 E9 }) i' o+ s
> whattype(Pi);
3 ?! S  s' U$ z+ q' r 2 m; N) |( @. C- x5 _  F& r9 m
> type(1.1,fraction);
' Q5 I) \2 x6 ^ - u2 N3 k3 w$ g- g0 S5 S# o/ |7 e
> whattype(1.1);5 J- W2 X+ z3 I9 C& c0 J* [# c
6 a! f  P$ Y/ E3 \7 q! C
4.2 序列, 列表和集合2 X2 E& V6 B! Z1 P, \& b- r- }
4.2.1 序列4 E9 T* b! ~$ a' o  O( z. R
所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:   & r6 E+ G5 x5 c/ k# F8 X0 L
> s:=1,4,9,16,25;2 _1 O( g# O' M- R
- ^& d: y/ d- H3 T  g- J
> t:=sin,com,tan,cot;. h5 G7 n0 `5 V5 I# w: Z! T  s; m5 l: j

* Z+ r/ a& @1 ]2 [一个序列也可以由若干个序列复合而成, 如:   ( @4 {4 Y' [& }2 b  h
> s:=1,(4,9,16),25;# K" a6 O6 q& C& ^& {& K+ s7 d

3 ?% G7 G; x3 p; w. w" @> s,s;
, K, d9 b# h( v2 a4 _2 Y* k; n
$ U8 l& V1 [% I" e: T4 o; S而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:   
- I$ _2 n0 }% K- p: P; S> max(s);
* [7 ]- v. N1 q# y; S / j$ w/ r2 a  b; H, a$ W
> min(s,0,s);5 j% F( Y$ a/ H: [
' c  D* S6 z4 M9 p3 |
值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中. ! N5 ]5 S; [' ?/ V; y
> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;
: I3 c4 O* g+ a, x & e# ?. t% g& v! V" G6 T9 t
> op(s);
8 `0 ~4 m) D  sError, wrong number (or type) of parameters in function op
4 `7 u! l9 C7 K/ R* L. p3 a7 l> nops(s);
0 u9 V2 n" `" ]9 c6 Q: ?Error, wrong number (or type) of parameters in function nops
8 @0 y% t9 m; M1 `! m2 J> op([s]);
( S+ v% S) {( y& l3 `) V& T! E 6 ]' p2 n6 b0 I+ p, W# D+ S2 `0 W+ S4 z
> nops([stuff]);
8 ^0 ?9 Y) I; k4 h/ C$ ^ 4 r; [9 }2 B1 [6 ~
函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:   : ~2 k, b! ^0 Z  R3 U1 c! F
seq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)
3 U- F+ @3 _% o% }1 r, vseq(f(i), i=expr);  # 生成一个f映射expr操作数的序列6 ?/ X! d( ]9 Y3 V/ T8 [
seq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列
0 h" ]' l* |( A7 G6 A; q  n> seq(i^2,i=1..10);
: F5 S. Q7 g2 V: ]" U  y   ^  ^5 t2 d9 h# h. W5 m1 P  h- N
> seq(ithprime(i),i=1..20);3 J1 w# m4 @" g1 @& Y8 O( ~* c

& i8 r$ w6 @& p& j4 X> seq(i^3,i=x+y+z);
' G" Q/ A' m/ s  @4 w7 d8 t) u, q9 Z 5 j8 p2 L* Y# Z/ b: V
> seq(D(f),f=[sin,cos,tan,cot]);
0 V+ f9 _- c" U & S, i0 Q5 O) z  r
> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));% U! o( k: A# u, L2 s
' c. q  m+ r2 m: e7 G" f' l, X
获得一个序列中的特定元素选用操作符[  ], 如:   ; v- C8 d2 K: s9 B- Q% Z% o
> seq(ithprime(i),i=1..20);3 I( G3 R' H0 M/ T$ w
! n6 y4 q8 {& Y  C" P
> %[6],%[17];
6 b* V* y, p  @: M; ^ $ O' T  j3 s1 h, G( }
4.2.2 列表9 b* _1 r# C. i% z
列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:   
0 P' ]" h+ W  F( I: K1 t6 J> l:=[x,1,1-z,x];
4 k' u4 j# y- h0 Y) R( G
4 K; n7 d4 Z; e" p  q5 M> whattype(%);
3 d+ R" h, `. A. F1 s
7 H  H; ], L- `+ z9 p/ O空列表定义为[ ].
- l& A: G; K+ G: b但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:   
. w0 c" E3 {2 @4 M8 I4 ]> L:=[1,2,3,4];
- F' N0 l, m4 J
- ?, E, n: w7 u5 i# U- f$ h> M:=[2,3,4,1];
. ^. j: k: O% I! n
' i( V( S% B7 }) w" y+ L" D$ u$ A4.2.3 集合
0 t, Z+ j4 I( Q  t5 g集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合. + t, k* Y  `2 D8 ~
> s:={x,1,1-z,x};. ?' S8 g; O4 h' _

' i$ Z4 V4 R  z) ^> whattype(%);& s5 x1 m; j9 h* o! N/ R

0 @# b# n: G6 I5 P; C2 J空集定义为{ }.
2 z! D: G6 U, `% j/ J' \函数nop返回列表或集合的元素数, 而op则可返回其第I个元素.
2 @1 g* R6 I7 F/ W) }" f+ s> op(1,s);  R5 d0 g3 s4 g7 ]/ U
4 H3 Q6 \+ P6 i8 J3 K
> s[1];
1 G& Y3 Y6 F. S% F
% g1 L7 |5 W$ L& A6 Y> op(1..3,s);
4 X: S& u9 W! `$ P0 J * ?% q: L, x- C: t4 B; F
> s[1..3];8 z  R) L" h# P! y- r, j

* e/ g. p9 b4 T! ?8 J) y' `函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false. 7 P1 G# b# x; ]8 Y  h+ D' e
> member(1+x,s);7 J9 x. S) U  o2 d& w' p$ q
8 c! t5 b, y/ k" r1 |
可以通过下述方法在列表中增减元素:   / z" |+ K: Z) M2 x2 N
> t:=[op(s),x];
2 _& w) Z2 G- U; L+ ^& _
+ F) X  z$ a2 S' r; R6 E> u:=[s[1..5],s[7..nops(s)]];
  E$ ~5 \  S" K8 M# o6 i
. U7 k' O" A: S% V' yMaple中集合的基本运算有交(intersect)、并(union)、差(minus):   
8 e' e% a5 w9 H> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};( s/ [' z* t2 o0 |

6 B3 t/ X( q9 [* F1 H , R0 c* f6 C9 w8 w+ r* b. @
> A intersect B; + G! L' _6 o! M7 o8 ^
) L0 ?/ y4 J1 v- d: v- f: L; E) t- d
> A union B;
5 ^2 y' ?1 a9 d  ` - r* L3 f) x! `/ @% B
> A minus B;
* z4 E$ _7 ?. W0 ]9 D
( k7 C& A$ P6 T! _1 d4.3 数组和表: B; U# ^6 o( v& M' n( n, a
在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令. ! A, m2 S! u' B" _3 E3 u
    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的.   M+ P& O) @9 H: p  d
> A:=array(1..4);( e* D- ~, Y1 E. A1 n
3 q2 J6 [: A' c6 ], N9 u1 M
> for i from 1 to 4 do A[i]:=i: od:! D: F: x9 l( B% j5 B% W
> eval(A);
. F/ d0 _' w; ]0 F- H $ Z! A4 E" B, X, z3 e! m5 P7 _% S
> type(A,array);
2 K+ y/ R3 Q, f  d: l
! a4 b0 J4 l# y3 ^% j) F> type(A,list);/ C6 u; V( c8 M5 k0 N$ ]* _

$ e$ J# }7 o$ l: ^$ w6 X, P> T:=table();' T5 K9 `" [; X$ J0 t* |
  O) @/ S9 R* Y# J- v; d
> T[1]:= 1;
8 Z( ~4 v4 G8 F% ~: Q  @
+ q: B' |' \: `5 A& Z> T[5]:= 5;
4 K# I0 J- \/ v* P  n% w; _& U , ^, H; c  g' I0 b$ q3 j
> T[3]:= 3;4 L" c' _- T; H, r
1 V  l" N5 {4 p) M% ~0 m
> T[sam]:=sally;# v$ ^* ]; G. Z$ V3 n9 q

  I* W5 q( R* f8 Y6 {$ e> T[Pi]:=exp(1);
) a% K9 u3 g# O0 C/ p
' B; N$ C( W# N> x:='x';: N8 j! @  ^7 }/ V; Q" Y3 A
1 y/ r& M9 f$ A/ Y. {* O
> T[(1+x+x^3)*sin(x)] := 0;
& P( E. }0 e6 z. B/ H8 q6 {2 j
  X% s; I2 c% U) r# ~# B1 F> eval(T);! K5 m/ q2 B! w" H  b) ]* P

% p% J  B9 q7 _) C8 ?2 b> T[3]:='T[3]';$ P3 P% l0 [& ^  G/ v9 H

8 j) _4 `5 K6 A8 K> eval(T);$ s; {- A, z: }0 d  t4 B: ?
" ?- F6 P9 e* M# ^' |, l2 Z
4.4 其他数据结构
- E  J, X) @; V$ Q3 l串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来.
0 ?6 P! B5 x5 y) o9 k索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立. : D  {8 y) Z6 M5 _
> x:=T[3];
; K2 L/ \7 D9 ?* G, Y
5 m: R1 {' j9 }8 d( @> eval(T);
9 L8 ~" q( F6 p2 F% ^ . Z8 C( g; U  a  c
> T[5]:=y;
% S; c: B+ L7 \* k
6 o; k3 F7 U. L1 h3 m> eval(T);
) \! i; a& J& {, h: k ' `, Z7 _. T" d0 }& S7 S
由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.     
# ^8 Y) X. P- ^8 d, S$ ?& j+ O4 ?9 x数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数.
* e$ R, A2 A- X, I; Z4.5 数据类型转换和合并
# w/ b- d2 Z2 t, j& |convert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:   
$ ?* l6 F* I5 a- Z' p! }> L:=[1,2,3,4];! {3 n9 m+ ]/ l- m) I. s3 ]

5 _% ~/ [$ W. f% H4 h& @. y> type(L,list);
% u9 x1 Q4 [, E5 n9 w. ^4 @
4 G4 r* P" I- B5 a* t> A:=convert(L,array);3 e7 Y! A1 q. l2 {" Z( Y

* P5 h0 I$ ]6 k0 E* M> type(A,list);. `) ~6 ?' S9 G4 O% c# B

* Q6 Q6 p5 a: d) O: M; W" e$ C- @- K> type(A,array);
3 Z7 u- H4 T3 b" C9 _% l
, H5 ^0 y1 j1 r( R另一个有用的函数zip则可把两个列表或向量合并:   
" E' w; z& o8 J9 x4 k' _( h>L:=[seq(i,i=1..10)];0 I9 P2 X# u$ R6 D. u, k" P
, g) g9 J  w" A
> Sqr:=(x)->x^2;
- [" f2 Z( E/ t2 F, f # N# ]# m4 |( Y+ K7 a" U' ~: q4 P! f
> M:=map(sqr,L);
) m8 X- X7 h( K# W$ t& b   {  f/ Z7 P  g1 W, k0 c( O# N
> LM:=zip((x,y)->[x,y],L,M);- o) k; {8 M( h% c. b
7 g) t+ o/ V* b: W
> map(op,LM);3 k) _% T! @0 S4 V; N* |

8 k! A8 A& X0 |5 P  `; w5 Maple高级输入与输出操作
2 L. w) E" d* @8 }2 f. |+ @4 U8 ~Maple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里. $ V  y' F4 X* z1 K
5.1 写入文件/ h! C$ F; o& v9 O
5.1.1 将数值数据写入到一个文件/ y/ V  ~; n4 k! M) Q8 S# d6 S
如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令.
4 y  o0 ~6 i4 d若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);
3 k3 ]% p$ U3 Y- r3 y4 N> with(linalg):
0 _8 |1 Z$ d# x7 ?7 }> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);8 ~9 l/ v1 ]+ B
3 m% \" S1 `% `* B; p6 H  |
> writedata("e:\\filename.txt",M);
. h4 z4 k8 r2 t8 Y4 `而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);, r1 B* l7 T1 ?6 u
> W:=matrix(2,2,[1,2,3,4]);% p) D/ V5 F' l0 c
6 \. d( o2 x- d9 P' R
> writedata[APPEND]("e:\\filename.txt",W);2 @0 r. O5 q1 M! Q! h
需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.0 I+ O6 c5 T+ X: N) r+ l9 R
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);4 \! y/ }( Q# u. A: Z1 g/ p# t6 w
> writedata[APPEND]("e:\\filename.txt",W); : x5 M8 W  z5 ?
> writedata('terminal',M);
# E" q0 l1 v+ _; e' T- A& P1                   2                   3           
; \7 y8 f* m! \2 e# }: l) X4                   5                   6           % l) e& n  m% \
7                   8                   9    6 I& m6 ~0 O! ?, U- {/ E5 y
5.1.2 将Maple语句写入一个文件
5 }) U7 m* q7 X3 ~  X! Y6 t  P如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:( T% s+ ~, A; R6 Y1 n0 \
save name, "filename";" B$ q( o$ Q) R" L5 [
save name1, name2, …, "filename";
- {$ c5 C2 X6 W, n" Y若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.
& _' h0 u* K% X/ V: I> myfunc:=(k,n)->sum(x^k/k!,x=1..n);8 L8 r1 l8 T8 H( C  J, G

) n6 S3 J! k/ N> myresult:=myfunc(6,8);  s# ]; c8 C8 ^1 a4 V

$ g( ?/ q0 f  p1 }, t  _- w; s> save myfunc,myresult,"e:\\test.m";8 J% X! c4 ^1 q) k6 V: H! [
调用已存m文件用命令read. 试看下述实验:
% {9 X3 ^  b5 m" A> restart:
# P# W! x0 P+ ~- P& d% X> myfunc(6,8);
, B9 I1 ?  M) C4 P
0 e  e3 Y4 B' O& l> read "e:\\test.m";
) e$ f% v. E. z: w5 Q5 A> myfunc(6,8);2 V, ^7 `* X* @# W& Y
" s; r  T& M4 |( A9 n+ }8 k
> myresult;: a. C/ q/ r  n" |: M, W
- J) Q1 @+ M/ g
    而存为txt文件时则将整个语句存为一个文件:& a7 J; w/ R% |- W$ E4 K3 S6 X1 {$ f4 X
> save myfunc,myresult,"e:\\test.txt";; w+ w' h; D4 ?
> restart: read"e:\\test.txt";
4 C: g/ }  V/ j# b % g% P4 e, D( D. d6 ~/ E$ q: P

$ C$ N& r/ K  c. Z( i. F5.2 读取文件
. h  O5 W" a1 G( c5 x! x6 J2 C* z- H在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.3 z  B3 F2 l- P; s$ p4 Z
5.2.1 读取数值数据
- V. k5 F# _0 x: \$ b( z/ h- k如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.
& }. j8 F2 z3 v+ z从filename文件里读取n行数据时使用命令: readdata("filename",n);
: o. ?: |0 R* o  ~) j以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);
: v( }. B& C4 g0 J> readdata("e:\\filename.txt",3);
7 e- H! v9 O; w, Q; W8 k
& e, L* W( N2 y7 U    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:
3 |1 S9 {8 h% T9 v# [: j> readdata("e:\\filename.txt",[integer,float,float]);  x0 N5 [2 _* a' i
5 }" D' s  K( g0 T, V( b
下面再看一个运用大量的实验数据在Maple环境绘图的实验:/ d0 `% v1 z# j2 `0 y" a
> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:
. |  c% r7 O/ I; t" K+ z> writedata("e:\\data.txt",evalf(mypts));
8 w. L+ \+ x, e> dots:=readdata("e:\\data.txt",100):% G2 w# r5 v% i3 O& G
> nops(dots);. @9 j7 H. O) Y/ ^
) q$ P  `! O$ j8 h/ w
> dots[1..4];/ f7 y" L/ s: S: y. A& p" X

' E) f: x7 K8 \; R! w' r  i: J4 |> plot(dots,style=line);0 x1 V, @( U/ C* v3 O! s' O9 L- A" f

  B2 \: i- R! i  d- \9 x# M7 V7 @2 s5.2.2 读取Maple的指令
7 D0 S. Q5 V3 Q( m7 Y在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:( r( a9 W/ P9 Y% b5 R; |# x
read "filename";  H5 S1 {& _/ E6 L+ w' f7 o; _
如下例:# K$ N) A% g3 p5 F$ s, g( ?6 L3 }' l
> reatart:: ?' H6 K' Y! A+ z8 i) y7 @
> myfunc:=(a::list)->add(i,i=a);% j& i( R% w- q+ ^1 ~- c
) b& c* |# d* u3 i; e# n
> avg:=(a::list)->myfunc(a)/nops(a);# t2 b& a2 p1 W1 H2 D3 e

" [8 ]% q0 V: K: d- P) u7 D$ U> save myfunc,avg,"e:\\function.m";
; f' r5 @7 K) f  s( @* R1 S> restart:
3 w5 M5 n& N/ a9 C( h' W> read "e:\\function.m";4 s) ^  X8 x* G
> myfunc([1,2,3,4,5,6,7,8,9]);
. Z5 c( v) j, W/ \9 p
% i0 M  C- X  W4 `& t> avg([1,2,3,4,5,6,7,8,9]);! `  |/ k# j) d* m* b  \5 i/ [  h
' s  I; d. {  }8 {
5.3 与其它程序语言的连接- J" D8 A" D, n5 a& b; t
5.3.1 转换成FORTRAN或C语言2 @& f9 T5 x8 X$ H: r
调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:6 B) ?' {2 V1 `. ]
> with(codegen,fortran):
; q1 W, f' I: l2 r) m8 a0 p+ hf:= 1-2*x+3*x^2-2*x^3+x^4;/ U, S- }! ~3 s! K3 A/ l: e- h1 h

/ s5 C) {9 D# j; B- Q> fortran(%);$ S- Z2 B, ]& o& C6 I/ P9 d
      t0 = 1-2*x+3*x**2-2*x**3+x**47 C% E8 k- M* _& L7 X# v
> fortran(f,optimized);) S" D- e$ w0 F0 c5 z- Y
      t2 = x**2
  ^. Z& |  b5 t' W1 V; }      t6 = t2**2! z8 `: Y7 o- h( p& u
      t7 = 1-2*x+3*t2-2*t2*x+t6
. v6 t6 _5 R7 @* {> fortran(convert(f,horner,x));
2 H+ ]* f- I6 f6 @, J      t0 = 1+(-2+(3+(-2+x)*x)*x)*x
# L6 v- _) o* b4 a% @) X而codegen程序包中的C命令可以把Maple结果转换成C语言格式:
& g, }) w! K) r> with(codegen,C):
0 H3 X& s$ q  w+ yf:=1-x/2+3*x^2-x^3+x^4;4 \8 _4 l) p% i

& c6 }- G. N$ u/ u5 W> C(f);
/ E% ?) D. }0 m8 c      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;
0 J, f# R, g) ^1 B) g> C(f,optimized);- L2 r% n9 @) G. |
      t2 = x*x;
7 m4 X! m$ t$ v+ D1 c      t5 = t2*t2;  b/ O) L7 w3 d* ]$ a, w" X
      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
; w$ e8 \- s! }7 C0 ~( y4 Joptimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.
$ Y% f1 n: d) X7 c) ]$ t6 _5.3.2 生成LATEX, T0 |( @: v, w8 N8 [2 x$ i
Maple可以把它的表达式转换成LATEX, 使用latex命令即可:
8 Y( q+ I% D" G( v* l> latex(x^2+y^2=z^2);5 M5 v3 l0 U- B4 \  t4 v% {
{x}^{2}+{y}^{2}={z}^{2}5 F8 {$ }' a6 I' \6 c; r
    还可以将转换结果存为一个文件(LatexFile):/ G) R6 y3 b9 `! G$ O+ W' l' Q
> latex(x^2 + y^2 = z^2, LatexFile);, L, O8 J' z# `, G' T; e
    再如下例:) {7 w4 g! M9 O- I4 }, _
> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));
* d" P: ?! Z3 [  p\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)
- G- C" o! }: b+ n- m& E7 I, ]  E+ Y' N, c) ?

作者: 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年!
; P0 i0 R9 c3 F) D* `
* Q; h- p8 |& `4 i
8 d9 W6 F+ i' i" f
作者: wangbutian    时间: 2012-6-14 11:53
正如2楼所言,弄成一个word文档阅读起来也好些,不是吗?
作者: 边缘d无奈    时间: 2012-7-24 20:38
顶一下~~~~~~~~~~
作者: 独守一座空城    时间: 2015-9-15 15:25
lz这样看很累人的啊。建议换成一个文档形式的。
1 H4 Z6 ?# v% X; c* D( r% c




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