数学建模社区-数学中国

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

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

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

9 s/ b; }8 |* a/ U+ U( I . K' ]9 j) M7 p6 a, x
4 n7 P+ C4 O% S
! _1 r' M9 c' Y2 R% q0 R9 o4 j  G

+ p7 J  R0 b- \4 ~6 a
6 e7 j8 G" s6 ~- [+ w: @+ ~
4 ?3 m, J& W) d; K; y7 h8 N$ a
0 Z& f: }$ y% M1 r3 ^
0 `2 Z  [7 c$ m5 F5 c# q
6 H! E* N) |, j# l/ [: n 6 s- X2 X9 ?' I5 j4 {( t# i
  y3 O' W; ?" T5 @4 A
alpha        beta        gamma        delta        epsilon        zeta        eta        theta        iota        kappa        lambda        mu1 ^3 E  O' Z3 {$ f. s4 s. w! }
- ~( p3 k9 K2 x" d! g
- Z: k* z- n4 ?
, @( W& h( w: t- ]

% \2 L! d* \9 S1 k) Y# y: }$ Z! @ # T# @8 t, g0 m9 e& `
0 v, Q; _! O8 e) D! n6 Q) C* R
& c) n8 g# m8 b  N& R- L
5 y; U3 x( u# n4 |
- R! |) ]" B6 u. m7 |6 E, b9 v
; W; t+ ]6 p, Y( {3 H" x7 @
( F" ]3 e7 b5 H4 g. j  C! l

2 J5 x2 C* Z& G8 [4 A- R$ ]1 {6 X' P
nu        xi        omicron        pi        rho        sigma        tau        upsilon        phi        chi        psi        omega* b4 Y4 c6 l  B6 W6 }
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:$ S* o! F, O0 w: ]" ?' y2 X
> for i to 10 do
) K: X% M. g+ I; Wprintf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));2 g8 p: u1 d% V8 x
od;
& @$ h* t4 f$ `i=+1 and i^(1/2)=+1.000i=+2 and i^(1/2)=+1.414i=+3 and i^(1/2)=+1.732i=+4 and i^(1/2)=+2.000i=+5 and i^(1/2)=+2.236i=+6 and i^(1/2)=+2.449i=+7 and i^(1/2)=+2.646i=+8 and i^(1/2)=+2.828i=+9 and i^(1/2)=+3.000i=+10 and i^(1/2)=+3.162
/ I2 k' A" W7 N$ V/ Z" N+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:
. T+ K' Y' g8 U7 l> for i to 10 do 1 j/ D, @% G* @( Y0 Z4 i4 \
printf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));
) j( ~) N9 D% \$ _+ u) [od;
9 i1 e4 _+ ]7 n. z  _: pi=+1 and i^(1/2)=+1.000
" o7 t: E+ u' }5 B  T& Y% C6 L8 h) Zi=+2 and i^(1/2)=+1.414" F4 a$ t# e2 {1 H) m" n1 O, d
i=+3 and i^(1/2)=+1.732( _1 N/ a  m) S. D+ }. |2 H
i=+4 and i^(1/2)=+2.000$ @% ^5 F$ y# `1 Q  x
i=+5 and i^(1/2)=+2.236
$ Y. E% \, z" z) {, U4 N1 b: Li=+6 and i^(1/2)=+2.449
5 C- w: B. U3 b7 Yi=+7 and i^(1/2)=+2.646
% _) [8 t4 b9 Ji=+8 and i^(1/2)=+2.828% n9 n# a5 D$ t6 ?: I$ Q
i=+9 and i^(1/2)=+3.000# Q* M6 A! Z$ o2 U0 ]
i=+10 and i^(1/2)=+3.162
' [* @1 P3 K: A: e) W  f: [: b  T再看下例:将输入的两个数字用特殊形式打印:
( S6 j4 I% Y8 y) N, v( o( p5 K> niceP:=proc(x,y)
9 R9 p2 b9 |2 e6 ~$ |) [- O7 z: xprintf("value of x=%6.4f, value of y=%6.4f",x,y);
# s( p9 {3 t( y$ v2 x" @% T" O2 Tend proc;; }; p1 ~( q; W' J% b

, ^# H' t" x- B, P' m> niceP(2.4,2002.204);
; v( Y; z. l4 X' |* x4 v& |- kvalue of x=2.4000, value of y=2002.2040
2 t' C2 z  D# f- }1.4 Maple联机帮助
6 Z) u. s* x8 d- x: o6 M/ H学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用. + i( f3 N) Z8 v- H$ w2 J7 _7 L
在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可. ' `5 z# B$ b. [9 l6 \
2  Maple的基本运算" k$ D" L5 r' l3 F0 c1 k' A" ~
2.1 数值计算问题: b. ?4 W# M: V* e1 m' d
算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”.
, R( g+ R- I4 Z- w' Z! D6 y在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之,  是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数.
; L$ i2 B! S' @. vMaple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算. . q" \% S! `& N2 G6 ?. h
但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
2 h4 Y5 f9 n8 T8 f0 s第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:   
% z1 O. H* l1 W! R> 3!!!;! z' h( I: [( ?  l
26012189435657951002049032270810436111915218750169457857275418378508356311569473822406785779581304570826199205758922472595366415651620520158737919845877408325291052446903888118841237643411919510455053466586162432719401971139098455367272785370993456298555867193697740700037004307837589974206767840169672078462806292290321071616698672605489884455142571939854994489395944960640451323621402659861930732493697704776060676806701764916694030348199618814556251955925669188308255149429475965372748456246288242345265977897377408964665539924359287862125159674832209760295056966999272846705637471375330192483135870761254126834158601294475660114554207495899525635430682886346310849656506827715529962567908452357025521862223581300167008345234432368219357931847019565107297818043541738905607274280485839959197290217266122912984205160675790362323376994539641914751755675576953922338030568253085999774416757843528159134613403946049012695420288383471013637338244845066600933484844407119312925376946573543373757247722301815340326471775319845373414786743270484579837866187032574059389242157096959946305575210632032634932092207383209233563099232675044017017605720260108292880423356066430898887102973807975780130560495763428386830571906622052911748225105366977566030295740433879834715185526028053338663571391010463364197690973974322859942198370469791099563033896046758898657957111765666700391567481531159439800436253993997312030664906013253113047190288984918562037666691644687911252491937544258458950003115616829743046411425380748972817233759553806617198014046779356147936352662656833395097600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002 h  \( I( {# v* }: `6 i# ?: J
上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?
. J8 G& r" R5 t; P9 o4 ?" U: y为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式
1 q% C: V% ^5 F* W' }6 Q7 r , [8 c/ Q6 q7 g. w
可得:  , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:   : l2 S' s6 W! p+ `# |0 Q

. B8 o, I& f' P* E( T/ u这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性. 2 g: W; E! X/ U' O1 h
另一个例子则想说明Maple计算的局限性:   
! u7 W& O9 |% K1 T; g  z  
5 j4 I# w5 ~# B' M7 T7 @) Y# BMaple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:   
( k- ]/ t- b% g" K7 }# t % B. b8 i* y; [( c6 f& f8 I, j
显然这是错误的. 这一点可以从代数的角度予以分析.
+ e0 r# Y  M; \不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果. 2 u% C% |& v  R" q$ i+ L. q* B: s: U
另一方面, 设 , 则 , 即:8 w, W7 F( @$ `
# E7 T" r, {( j( u& A9 w+ l8 i
显然 有6个结果, -2、2是其实数结果. ' Y5 Q6 @% W: X" u
这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性. ( E& c2 \+ {" C8 M1 l' T: Q
尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的.
1 o+ Q8 A( M3 L2 O" x! n0 H) n1 E2.1.1 有理数运算
: L7 t6 t. m! q4 p作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20). ; S& C6 C3 z& X6 v* A
> 12!+(7*8^2)-12345/125;
% ^8 p7 ?+ V# Q- I$ t + ]5 C4 t* |6 ~0 M& V
> 123456789/987654321;
1 B5 Z  p& _+ k- H1 v2 B! m  m, E
( S( ?: C. Z0 E( |7 W" K- ?/ M" O> evalf(%);
  X: q4 ?; a' t* N% d9 ]" w/ y8 @ 3 \4 ?" Y# c* V* l' O5 R: t
> 10!; 100*100+1000+10+1; (100+100)*100-9;( o- w. C. e5 b  N
7 @1 q  }8 s' h0 ^% m

# J. q8 E/ f8 m8 J  @; A9 \: D, _   U0 ?8 _' O0 O1 f/ W9 A# w
> big_number:=3^(3^3);6 }% W# y7 i' r
6 E- B! P: i* Z/ S: p8 e' J
> length(%);
$ Q& K& d) O. x3 y & k- z* W9 }, N# D% M# w' P
上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:   9 d; l5 ~  e: d/ r1 v* \
    1)整数的余(irem)/商(iquo)
- y" R9 m& E: Z- j7 a: O5 R: z命令格式:   8 z2 u. G6 Q9 U9 p8 C  ?
irem(m,n);        #求m除以n的余数6 q5 j! t& W' u& K6 c
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q- n' @8 q; R  O  Z
iquo(m,n);        #求m除以n的商数
6 `) c% j& h6 z3 B9 ^iquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r# i+ E6 y$ S6 a/ X! m3 [- X3 j7 v
其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
6 w/ L- M; W# E5 d$ _$ E> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
. R' a- T5 @6 y9 n" v" z3 ? ! K: X$ z3 P. W: E% T; c1 {7 \
> q; #显示q+ ?) p/ A; _; S; E3 ?# L  |7 X4 f
3 [1 j- i2 n$ S% S! m
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r
) K! {( N3 ]8 x" n5 W5 R 9 W% d4 X. R0 A4 V
> r; #显示r' B1 Y" n0 X& e- V# v
8 H" y7 s1 F( K9 g$ z6 B! R% L+ C
> irem(x,3);2 x/ N, ~  [5 Z, M

- z2 b# G  e0 U8 G2)素数判别(isprime)3 U  x' D! {3 Q0 L# {, D
素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n);
1 X" f, B- A8 O1 e0 [9 N    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
0 O4 W5 P6 k& w5 g7 [8 O2 q> isprime(2^(2^4)+1);# j/ [+ ^$ m2 m

9 s7 j8 D% k$ ?6 @> isprime(2^(2^5)+1);6 ^  i* P1 z& z# v$ k

/ _  p' m% S9 c$ m9 F0 g1 f: z上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多. / \6 q; D2 I5 s$ V
3) 确定第i个素数(ithprime)$ J8 [1 P# _9 b$ ^* @
若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);   
/ H$ P! _; `/ k" j4 |% v, G> ithprime(2002);4 M( E4 O( m/ l7 G8 }' X$ ?

5 l- }6 C0 a2 a: r> ithprime(10000);& ?) y: D3 a' G- y! f7 V
  _6 w! n: G7 d; ~# X
4) 确定下一个较大(nextprime)/较小(prevprime)素数
1 Y7 j  l5 E( P5 ]4 V0 Q' _) s8 P当n为整数时,判断比n稍大或稍小的素数的命令格式为:   
4 C* P9 Z$ Z1 x& xnextprime(n);  
0 \' w8 N5 E& Hprevprime(n);
2 L% b; r  `: R4 O% q' S  c> nextprime(2002);, l4 D( \) J$ d8 o

/ }3 O' _4 S2 p8 ]% S) z0 z9 I' r> prevprime(2002);
/ g0 f7 ?/ ^9 R$ m) x( a / E6 v+ \: d: k1 f
5) 一组数的最大值(max)/最小值(min)- Z) _. ?; Q# z7 O) X
命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值* u" O  M7 U# U1 j9 v0 a1 }  m
             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值; E' H* p  j' p- v
> max(1/5,ln(3),9/17,-infinity);
% Q! q4 u9 [3 e* k5 n: S ' u* n9 w# |8 e$ {0 [
> min(x+1,x+2,y);
' T- q/ P$ h, n$ h8 S
' s5 L6 s. M2 v4 e+ \6)模运算(mod/modp/mods)
( x( O2 v( u. J# s7 M. w命令格式:  e mod m;    # 表达式e对m的整数的模运算! ?9 l; A1 s! t. p1 }7 w* N1 c  Y
modp(e,m);  # e对正数m的模运算
2 Q$ R7 o* L; N# ?. x/ l5 w) q* xmods(e,m);  # e对m负对称数(即 -m)的模运算2 z- q% d6 G, Y: |& _1 n
`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价
2 s  B+ k, I5 r9 ~- I( L值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/. 5 g$ L3 O! p+ Q% ?
> 2002 mod 101;! A( ~1 s/ w& n" b; ^8 ]! ?7 M
6 s: V9 A9 w  T5 _2 W- r
> modp(2002,101);
) d' b. c4 M" Z8 B2 F
0 O7 W$ i5 n+ S6 K& r> mods(49,100);" C( r, M$ ]; A+ @! ~7 q3 c

- ]" {% K3 r) Y> mods(51,100);! C& `2 O* i- ?1 ^5 R
  Z" D5 ], @3 h6 \" ^" |
> 2^101 mod 2002;  # 同 2 &^101 mod 2002;; K9 ^! b$ D2 z( p: p& Q

9 f! \: x5 {! h: F  _0 U# T/ s" v  D7)随机数生成器(rand)) O( {2 b2 ?5 c' [4 G: e6 ]
命令格式:   
/ h% O; E2 L. i' u: n3 qrand( );    #随机返回一个12位数字的非负整数
6 P% I# ~" t( y9 q6 m; \! c. nrand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数
  T0 N6 R, j& p! c> rand();& {, z1 ^' \8 J3 H9 p! D$ m) u

4 I  I$ E( V% f2 N' `0 k% S& @> myproc:=rand(1..2002):# m: _( o9 S' w5 ~, j! w; L1 u
> myproc();$ h* p% C1 x0 w

/ G% \! U5 ^6 _> myproc();
1 D' j# a+ S6 ]- b' W# Q " v( w5 f; `. N" w7 r$ {
    注意, rand(n)是rand(0..n-1)的简写形式.
6 ?1 q  J2 {/ p; j2.1.2 复数运算
$ l7 w& x- E, B5 T1 Q! t/ M复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:   
5 z) _+ n1 t, f# _> complex_number:=(1+2*I)*(3+4*I);, }, D# m# D! o; |

  a) V, ~9 p. Q3 F> Re(%);Im(%%);conjugate(%%%);argument(complex_number);
% N  [, q; c$ ~4 `/ O
6 b$ {7 U' H# e% k- e+ O& J! o$ d ! B" z, O6 w  Q7 P5 x

5 H8 S$ F! P- f) o
3 w0 s0 z3 a5 G. e" d; F值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%.
/ T! o; v1 D& W  L, t; f' U* @: Q/ T为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:   $ W4 G9 i% z3 b0 ^
1) 绝对值函数# x( m8 Q1 f/ t$ g; A* j8 A
命令格式: abs(expr);  , l+ {. l4 y: g: j6 r
当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.
2 ?- ?; \7 h- {; ?0 E: ^7 t6 F> abs(-2002);    #常数的绝对值
% V, \, W- J! k, z, ^
! U* k/ y) L) J# @; ?> abs(1+2*I);   #复数的模  b3 q) w2 i% V9 g

& R6 U9 O: U1 }- Y> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值
( P. W0 L9 M0 d ) E6 }; c) e6 x4 x% t2 X$ P
> abs(2*x-5);   #函数表达式的绝对值& A- i2 g% f7 r( e5 s% @" K
- g: q) Q5 Y& E9 d, ~, @
2)复数的幅角函数  p# Q* e9 u9 f" [5 O9 [
命令格式:   argument(x);  #返回复数x的幅角的主值
4 P' I: Z/ e/ ?0 {3 d8 Z8 \> argument(6+11*I);
* J- V; o9 f& C   O- _( _7 d5 N; Y( m. h
> argument(exp(4*Pi/3*I));
0 l" B2 j5 \. }3 H ( D) a/ o( b2 ^3 P" C" y
3)共轭复数
$ p* N* p- c" J$ I( N5 @命令格式:   conjugate(x);  #返回x的共轭复数. i: ]) s6 E1 y; {3 [
> conjugate(6+8*I);- C( }- i6 A$ i* x8 V
' ]0 f- D0 G8 i  U& I
> conjugate(exp(4*Pi/3*I));4 |- m+ V) l1 K7 D! {0 j  r
1 Z0 `) b/ F- |; Q  w7 I
2.1.3 数的进制转换/ y# f% G: @. b6 F! n$ h
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可.
+ b" i" x1 J9 X命令格式:   convert(expr, form, arg3, ...);   
" T# s4 N3 ~& J+ V# t* X其中, expr为任意表达式, form为一名称, arg3, ... 可选项. + l" S) [$ s. }
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述.
; w! W! c" K0 ?4 {: Q$ ]    1)基数之间的转换
- t1 [* g" A& ]; C( G. O" b9 L$ I命令格式:   
3 }  K+ B) \- qconvert(n, base, beta);      #将基数为10的数n转换为基数为beta的数/ {/ H  [1 k( F) }
    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数
, ?+ J* a& w) G/ z$ }> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7& y5 u# F+ Z. a% P; ]
; A& a* Q) ?% P9 |
> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数! X# y6 @: M6 h2 `
" g& ~0 u  W, t( N8 D7 {- G0 ]  ]
> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
. h# F9 o: A% R9 F5 I  O# [
1 w/ D) {7 i" b" p/ s/ Q    2)转换为二进制形式
% H7 D6 @1 p" }+ W! j命令格式: convert(n, binary);
1 l" l9 o% ]: H9 h! a其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂. 7 Z, i& S$ Q) C
> convert(2002,binary);   % C- H) k) b7 A5 J; s  J
7 x7 t$ P# ]0 h6 }- x3 l8 x
> convert(-1999,binary);
% ~! c) a2 {$ C4 Q" G& f* Z) N 2 q6 f6 o. x) F  j
> convert(1999.7,binary); / G+ U+ P# ?/ R0 Q

5 l: m2 D, `: }! I0 g6 C! A! ~3)转换为十进制形式
. y/ g9 o5 o% E其它数值转换为十进制的命令格式为:   , ?' n# y: @2 n* y
convert(n, decimal, binary);   #将一个2进制数n转换为10进制数; b7 w, f7 X- a( x
    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数) Q$ p+ j- ?$ H  L$ B: R) }& c3 a* q
    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数
- T7 k1 R# f1 Q9 O8 q) Q0 W& l> convert(11111010010, decimal, binary);   
8 d% A) n& K9 U: Q7 Y% q # A. M* R  y6 {$ J$ N" L
> convert(-1234, decimal, octal);           
' N$ q) A/ Q0 X* C) c; q7 X7 s  w/ K
; U+ _3 P6 y8 U7 e' q2 s; d! C> convert("2A.C", decimal, hex);         
% @/ X1 e% O0 J4 d" Z 1 \( g$ q/ c5 s) Y
4) 转换为16进制数
, b) _. @% d4 u将自然数n转换为16进制数的命令格式为: convert(n, hex);   
, A  P) V; ~' R> convert(2002,hex);  convert(1999,hex);2 ~0 t6 K& C3 k- N* |
) f/ p/ J3 }1 U5 w

& _( C7 I& |/ @! v9 F) I' K5)转换为浮点数8 O) a- i9 K/ T* H
命令格式: convert(expr, float);
& e* R* B( l$ w. e注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用. 6 @% d' [7 D% _' m
> convert(1999/2002,float);$ B1 t2 k% |2 n! ^' f6 \

! A6 r4 F$ n' y* [" [! @> convert(Pi,float);
0 j* q9 W, g0 L3 ^+ x( J/ O
) e1 x: O0 {; M- y/ o; v! u9 F2.2 初等数学- K0 S4 a- Q( g! ~  \0 t
    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识. ) n! T/ B) B5 I/ q6 u& ~1 `
2.2.1 常用函数
7 Y$ ~* c; Z5 [作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:   5 N, g1 K2 r3 \4 \! A" A, f* c
指数函数: exp- g+ N& X6 h( |' `9 M! s
一般对数: log[a]) g' T2 a( y' O- D
自然函数: ln8 V4 L6 c8 d: R& ?0 H1 \
常用对数: log10
. ?8 R. o7 d2 V2 C5 y( _平方根: sqrt
8 ]0 p% E+ o1 j! Q! F绝对值: abs5 a( _$ i8 I: P4 b
三角函数: sin、cos、tan、sec、csc、cot
7 {, P  V; ?; W0 v2 K1 i反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot
0 W3 x5 d1 F0 |, B" W. L5 V8 |双曲函数: sinh、cosh、tanh、sech、csch、coth0 h- `; N! r9 b( v+ P
反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth7 u+ ~8 Z5 K2 j- h1 h
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY
9 l0 Y  i* |; p# Y& KGamma函数: GAMMA6 C/ }. j  O6 y, i' v' Y2 g
误差函数: erf
$ b9 ?1 ?+ p: a& a4 K# H函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能. % c4 M. e# c4 W6 k5 {
1) 确定乘积和不确定乘积
* a9 Z9 m8 k8 e  M( p  q& t' c' l命令格式: product(f,k);  1 Y) N' V' U" X5 k% y
product(f,k=m..n);  
1 S* [% |0 L% h0 c, H: eproduct(f,k=alpha); ( I- C) n# `/ n* h
product(f,k=expr);5 _  A' b. a% I  ^* n( x$ C5 v
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式.
1 Y& w; ^, q8 U> product(k^2,k=1..10);   #计算 关于1..10的连乘3 I# L5 h& k7 A

; l2 P8 T; f" P2 s) b8 d2 y> product(k^2,k);         #计算 的不确定乘积
! V, P, \' \& m
, w% m) M. N, x  I7 |> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘
" P( u: u& `8 B2 o  I7 [: W, R- @
  N& u8 `2 r2 `$ X! p0 b+ G* y> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘
) d* ?) e/ c. D5 b 1 [. q, J/ }. b! V. ?
> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式3 Q! l4 L4 Y; ~6 N& U9 M

1 D5 _& w  o7 O: J2 Z# t! u1 P6 t> product(k,k=RootOf(x^3-2));     #计算 的三个根的乘积
) p3 s3 i  _4 v; W- S) y 8 W' \/ R* u5 z: p- g
    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:   
" b+ G4 E: i- R! R> product(x+k,k=0..n-1);
. w+ X* g$ n! r% p ; U+ P( g0 V' i
如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:     B! w3 F7 H9 X- V# |( o
> mul(x+k,k=0..3);2 u7 @/ W" O' o; C$ _1 Z' ]

& v& K- I1 n/ u2 w2)指数函数9 h) h. Q# O9 y  e( a
计算指数函数exp关于x的表达式的命令格式为: exp(x);
3 H, b" E% ?, Z, H* k  [> exp(1);7 _2 v/ ?7 @$ [$ C& M1 Y
$ }% E' ]/ ?( ?
> evalf(%);1 n) ?- I8 g5 C; I

$ g1 p' ^% Y7 j> exp(1.29+2*I);
4 o. x1 Z$ i" x$ J) Q # G" [2 G' w! e# B
> evalc(exp(x+I*y));' K$ v& i; v9 }8 r# X8 X2 P

, K$ H* Z2 z! v# n- L0 p( X+ B3)确定求和与不确定求和sum
2 p% Z- u8 |! m" B/ D1 A命令格式: sum(f,k);  
; s- B; _5 J) g6 Bsum(f,k=m..n);    r8 d. c- |4 d3 m0 d
sum(f,k=alpha); 1 a1 \$ o/ I4 J: c
sum(f,k=expr);+ D: j* e3 e. x: A$ Y% C
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式. 8 {) ~6 W8 y  R) n0 o3 u0 k
> Sum(k^2,k=1..n)=sum(k^2,k=1..n);7 s' t' E5 q7 e$ e; G1 J9 n
- p! f0 `5 j* c5 z, m
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);# Q* [6 V+ @: {4 Z6 V

* y6 i$ }9 i3 [6 b> Sum(k^4,k=1..n)=sum(k^4,k=1..n);
, R  ]7 o/ i) n; l5 a& k1 Z
% [: _  [7 P0 _- R> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);* R+ w. u0 x; U9 c* u3 h+ n1 p

' p- W9 y0 B# n5 ]2 u> sum(a[k]*x[k],k=0..n);
; S+ h0 R$ O  c2 I* q. T " f6 h5 \' X2 ]  S$ e
> Sum(k/(k+1),k)=sum(k/(k+1),k);7 B/ A$ Y+ N. \; K+ I* g: m% _

7 d2 l7 ^! s8 o% A3 G4 E8 L# z: d> sum(k/(k+1),k=RootOf(x^2-3));
$ b' h2 B% l! ^3 l
% c9 N7 V5 p9 p; {9 q, Usum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的. 2 s( w, [7 P$ M# f( @9 Y/ X
> Sum('k','k'=0..n)=sum('k','k'=0..n);
9 {: H( L8 ~+ M9 h# g# [ . ^4 c' N' d: g
如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:   1 I' L" A+ R& Y( ]
> add(k,k=1..100);! K9 G" i* @. l2 Z
3 X5 I" ^% f9 h4 w  m4 x6 O3 u
尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令.
* x) @! L3 U. {. V另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性.
2 o9 v% y+ L( L: H* o3)三角函数/双曲函数* }, p! e6 f/ l6 y( r, l
命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);2 F0 E- G7 G2 b2 q
          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);/ C! R6 J0 K/ n& m* ]1 K
其中, x为任意表达式.
1 K3 }5 f+ S+ e值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.3 D, _% u' i3 o
> Sin(Pi)=sin(Pi);
# L0 \3 l$ a: q2 n8 v ) d9 V& q$ W& n# Z
> coth(1.9+2.1*I);
: D: `. [$ s% l# T8 @
" w9 c- U" y- _) Z# |+ k' k5 ?8 [> expand(sin(x+y));     #展开表达式
% d9 N/ J* p1 Y1 u5 j) W/ k6 F . M. h' g* X# a
> combine(%);        #合并表达式! f) C& j% T/ `
. r$ h( d: r: C
> convert(sin(7*Pi/60),'radical');8 w0 D0 ?( Z; Q) d) B, I7 _) x' q' S
4 Y7 @! U( U  T: n, r
> evalf(%);
; R9 D" |6 j5 c9 M+ y ! ^/ S7 L% Q" o5 W8 [* t
但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.
3 C: W5 ~- {: @9 L1 d4)反三角函数/反双曲函数
/ \/ b! h& }( j, s0 i* g' s命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);4 L% E8 G+ Q- A# Y
     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);   - @* q& @, ^) d" W
arctan(y,x);
! V- q  O! n: w+ o7 a# B  y其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算.
( S; t  W0 X' ?* F6 Z3 B算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.7 N5 I4 k- c' l+ I' K5 V
> arcsinh(1);
8 u: w2 @/ I6 X0 n9 n" d2 F. ?. t- [ ( H8 s6 G2 q; B3 |) j; W; S
> cos(arcsin(x));9 `: _5 _1 A( h3 S; G

( |& t: o9 n  {/ Y) p> arcsin(1.9+2.1*I);4 ]+ T5 A) Z) ?+ ^
8 d( F4 V  `; \) _6 A+ Z# Y
5)对数函数
6 x% K7 o. ^  ^& l2 M命令格式: ln(x);           #自然对数2 H8 h0 C3 Z9 ~: L3 m
log[a](x);        #一般对数: y' v* Q9 V1 L
log10(x);        #常用对数
0 @  Q( g5 e% v! M一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:   
( W. ~* d$ s$ o0 p& }, }  (其中,  )
  J4 Z# ^8 I  i% W> ln(2002.0);
( @* P. O/ f% r
/ |8 g. T( W. p) J) M5 T> ln(3+4*I);5 [( R% }2 J( y+ R2 b6 o

" q; l* Z- n6 q% f* Q! I! Z> evalc(%);    # 求出上式的实部、虚部! t' ?5 [- }7 |, O2 B; [

0 o& M7 F2 Z# C" C* U, m, ^0 f> log10(1000000);9 f3 ~3 v4 i$ }" P7 Z! u* H
1 s& N0 |( E/ j% }2 T& V+ w
> simplify(%);   #化简上式
# t5 L5 W1 p  x) V
6 J# \, K) U9 ]5 p2.2.2 函数的定义! O+ S7 X$ B0 M; @( P
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:   
& u  r. |3 L7 b% i% ?; f> f(x):=a*x^2+b*x+c;+ S, z: j" ]2 K) d+ g
' l7 ?1 c2 ]# b$ y* R) n1 m1 [
可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:   4 j. m; ^! L9 L: f! @0 O3 p( \: E: v
> f(x),f(0),f(1/a);$ {  a4 w: J# U: }' o+ W4 T# Y: q

) n# {1 V/ ?, S" n9 P3 l5 c由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:   
; B" o9 Q" v. y8 V+ o8 A> print(f);
% V: _+ U$ `* Y% p# X$ [" t8 b
; F. B3 b, h8 b0 q) ~" L事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式.
! W0 Z0 I: o7 F2 b1 T在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):   
" T& J- Y9 w3 t> f:=x->a*x^2+b*x+c;
- V9 F: G5 \: `* [) o. v- A
! P. T. \- r0 C: e7 l> f(x),f(0),f(1/a);
$ o! P- C& U0 ?: t/ q , _5 t+ B4 \8 J' q( i4 c  ]
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
( O/ E# \- n) y! r> f:=(x,y)->x^2+y^2;
# Z% `& j. c9 S$ V8 F- z' l
; \* A: h+ L8 S" W2 d, c> f(1,2);
6 Q; e, p: p' y7 W, @3 f& ` $ W9 z( J! u& o3 V4 l
> f:=(x,y)->a*x*y*exp(x^2+y^2);2 G  |& u/ u4 [! g- }+ N; a3 F- f

8 @; V% v8 z& y7 f- u综上所述, 箭头操作符定义函数的方式一般为:   
6 k; l+ ~. G$ b一元函数: 参数->函数表达式2 b" B7 k" B# c- B$ T9 v2 v
多多函数: (参数序列)->函数表达式- ]$ m8 c; C: ]6 g1 E
无参数函数也许不好理解, 但可以用来定义常函数:   
3 \/ S0 `+ F0 X& |> E:=()->exp(1);& E$ G# ?6 x4 u0 j* V( [/ Y- x
7 N; U" [5 D1 \; I
> E();
! }* p  Q. h$ h # k) J) S* B; _4 C! A
> E(x);
$ _" k0 I) h" g2 w2 Y5 x+ c. m  v* C8 L
7 ]5 N0 b- M, a2 ?3 Z0 N7 K0 t另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数.
) t' y# X0 w. U, J. k3 [  K定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);         
! Y' z* Q$ w) p1 e5 o* L定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);     
$ M/ t% b7 Q  ?4 \- E8 P> f:=unapply(x^4+x^3+x^2+x+1,x);
7 X) V* i, B1 J; i0 E% W  Q* c 9 V6 ?# A/ k* U/ U$ {4 @
> f(4);3 u8 ]4 @, ^% j, c; Q" K. I
* P# @+ e  U6 @' F9 h) ?
> f:=unapply(x*y/(x^2+y^2),x,y);/ ]2 D5 d$ f( e8 o- R! s& m

" b% V" e5 ~9 @' L7 R> f(1,1);* q+ }/ A3 U* G5 l( B

; H! V5 Z% Y- v3 b& D借助函数piecewise可以生成简单分段函数:
$ x7 z0 c* Y) h$ x> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);
# ]3 ]: |- [9 g
$ w( A1 n: h3 F2 z( {清除函数的定义用命令unassign.
! V8 m# y* Y) {# f' l> unassign(f);
4 W. ]5 k9 a$ `  C& X* L7 E) Q> f(1,1);" Y- k% o' S% l  h: S

1 P& T7 |* i# t0 P7 k$ l除此之外, 还可以通过程序设计方式定义函数(参见第6章).
2 d" j, t, \! j* C4 M# g5 |定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:
& r3 T0 _0 \' |0 M' bop(expr);         
7 J" q& N2 _* hop(i, expr);         ' c! @! n5 n& N3 a  R! u/ h4 c, w8 q+ \  i
op(i .. j, expr);      . {" ^* M; G% y
nops(expr);$ Z. {3 H( k1 s8 }! A; u/ {( A
如果函数op中的参数i是正整数,则op取出expr里第i个操作数, 如果i是负整数, 则其结果为op(nops(expr)+i+1, expr); 而i=0的情形较为复杂, 当expr为函数时, op(0, expr)返回函数名, 当expr为级数时, 返回级数的展开点(x-x0), 其它数据类型, op(0, expr)返回expr的类型.
+ r* D. V5 t! {0 o7 g, V命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.% m/ v6 Y& m9 C6 J( L& ^
命令op(expr); 等价于op(1..nops(expr), expr);
9 _" M$ X' q& ?( t0 J8 x特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
7 y: ]' w) Z: P3 J而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和.
7 M3 j  `" \) S" l> expr:=6+cos(x)+sin(x)*cos(x)^2;  s5 P5 |8 Q. }! k3 U

! W$ O5 r- W5 J> op(expr);# o9 O5 l" Q1 P& w  x

1 i6 A6 h5 c' V, O7 b> nops(expr);
; m# u5 ?, Q: s2 F1 A+ ~ . Q/ ~9 A- e  {& Y. a0 N- a- ^
> p:=x^2*y+3*x^3*z+2;
$ n0 Y% x9 Q% f4 O7 D+ E5 \
8 k, V0 G% z+ f. r, W- H> op(1,p);
5 j" B" x4 \; q1 d # Q2 [+ X+ n* h# p
> op(1..nops(p),p);
0 ~# ]+ X9 S. ^9 B / p  D) p" `; E
> op(op(2,p));
, N2 `% p- g9 v- K! ]
) c5 m+ H5 [9 e> u:=[1,4,9];4 b/ T5 N/ x* l' A6 f1 w6 y
* u* p2 n+ h3 O: h3 G% d
> op(0,u);: l$ U3 |6 X0 x4 U, I4 y
- b+ M) ~- A1 i2 ~
> s:=series(sin(x),x=1,3);
. T$ ~# `; K* i: f $ Q, s! N$ N: j  l9 b6 \
> op(0,s);: n! {$ i! q8 O6 S8 T& q
       
4 \* H  E! z6 d1 Z8 j$ h> nops(s);; ?) q6 t( C: i1 Q. T+ w$ S) O

4 i4 B7 N+ |8 m/ W. G8 Y下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:- U6 s8 q$ C# ~+ E& L' W4 E
> op(x*y*z);
. _  T! b  ?7 e3 l, B1 k2 Q
6 B4 I) L4 L; \, _> op(x*y*z+1);6 ^$ T' U& A$ ]( J' ^9 R1 p9 H* s% {

" M8 f5 Z+ j( ^2.2.3 Maple中的常量与变量名
2 c: N" ~* ^  D6 n; Y为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:   % f9 m3 M. ^* |, U! p
> constants;
" ^) v4 ]: p; H0 v 4 V9 w; l, s; T/ ~9 d" M$ O; M: a  I
为了方便使用, 现将上述常数的具体含义列示如下:   
  W9 F2 M. X& X4 n6 |" k9 z7 O常    数        名 称        近似值4 v$ q6 b; d# ]7 n
圆周率 + L) k0 q* y9 R
Pi        3.1415926535
/ Q, q% [8 ^* m) U: D3 g+ j/ DCatalan常数
# B  F  J* c- J& ~% ]( j, }$ a+ vCatalan        0.9159655942
6 P, I2 l( o! f. E4 l; Q* zEuler-Mascheroni常数 . C% X: ]( H! t  `4 r4 l8 i9 Y% w( f
gamma        0.5772156649. }% k& N. U& R+ l) `: K9 N" |) s
$ }+ x5 N; P6 @( V: z& P; W4 s) O
infinity        2 E* b1 i; p4 v8 F& d6 }

. D  f# ~) k* {需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取.
' n1 G/ K0 V! I! l8 Z在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”.
2 F0 Y. e+ ?. {% G" X* u- }+ o( A值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名. 3 u, r9 m9 u- v/ n# x0 e5 \; l8 E
在Maple中有一些保留字不可以被用作变量名:   ! e! _- G+ A, r" ^. W3 J8 u
by      do      done     elif     else     end        fi        for      5 c& k1 [1 ^+ `3 u# c/ W, M! S
from    if       in       local     od     option    options     proc         8 z7 W7 h. ^* \6 V' K% j# l# z
quit    read     save     stop     then     to        while      D, Q! v. L0 W6 l' }5 Y( w7 D* H
Maple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名.
* @% d/ U; c3 D- M另外一个值得注意的是在Maple中三种类型引号的不同作用:   
( H" y& o# k4 w`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;    : F7 Y* t; K0 w- B
'  ':   界定一个暂时不求值的表达式;   
. s9 c7 ]. w1 p"  ":   界定一个字符串, 它不能被赋值. " ]/ X7 P& d& C
2.2.4 函数类型转换           * J& I, Y) }: b, Q6 T4 D* m
函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:  
) T5 w4 V3 _% a6 d    convert(expr, form);        #把数学式expr转换成form的形式$ A9 q$ q. t4 v$ r$ ?5 _! p
convert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos
& Q0 h% n6 a# t5 M9 F% V2 p- bconvert指令所提供的三角函数、指数与函数的转换共有exp等7种:   
5 {! ?: ^5 c/ E/ ^. U7 Y/ h(1) exp: 将三角函数转换成指数) }& l: M, m- e" q
(2) expln: 把数学式转换成指数与对数1 O" {% U. d: D0 N1 H
(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式
$ D, u+ r9 p& P) G(4) ln: 将反三角函数转换成对数
/ j8 O9 g1 v- K/ W(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式7 w" G7 ]% k' \- P& E
(6) tan: 将三角函数转换成tan的形式+ a1 ~! \/ D# A- x
(7) trig: 将指数函数转换成三角函数与对数函数1 w! Z+ a2 \4 i. j& N/ x6 t: j0 n
> convert(sinh(x),exp);   #将sinh(x)转换成exp类型
+ K  ], `, _  b0 \3 Q: a. X ' }1 s; @5 R3 L: L2 r  {
> convert(cos(x)*sinh(y),exp);" [8 z! M# j2 w+ d3 V$ @/ b) q

# \; V  ~2 Z3 u! v# C: o> convert(cos(x)*sinh(y),exp,y);8 w0 C* k. W8 q8 g2 P" L" h

/ e. ]# t3 i6 c1 t- H! l> convert(exp(x)*exp(x^(-2)),trig);
: y0 M" m! }: q4 c5 t! g
) G/ q  b5 Z6 N> convert(arcsinh(x)*cos(x),expln);
/ O6 O% ^1 c' [/ }' u6 l " g* Z$ [; T, A% q2 X; y
> convert(cot(x)+sinh(x),expsincos);
' N3 T1 O  g' i- G, j; V' k + t0 y& j0 [& ~( R+ U
> convert(arctanh(x),ln);
: |& A: F* N5 `( T1 Q- I% F% I
/ [* k6 M) f/ n- e" Bconvert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:   8 g! ?' F( g3 R
> with(codegen):
, c6 U! B( c, c" ?$ P! }% I> p:=4*x^4+3*x^3+2*x^2-x;
4 j/ Z0 i( F, S8 P7 R, \' X % D9 b" _: z6 Z5 E
> cost(p);
; q) M2 L! z( w' g1 n0 S1 A( S- y ( `* _9 ]+ r! k7 z1 e+ x
> convert(p,'horner');  #将展开的表达式转换成嵌套形式7 @4 g; E3 q* S* z) d

2 h" A" w  i: e* {3 x6 `> cost(%);
( t/ s2 h- f( c8 Z4 m1 H: m
; ^$ B" K* j5 a- O2 P) j同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量. " z8 H' y1 H) D2 @
> (1+x+x^2+x^3)/p;' |* g' t7 C0 c0 Q2 s  B7 C" V& ]
. s' k- [, k0 x- D3 }- m6 V
> cost(%);; C- r# B7 z3 q/ }

0 T6 X# \1 Z. `) l7 ?+ u" l* y/ |! Z) C> convert(%%,'confrac',x);
  ]& L. b' \! g2 p- J& T 8 _) K; P6 [7 V/ f5 j3 p
> cost(%);; f  z1 U$ F  i/ u' ~: O8 C( I
4 C6 m& n5 T) ~! p4 |
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式. : w; k/ C4 d# P: w; B: I" V
> convert(%%, 'parfrac',x);+ I" J4 |0 O. h% r' e  ]1 x: `

3 [1 D4 W3 a, \* g; k( R- c  m7 D> cost(%);/ @! ^8 s  _" Z$ d. v: I9 S
" _: \. S5 L! A6 ~: `
而把分数转换成连分数的方法为:, K/ F! }$ D+ O$ i8 h* L
> with(numtheory):* f. \  M" K6 K+ |
> cfrac(339/284);
: |+ {: z; K) v# w4 u
5 L7 C; s* ?* O+ Q) F2.2.5 函数的映射—map指令
6 v+ P- G5 F8 I  Z9 h, q在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:
! N! u4 t: N5 j7 `; c6 Nmap(f, expr);      #将函数f映射到expr的每个操作数
: b2 T6 t% {& N' m' q7 n# nmap(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量; Y- q+ y) b% I# A5 e! H3 S
map(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量  c- N+ ~7 Q" [' R! m
map2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为
4 c0 i4 w& u5 f第3个自变量…, an为第n+1个自变量来映射函数f4 C0 \% F7 q/ x8 g0 X* v
> map(f,x1+x2+x3+x4,a1,a2,a3,a4);
9 \$ q+ N. Z  c7 C . Y  m: X0 |' l$ n7 k
> f:=x->sqrt(x)+x^2;  }8 e) W7 Q. z1 p! F7 n) P
  N# q5 l) R9 B2 v
> map(f,[a,b,c]);7 q  Y  o) I& B" U) T( e
! X5 t3 V1 Z* n5 E1 c4 }: |
> map(h, [a,b,c],x,y); % r* j& B( }2 r  g# A

7 V) t2 Q) G4 a8 b8 J> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);1 n# E! L1 z! C, @' V* \
1 x, @: _$ s( T' r+ f5 v& h* |
> map(x->convert(x,exp),[sin(x),cos(x)]);5 a+ D+ x6 z2 ~' t  V- J3 D7 M
" Q8 Y" ?9 ^- ~# ~3 E. Q& r6 l0 S
上式的映射关系可通过下式理解:
- J: j6 c- K. n) P( Q> [convert(sin(x),exp),convert(cos(x),exp)];4 P9 r& t' S2 B6 l1 V2 F  f

5 S1 N; u* Q) n> restart:
- y, [2 D' O  O$ Rmap2(f,a1,x1+x2+x3+x4,a2,a3,a4);7 Q/ T3 q4 E  u6 c/ v0 H0 B
! z* _7 b& P' n" c
> map2(max,k,[a,b,c,d]); ( |! I% v# C' C& |3 e% M1 a

, i1 T$ R: Y& R2 m! \再看下面示例:   
! q! ]' i6 ?" P  F8 e- i8 Z> L:=[seq(i,i=1..10)];
( j- A; N, w$ ^  Q& |( b( V ( y% \; e) v; f
> nops(L);
* a" T4 _" x- K3 T5 ^! R $ U& T1 K+ O; ?. z
> sqr:=(x)->x^2;
! P" Z) h& C7 J  Y- L8 g( [' ^5 \
, y' Q5 F" J7 F> map(sqr,L);
2 I4 Y6 P/ g2 ], W$ @( o . J/ A9 @* _2 w# h$ |0 |
> map((x)->x+1,L);5 P  E1 H2 B( w, t6 \. a

0 X( Y( g4 H5 Z/ m& I: i> map(f,L);7 E( {7 T; t, s1 U
& Q# {  U# G, [; z
> map(f,{a,b,c});$ z9 W9 C$ j, V  I8 l; F* K
8 @* D/ X8 g0 Q" C5 V
> map(sqr,x+y*z);
: w& ?1 ?1 z3 y- S. z3 E. e! J# h ' o3 B% B  H$ l
> M:=linalg[matrix](3,3,(i,j)->i+j);
; {' ~! s& i8 O6 _) B0 X. A
& U' B. P7 ~+ U4 h1 ?) D4 |> map((x)->1/x,M);
5 F4 s4 p4 f" X. ?" Y0 W
% s1 ^/ m1 P( i0 ^3 求 值9 w9 q) C; ]# @$ t5 Q7 c" u
3.1 赋值0 D: C% W& V' g- N' g/ \
在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子. 1 h, p8 Q2 ]5 g; E3 U, f
> p:=9*x^3-37*x^2+47*x-19;
; C5 Q  V6 @: f  Z3 R3 B7 X
) l) ^" l: f7 H7 X6 [> roots(p);
. @& {/ P8 h; D* m. g& p
) [3 i# S( r- a  W1 v8 h, [6 `> subs(x=19/9,p);# ~2 L& K" V6 X
% d- B; J. g  f- J  [
在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量p和多项式9x3-37x2+47x-19相关联, 在此之后, 每当Maple遇到变量p时就取与之唯一关联的“值”, 比如随后的语句roots(p)就被理解为roots(9x3-37x2+47x-19)了, 而变量x还没被赋值, 只有符号“x”, 通过subs语句得到将p所关联的多项式中的所有x都替换成19/9后的结果, 这正是我们在数学中常用的方法—变量替换, 但此时无论x还是p的值仍未改变, 通过“> x; p;”这样的简单语句即可验证.
# Q* j* h& O0 F8 Y1 }4 A3.2 变量代换/ w* }- Q& R6 W4 T: F7 [3 |
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:   
1 l& e7 v, P5 ksubs ( var = repacedment, expression);% L2 N; L3 k  x* j
调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement. 1 X" t" ]  k" |0 Y; z( a
> f:=x^2+exp(x^3)-8;6 c) X  e8 Q+ c; Y! l
# H) ^. R5 w2 S5 L! ]
> subs(x=1,f);
' H2 x( g+ D4 g* s9 Q  t
+ o( q' h3 b7 N" s) Z4 d> subs(x=0,cos(x)*(sin(x)+x^2+5));
8 v0 L* D' J$ j6 B1 p$ _
& U% j8 X' ^& v* Y1 Z  I/ q    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:   
$ X' G( B% U4 P/ A! q! O> evalf(%);, j4 I6 i. V2 c& w

/ D" |& v' K" L7 l( R( _- S变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:   ) n4 c9 `7 ~8 k, K& C+ p$ t6 W
subs (var1 = repacedment1, var2 = repacedment2, expression)5 p, d9 v) L  s) U
调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:   # O+ n7 c  r- T. s7 M
subs ( {var1 = repacedment1, var2 = repacedment2 }, expression)
; S( e$ D$ S) R( s6 P0 \; Y1 W下面通过例子说明这几种形式的替换.
2 `7 o" W4 |( X- T3 l> subs(x=y,y=z,x^2*y);              (顺序替换)
8 c  m& ^+ S7 d
& x. M  L  f+ M> subs({x=y,y=z},x^2*y);            (同步替换)6 r5 R# R# d  ^, G, x! z( b
; F8 j& H6 N% \% n1 D
> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)
9 X3 }: y( k! p5 A' C # u4 L: ?8 K+ w% x
> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)) E2 \  g2 V+ {0 D

4 a5 D# I; K9 ?( @5 {> subs({p=q,q=p},f(p,q));             (互  换)3 z& k/ h4 B! ~# l5 m

  ]+ ~0 N" P+ Z! s" x# n3.3 假设机制
. _( `* I6 C1 ?2 j2 wMaple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点.
5 ]$ m* W$ @3 C0 ?& |在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);. y; F- _% z  q( s5 E* p
函数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);”也不会产生矛盾. * U  x' F. E3 Q3 t) ?3 h% Z
> Int(exp(-s*t),t=0..infinity);% Z8 d0 ^3 k0 C8 ~& \& k

6 o- S& o( d: S" ^! b8 F! ^  {6 s> value(%);! l& ~+ k; c1 y! F) \% e/ L8 ^+ D7 `
Definite integration: Can't determine if the integral is convergent.
9 s* t7 G$ u. L/ ?! I) kNeed to know the sign of --> s/ q5 o( b" i6 i% [
Will now try indefinite integration and then take limits.
& p7 {4 M  q+ R& x$ G- X 2 j3 ]6 e. O; \4 p& J; x
> assume(s>0);3 u- J0 z+ W6 ], k* J( F
> Int(exp(-s*t),t=0..infinity);
5 l- g( M3 z7 _1 X. g9 u: ^9 B
9 Z0 ^% b2 Z4 {& ~% g# H> value(%);
) r9 d" A$ @" w1 x: P8 A 9 I5 d- s# s6 c* |3 ~" e
3.4 求值规则
- f3 M2 X2 a9 O0 j; Y8 C' h在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:   + F! V# o7 T* T$ p, r: c% D
> x:=y;
; u& ]4 q" J' n) g7 Y% O
! [, H, j; f1 a& O+ Q' y> y:=z;
1 P! b9 Z- v# t1 u# Y
- g6 x; i0 x; ?2 ]# O> z:=3;. t6 _5 I# b/ J9 @5 C* g
4 r$ D( x2 R" Y$ Q! K) i8 _
> x;! a4 N% J6 k7 s) x. Y1 T) d; [2 w
! L7 Q" b* M8 Z" D! A0 q4 ^: |
> y;
, L' I$ L& F! ~6 `, r$ o3 z9 l
* ^$ J" p; y# _+ c; \> x:='x';$ A( m1 m0 X8 e% h- j) H0 V7 q
- w1 |& j9 M9 e, _! h1 ?: p+ c
> x;
$ c; _- l" k: x  a$ O% O  V1 w
1 ]. e% a" a2 l5 ^% S+ K; M( L, R4 q> y;
/ b9 U- A( ]& M3 |, ^7 b
) q: L! g% d0 l% T对于不同的问题, Maple设计了不同的求值命令. 现分述如下:   ( U) f. E# i, \
1) 对表达式求值
3 z6 {$ V1 Y) h" |! t- D! ~命令格式: eval(e, x=a);  #求表达式e在x=a处的值
/ p! b4 {' s& c! L) M6 C             eval(e, eqns); #对方程或方程组eqns求值
, V% j7 [) b* z1 |$ d5 q& P* |2 a             eval(e);      #表达式e求值到上面两层* b/ b5 L6 |) [
             eval(x,n);    #给出求值名称的第n层求值0 s6 V4 H+ m8 G9 X1 [& Z
> p:=x^5+x^4+x^3+x^2+x+73;
: r5 m8 e# ^, v% Y  F" n4 L 4 X. Y; H: @  i+ h% G
> eval(p,x=7);+ Q' j6 C' Z7 |: p( P) g  ]: i" W- }6 W
) z6 ?) V( D* f. [
> P:=exp(y)+x*y+exp(x);
/ ^2 ~9 t- Q5 }3 V% @; ~, D
. {+ |; O/ R; ^1 a  y; E> eval(P,[x=2,y=3]);
; S5 q! o. G# y  U
8 m: x) C! y) S/ J0 S; g' Z& I' G    当表达式在异常点处求值时, eval会给一个错误消息. 如下:   
+ G& a7 y: q# E. }> eval(sin(x)/x,x=0);
: _4 ?3 O0 r+ w8 {/ V6 aError, numeric exception: division by zero5 \' H6 Q% M! W: {0 D
    下面再看使用eval进行全层求值或者对名称几层求值的示例:   
7 W# H, r- P& {7 Q> a:=b: b:=c: c:=x+1:
+ w; z- p- W2 q> a;              #默认的全层递归求值
0 q  T) u& R( c/ \( W; G$ D + }; F( X: R: B+ Q  C
> eval(a);        #强制全层递归求值" q$ @6 ^4 R9 L( O! i' O
' U8 N( M8 R- V, v. ~" U
> eval(a,1);       #对a一层求值
8 l9 ^/ g; b$ j  Q1 [+ v
2 [- n& o: E) |* C2 r( k> eval(a,2);       #对a二层求值6 Z5 u7 b* p* z. R- \

; Y% P) g7 c6 ]9 c$ b3 O/ M> eval(a,3);       #对a三层求值
6 Z# A, C; C; ]; s( ~8 P$ W5 e* F
! N+ t' B) `- b4 o> eval(a,4);       #对a四层求值. C7 b0 X# v, Q# x0 e# q

* W  J9 Q+ |1 m9 n( a0 X    2) 在代数数(或者函数)域求值9 H2 Z$ l, N; O0 w& [' s
命令格式: evala(expr);       # 对表达式或者未求值函数求值
, `1 ^3 s! \6 V! K/ w. d* l* y             evala(expr,opts);   #求值时可加选项(opts)' {( U) \2 a: Z6 b8 y# M6 }
所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式. 4 Y4 f6 }2 {. b; s- V* u9 t
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:   / w: O& Q0 v" h4 b5 ?: D. V
> alpha:=RootOf(x^2-3,x);( j  F  o+ d# L5 D/ A! M5 l
% I' W# b5 N( u: I% B
> simplify(alpha^2);/ w7 g6 m& j9 u3 q5 v4 O

8 O7 E8 c% i0 O% H% T- Y+ W, e; w在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:
/ Z) L/ T$ x, s; L+ V+ P( \9 A> alias(alpha=RootOf(x^2-2)):
/ ]: J7 O7 g7 ]/ }# P. l+ f> evala(factor(x^2-2,alpha),lenstra);
" ^$ A! g# S8 m& J( i+ d3 Q; Q) e & z; d! e/ @/ S! i, [/ S7 u
> evala(quo(x^2-x+3,x-alpha,x,'r')); % H% q3 q, O' H$ \+ y

) `0 @! |6 k+ F' t% X1 H: s2 a> r;7 x- H# \4 o, Y/ A; D# z) V

8 H. M& }" @3 i& `6 y4 a> simplify(%);
! O# ?, D9 R' ^3 A; b1 {" h" ] $ o" E+ V; a! @7 j  N8 x( z
3) 在复数域上符号求值7 f' p9 s/ |8 z+ i* Z9 f" Q1 y
操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
5 C7 D1 N# I9 p6 s6 c. x; mevalc(expr);   
2 _4 G5 C1 d2 r" ~+ Zevalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2. 1 w; F" b- N" H' l+ C% ?
> evalc(sin(6+8*I));
6 ~, D3 r5 h9 {# }5 N1 [/ F
6 w) u; Y* U- E> evalc(f(exp(alpha+x*I)));
/ u/ b0 _& t8 s* n ! q3 l$ ?  D* w7 H4 g" |& |
> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));
6 z4 G3 K2 s" o8 ?, {9 e1 G7 @* I3 y% p / j8 ]5 P5 i; R( w3 I8 ]
4) 使用浮点算法求值
" e" g/ A, @" Y: _( L浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);       _% Q: S% ~# U3 \; S9 x1 J
> evalf(Pi,50);    ; N8 z: }* U# i. ^3 a
. M$ Q; |% ^! m1 y* [. [" e
> evalf(sin(3+4*I));   
' f" B/ Q2 J* J  i$ a7 b ) v3 o% O& q1 |3 a! S9 z' L
> evalf(int(sin(x)/x,x=0..1),20);
3 A3 w2 {5 a8 [$ M# R
9 r' {4 D) X2 k5 Q5) 对惰性函数求值7 Q1 _0 D6 H3 H
把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);   ' g8 f" L" G, ]
> F:=Int(exp(x),x);' G- U5 d% o& Z- l
5 `$ l3 x" _/ E8 y# f
> value(%);/ l6 {" O: S$ |" e! X
  f* G5 e1 L' j; Q' a: ]. |8 W2 u
> f:=Limit(sin(x)/x,x=0);4 D8 `# V: S0 a' H' m
7 o  b/ x7 k& f1 \) u; u
> value(%);
) u  A5 k4 j6 x5 ~  ^ ! d7 H3 y% g* l7 T6 ]& U* P$ F( c' s6 a
另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:   
: P- {4 |8 }0 _! p3 q* X& `> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);& N; H8 e3 M" ^  ^  E5 W8 \. L
" Q) h. h; r+ \. z6 G. g8 \
4 数据结构
, x$ V; S' u2 F$ z+ J2 Z! R) L: FMaple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
" d% c' K0 S5 p- a3 _! E4 }4.1 数据类型查询/ Y8 {7 c3 }) G* {- F& [$ \5 n
在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为:
+ z. u! a, I# Hwhattype(expr)        # 查询expr的数据类型( V+ S9 V3 w% Y
type(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false
' ?0 s: A; Q+ T4 E7 U/ ~' @> whattype(12);' ]+ `  F- D: d0 p* t7 C' w8 u

+ p: M; N3 Z2 {* V  u3 S# \! G> whattype(Pi);
1 I" s7 x$ u, F: l! X& |! k. S $ X- p# u& A& ?! e$ w/ I
> type(1.1,fraction);  w* T0 r& |4 v9 j0 F
( U2 o. V7 `7 x' W
> whattype(1.1);
: w) A1 J: p1 B, F4 _ # S) \6 O6 T5 [( x& F: Y8 T3 k
4.2 序列, 列表和集合9 [, {) P% a+ u6 p, Y- d6 O# V4 x
4.2.1 序列( K7 ^0 }6 ^0 B. C2 s5 X
所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:   / `8 k: k) h! d/ N7 ^  G
> s:=1,4,9,16,25;
4 M/ |$ e& S8 s% u8 v8 E
4 }2 O2 S- v! T  f& r: F> t:=sin,com,tan,cot;3 H$ H4 N0 c# {# i  Y2 P5 x( h' `

' U+ A; W* A2 e7 R一个序列也可以由若干个序列复合而成, 如:   3 n, `# r# K% v+ c# h. q" L
> s:=1,(4,9,16),25;
4 [5 j3 d5 o- ?2 n$ h% d, B 2 ]8 |5 y- g, T( `  U. i
> s,s;; H0 ?! p9 \& Z  L: K
: ]5 t% l3 T6 A
而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:   
! `. D. y) L" L. q' e  O> max(s);! c) V7 v+ N: G+ q. [
* }2 D5 o. `* ?
> min(s,0,s);
, C9 Q' O( `4 o( g3 { + ]1 a3 V: R0 p  R
值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中.
+ G6 B3 I. r7 r> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;
( _9 [2 a- O# Z% L3 H# r 4 ^, d8 \4 r$ S. K) b3 v+ j
> op(s);
- J; h  ]% n$ A3 aError, wrong number (or type) of parameters in function op! z% x0 g; N+ X& |: P1 A& o
> nops(s);
8 p$ y. M# @3 Y$ Z' E- L9 mError, wrong number (or type) of parameters in function nops
6 G; i7 @2 b* P> op([s]);
% N) t9 Z! Z- A% _ * w5 O/ S' K- _& l. a$ _# e8 O3 e( l
> nops([stuff]);) J: d% k* h. @6 a8 |: K# A

/ R/ V: y4 Y- P* y函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:   
7 e# ~) y- y5 r, b9 d5 ?seq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)
% l( I& ~2 r3 j" o& pseq(f(i), i=expr);  # 生成一个f映射expr操作数的序列! j$ U8 T9 s7 K
seq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列
: e4 l9 Z- y2 h- ?, P: w' G> seq(i^2,i=1..10);
1 H' u! I* W1 | , [7 f9 u( C; T+ J" [
> seq(ithprime(i),i=1..20);$ t* z2 N2 `3 c6 s2 N
" q; T8 {# q9 Y
> seq(i^3,i=x+y+z);
6 g( c* J1 c: N* p) Y2 X1 l 6 U; i" o* r4 A& `  [$ u* ~$ ?
> seq(D(f),f=[sin,cos,tan,cot]);# l0 z9 K( O9 k- r8 z  u0 l

; f+ }% N7 c+ Y. t5 A> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));
" d! _' o1 J+ g: L2 Y
$ F0 g7 k/ q7 e' R7 [( C获得一个序列中的特定元素选用操作符[  ], 如:   
8 y! q+ G' M: L6 z> seq(ithprime(i),i=1..20);
% T$ `( l) M/ ~/ N; P( |$ Y! W4 t- ~0 y 8 e" a# B$ y4 Z
> %[6],%[17];
7 B  T# i6 V6 m; k* ?
; b0 P0 |! _! p: D7 _9 Z# F4.2.2 列表3 P* c2 ?  |( J  \9 O8 \
列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:   / w, m* Z2 }, x# P7 Z5 V
> l:=[x,1,1-z,x];
0 }! j; ~) R7 |
6 u3 A. V9 q3 P; L3 G: y9 i> whattype(%);
" t$ E( n8 _/ C' H( k' ?5 f5 } + m7 c+ `) q' e
空列表定义为[ ]. 6 R. A3 _" E5 L  C: _2 Q
但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:   ! L9 X+ B  N2 A7 Q1 c- M
> L:=[1,2,3,4];
" g7 E/ _$ u8 i; }) e: F& y- ` - {5 O: ]/ w6 T' l5 v4 i/ F; O
> M:=[2,3,4,1];6 u1 Y3 _% O9 [- M1 `3 X

) |5 f9 a2 g( _& d: C; E4.2.3 集合: G. Q# N0 F2 }; B6 r+ z6 [& s' K
集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合. ' Z1 B0 U  T% m! @
> s:={x,1,1-z,x};
; m! T" [0 b$ f% ? , C0 m; x: g, c% S* o1 I
> whattype(%);4 p& D$ w- r9 q  z; E

+ E+ j: A) h9 g( S空集定义为{ }. # K% A- K; ?( T' S, O0 w- h
函数nop返回列表或集合的元素数, 而op则可返回其第I个元素.
: \# j  ^1 B: G2 E9 e8 E/ w> op(1,s);; E; b( S9 w3 ~' y/ I
* w+ K" v# Y0 n+ L# i1 H
> s[1];
1 n$ ~3 q: F1 p: o; _& X9 m / P1 f# b/ `8 }/ T3 [/ b8 [% x9 {
> op(1..3,s);! Z1 u, [4 W  Z2 r- U

, G3 _% ]5 Q: ]5 A9 R0 }- E7 v5 q> s[1..3];
( x5 z5 e% x3 q8 @' X* C$ d3 D" q: w
7 W3 h9 r& N/ X) x. ?函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false.
( Z5 _* t% U1 m* C" H> member(1+x,s);
( G6 k) Y% K# Y& F8 E3 B
( b2 R- f! k* m可以通过下述方法在列表中增减元素:   
) M& n% q, D0 m# a8 f> t:=[op(s),x];# C+ H8 ?" }8 X! P1 _) H( e: H3 t

: U) L% ?8 H" O4 A> u:=[s[1..5],s[7..nops(s)]];3 ~# Y; T6 o/ Z/ J) f) H

' q1 A4 `7 b7 v# ?# C9 b# gMaple中集合的基本运算有交(intersect)、并(union)、差(minus):   2 S% F( l1 ^7 w! X
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};5 P% [4 _" p0 w  S* A2 L- z
/ v. p0 f8 W1 v$ n0 E

& I- j" Z1 z  T) W( m4 u> A intersect B; & ^& w/ s8 u$ d3 r" W0 F! _

0 L) D4 b& f) m> A union B; 1 S5 }. P  |* R! [. i

4 C, K/ S; s# }: B+ r  ]> A minus B;5 n" z& o" F9 Z, u' U3 ^1 a8 y
, H% `" T' O5 H! m
4.3 数组和表
0 G4 c% l' I" U4 ~$ z在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令.
. N3 g8 s8 f1 a: m# F0 r" N) B) c+ s    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的.
' f; q3 C2 r$ k+ L* v$ {> A:=array(1..4);
& P$ l7 n7 [: T; a
2 B" F+ P+ K2 Y) i. u3 F4 p> for i from 1 to 4 do A[i]:=i: od:7 _. |4 F* u" P7 c3 \
> eval(A);3 J+ \+ s  K2 U8 Z3 Z

, C1 O6 A1 _9 q0 v7 M4 W3 S9 i  v> type(A,array);0 Y5 ~& M, h- S. x- V( j6 }( L1 x
8 A' M( t& |. |% [3 |4 E& U
> type(A,list);
, `5 b5 X/ k7 Q8 E9 e2 Y ) ?% K0 ~; Y# s$ H  r  }$ F- A
> T:=table();
0 o+ d& {+ O& M4 A2 d4 \
3 p) @. C! j$ Y6 {$ v> T[1]:= 1;3 I- L5 y" n& [& o0 q0 @  v

$ e# ~' f! K( v8 p/ I' G1 G> T[5]:= 5;' V% P% I0 V; S) |; \/ C
; x1 P6 B9 x& r. w$ X
> T[3]:= 3;% b5 J, I' \- b) S- t1 a5 x" u( s
) e6 X5 r( U1 J3 X
> T[sam]:=sally;
9 T& r2 T! x9 M4 w
/ l( }+ N: _& m  t! q> T[Pi]:=exp(1);6 J0 v) |3 P# f1 e2 P
" F- d. J" w& `2 Y
> x:='x';, j3 [3 a3 F/ J: B- w  T6 E

/ n; v+ S$ h( _3 e& k> T[(1+x+x^3)*sin(x)] := 0;
0 a5 e# F% O. O2 X5 `( w
( U* N' }2 v+ j0 ], I& F> eval(T);. v7 u! ]: S5 C

' G8 K5 \1 Q6 U7 b/ G* _7 U> T[3]:='T[3]';+ O2 f- \. d7 Z1 W5 K
3 `6 ?5 {3 ]- Q/ D3 }
> eval(T);
# k) U0 I! P, _  v, }
: k' Y( W6 K7 A2 n+ u. U4.4 其他数据结构  h/ [7 I3 w+ ?, a9 D+ V, @
串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来. 7 J+ F+ ]" ~+ L; S( j: W7 `
索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立. $ p3 N( g0 x6 y% ]  w0 A
> x:=T[3];
1 `) G% ~  `. D8 x+ }
5 I. \, z: c% {# r" H; I; P) N> eval(T);  o) L9 ^6 L5 R
6 ~. ]- x9 G4 f# f/ {& w; d0 c
> T[5]:=y;0 Y& E" {. h  V+ ~
( E9 J0 A% x) {. J+ g
> eval(T);% G& r; C7 Z' T% V. l
; K; V: E) r; m/ x  @' O* i0 l
由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.     ; Y  ~' U+ E  T- k9 r/ }
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数.
8 _7 \) }  D5 k9 a1 w  ~8 Q4.5 数据类型转换和合并
2 P6 |8 s) x  j- m, O; r9 Zconvert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:   * k+ V  `/ Z% c8 [- a" c) O
> L:=[1,2,3,4];1 B; y" z* u% {. l' S
% X( Z, l/ [8 d% D: h- }
> type(L,list);2 n" y( u3 K4 t0 q  z

, [) g( C3 K+ K/ F> A:=convert(L,array);
3 Y/ i0 J8 e2 C( L0 l; N
; W3 [) A# o, G/ \0 ^> type(A,list);- l% X1 `2 P% L
4 C" O# p  y2 A; O9 y
> type(A,array);, D3 r* V! W, K% q4 ]  b

# l5 I: U* I6 _+ e另一个有用的函数zip则可把两个列表或向量合并:   
( Q) h2 ]1 P$ D7 _4 s>L:=[seq(i,i=1..10)];1 k* b  Q8 {1 q  m
0 Y0 C" f1 s: C1 d7 u$ S9 r- d
> Sqr:=(x)->x^2;! i" ?: _" p% ^( {- `2 h7 U. G" A/ M
/ u! F$ T  @: X
> M:=map(sqr,L);& Y  \) {2 C. t4 A4 Y2 b( j

. {) v5 p& S" j8 D* a( L' d> LM:=zip((x,y)->[x,y],L,M);7 b7 O) x/ a! S7 f3 a

" N; Y4 r4 h& ]/ S- ^) q7 p" m$ D> map(op,LM);3 L8 v- \/ F4 b+ Z: m9 n. s4 G
9 W4 Z4 X" I* G/ b
5 Maple高级输入与输出操作. H  @! y& n# z$ T! ]' [0 ]
Maple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里.
* @! f3 M# X8 H* ]! x+ l5.1 写入文件, s/ J% s, i) x  C+ I- x' Y
5.1.1 将数值数据写入到一个文件( n. Z. w* p3 Y$ I6 |
如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令.   z! @; s+ n9 Y' _# I- M4 p
若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);" @: s- |) G/ h2 ]* ^* G
> with(linalg):
# T( ^) m9 L8 U8 t! l# T' Z6 d. e  V> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);2 u0 D) X2 B1 j% R, @  w
6 L* D# G1 G) M; t2 C1 n4 {' [* y
> writedata("e:\\filename.txt",M);
* l3 Q; C) f0 \/ I而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);- p# K! c: y! U0 ]* l2 k! E
> W:=matrix(2,2,[1,2,3,4]);
. m/ h- c. }: K: z  ?# a 3 a9 @8 a; X9 s7 t5 a+ d/ ?
> writedata[APPEND]("e:\\filename.txt",W);) C7 r) ^, S6 C1 X2 t$ H4 h# T0 h
需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.9 w( v# a, z9 g2 T- R5 {
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);; h2 s0 n6 Z9 ~$ @: l6 I7 H" [
> writedata[APPEND]("e:\\filename.txt",W); # U; a! [$ {2 x, @; n5 v' V
> writedata('terminal',M);
0 y4 O. s1 ^# s- `7 P1                   2                   3           
* c9 u/ Y  N" N6 |4 g4                   5                   6           
6 T+ s- o: S, F" ~0 c/ P, c7                   8                   9    : h  }! H, H5 b; J7 o6 ~+ `
5.1.2 将Maple语句写入一个文件9 a& g) \7 q& A  T! F
如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:
# H4 R! C% b/ ^% hsave name, "filename";) j/ H3 |/ d/ @/ w0 I
save name1, name2, …, "filename";
/ o% M4 T) L3 d( M7 L若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.( N" _+ P# p9 ~9 p2 w5 H
> myfunc:=(k,n)->sum(x^k/k!,x=1..n);
- {' G: c% k8 L1 ^7 ~9 X. b$ f 1 c* v9 b5 a: M' z
> myresult:=myfunc(6,8);% R% o, ?, E. a7 ]

  D, D6 ]- J/ t2 c6 ]> save myfunc,myresult,"e:\\test.m";
: m0 H" K% e+ J. \6 o# e  S+ ]调用已存m文件用命令read. 试看下述实验:/ |4 K7 f% ?! M  Z4 {1 G
> restart:
' W. b: b. q. O$ w> myfunc(6,8);1 _3 N# j8 S" b& \; ~5 j
- D2 L) ^; p1 G/ l# s
> read "e:\\test.m";
: |' H  h1 f8 v1 d> myfunc(6,8);/ w. R. g& @' _5 V- L

+ E3 j$ X' r3 E3 r8 }& P1 p> myresult;
0 o: p" [; P- p* E0 ^ / ~. E. s0 L+ _3 z4 c* {* u
    而存为txt文件时则将整个语句存为一个文件:
' S6 ~" y: O& i> save myfunc,myresult,"e:\\test.txt";
, {( F4 w! L8 ?1 A. y> restart: read"e:\\test.txt";
% X+ _; R4 u0 S
7 d$ H' T6 ]( _! n0 m
& Y5 _6 d- m. f5.2 读取文件
* _' h$ o, E9 m, W5 o在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.  x+ o" A% g' L5 |5 U1 I( G' d
5.2.1 读取数值数据
" ]0 {! e* x& f$ R8 N如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.
5 B$ Y% F% H4 H% V5 z! i# \/ E从filename文件里读取n行数据时使用命令: readdata("filename",n);
1 h% }, x# {( ~; z* x以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);
- ^' M/ D- }8 v5 Q! n" a- C> readdata("e:\\filename.txt",3);9 t* W3 t4 _  O% z- I& V% B  T9 k

9 x# X0 z0 t, K  B    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:
8 |$ C( \8 c' t; k2 v3 F0 W2 t4 A% @> readdata("e:\\filename.txt",[integer,float,float]);
8 V2 v4 X: o1 X6 u' Q # G* o6 m  |6 r  N/ f+ R5 f
下面再看一个运用大量的实验数据在Maple环境绘图的实验:
7 T' a3 ^+ p4 q> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:
! F! p' o' ?3 _( k; j6 x> writedata("e:\\data.txt",evalf(mypts));
7 C( B( D& e, U+ N5 G# }9 T> dots:=readdata("e:\\data.txt",100):- F2 z) n6 P4 x; R( {
> nops(dots);5 D# E! p' y9 a

! ~; _$ a/ l% [% y1 ]> dots[1..4];% R( a, g. A0 D" `

4 D! \! q1 b9 Q5 P> plot(dots,style=line);
9 V7 t6 K1 g+ r- v. V
0 O( [) ~1 Y0 _# J0 d, X5 x- B5.2.2 读取Maple的指令, Y: L. F" m9 F" L3 Q
在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:
( ~, G2 K2 F& a- T1 s* {& ]- y1 Fread "filename";
) {8 T6 E7 p- o, |7 X如下例:; F6 K2 G+ @! W* E9 e! f: \
> reatart:  R; b% y- o( S+ {8 G0 v0 d9 H/ P' K
> myfunc:=(a::list)->add(i,i=a);% H* _& x& R1 Y  ?+ Q. P( p

) j/ Q4 ^7 R2 Q  h; t3 ^: I> avg:=(a::list)->myfunc(a)/nops(a);$ W9 ]: B9 P- R( p' H

  h( q0 R5 g5 z0 z5 v8 Q+ _( y> save myfunc,avg,"e:\\function.m";  F% \1 V' u; s' w
> restart:
  [! O: I. T2 r& I9 p8 C; V2 A> read "e:\\function.m";: ]: A/ Q8 C- g
> myfunc([1,2,3,4,5,6,7,8,9]);  I" H4 ?6 ^/ @
. j9 |) R: R/ Q8 u7 e7 G
> avg([1,2,3,4,5,6,7,8,9]);
: H# }( o! s1 O* k5 h4 {6 L + J9 m/ ?4 z+ [5 @5 w7 \
5.3 与其它程序语言的连接/ C8 i" @& g, F/ [3 H
5.3.1 转换成FORTRAN或C语言
: u; P) [. o. b6 C) S/ U调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:' w% Q7 I3 s( Q
> with(codegen,fortran):
0 D: [6 }% M( v* n1 o" af:= 1-2*x+3*x^2-2*x^3+x^4;
/ f7 T$ f* ?! X2 |5 _, l ) D, U; h! U; U( |
> fortran(%);
) R6 I7 @5 @5 }2 I      t0 = 1-2*x+3*x**2-2*x**3+x**4
% o8 e5 K5 [# A% Z+ X% \( v7 b > fortran(f,optimized);
8 y9 k" ]' ?* D. [" A8 m      t2 = x**2
9 m6 h3 m  m9 P& W/ m4 w" s      t6 = t2**2
; n6 c  r' C6 o$ @+ l7 k      t7 = 1-2*x+3*t2-2*t2*x+t6
" f9 |' P& Q; ^) R8 j> fortran(convert(f,horner,x));
4 N" g  y2 L5 z* t      t0 = 1+(-2+(3+(-2+x)*x)*x)*x* L( c) g8 C4 u. @
而codegen程序包中的C命令可以把Maple结果转换成C语言格式:2 _: N( k8 u- |4 o
> with(codegen,C):
5 B* }6 H: W# X, y3 q2 o( Af:=1-x/2+3*x^2-x^3+x^4;6 m6 h0 w/ e- n+ V1 y2 h  s
6 D: N( t4 |# j- q- p1 L4 r
> C(f);
6 D% l* x! y" k      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;
' N5 e2 p' `" n* o9 ~> C(f,optimized);$ x# R1 `8 X5 s! ?6 O/ H+ H8 ^8 B
      t2 = x*x;
- e0 D! e. n/ G7 j( o$ |& n      t5 = t2*t2;
$ y5 M0 I( L' g, r1 Z) D$ R7 q      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
2 J; {. J6 Q5 i! i! g2 G. y6 boptimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.9 P( e' `1 w. R' Y
5.3.2 生成LATEX
0 b* |7 h: s+ u( D- QMaple可以把它的表达式转换成LATEX, 使用latex命令即可:! ~! x- w/ t# T4 m! t
> latex(x^2+y^2=z^2);
3 W& l2 W# m, z* b2 H: ?9 w) i{x}^{2}+{y}^{2}={z}^{2}
8 F$ b/ @. I9 F1 ^# {3 U+ }    还可以将转换结果存为一个文件(LatexFile):% K/ o# J( q9 k* r  w4 [
> latex(x^2 + y^2 = z^2, LatexFile);9 S# l# Z  _, k& z* Q5 c2 B
    再如下例:
5 N7 _0 b5 @' w; ?! `* K> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));
  m2 S* \4 c9 E- D. M4 k. P" b\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)) ^9 z" T. ^7 Q7 Q

$ |7 x6 L, B9 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年!
1 T- C% l( y, o8 m% l0 ~- |" X! o7 V$ J' `6 v0 P9 ?* a

$ f+ p) L5 Z7 ?) D0 b7 c6 h# V
作者: wangbutian    时间: 2012-6-14 11:53
正如2楼所言,弄成一个word文档阅读起来也好些,不是吗?
作者: 边缘d无奈    时间: 2012-7-24 20:38
顶一下~~~~~~~~~~
作者: 独守一座空城    时间: 2015-9-15 15:25
lz这样看很累人的啊。建议换成一个文档形式的。; n2 N* E1 I+ W* [5 c" h* I





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