- 在线时间
- 0 小时
- 最后登录
- 2012-6-12
- 注册时间
- 2012-6-11
- 听众数
- 5
- 收听数
- 0
- 能力
- 0 分
- 体力
- 5 点
- 威望
- 0 点
- 阅读权限
- 10
- 积分
- 4
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 5
- 主题
- 1
- 精华
- 0
- 分享
- 0
- 好友
- 4
升级   80% 该用户从未签到
- 自我介绍
- 爱学习
 |
) K4 O; v+ g: H& J# F
第一章 Maple基础* D+ f; E; y" f" p9 v7 y
# _0 ?% ?( j0 `% D" O- @9 G' l& I1 初识计算机代数系统Maple
! t' Q$ {. ^: i, ?& t. |1.1 Maple简说0 Q" c3 ]$ ?7 W& O
1980年9月, 加拿大Waterloo大学的符号计算机研究小组成立, 开始了符号计算在计算机上实现的研究项目, 数学软件Maple是这个项目的产品. 目前, 这仍是一个正在研究的项目. 2 p- B, Y/ c& q: j3 f- P7 w5 ?6 C+ n
Maple的第一个商业版本是1985年出版的. 随后几经更新, 到1992年, Windows系统下的Maple 2面世后, Maple被广泛地使用, 得到越来越多的用户. 特别是1994年, Maple 3出版后, 兴起了Maple热. 1996年初, Maple 4问世, 1998年初, Maple 5正式发行. 目前广泛流行的是Maple 7以及2002年5月面市的Maple 8.
: @+ o+ P: [' s: N6 bMaple是一个具有强大符号运算能力、数值计算能力、图形处理能力的交互式计算机代数系统(Computer Algebra System). 它可以借助键盘和显示器代替原来的笔和纸进行各种科学计算、数学推理、猜想的证明以及智能化文字处理. 8 W l5 P, r$ @& I
Maple这个超强数学工具不仅适合数学家、物理学家、工程师, 还适合化学家、生物学家和社会学家, 总之, 它适合于所有需要科学计算的人. 0 l. P9 |3 @8 f* j- E5 O! O+ V
1.2 Maple结构. f9 x; R+ E/ i
Maple软件主要由三个部分组成: 用户界面(Iris)、代数运算器(Kernel)、外部函数库(External library). 用户界面和代数运算器是用C语言写成的, 只占整个软件的一小部分, 当系统启动时, 即被装入, 主要负责输入命令和算式的初步处理、显示结果、函数图象的显示等. 代数运算器负责输入的编译、基本的代数运算(如有理数运算、初等代数运算等)以及内存的管理. Maple的大部分数学函数和过程是用Maple自身的语言写成的, 存于外部函数库中. 当一个函数被调用时, 在多数情况下, Maple会自动将该函数的过程调入内存, 一些不常用的函数才需要用户自己调入, 如线性代数包、统计包等, 这使得Maple在资源的利用上具有很大的优势, 只有最有用的东西才留驻内存, 这保证了Maple可以在较小内存的计算机上正常运行. 用户可以查看Maple的非内存函数的源程序, 也可以将自己编的函数、过程加到Maple的程序库中, 或建立自己的函数库. / B7 D, E5 i+ G
1.3 Maple输入输出方式, t# A& s; u2 q
为了满足不同用户的需要, Maple可以更换输入输出格式: 从菜单“Options | Input Display和Out Display下可以选择所需的输入输出格式.
$ Y) o9 O+ Z& j oMaple 7有2种输入方式: Maple语言(Maple Notation)和标准数学记法(Standard Math Notation). Maple语言是一种结构良好、方便实用的内建高级语言, 它的语法和Pascal或C有一定程度的相似, 但有很大差别. 它支持多种数据操作命令, 如函数、序列、集合、列表、数组、表, 还包含许多数据操作命令, 如类型检验、选择、组合等. 标准数学记法就是我们常用的数学语言. 6 i# q$ I5 F: o& @9 k+ f+ O6 p
启动Maple, 会出现新建文档中的“[>”提示符, 这是Maple中可执行块的标志, 在“>”后即可输入命令, 结束用“;”(显示输出结果)或者“:”(不显示输出结果). 但是, 值得注意的是, 并不是说Maple的每一行只能执行一句命令, 而是在一个完整的可执行块中健入回车之后, Maple会执行当前执行块中所有命令(可以是若干条命令或者是一段程序). 如果要输入的命令很长, 不能在一行输完, 可以换行输入, 此时换行命令用“shift+Enter”组合键, 而在最后一行加入结束标志“;”或“:”, 也可在非末行尾加符号“\”完成.
7 w1 S7 k( W% {6 n, r2 {Maple 7有4种输出方式: Maple语言、格式化文本(Character Notation)、固定格式记法(Typeset Notation)、标准数学记法(Standard Math Notation). 通常采用标准数学记法.
) A* O/ W3 U+ t5 xMaple会认识一些输入的变量名称, 如希腊字母等. 为了使用方便, 现将希腊字母表罗列如下,输入时只需录入相应的英文,要输入大写希腊字母, 只需把英文首字母大写:
5 u% |4 e- h6 ? 0 t0 \2 A: G7 w) a+ F' d
/ ]3 a: s4 R: m% K9 f- P* B 3 H2 L7 _! N" a$ J
3 }) Z) x- B; L2 s; ?, @& c
+ n8 B0 E1 b: K6 f; a* _; x$ S6 K8 _ 7 x) `- o# }' w. A- h6 z
1 ~! |/ {; e& ]$ g- J4 ?1 |6 O
9 t, P- X" ^3 ~2 j- u" d9 h8 k
$ P( |8 D+ G* h1 @" X; l 7 G& F9 C1 y; d3 j
6 [( j1 r8 i% s' {
. f1 S2 L3 F! F8 q7 _& U$ _
- _& r6 L+ W) a K3 c0 Talpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu
1 B2 E$ p% G3 I- K- {% q+ B Q" ^ " K3 K6 u4 U- u7 t) \' ^7 S7 w
5 |5 P' g. x% u$ y( H, l
4 D5 C- x: Y7 s8 p
8 I8 \9 h" S8 | B+ G8 a' m
5 \! p0 T1 E, F/ \ ; d1 ^& L( ~& J- i" b2 j) a
1 Y8 ?! {0 c' }
" @3 r' I1 [: e" |. k9 ^3 f4 u ( f/ t$ @( ~- Z3 \
/ k/ v, K+ z$ ]; \
; ]5 A5 N+ b7 b- v + K N. ?6 ?/ u: P" i) p
4 a+ F8 `: j# I2 J" y8 v$ r% F
nu xi omicron pi rho sigma tau upsilon phi chi psi omega
. P+ l5 K& y- i有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:
6 H8 O! ]$ `" M' B! g> for i to 10 do
/ b+ I5 o4 P! b' b. m* ^printf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));
4 j4 ^' d* j- s6 I P# ]& rod;
3 k" d! Y- s- d8 M& [i=+1 and i^(1/2)=+1.000i=+2 and i^(1/2)=+1.414i=+3 and i^(1/2)=+1.732i=+4 and i^(1/2)=+2.000i=+5 and i^(1/2)=+2.236i=+6 and i^(1/2)=+2.449i=+7 and i^(1/2)=+2.646i=+8 and i^(1/2)=+2.828i=+9 and i^(1/2)=+3.000i=+10 and i^(1/2)=+3.162
5 G K; m& Z1 s; {/ @+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:- ~9 q" z2 h8 Q, v2 c% P
> for i to 10 do
/ [& o7 w( x1 }' \. `, _0 s* jprintf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));7 j, h8 r6 P6 H8 U, e
od;
4 O7 S! o* a& t1 F1 c3 n# u5 oi=+1 and i^(1/2)=+1.0009 S2 n+ z, `" d% b7 v/ U
i=+2 and i^(1/2)=+1.4140 R3 k5 i9 \1 g
i=+3 and i^(1/2)=+1.732% x* B7 c# K" G! K* y4 u* \
i=+4 and i^(1/2)=+2.0004 M* o! Q5 w; D; T1 t- f% K% |
i=+5 and i^(1/2)=+2.236# a/ b5 E/ d3 v- I$ N1 q+ o
i=+6 and i^(1/2)=+2.449
; ?3 Q1 ]$ j. ~/ b" ?i=+7 and i^(1/2)=+2.646" h, }8 f! ?8 Y. ?
i=+8 and i^(1/2)=+2.828
) l! o3 d' n) U w, pi=+9 and i^(1/2)=+3.000
G! z9 L2 @! h6 p8 Q6 _+ Q6 hi=+10 and i^(1/2)=+3.162; B3 E. ^* m9 v+ [2 U# f
再看下例:将输入的两个数字用特殊形式打印:; B- ?! l1 f3 B+ P6 M7 N2 w: \
> niceP:=proc(x,y)) Q" Z3 m; L9 a- S: V
printf("value of x=%6.4f, value of y=%6.4f",x,y);0 D# H7 e. N6 n% [
end proc;
# Z, X- B' v: B6 J5 f
" o, n& z( W. k> niceP(2.4,2002.204);
1 R3 T, F6 M# h/ h0 Tvalue of x=2.4000, value of y=2002.2040
) O3 N; ], G; @7 ?. \# S1.4 Maple联机帮助
, X) H( D, a. O# V9 C学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用.
% b1 w3 u: b8 J4 J9 }- k3 i. q在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可. . l0 k1 q5 _! G% ?" Z5 {
2 Maple的基本运算
4 L: F( n$ N9 O n( {2.1 数值计算问题( O v9 P+ p) A6 N& f& {
算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”. , C; `# y' F1 } Q! Y4 _1 q
在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之, 是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数. 7 |& A) F7 T0 G1 R( a
Maple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算. * R% B. D3 m; @* p) @
但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
c( O" l$ F# S) ~$ _第一个简单的数值计算实例想说明Maple数值计算的答案的正确性: , r5 e5 T/ v7 q" @9 z6 x# ]
> 3!!!;6 Q( j( L5 ?/ W) {9 D8 M8 T$ C
26012189435657951002049032270810436111915218750169457857275418378508356311569473822406785779581304570826199205758922472595366415651620520158737919845877408325291052446903888118841237643411919510455053466586162432719401971139098455367272785370993456298555867193697740700037004307837589974206767840169672078462806292290321071616698672605489884455142571939854994489395944960640451323621402659861930732493697704776060676806701764916694030348199618814556251955925669188308255149429475965372748456246288242345265977897377408964665539924359287862125159674832209760295056966999272846705637471375330192483135870761254126834158601294475660114554207495899525635430682886346310849656506827715529962567908452357025521862223581300167008345234432368219357931847019565107297818043541738905607274280485839959197290217266122912984205160675790362323376994539641914751755675576953922338030568253085999774416757843528159134613403946049012695420288383471013637338244845066600933484844407119312925376946573543373757247722301815340326471775319845373414786743270484579837866187032574059389242157096959946305575210632032634932092207383209233563099232675044017017605720260108292880423356066430898887102973807975780130560495763428386830571906622052911748225105366977566030295740433879834715185526028053338663571391010463364197690973974322859942198370469791099563033896046758898657957111765666700391567481531159439800436253993997312030664906013253113047190288984918562037666691644687911252491937544258458950003115616829743046411425380748972817233759553806617198014046779356147936352662656833395097600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006 b5 @8 L6 `, f% V7 v+ [
上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?( y9 |" b' w" A. G# x H
为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式! G: `* S3 J* x6 ?; y/ L! ]: B
* S1 Z7 N) k) t. Y9 A
可得: , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为: 2 p1 {1 r! h. m' h6 H z! {9 Y" X
+ ?1 J: D* ~7 `9 i! U
这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性. 8 L: j) j* x' @; K" V
另一个例子则想说明Maple计算的局限性:
! K- ]) T& d7 ?8 @' Z* W$ d w 7 E; U1 }: y( L$ W" w( A8 d+ Z
Maple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:
/ b" W j6 q- _* z
* x' ?8 {6 o! K. ]显然这是错误的. 这一点可以从代数的角度予以分析. ! Y8 f# {6 g" F$ j6 e6 N d0 m
不妨设 , 则 , 即 , 显然 有3个结果, -2是其实数结果.
0 i& y2 d5 X- J4 C. Q: j另一方面, 设 , 则 , 即:$ V8 J2 S0 Y$ E' v9 x7 t
+ W. O E6 @& K7 K# T6 a
显然 有6个结果, -2、2是其实数结果. / M9 B% B$ s! _
这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性. & Z! R& N! T/ [' r6 H1 B
尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的.
5 @1 u2 _2 \! m* C' D* J2.1.1 有理数运算
% B# A4 l ]: H作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20). 8 d% m. h2 b) p
> 12!+(7*8^2)-12345/125;
" o) o: X, [. [) a' U! l
; v( C# Y% x+ x% m) z> 123456789/987654321;2 d8 B( A/ X3 |* O5 j' u
9 K) B0 D* q. s: [. Y
> evalf(%);# h6 F7 ?; _9 y5 `/ D) n7 t0 h3 F
0 R8 o3 ^& w: h> 10!; 100*100+1000+10+1; (100+100)*100-9;
7 l6 r% `. w- m* f" D+ S# p1 \2 Q
_# }+ S) t: C# ^8 M4 u
9 a5 r' X" ^, Z [' [" s 5 ?/ @' Y d- ]% _. o N
> big_number:=3^(3^3);' y* Y' V* e( S# M/ S0 X
! u5 m x* J; R
> length(%);
8 H( v0 o& [: o# ~0 N( z! F3 @
0 {( ]" f" W& o" b5 V/ n上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:
! ~/ _( s+ T( j( R 1)整数的余(irem)/商(iquo): d) G3 }! [; \; ?% W- w
命令格式:
4 M% \7 F( D; j" A- sirem(m,n); #求m除以n的余数, H9 K& z6 m: x+ E8 `$ F& M4 v
irem(m,n,'q'); #求m除以n的余数, 并将商赋给q
4 L/ @( x' T0 T. ]' Fiquo(m,n); #求m除以n的商数& K9 y) |- f( _2 F- x+ T3 K& {% j
iquo(m,n,'r'); #求m除以n的商数, 并将余数赋给r. d* p! A7 M+ V3 G& E0 v7 v% }
其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值. 4 b" T2 t$ i: {6 N Y. i+ Q7 a& d
> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
. n9 k* _8 w! O2 h% w' g , \- g4 D+ V' g
> q; #显示q) @/ |! j: o& [% g! _* {
; }/ D. n1 k* J7 k+ x
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r3 r+ ^* u0 ]( W% U8 ?% M* u
( j P& _5 i7 Z" g/ X6 E> r; #显示r
9 W. F$ d4 k& a2 Q0 A2 A
' n& p4 h+ Z" h0 r+ O7 h> irem(x,3);
* w [' g+ ?: f/ u, G1 v7 t ^
7 |* f& _) I# C, Z9 w+ {2)素数判别(isprime)
6 G3 c# J; l0 k( v- U: T' f素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n); * {1 h" ^4 f. h# I4 o3 w0 b1 n7 a
如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
/ d8 {0 |. ~& u1 L> isprime(2^(2^4)+1);8 s t* ]% ^( k& H
" h4 n l: X6 w
> isprime(2^(2^5)+1);
- }& e3 E Z+ b# J: E/ c7 ^( H# u 8 @( [( f) h' b5 c7 _% k" {9 X
上述两个例子是一个有趣的数论难题。形如 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多. " p+ v# L" c; {
3) 确定第i个素数(ithprime)
% Z7 h; c0 a: ~, N" g( `若记第1个素数为2,判断第i个素数的命令格式: ithprime(i); " M+ b5 b! }: q2 t% e! J* ?
> ithprime(2002);5 r; z: K& Y2 g- r! K8 ] ^
/ W# J7 U5 w; b* J2 {/ _
> ithprime(10000);) G7 E: q1 e* |9 [) \# ] r
1 T1 R$ Q1 B9 }2 s
4) 确定下一个较大(nextprime)/较小(prevprime)素数+ J- l3 S! P( g( L2 ^
当n为整数时,判断比n稍大或稍小的素数的命令格式为:
{( f5 s5 T$ X' S% Fnextprime(n); ; y" x8 n, o, `9 S* v
prevprime(n);
& t. |9 [9 S+ X; s. D+ s9 h! D( d2 c> nextprime(2002);
! {. t2 B5 b' |. c . J; @9 l3 T3 @0 x, q& j1 D1 A& ]
> prevprime(2002);
; ?- Z5 v( u$ l3 Y
% n- J( e/ a- G" D) J& Y( @0 g5) 一组数的最大值(max)/最小值(min)
/ b$ t5 Z* e& T9 Y命令格式: max(x1,x2,…,xn); #求x1,x2,…,xn中的最大值
3 |) @- \0 X- F( ? min(x1,x2,…,xn); #求x1,x2,…,xn中的最小值
: z; w2 a7 f' S1 A4 d6 Q8 K6 y> max(1/5,ln(3),9/17,-infinity);( B+ u% Y @# K3 {( O8 F' u
3 Z5 O8 I+ n' ~; j
> min(x+1,x+2,y);) ^6 G2 L0 _ c; Z C9 J, i" Q
+ x. @. Q, H1 v8 n2 j* |' V6)模运算(mod/modp/mods)& Q# c; N. l% ]4 \# `
命令格式: e mod m; # 表达式e对m的整数的模运算5 ? L! Z q2 u( O. Y0 S) }
modp(e,m); # e对正数m的模运算! ~- {3 r2 F: H0 g
mods(e,m); # e对m负对称数(即 -m)的模运算, w* |, t& ~7 M( P0 I
`mod`(e,m); # 表达式e对m的整数的模运算, 与e mod m等价# ~+ n4 Q' v, }) y
值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/. ! s7 K* c0 t7 x" ~
> 2002 mod 101;
8 k3 V$ J& N/ Q8 ? l 2 v" e& }2 t0 I
> modp(2002,101);
$ F2 o: f# E" {6 @) a4 ? o2 X1 _0 g
$ _ T8 [% r( e; e> mods(49,100);
0 y/ R" k7 A& \( h
: p: x+ A! `' R. g+ m \7 n9 T$ J> mods(51,100);
+ l3 F7 |/ e- ?+ R- x' c4 D4 N+ l4 w
, e' A+ D8 b9 j/ `: {> 2^101 mod 2002; # 同 2 &^101 mod 2002;6 \, Y y4 X5 k* N2 a w R0 V
5 S, b: J: e9 b. P2 L
7)随机数生成器(rand)
3 U- Q; U2 f, ~6 x命令格式: 7 B# K5 ]6 ~' T& `- V5 m+ l0 S' n
rand( ); #随机返回一个12位数字的非负整数! u! D* P8 w# P
rand(a..b); #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数2 L; k& y" W! y3 M3 L
> rand();! C, J- J) [8 O
3 Q% I! |$ X- q6 R( M# U# y
> myproc:=rand(1..2002):
7 O# Q/ x% N+ r% a" o6 V1 d. `! ~> myproc();
) J- g$ _ @8 }
* a, L# @4 t5 h> myproc();1 o( D& `1 e5 n+ [' P5 G$ w
; a3 E; J5 z$ f% l
注意, rand(n)是rand(0..n-1)的简写形式./ `# e* W" A4 ?5 r* [2 A6 ]& ?
2.1.2 复数运算
# p. i+ R5 ^0 T复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验: % G* Z0 o+ n- f' O, b2 ~4 u+ B2 b
> complex_number:=(1+2*I)*(3+4*I);
, k, q) k7 d" j& U ) I. W9 K3 l$ L+ w9 M
> Re(%);Im(%%);conjugate(%%%);argument(complex_number);: t& ?2 P/ @( B; j( d' Y4 q; W
7 d* P4 o$ w1 \, m% O0 U- B 8 J+ u S0 ~1 E
" p" U4 z) n: }8 E$ j, K5 n8 E; _
) h. [) n' ~# z值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%. % u+ T6 h% K& v! N4 @
为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下: + g$ H% d4 [( c ?
1) 绝对值函数
1 F& |* A5 `- l# l( j1 T命令格式: abs(expr);
3 a8 q) D& d% F7 p当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.
) O* I3 H' ]: R> abs(-2002); #常数的绝对值: A! C" m% L- a$ S3 m, [ r5 B/ D! @
- P$ R) \, `7 ]; k4 e& M" R
> abs(1+2*I); #复数的模
5 g) z: | q; ]
1 d- G) D" E+ M# U+ n& `2 c1 ?; ?> abs(sqrt(3)*I*u^2*v); #复数表达式的绝对值
6 }4 P0 t5 D! B% k 2 a) R6 D; f. y+ u7 D8 J
> abs(2*x-5); #函数表达式的绝对值
& C h* y* G* s; i
* g- g/ g6 Z7 G( e2 X9 I: Z2)复数的幅角函数$ v2 e: m+ K( a2 J
命令格式: argument(x); #返回复数x的幅角的主值' t: h! d* X$ \ @; k4 Z
> argument(6+11*I);
; e) d5 J9 K. e5 {
4 _# s# T, U; v$ x5 T$ Y2 l> argument(exp(4*Pi/3*I));- y- q$ Q* I3 I( b
/ H8 U9 s0 x5 t# C# |3)共轭复数
: @2 `3 D+ l' D9 R# Q1 P( z) l命令格式: conjugate(x); #返回x的共轭复数0 c6 d' i7 T! I& @' U- I' K
> conjugate(6+8*I);. L% V8 h' l0 s0 t; |$ L
^2 M: U2 C9 g/ y
> conjugate(exp(4*Pi/3*I));
6 y1 R+ b; [. a# F' ~; \- ?) z' _
# a# _% [& D- q5 p. m2.1.3 数的进制转换0 j8 s6 p. X6 m0 V* v* C# y
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可.
0 M0 @/ x% Q% S5 r/ Z8 ]; ]命令格式: convert(expr, form, arg3, ...); + ^; v% D$ M5 l# R p
其中, expr为任意表达式, form为一名称, arg3, ... 可选项. 0 t" B: s& B! `6 S
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述. 2 Y" O& O/ h8 x$ S' u' r" q
1)基数之间的转换7 d1 h/ N* U- h% G7 q. }# d
命令格式: 8 ^& E8 l; C9 X
convert(n, base, beta); #将基数为10的数n转换为基数为beta的数% K+ F( C+ _8 k9 f$ b) ?( ?
convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数3 ^# b7 r2 n# @7 K" W* V I" }
> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
! T8 l/ o1 P/ r( l- n5 r* t ) p! y& a- R( N7 y' Z6 c" t, g
> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数# l- R$ [$ x* N' d
' M& ?% k' y- c& z& @> convert(2002,base,60); #将十进制数2002转换为60进制数, 得33(分钟)22(秒); y2 m* P" y/ ?$ p! b5 u- J
& Z, C6 k2 \0 E- {8 B- \5 a 2)转换为二进制形式- `+ w' ? y* @* x$ q
命令格式: convert(n, binary);# s3 M) D- f# k+ ?+ c7 l
其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂. ; I9 v1 o$ h! h& o! g! h4 B: q
> convert(2002,binary);
2 b7 U" F! t: v2 y9 b' c7 Q( D 6 c. E! O% u$ u
> convert(-1999,binary);
- s ]# `0 U1 S; G! ~7 g! H
7 L7 y/ e: B$ J. _> convert(1999.7,binary); 4 v- L' G/ R" y+ A( d3 N
! M! \/ {& T- J" }
3)转换为十进制形式
& f- _8 h; F) s/ k其它数值转换为十进制的命令格式为: 7 s% A8 H# s, M; {3 G
convert(n, decimal, binary); #将一个2进制数n转换为10进制数
2 ^, d: D) o7 \% t/ H0 G1 V convert(n, decimal, octal); #将一个8进制数n转换为10进制数/ E; f6 s' h0 r3 z& u8 u( V$ c9 X
convert(string, decimal, hex); #将一个16进制字符串string转换为10进制数
2 R) A* p2 ?% [> convert(11111010010, decimal, binary); 2 G2 c8 W9 R+ r8 S6 Y/ H
& i5 K+ K0 m( D7 Z: v> convert(-1234, decimal, octal);
6 @8 O' e# ^4 i; [' L0 x4 s
2 b! d" F8 Z" k# m. j! S9 o+ Z3 J> convert("2A.C", decimal, hex);
2 L6 E6 [7 c0 g
: S6 y2 r/ u& t( K0 Y4) 转换为16进制数
J' S' {/ M6 H Q, g8 r2 n3 z3 s将自然数n转换为16进制数的命令格式为: convert(n, hex);
- {$ g" O% T5 s5 E! e> convert(2002,hex); convert(1999,hex);
1 p( a( d- I+ ^
6 N. D0 K+ b( N
5 l1 s# }) I1 n5)转换为浮点数: s/ U, A7 f. s8 Y8 J
命令格式: convert(expr, float);1 w7 S6 f9 c+ b3 d
注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用. ' i5 m: \/ `4 W5 R& K% ~
> convert(1999/2002,float);
% C4 B, \% @6 h+ X; G9 ?% O
7 T: `5 Y2 v1 L3 m> convert(Pi,float);
" p. u$ A3 I( j- o5 E 8 d- g5 T: g! F5 Y
2.2 初等数学2 r$ W) [* ]( y6 k, _$ g \
初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识.
' N9 N* i1 e% V4 [6 V3 P2.2.1 常用函数
+ I1 S1 |* N/ B% U2 \4 T- O+ W3 H' S作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下: 0 @0 a& v. x0 l
指数函数: exp
+ b9 M: t' }: j一般对数: log[a]$ ]# w: [. X" u+ j u
自然函数: ln) O$ J, e3 D* R, x- ^- S3 H# V
常用对数: log10$ Z( P, p( {1 R, O; h
平方根: sqrt
' t) r% b# b1 t6 [绝对值: abs
' a4 e# \: ^) }' t5 G% ^/ c! ]/ Y; B三角函数: sin、cos、tan、sec、csc、cot
1 A1 D' v. Z) t8 @/ @反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot2 r% s8 s u/ T0 ]% |" |
双曲函数: sinh、cosh、tanh、sech、csch、coth
& X: L" w2 g8 r& N( c! ?( Y7 V反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth# V; ]2 |8 C T& |' i4 L% R& i
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY
' c- z( {4 [- ? A, g$ jGamma函数: GAMMA
( @" S r! `8 n1 d6 ?# V3 O误差函数: erf6 C' P5 w8 \! y
函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能. ( x, V* K/ c4 j" I4 y) t& c
1) 确定乘积和不确定乘积
' g9 W& Z% b7 p U0 N# ]' K命令格式: product(f,k);
! p8 v4 i# p, X: p# i+ gproduct(f,k=m..n); - X w- j0 d1 ? k0 p7 H; K7 _
product(f,k=alpha);
3 _! \# r: J5 zproduct(f,k=expr);: T8 \, z( `( w8 E E" G/ ^
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf, expr—包含k的任意表达式.
2 E( c; z5 k" y9 E X> product(k^2,k=1..10); #计算 关于1..10的连乘
4 ^, l1 h0 _/ R+ Q/ j- p& e; } ' c4 ?! r( N) P4 d$ l) B1 W% a7 O5 V
> product(k^2,k); #计算 的不确定乘积7 X/ e9 n; n! N3 |. K) q
: _9 K# \, a: i- ~
> product(a[k],k=0..5); #计算ai(i=0..5)的连乘9 ~' l* i! M. ^0 I$ T q5 e; ^
* {/ N4 i1 n+ ~! j7 a! H8 U c
> product(a[k],k=0..n); #计算ai(i=0..n)的连乘2 F! |( t; a6 e% O
0 R9 l9 u- A8 E, B& C+ ~" R
> Product(n+k,k=0..m)=product(n+k,k=0..m); #计算(n+k)的连乘, 并写出其惰性表达式% x$ }) L- f3 p% M
2 P- N/ V1 r8 F4 Y
> product(k,k=RootOf(x^3-2)); #计算 的三个根的乘积 o. X6 D! a. }' ^8 k
3 A( E% L4 l2 _9 Z3 G product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回 函数. 典型的例子是:
# I9 G; S1 X& Q) F% }1 t> product(x+k,k=0..n-1);* d" G' s- \4 q3 ]1 j3 n6 d
" Y6 J9 H0 {6 _9 e" g( D如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如: * @' i P$ x+ ~: V
> mul(x+k,k=0..3);
/ x# {/ o D! a4 u % x$ ]1 A. y; k
2)指数函数; X' \9 I6 t0 t/ e
计算指数函数exp关于x的表达式的命令格式为: exp(x);
8 y J/ r/ }' u3 _- H: M> exp(1);7 d4 U/ ?% L$ F. `7 Y, I
, |; n- O* x* F2 r3 p
> evalf(%);
8 _& R& `1 c; S# w8 E
. K6 `+ e5 `& @* {9 s% @. K! `> exp(1.29+2*I);: `8 r$ P' o# \- U4 g+ Z
$ p5 H7 t# j& n [) s% d# \2 U
> evalc(exp(x+I*y));% ~$ d# i, ^, z& Z3 D+ S
1 Q) q; a/ Y, w9 T
3)确定求和与不确定求和sum$ S8 ]6 J" W7 l5 _
命令格式: sum(f,k);
) S8 t9 h* Z! h4 z0 z' B; zsum(f,k=m..n);
/ I& e2 {/ M. [2 @& ~( `sum(f,k=alpha); 3 \: ^& i# o8 a0 Q4 I+ E5 Q4 r9 `2 C
sum(f,k=expr);, s! g6 o/ ?) N* N$ f; N
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf, expr—不含k的表达式.
& k: R8 Y, k4 O$ d( b$ E- G0 O> Sum(k^2,k=1..n)=sum(k^2,k=1..n);1 h/ c, b1 L6 K! _2 {2 Y5 }' ]
' h+ V* A2 k# U9 A# [; e& a! K% j, W
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);
' ], M B$ {' ~6 E3 q: y) ]+ E . S* O1 f8 ?* q% }
> Sum(k^4,k=1..n)=sum(k^4,k=1..n);/ _' ?( C4 ~" T; R" T# H
( L' a7 ?( g3 s6 a
> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);
- n7 H+ T" Y7 w5 z, p2 }, |( q- p- `! w
5 g& C2 h z# d) ?; C> sum(a[k]*x[k],k=0..n);( L2 b5 W2 e5 |1 O$ V
' P4 F& K+ {$ f' a6 n2 H
> Sum(k/(k+1),k)=sum(k/(k+1),k);
6 [6 n8 W& q0 O3 h5 r4 _
3 R8 [+ N! {- ?: Y1 _5 d> sum(k/(k+1),k=RootOf(x^2-3));5 ~- Z1 \. }* _9 k W
0 i8 N [( E# zsum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的. # V/ d' S" G* X: R! V4 _
> Sum('k','k'=0..n)=sum('k','k'=0..n);
0 G: v1 c* z; j0 r1 b5 {4 q) K
9 [; |' j6 i, J; ]2 u4 r如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:
6 K6 {' e7 ~8 g- k0 a _0 x> add(k,k=1..100);5 y( ^4 }+ \; e& b$ Q y
0 K3 l& q8 t4 \/ q6 E
尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令. . a: D Q2 Q0 i& e
另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性. " S( b W( X2 D" v |9 v
3)三角函数/双曲函数0 e8 ~4 A" H2 [: i
命令格式: sin(x); cos(x); tan(x); cot(x); sec(x); csc(x);0 x3 j3 e5 N7 F
sinh(x); cosh(x); tanh(x); coth(x); sech(x); csch(x);; @4 H( Y+ p7 z. Q1 j4 c6 Z3 k
其中, x为任意表达式.
0 A9 W/ i! v. \, B2 v1 n值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.5 O {& a! s4 W9 Q* D3 C
> Sin(Pi)=sin(Pi);7 i7 M* ^. y7 w( V. a& C0 T
9 b) r# O: g/ c( e9 D1 ^- [) G> coth(1.9+2.1*I);5 ^8 U0 i+ R% T( Z
6 d4 j9 u4 z4 l" N# U
> expand(sin(x+y)); #展开表达式$ _; I* N- s2 y$ y. E6 T1 C7 ^
) ~( H5 M( n* C% Z; K
> combine(%); #合并表达式1 e; ?' ]# C& B/ h5 t5 B
5 l$ C* L* n# S. s3 r- I> convert(sin(7*Pi/60),'radical');" s! ?7 D( C3 M/ R9 {; N; G
2 v( E/ j, b# `6 ^2 n
> evalf(%);# N5 g' s" W# x# {9 g( M* O
; I- {5 E% n3 U6 `$ f5 _9 n& v+ K但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.
/ S) m+ C, K0 x+ I+ H4 ?* T4)反三角函数/反双曲函数
# F7 I! v) q# _# g5 E命令格式: arcsin(x); arccos(x); arctan(x); arccot(x); arcsec(x); arccsc(x);
# Y. O+ j5 X% D* L% M arcsinh(x); arccosh(x); arctanh(x); arccoth(x); arcsech(x); arccsch(x); " z- P% Z7 Q5 R/ c# q) g
arctan(y,x);: [. G7 t) O+ s6 g. |
其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算. 2 S- p m- |8 i
算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.
7 q4 y* Q$ {% }( }> arcsinh(1);
# e, e1 t2 |& ]$ {- l
8 g$ h: Q7 v$ i9 u1 X" y> cos(arcsin(x));, B! ]1 i6 Y9 `; c x& }
' ?: C& l7 b4 W" E* t
> arcsin(1.9+2.1*I);1 @1 Y. P$ _; ~7 h' ^: u
- B- C! [* s* i- s1 d
5)对数函数$ ?: ]1 S- k0 O+ A
命令格式: ln(x); #自然对数
; Q8 c$ E7 x0 ?1 d" v; elog[a](x); #一般对数3 Q8 n: X0 S8 y- y' K: e# l
log10(x); #常用对数# P7 G+ c- {: Y Q5 T0 x! k* Q
一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有: . K0 `: p/ T m# j
(其中, ). J' S) I- U; J6 h; W$ R
> ln(2002.0);
A6 ?9 \; d7 V0 ~4 U. l
6 w$ z9 j% T2 c: i& _> ln(3+4*I);/ n; B3 l8 n/ n+ R$ u& }' G
0 V; ^4 K: Y: E0 ^' J6 D3 P> evalc(%); # 求出上式的实部、虚部
6 e/ ?+ b1 I/ K2 N: y5 }5 j
5 F; H K& s v2 Y: u- N> log10(1000000);
1 @1 Y' D* p. Y2 X. B8 ~! Z
2 G2 @4 O9 u/ X# O! \7 q> simplify(%); #化简上式* V7 `: f$ b v
- T& {1 B0 y" T1 [8 j2.2.2 函数的定义+ g* q; r: C0 F- |2 g/ k, A+ f
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子: , r B/ o+ O1 Z& s
> f(x):=a*x^2+b*x+c;; @3 i o% a' K1 k7 l
% r4 R. K2 r8 X* V& m/ \4 D
可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:
( a, o3 a i% {" r> f(x),f(0),f(1/a);8 f* M) s1 `; j, h0 d* B% I G2 A
& m0 Z E) K/ C6 o
由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:
/ @4 u# @( {) u/ i7 K- o2 o> print(f);+ g' K+ r* y- ~' H. g: c
; C& p9 h, E9 z9 f3 W
事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式.
- N3 y* W z& k7 U5 p9 |% [6 k在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):
" v8 E) i4 `6 x5 F' e( Y4 @, s> f:=x->a*x^2+b*x+c;6 w/ c: x7 U4 X- v! I+ z4 I
l$ K) ]' X3 Q N+ j3 b% s6 P> f(x),f(0),f(1/a);
5 K c7 `" ]1 V3 D 5 b- c8 e+ e; F3 D) ~
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
$ Z5 { b: r; P> f:=(x,y)->x^2+y^2;
/ K2 v2 h i6 i
% g9 D) x+ V" ^% C> f(1,2);4 S, v' b/ F. c% N/ y
J6 X u- Q% M6 b> f:=(x,y)->a*x*y*exp(x^2+y^2);
: x- x' L5 x/ V$ [# a3 q# x/ m + t' t2 l' W6 s# l O( h, [* Y6 W
综上所述, 箭头操作符定义函数的方式一般为: 5 |' r+ m8 |' y
一元函数: 参数->函数表达式
8 `! N) m* \8 U8 l多多函数: (参数序列)->函数表达式
# }& E0 C. I1 c无参数函数也许不好理解, 但可以用来定义常函数: 8 q0 P3 b3 a) i4 X* y
> E:=()->exp(1);
0 n' U& I, Z! I. ]
2 [8 z& B' E! c8 i% O$ E> E();( m& |0 b: H1 g+ U* P* g: a& d
1 o* w6 ^/ s; G, I* Y4 E ?0 X
> E(x);+ ?/ n$ M# L$ `4 @. w
' R: J" Q# W. G* p) q另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数. $ R( _/ T) X2 ^0 B% j; {
定义一个表达式为expr的关于x的函数f的命令格式为: f:=unapply(expr, x); 7 D! y4 {3 q0 v; C
定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为: f:=unapply(expr, x, y, …); ( A; D1 V( j; t% O- o0 q
> f:=unapply(x^4+x^3+x^2+x+1,x);! L2 v3 Z% @: J6 ^) w; e( S
1 J. D1 h; R2 S$ i8 ]# {
> f(4);
P } [! w; k W, q % p5 @, z1 C4 _: a& K& r5 X! G
> f:=unapply(x*y/(x^2+y^2),x,y);) H0 `! {3 W" J3 d5 \' y8 ?- y# \% y
, g7 @/ x0 R' B } R% O
> f(1,1);) [+ T B( ^" X
$ B: K. Z. o* g" J
借助函数piecewise可以生成简单分段函数:* L" _6 b9 a* i
> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);9 A! A' T0 F( [( x8 e
4 i1 w4 g" z% {) k# f清除函数的定义用命令unassign. # {; W6 T' L } `4 G; x5 N
> unassign(f);2 N Y0 B7 m9 W, u/ z' E( q
> f(1,1);0 Z) w0 {% n7 U7 x
) K- @- }' J" G: K6 H) Y
除此之外, 还可以通过程序设计方式定义函数(参见第6章).
4 N9 {# Y6 V: i& P% J' J定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:
. w2 d! s) j5 H+ A$ yop(expr);
7 e, J9 D) d* t# u3 ]2 E2 Hop(i, expr); ( H$ Y3 K% {. H
op(i .. j, expr);
- O1 [! Q/ s; W1 Z2 U5 S, Knops(expr);9 s5 i! c8 B; `3 B U
如果函数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的类型.
4 J& }* g: l6 R& c3 J命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.+ c# ~% t8 t; p# b
命令op(expr); 等价于op(1..nops(expr), expr); - l& f2 K. m5 `1 D% Z- C1 Z" j) y. P" \
特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
8 F1 O- p. @! n( B ?: f6 r; p而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和. 0 p! b% A$ U( k
> expr:=6+cos(x)+sin(x)*cos(x)^2;' h9 ~3 S# G5 ~, o: @2 E- R1 `
- Y7 S2 {+ t/ ~2 L% a. F9 [( J# C> op(expr);
+ J: Z6 B- y; l7 o; I
, M+ G- k, R$ U' F> nops(expr);, H! I# t4 @6 E0 J3 T
5 H1 V4 L* a# I! Y3 J
> p:=x^2*y+3*x^3*z+2;" Y( A: C4 p1 ^' a! ~# M- Y! M
9 w& T6 j, @4 _1 x
> op(1,p);% P" |: b- j. B
& V( J' W" N! B' E> op(1..nops(p),p);$ h% d' _# `. O+ ]1 j, k
& G; j# `) A f7 c' u* j0 }3 _
> op(op(2,p));7 e) o1 I ^5 T
) G! v: a: d2 t, c& m1 \ }
> u:=[1,4,9];
; w* N/ ~& g# q" m& l* x& x
+ D8 a) h' F* w> op(0,u);
, r+ G, @5 N, ^; x: S . @' x4 ^+ H# Y2 c" ]
> s:=series(sin(x),x=1,3);+ W# V8 ^1 Y1 B/ N i! p' a3 i
6 v+ {. p" b( s* z. C, r& e4 i> op(0,s);
" E1 v6 x- x( _9 z6 o" R # B; y y) }; D7 Z$ l9 h
> nops(s);2 M4 v5 n6 S$ t+ b% a
/ w: j4 b; E7 I, W. h下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:
' E" p9 k& j# C2 N( j3 n) `> op(x*y*z);3 k6 S& j8 v q# ^7 ] n: t: ^
, U* h3 p. A7 W+ C- k5 k6 I+ m0 g
> op(x*y*z+1);
8 l8 Z Q- P, }, J, F! z
, @; `- ?4 e" I4 B% z5 N2.2.3 Maple中的常量与变量名; I4 _$ g/ i- w4 S+ q
为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中: 8 e% F% K$ V1 G) e
> constants;8 K. N, w% C! N& N8 }, u- m
6 g, ~7 t! Q) R
为了方便使用, 现将上述常数的具体含义列示如下: 4 W! \) d- w' R5 {; i# w; r
常 数 名 称 近似值
* s7 w: ?' h" [5 y9 @ o6 F圆周率
7 P. u1 m! }; q: J0 [Pi 3.1415926535
$ a8 E; Q/ d1 kCatalan常数 % d$ e$ j. m" H/ {; }
Catalan 0.9159655942
( t' b* [7 Q2 {1 n$ t Q* H( w- H! REuler-Mascheroni常数 + L4 p9 p% ]/ h
gamma 0.57721566491 z F4 f' ]1 M$ G
" T0 h1 {; N6 Z: \: T7 h! E
infinity
Q9 \" u8 s3 y; G
& R9 H! ?& y: ~需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取.
4 x: m( W* P& E1 f& k在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”. ) Z& O8 s1 ?2 x9 @( t+ f
值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量 用Pi表示, 而pi则仅为符号 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名.
$ O* o! [$ ^7 s% k+ z/ {在Maple中有一些保留字不可以被用作变量名: + j9 O0 p, _% d- r( c
by do done elif else end fi for
8 z+ ?' c) o2 h. n' }from if in local od option options proc h8 o' c6 _+ R( |$ Q
quit read save stop then to while D( C) F4 {+ Q0 L6 h1 ?) t
Maple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名. 8 K2 W( w4 K- f! E
另外一个值得注意的是在Maple中三种类型引号的不同作用: ' a% e2 w) |, x
` `: 界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;
/ ~' u8 [- k3 i4 t7 t$ @4 [2 y% \# z; z' ': 界定一个暂时不求值的表达式;
. O1 I2 [ K9 T1 Q; i; d" ": 界定一个字符串, 它不能被赋值. . [3 R6 N, _0 ^ @
2.2.4 函数类型转换 5 b: h: X) o4 f( L& m" a; z: f
函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式:
1 G U9 x, a' _( R4 h$ j; o# W convert(expr, form); #把数学式expr转换成form的形式
2 h$ N4 P& U6 R, P& | A* P Iconvert(expr, form, x); #指定变量x, 此时form只适于exp、sin、cos: j j6 q. D$ ^) y
convert指令所提供的三角函数、指数与函数的转换共有exp等7种:
( B9 {* p( Y4 _" T% P; W+ H- D K2 @(1) exp: 将三角函数转换成指数! O# h+ G! A4 Y/ [2 \# t) J4 h
(2) expln: 把数学式转换成指数与对数
$ _9 }, i2 D5 B' G( h: A @(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式
" w3 k# P4 T: _. K: d8 ]6 Q(4) ln: 将反三角函数转换成对数
+ B$ _' Y( N; v( N1 c(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式
$ W/ O- g$ p) A( x' ^: h+ x(6) tan: 将三角函数转换成tan的形式
0 x" U; ]2 o' P, B# ~$ u! b4 U7 s1 T6 X& _(7) trig: 将指数函数转换成三角函数与对数函数& L' q( {* v' r) X0 y
> convert(sinh(x),exp); #将sinh(x)转换成exp类型+ R7 H8 {4 h: G0 O4 A8 N
: k1 ]2 p: G3 n% `$ T7 S> convert(cos(x)*sinh(y),exp);
; ]9 {! G# G V- H) [: v5 p 9 g/ p0 X W. @9 L" a
> convert(cos(x)*sinh(y),exp,y);
7 b \ A6 e/ V) e
# o0 I0 R; s5 }2 d, D> convert(exp(x)*exp(x^(-2)),trig);/ w, v9 s( G7 z( j9 j ~/ G
( ~% L$ p' P5 F7 F> convert(arcsinh(x)*cos(x),expln);
[2 n# L4 d& I, N4 Q! |
0 p3 q1 e8 O6 |> convert(cot(x)+sinh(x),expsincos);
" f* T4 V4 H+ s$ C. B& u. I4 y+ {
* E4 O" e; o: h$ o> convert(arctanh(x),ln);
" F5 W* u3 m' {# f* w - z3 ]& Z8 H4 h9 d
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:
$ L3 X+ C" v- M8 d, R8 P> with(codegen):
6 s; }8 o4 }4 u5 @5 W> p:=4*x^4+3*x^3+2*x^2-x;
5 h2 m) l8 _! p8 I1 T0 ` O2 t * a+ X F" d/ U) c
> cost(p);! _ K% Z, [& k2 D6 M: Y/ J
# ]! g7 f) {2 q ]& Q& E3 H> convert(p,'horner'); #将展开的表达式转换成嵌套形式
* }5 J8 |# G: \* }8 `- {. \* M
2 v* t, S5 C, P" Q8 u% a& f2 J% X> cost(%);
$ R: T5 [2 b1 | D' n4 F+ Q E
% ]2 G! E* O1 G+ ]! A- Y/ K" y同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量.
6 C: I5 ]2 B4 k" T6 I. v+ t" G; o> (1+x+x^2+x^3)/p;
" J$ r- V" n4 C0 k- ~; A
5 q; b9 S! ~6 B! P1 h/ W- Q> cost(%);
* [# l. V( D" P1 `/ ] 4 \$ A" K! P- O6 j+ N# S
> convert(%%,'confrac',x);
% o% H7 T% C/ s3 e3 N2 G
; i! ^5 ~" T5 ]: R/ k% d7 Q* Q> cost(%);
3 _% d2 h3 F: m0 j, S) n$ k1 j % u7 o7 e% [6 `+ v. V6 ]1 V
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式. * k5 o8 S; K) M: I, b$ d
> convert(%%, 'parfrac',x);
6 P3 [% y: B: U8 H* f
1 h3 \: b# C0 P( P ]> cost(%);
, [! @& Q1 o/ W" ?, L 1 I3 B; ~; A5 r
而把分数转换成连分数的方法为:
1 k: |. u( ~( p7 J5 U> with(numtheory):
+ M" D3 \6 F. z' q9 p; k8 R> cfrac(339/284);' e w# h" G+ ]$ Z
D8 ^- ^8 W: D/ a. {7 s2.2.5 函数的映射—map指令
Y& v/ w+ c( _: x5 }在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:1 ?* S/ e! `7 ?* k' E% C0 \
map(f, expr); #将函数f映射到expr的每个操作数
k! ~& H: M/ c& h& |4 dmap(f, expr, a); #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量: f) A/ ^1 r* g$ w& F- w2 x4 q
map(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量
) W) X# l( `% z/ i% {# [map2(f, a1, expr, a2, …, an); #以a1为第1个自变量, expr的操作数为第2个自变量, a2为! `' r% T- ^$ r, ~0 U8 d2 d
第3个自变量…, an为第n+1个自变量来映射函数f3 j* Z5 a2 C9 G% w
> map(f,x1+x2+x3+x4,a1,a2,a3,a4);! B' T& x) A/ K9 L5 N
0 ?1 u( \3 A' } L6 M! q; P; d% O> f:=x->sqrt(x)+x^2;
/ Q- g( T7 ~' O }
, U9 m V' I) V/ t> map(f,[a,b,c]);
X0 H) z; T0 r$ e6 b5 F
! g, ?3 q' c8 @! d, M> map(h, [a,b,c],x,y);
9 V1 [5 n% L0 M+ m8 z # f" q4 p) t7 g$ Q
> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);0 z% W4 R0 }9 {2 h e
$ R. ?7 E/ j& [0 d( N' u
> map(x->convert(x,exp),[sin(x),cos(x)]);7 B. `1 P( o1 M. r8 I) z- I
0 g. b1 Z) r8 G9 z( t0 _/ |2 @
上式的映射关系可通过下式理解:5 V. ~, g+ C: d
> [convert(sin(x),exp),convert(cos(x),exp)];
0 @# a3 ~4 V( [( y* j' s ! ?1 h$ C2 }& `/ P. v( T! x; c. A
> restart: - C$ i. i; e* |- J4 s
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);
* \" {' q1 ?$ F! o$ \ + M! G+ l* p& \, \$ ^3 R5 V5 D
> map2(max,k,[a,b,c,d]);
+ R! ^1 ^6 O' U9 [! P* H
. J: ?9 r z1 X% K) N Y; H再看下面示例:
# E2 X' V2 W' O, N" t5 T5 U> L:=[seq(i,i=1..10)];) D$ f# g [1 W4 _( k- i
; J# y8 ^& b+ a5 Q! g4 X1 ~> nops(L);
# {) A6 W# \+ T
7 R c5 ?" \' G3 l> sqr:=(x)->x^2;
# o& j! Q/ D2 C" G: W* a6 N; n + @3 T- T& \4 J! R |
> map(sqr,L);
6 U" t1 _9 P& x# C* p3 }
8 T+ G3 O7 L4 j* V; a> map((x)->x+1,L);6 H" D4 d/ {7 C5 ~ V3 b
& A6 H' K7 I0 t4 ]1 `> map(f,L);
3 W& ]9 M' ?+ j8 N, ~1 C { 1 Q8 r& o* X2 ?. u
> map(f,{a,b,c});
8 ^' B3 m; v9 b1 s* |( X
+ l' X3 j* ~; I, T+ B% _9 h" H$ D> map(sqr,x+y*z);
1 k+ ?, E% l$ @! x; F. g " h4 L4 S4 @) o( ?! }. o: ^- Y; M1 @
> M:=linalg[matrix](3,3,(i,j)->i+j);- r) |. o& l5 l( ?) D# h& l
0 r" i( K* o1 K> map((x)->1/x,M);
/ v; K4 l4 c/ o/ u% Y 9 D6 [: e3 E! E9 q
3 求 值 a' p3 q7 b5 T+ ]" B8 `+ |
3.1 赋值
$ r V0 e: Z/ j5 a在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子.
; c% K% k! z' X8 ~ B1 e> p:=9*x^3-37*x^2+47*x-19;
$ t# O3 r$ @8 E1 o
6 B, @3 ?5 g; n) Y> roots(p);
2 T/ }- K8 f2 c& {& R' x
# D7 i @) n+ ?$ ^& q( T- e> subs(x=19/9,p);) V1 u, Q2 v- F E. o
9 [2 Z# Q) f( O4 o8 O" L7 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;”这样的简单语句即可验证. # _! Y! \6 z) }
3.2 变量代换, \4 u" v" a5 Z
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:
( h' ^4 e2 ? \- y# Psubs ( var = repacedment, expression);' I) x; t( o5 X. g( B
调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement.
" k: e4 V t, @$ o> f:=x^2+exp(x^3)-8;, e- Y: V; S; {7 F* i/ ]
' f1 ]; U* f/ y+ _4 t+ s
> subs(x=1,f);- U! L+ @$ t" Q: G6 j& z9 z( ]# d( Z
2 z* Y3 B% d% a% m' A* l5 t
> subs(x=0,cos(x)*(sin(x)+x^2+5));
2 H8 p* N P" I' r" k 6 P6 N8 R6 ` j9 T" }
由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如: C# L) ?! k v: [- \$ @
> evalf(%);0 ]- w9 Y/ [8 ]. I5 ?
8 R3 r0 J- p6 s" c变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:
' |! P! l6 b$ d, vsubs (var1 = repacedment1, var2 = repacedment2, expression)% o& L; d0 R7 ]$ S/ b
调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换; 与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:
' f( B2 n/ S6 J2 m% O6 _subs ( {var1 = repacedment1, var2 = repacedment2 }, expression)
" e# M: d) n8 l2 Y+ l4 d下面通过例子说明这几种形式的替换. $ J2 @$ L' N' y' t, E! w2 B
> subs(x=y,y=z,x^2*y); (顺序替换)
0 P6 o$ T) h; e* d+ r
2 C6 w, g5 U% O1 x> subs({x=y,y=z},x^2*y); (同步替换)
7 h: u0 p! x/ K6 f4 K% L3 \
4 R# o9 e' e; [ J> subs((a=b,b=c,c=a),a+2*b+3*c); (顺序替换)( @8 j- x; G2 V) e4 Z. q
$ w, w( r' d1 y( }7 k) E1 B
> subs({a=b,b=c,c=a},a+2*b+3*c); (轮 换)
/ a2 R$ l6 Q3 V& n% i 8 `0 n4 M% z, j6 T+ \
> subs({p=q,q=p},f(p,q)); (互 换)5 K" o- @, d7 g, O6 Y
$ }$ D1 D2 O1 {" h6 d |3 j- c3.3 假设机制
7 @/ v$ B5 H! dMaple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程 的解. 如果k是实数, 结果显然是x=1, 但如果k是 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点. 3 ^1 A+ J; Z" A0 R9 X" G
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);
: C9 ]0 P# P* F( @, i函数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);”也不会产生矛盾.
/ q% f& A; J7 w4 i> Int(exp(-s*t),t=0..infinity);
, q9 x: B1 M: ^( v
8 g- {4 e+ q$ M- p> value(%);+ C1 a) A6 {4 N% }! o; U* `% R6 ~
Definite integration: Can't determine if the integral is convergent.: N8 H# a% d% l- E' U# l1 s
Need to know the sign of --> s
" j. t; c4 p; k! v( BWill now try indefinite integration and then take limits.
, O" c# m0 m' S6 T4 x2 K
4 i1 X5 ~0 v( G6 Q& D> assume(s>0);5 x7 n# ]! `- h2 Q2 O* C
> Int(exp(-s*t),t=0..infinity);
/ B5 q, I9 r& w3 b! J4 j 8 \# }6 c" y" f: ?; C
> value(%);
2 c/ b0 u; e+ a + x r- d7 l1 l! v3 n
3.4 求值规则
. m$ C+ d' [1 c0 Q* I0 {4 E在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:
: k' c+ x8 y' U3 S% q1 j6 S0 E V> x:=y;
& { b# N$ V+ \/ X& k2 ?/ K4 ^3 D
2 T( L! I6 z* `, w/ k: h> y:=z;
. g! p) W- }. n2 S% _- m ) M' b( ` B$ a& E2 g% o% e! t4 Y5 w
> z:=3;; o, B$ u) Z4 A1 g
) `# D! d8 b! [' n> x;
, s2 z% W+ V( h9 F# t
& b: p9 H$ o$ v' e! }> y;1 T% }5 \! k! r! z% h$ z6 Z
; d2 K5 ?/ }. k l+ A# M> x:='x';
" z% D# r1 @9 S; r1 e6 \
/ k$ a4 |1 I; V- n' p6 E: S& x) T> x;
$ {& H2 q0 x ^ K a s3 R/ Z# c% F" @5 [# K
> y;/ F3 a9 e; u, c% }7 Z
& O9 W* B/ p' |2 ?0 B2 P3 i
对于不同的问题, Maple设计了不同的求值命令. 现分述如下:
& |3 C2 n' y9 H, F# O2 ^1) 对表达式求值
+ o$ e2 q* S1 e8 [5 Y' ]9 N$ i命令格式: eval(e, x=a); #求表达式e在x=a处的值
% ?) h# j0 x3 E eval(e, eqns); #对方程或方程组eqns求值6 ~( g& t. `0 E6 o' f
eval(e); #表达式e求值到上面两层5 o- r0 e, b/ h/ n8 p
eval(x,n); #给出求值名称的第n层求值2 h2 _) k2 p+ X$ g
> p:=x^5+x^4+x^3+x^2+x+73;& a) `' [. I" S# r+ |
^' ]- l. j' M! i. N' U) b* P
> eval(p,x=7);$ I& p* @6 s8 o0 p. S, p- s; q
. S n0 X1 r! m3 c3 S
> P:=exp(y)+x*y+exp(x);9 P8 b8 s5 ~5 }3 n; q3 b( A
4 u6 @; c0 t& Z8 a2 W) I> eval(P,[x=2,y=3]);
) ~/ z7 a, z f/ y9 _; I: ` ; ?- \- e1 s# b5 a0 e8 a7 ^' ? G
当表达式在异常点处求值时, eval会给一个错误消息. 如下: ) ?" ^" M& C5 A4 y
> eval(sin(x)/x,x=0);
7 l0 k+ M& v; v o: G$ e6 ^3 RError, numeric exception: division by zero
. [2 S5 S6 T( g- o# [% t 下面再看使用eval进行全层求值或者对名称几层求值的示例:
! S0 m4 J+ z6 E4 L4 f; O, \> a:=b: b:=c: c:=x+1:
* j; p8 ^0 F5 o: \3 [( @. k/ J> a; #默认的全层递归求值
& @6 _( \6 T9 l ; C4 j- e4 @# M2 b
> eval(a); #强制全层递归求值
. B; V0 }4 f2 O4 M h( D 0 K1 ^8 p# H6 [# n# e& g+ b9 o2 |
> eval(a,1); #对a一层求值
% g. X0 ]* x) m 7 _' c6 s4 z' Y/ W0 v
> eval(a,2); #对a二层求值
: @9 q) U& Q6 n7 D3 O" b Z
& @3 p( m3 Q, \( S8 D |> eval(a,3); #对a三层求值
`3 O; K- O7 P- U4 [& h" M, `) \
3 b/ R' y- P- o6 Z. @> eval(a,4); #对a四层求值
2 I' u, m! M7 x1 Q 3 t0 i( V/ R& R9 J+ g; q
2) 在代数数(或者函数)域求值4 }' U# S3 Q* i- ^( I& Z2 q
命令格式: evala(expr); # 对表达式或者未求值函数求值
* K5 i. m* h# U' o* Y3 x evala(expr,opts); #求值时可加选项(opts)
6 l4 d1 O; I+ j5 @! r( D8 R所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式 的根就不能表示成为根式的形式.
. f9 Z3 h/ R+ E$ ?' I代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如 作为一个代数数, 可以表示为:
5 G% A7 s) \( s1 N4 ^) K6 H> alpha:=RootOf(x^2-3,x);' \4 x) _! P" T0 i
- J6 N! X, t$ C; p0 y> simplify(alpha^2);
$ p. Y% d5 a& O 6 x& U5 @, _ M- u
在Maple内部, 代数数 不再表示为根式, 而在化简时, 仅仅利用到 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:
0 F: N% E+ A, }> alias(alpha=RootOf(x^2-2)):
5 ^/ q) V# }0 f9 y# M> evala(factor(x^2-2,alpha),lenstra);
$ k, m" K: h$ r* [' N& n4 X # t/ S; S' Y+ E4 \
> evala(quo(x^2-x+3,x-alpha,x,'r'));
' n+ x7 Z: `; x8 Z& h8 G6 F# g * K$ c1 w' m$ N/ M3 f; Z) o" }; |
> r;- R3 x t z E3 t
* v; ^* V% Y' x
> simplify(%);
5 D4 m5 G5 o% H! q) q2 e. k
) A" e; J' M% x3) 在复数域上符号求值
, V6 t8 N* E7 q- d7 T操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
$ P4 k; v* g) \evalc(expr);
- `! {) d5 g4 ~' fevalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
7 o0 c6 c, d* o- b" ?5 f> evalc(sin(6+8*I));4 X* n- w! D O' [1 P
. @5 {4 i9 U: A8 r
> evalc(f(exp(alpha+x*I)));
r! x: R) k- E* m! i' ~7 G% M$ U: H * X! s1 i y( l1 L3 ?- k' z p
> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));
5 t2 @8 R+ P8 r V& ]0 D5 v: C8 M/ l ; ^. u/ Z) A2 o, J: U. ^ x
4) 使用浮点算法求值3 m. \1 q' P. j1 t; R
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n); ! ?* Q' ?+ N# y$ t
> evalf(Pi,50);
$ M l F- S0 r8 Z4 |% E1 [
% s3 h0 Y: y. S> evalf(sin(3+4*I));
0 V" Q3 |9 u4 Z) S 2 Z" I# Z1 ^7 X% E4 C
> evalf(int(sin(x)/x,x=0..1),20);3 y1 T: H9 p3 b6 n( X- y, X
" h0 I( G8 w% G* _ l3 F$ t, t5) 对惰性函数求值+ D% n% e8 \( \. }* }& e' {
把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f); 3 I$ v6 R4 B/ {) n% N+ B2 o
> F:=Int(exp(x),x);
; `9 }: C/ C* a1 f8 ? / L# h( ^ Y2 @5 _5 M, d
> value(%);
- D+ |( }* s p$ j) } # \- H. q0 A/ a% K% |" r+ n) I
> f:=Limit(sin(x)/x,x=0);& `2 T+ |5 R6 v/ v
) q( Y* g* s- q ^! O$ L) X: F> value(%);5 ?0 W9 a2 {9 D+ F$ G
" ~7 M; ~% k' ^/ s
另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:
2 a5 N$ t9 w9 A# Y O& }> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);
( i7 i9 ]1 O% F, g
6 t2 A! P5 U k4 数据结构
# @2 v( `8 D# D0 Z$ fMaple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
& [' M a J3 \! c! P, G+ L8 p2 z4.1 数据类型查询
0 R, {) G, Q8 x8 S% F) _; p* g; Y在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为: 7 u% d6 z# b4 u
whattype(expr) # 查询expr的数据类型
- S1 R; i5 ?7 s3 M$ Ntype(expr, t) # 查询expr是否为t类型, 若是则返回true, 否则返回false3 X5 U; R4 a8 j x8 q7 y
> whattype(12);: s1 B$ D( O: I7 f& N
6 t5 e4 Q. j) b9 J: X! L% O) [> whattype(Pi);
6 }& W0 Z. F [, J; u# b# k
. E W/ W# ]; b; g> type(1.1,fraction);
- E9 C# p2 l B , |! [$ W* G. R. I
> whattype(1.1);0 ?1 e; A6 q4 [% S
; L3 ?; ^+ [2 ]3 g, R. q9 U5 r
4.2 序列, 列表和集合
6 b$ R" A$ b, T3 f) c2 L4.2.1 序列
' ]7 y' ]7 L! r$ A1 b9 E9 j; j所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:
( F' D0 A7 X( ]1 V> s:=1,4,9,16,25;
8 ]' d8 ]$ T$ k) H 6 d8 `( v3 ?1 K1 l3 C3 w5 L
> t:=sin,com,tan,cot;
/ z3 P: a9 ]& n" O, `
# C. H/ b- J. m* P2 X3 T& m# i一个序列也可以由若干个序列复合而成, 如: ( \ q9 j5 |; h4 N1 L
> s:=1,(4,9,16),25;9 w+ h, a2 U: \: A% I
4 j, e! p& B1 L4 [' H+ v> s,s;/ A7 R# }( e* q
0 |3 g m! U# d8 J, L1 ~
而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:
! F1 g# S5 c2 K6 z: i> max(s);1 O, I, E9 X! `
% n: m, F. g/ P9 Q# T" o, x
> min(s,0,s);4 v5 i+ g# x2 o4 Z
) s9 ]# q, w9 k' S ?. d
值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中.
{5 |+ R) S7 I% u% F* B+ ]* q2 z> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;( G8 d4 G, t' S6 F
% C: p7 t! [+ N# K% a
> op(s);4 `3 I, K$ w/ N U U( [1 t
Error, wrong number (or type) of parameters in function op
2 y4 b- m" z+ f' H# F% G& A> nops(s);
3 x* [) ]. P6 u/ e) G* sError, wrong number (or type) of parameters in function nops
8 n) I5 {: g3 }> op([s]);
2 D5 V% T( ~& _! I 5 b5 u8 t4 I0 K: D
> nops([stuff]);' s7 h. k7 L G" B
9 L/ e: b8 u( d; ^7 `6 _( Q函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:
2 ]9 ?, ~$ o8 ?% y- }& |seq(f(i), i=m..n); # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)( A, H9 i3 S" L" j" g
seq(f(i), i=expr); # 生成一个f映射expr操作数的序列
2 q0 {- q" _! e1 Tseq(f(op(i,expr)), i=1..nops(expr)); # 生成nops(expr)个元素组成的序列
" M& ]5 ?* }, Q2 t, n ]* ?> seq(i^2,i=1..10);& @) B- s5 D1 B# V
% T4 Q1 l" X) }( k7 ]1 y" ~> seq(ithprime(i),i=1..20);7 f8 g/ i) ]1 E8 O+ R% `
" i- e$ w( e6 E4 R4 x+ L! k
> seq(i^3,i=x+y+z);
, M+ f0 h& h1 Z $ L% m* l' `! R- }" Q
> seq(D(f),f=[sin,cos,tan,cot]);
1 ^, ^ Z W8 I& O 6 h; e: I0 ]2 H/ u/ u$ m
> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));* x$ m2 d- ~* a8 Z
3 z, a2 v u+ i5 o/ y5 c! N获得一个序列中的特定元素选用操作符[ ], 如:
9 |! V& f0 M) P% Z8 ^> seq(ithprime(i),i=1..20);
" L* W5 e, x! i5 P . J. k1 @/ _) l: P# [2 @
> %[6],%[17];
1 X3 {9 Q* B7 L, d: b ; _ O% P5 k1 a U i) t9 P
4.2.2 列表
* H+ b2 {1 O: q S1 K, _列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[ ]表示列表. 如下例:
+ F8 Y1 j+ l: D- ]+ U> l:=[x,1,1-z,x];1 M! M' l( z' c5 r2 e8 m/ \9 [
5 Y* r# M- [: w* C1 H1 Q8 O
> whattype(%);
( T" S# f8 ~# |8 h: K( x J% p6 I ' ?2 f/ u/ i; N4 S: N
空列表定义为[ ]. ( j. h' U0 x/ L2 p
但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的: . c4 |( @+ s |/ l$ @8 k
> L:=[1,2,3,4];4 b5 e! v. a1 ^6 v! ^8 X
( k0 u# J* p, t, C
> M:=[2,3,4,1];
6 Z& f7 s$ |3 N # D9 w! J! P& U5 A# ~% X% z M
4.2.3 集合, m. Z* S4 ^: I
集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合.
* Y/ |- n/ S1 w4 [/ t> s:={x,1,1-z,x};+ V: ?+ z6 T; n, j) Q
0 A/ W6 Q. y2 z
> whattype(%);3 ]3 W* B4 ^7 \+ {3 Z" E& d+ s
3 F7 a. t% u: O/ Q空集定义为{ }.
$ M( N! d4 {- i7 t' Z: w h函数nop返回列表或集合的元素数, 而op则可返回其第I个元素. ( H, q' B. i9 |+ g; m: Z
> op(1,s);
+ W- J Q- M6 C* q0 x$ d
: ^0 p' J2 j* U> s[1];/ ~$ c9 W& v3 h, l, `# X
7 b0 I4 o* b) v( |- r( K> op(1..3,s);
+ F: e- h) w0 I7 d6 X
: R6 b: S# H5 D( e: g. t> s[1..3];
( R, B* D5 |1 B0 G1 x 2 E7 G% G6 Y2 W) L. x: M5 N& r+ v
函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false.
$ n; l- O0 I! ]- q6 m7 [; D> member(1+x,s);3 a% j; l; N; g3 s8 n
) a: B" }# @2 a1 v" v6 r$ t可以通过下述方法在列表中增减元素:
7 h) e' n U( ?0 F> t:=[op(s),x];2 X4 M: E! n4 {) l/ x4 D
& {/ h$ B! y- e" D1 M
> u:=[s[1..5],s[7..nops(s)]];
5 O" d8 g( h r
' z1 A6 b4 W V' L" x) a1 H* n3 ^# oMaple中集合的基本运算有交(intersect)、并(union)、差(minus): 7 Y$ F& w: l4 E" t4 \$ Z* g
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};- L1 r" v; C; C7 v1 K9 r5 {( D* o
( Z# i8 ^9 _# y' p& D& | 8 a& Q( y n& y
> A intersect B; C/ q G$ i ]7 n' N, {4 P$ b# K! \
$ f9 q" z0 r9 ^' E' n+ C6 B
> A union B; ' |( r8 J5 f) c* f
* d C+ }8 h, V1 f0 P> A minus B;& C% C2 u0 t1 }8 d
# X7 Z' b9 \! K6 e; c; n1 c- j
4.3 数组和表# c' x6 c8 P) B0 B! Q
在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令. 7 @8 T; o0 q3 ^% D3 b; @
表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的.
5 |$ z- J8 G. {! p> A:=array(1..4);
9 U7 U8 L% t$ ?5 f+ j& s% Q! P ' w* F- \9 g& e$ U) M
> for i from 1 to 4 do A[i]:=i: od:- |8 d( G: B! U& i1 W1 ~6 C$ _! m
> eval(A);! X L! q" `: Q4 U& P4 c, {. P8 m
5 J0 v. l( k4 n9 P: H& z8 }
> type(A,array);3 Y, K% W8 ~* h) a' D. B
# W+ g4 ~5 I) c/ r" s> type(A,list);$ |6 ]+ ]# C! A: U: X* u3 `0 d# x4 X3 l
0 `3 o/ E( X- V. N
> T:=table();
+ B- M$ W! a8 L7 m0 d7 B" G 6 `+ R6 z. _" T- `5 o" j) d
> T[1]:= 1;4 r( _% l6 {+ e8 n# {1 p8 m
/ @7 g/ H7 \+ {5 Z7 z _
> T[5]:= 5;
* G) ?) ? b" r# l3 F 7 e3 x* H6 {9 t7 ?2 e. b, q, s8 q
> T[3]:= 3;
0 g$ [; F: _" v( k Z* Y5 w9 _
: R% H6 v% w# y" D> T[sam]:=sally;
3 v+ n' x) c4 F4 m' w+ R& |
" v* m; m6 M; G( P: B1 k- N> T[Pi]:=exp(1);
! }' W* W$ e1 _4 S( i2 p ) G# \$ H" N8 b: V1 ~5 @: y# f
> x:='x';
% E- W( q7 I1 B3 q. f5 b: @
" _0 S% b V; {8 n> T[(1+x+x^3)*sin(x)] := 0;
3 ~5 ?7 q* l% {2 ~4 s* m. v
( d, [8 c: o# D. j$ X( G1 I# C# r> eval(T);
5 f) U2 z0 v% `' t& W+ H
: y* _4 s U$ ]> T[3]:='T[3]';4 M: q3 t" v: q
3 U! y' o0 R/ j& n8 g$ e
> eval(T);. b. k+ d3 w3 [) ^7 h8 t
; A0 |7 |8 H; x
4.4 其他数据结构9 h# P6 M' }2 U5 ?5 q/ @
串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来.
' a$ ?, R+ P2 m& \4 D- h8 r4 q索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立. ! b; Q8 }5 L% P0 e" \$ i B7 Z1 e
> x:=T[3];
- Z$ i3 D3 Q1 g# m: t+ [4 `" {
8 q" l& Q+ _& v8 i$ I0 e: _: K> eval(T);$ m) n; C$ _' \ {
% b! ~; q% j$ q% k
> T[5]:=y;1 U8 t4 V9 k+ w! ^. p
. X3 ?7 g9 d" J. \4 ?, q
> eval(T); ^0 [3 t0 B( k8 C
8 \; a( |6 @4 l, h, u
由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值. 7 a# W- X6 \1 t
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数. : M5 l7 `6 {9 [1 Q8 ?
4.5 数据类型转换和合并
8 ^& s% S+ w0 v1 ~, w1 Mconvert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换: ! ?1 C5 @% U" V) K) z" b
> L:=[1,2,3,4];8 @1 {6 _) H# K$ D! X
# C2 a; H6 c; R, d4 B> type(L,list);
' w3 Y& m) E& }1 d
" N" ]$ {7 B8 L* `> A:=convert(L,array);
4 j+ u6 j1 t2 ~, W& J* ?1 U 9 n6 y5 J! ]* f3 |
> type(A,list);, K W+ y5 {4 X: i
; o9 z+ I$ `) m> type(A,array);
$ d2 o7 P* u2 d/ X+ J1 x( k- ]
% n) ?$ Z: t6 l, H7 g另一个有用的函数zip则可把两个列表或向量合并:
# q9 E0 B# [, E/ h# m0 h>L:=[seq(i,i=1..10)];
' H& U4 u" Q2 s* u0 m/ r1 ? 1 [! y8 N( w4 M: m( r0 T
> Sqr:=(x)->x^2;1 x8 s' [5 G! h1 l: `
/ ^$ w! @2 f7 e2 |+ |> M:=map(sqr,L);; }4 Z5 T; p& D& O6 g5 _" H
" {$ c$ }5 r* w8 R
> LM:=zip((x,y)->[x,y],L,M); S+ f! L/ y! X" p) V2 D4 X; Z e& x
/ @1 d8 O1 m; H5 H
> map(op,LM);' |7 X H+ S+ b# c g
6 U. v1 |! _* B2 c8 u# T
5 Maple高级输入与输出操作5 q+ j# q# H8 c' z( m7 i. K5 a. p
Maple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里.
/ a) D# t" [. f, T6 a. Y/ Z5.1 写入文件
, S q* t' e4 l u. ^" O# _, p5.1.1 将数值数据写入到一个文件
* i7 T8 k6 I' V' ~: J( ]如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令. - G+ U' Y9 L5 I$ l! h) m. F1 D& T
若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);2 |. S+ q% {4 Y, c$ h, V; g: }/ F4 k
> with(linalg):' m5 K1 o$ C- F; Q5 |0 B1 }
> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);
! d7 l: M% b3 E9 x. t' p& l
# I! `1 s5 W4 A$ M/ h> writedata("e:\\filename.txt",M);. x+ Q5 X5 H7 O. D$ X: Y6 L
而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);
+ ~9 Y1 g9 K7 Z2 a) g7 P> W:=matrix(2,2,[1,2,3,4]);
4 }" b" M7 M M& H
. h) z" v0 s6 U& ]8 D! T7 \> writedata[APPEND]("e:\\filename.txt",W);' v9 e; O- x, [, L
需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.6 l+ g5 c+ x$ J1 T& ^
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);& c% A4 p( X2 `# l% ^3 u! `6 n
> writedata[APPEND]("e:\\filename.txt",W); 9 i' B7 {5 m2 Y. K) }% z
> writedata('terminal',M);
1 A+ p" G3 d2 K& m% {2 [4 d1 2 3
1 X" _7 L4 l0 v+ Q* `( R: R4 5 6
3 J& r( ^' s- Y! o1 m) c7 8 9
Y' x/ T- {6 Q3 v; I( _- Z1 e5.1.2 将Maple语句写入一个文件7 y" Z) ~7 V2 ?5 k9 e% T
如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:
7 s) {3 n7 @1 p. A3 b# Zsave name, "filename";/ M4 L4 W" F* K5 \
save name1, name2, …, "filename";& |& T A' f D
若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.& h! e) b* t* ~& r" C
> myfunc:=(k,n)->sum(x^k/k!,x=1..n);2 O, F4 I1 u" c! \$ a# X5 ~ P
" l" M7 t) s5 H" n! P- v" Z m
> myresult:=myfunc(6,8);
+ F% p5 {1 _6 \' O% l4 O9 Z $ |0 Z' p( Q# `( a9 o
> save myfunc,myresult,"e:\\test.m";
' I8 G7 w: `- g% ]4 s调用已存m文件用命令read. 试看下述实验:8 z) O4 v p, s# n4 n) U
> restart:8 j7 }. h* s: o0 h5 _+ Z
> myfunc(6,8);
: n" @& b* L" F) c* H3 { & }& u9 @4 h% k9 j, s
> read "e:\\test.m";
* T! w4 C: v8 H" y9 x0 ?0 W8 i: S> myfunc(6,8);8 T% r9 v( [6 o# G( w
, ^- h$ A! V }( H+ c6 Q, Z6 z> myresult;: ~" M6 T1 }* y- z; ^
1 Y# R2 p7 X5 t; m7 f: s0 S$ b 而存为txt文件时则将整个语句存为一个文件:
Y4 |9 {; w2 Z- s: Q' g9 i> save myfunc,myresult,"e:\\test.txt";
$ a' s5 \5 ]; Z! m> restart: read"e:\\test.txt";
" e: e; F$ ]3 a+ ~5 h' s6 ~ / _# F6 ]7 X: T3 T" [! w. s
( H7 S* ]3 s: H5.2 读取文件( f% H6 N$ e8 o- b- T/ Y5 n* o
在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.
6 F9 P! N4 B: p# |$ Z' U, A2 Y* F5.2.1 读取数值数据
( [' v5 b* E3 X如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.# G4 E1 b+ K0 \- ]4 I
从filename文件里读取n行数据时使用命令: readdata("filename",n);
/ w6 C: {, a$ Q3 p% H以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);
# V j V2 ? j" B: U' z0 V- ` H> readdata("e:\\filename.txt",3);
" c* }% X# Y& h
9 r0 v$ f0 w& ]# T2 s- w1 {& F 读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:7 G }$ E$ {. c4 N# v3 u
> readdata("e:\\filename.txt",[integer,float,float]);/ c, S( q: R F) U
6 y! g) K8 m1 Q- |1 q下面再看一个运用大量的实验数据在Maple环境绘图的实验:
: z1 W) z/ T9 `, O9 @> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:) |9 R7 y$ ^7 _/ j/ M% Z
> writedata("e:\\data.txt",evalf(mypts));
% g/ E! g, K* W> dots:=readdata("e:\\data.txt",100):- s! Q3 B$ w3 N2 Y& ^* I5 g! b
> nops(dots);
; \! R, H3 V3 @+ X- J* |0 H( u% ^ J
8 ?6 j2 a: y" {! c- g5 A7 h6 h> dots[1..4];! _$ `. z# A! U8 f5 J& f* B
6 p3 v# t6 {- T
> plot(dots,style=line);
- N" v9 `* `* x* t3 R0 |& ^ 2 m% }2 E* |! Q
5.2.2 读取Maple的指令! a: U4 d" x. L# k$ X
在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:4 ]" J8 b! T6 C. `8 L( I! U) Q
read "filename";
% e" I) m! u1 I1 S如下例:( N" @$ e8 F6 Z% U' { i
> reatart:
, p- Y' |! C- y+ H+ y) g! F$ J7 y> myfunc:=(a::list)->add(i,i=a);
h7 H2 o, }4 l; ~! o
& V; j1 f1 |3 O# b' y> avg:=(a::list)->myfunc(a)/nops(a);
/ N+ o4 L0 Q# P% c: [% m 9 W0 }3 o! }6 W% h% o3 m
> save myfunc,avg,"e:\\function.m";
: h9 s, R/ ~) m1 |" Y& X) I, W; v> restart:
8 |0 ~2 |% `, p, n8 _1 g) G2 \> read "e:\\function.m";
5 Q' a& [/ X% ^% j$ q( I3 J# Z, z> myfunc([1,2,3,4,5,6,7,8,9]);& J9 F+ k" V' P" C8 l
5 g. Q5 f/ F& P! n, C2 M> avg([1,2,3,4,5,6,7,8,9]);5 Y% z4 J2 ]- v9 G' R1 l
& J7 n* f T+ V G& @5.3 与其它程序语言的连接1 h! L* B! c r
5.3.1 转换成FORTRAN或C语言' x! N2 I8 ~9 z: {% I3 f y
调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:. \+ P4 u/ k, o( q
> with(codegen,fortran):
$ o) M& g6 F1 D, x0 Ff:= 1-2*x+3*x^2-2*x^3+x^4;6 P2 j9 Y5 k/ y8 O: |7 V
# ?- [0 ?. j$ p
> fortran(%);
) P7 @+ o ^& C4 A V t0 = 1-2*x+3*x**2-2*x**3+x**4
# O. G) }# ] e6 I > fortran(f,optimized);
% ~2 c- Y7 {+ x1 U+ L, f t2 = x**28 N; H. b$ @, z: U$ f4 A0 g
t6 = t2**2
. i2 w5 k @* T- R2 M/ m t7 = 1-2*x+3*t2-2*t2*x+t65 W9 g1 N! m6 G
> fortran(convert(f,horner,x));
$ w! M9 `9 x& r9 S2 `/ u t0 = 1+(-2+(3+(-2+x)*x)*x)*x
; L. A. M2 P& O* p而codegen程序包中的C命令可以把Maple结果转换成C语言格式:
8 t) Q9 M j9 [/ V" |> with(codegen,C):
" D2 R: j# X+ {. s' Xf:=1-x/2+3*x^2-x^3+x^4;
/ V# F p2 I# u" w6 ] b, U + t+ `! @7 t# V7 h
> C(f);! z. m3 z! Q# O9 N8 R
t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;
* K! G3 P1 H7 w$ W# E9 d> C(f,optimized); @7 B9 }2 M1 Q9 g5 W- n- \
t2 = x*x;
& N1 @6 r2 m; K$ d/ z$ R. S t5 = t2*t2;
) K# X4 t' r4 y( U+ k t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;* f7 @, @- p3 f! D. S+ f* b
optimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.
5 R/ c& c' N {0 o" q2 k, p5.3.2 生成LATEX% i$ W1 {' ]) o1 p7 F# M
Maple可以把它的表达式转换成LATEX, 使用latex命令即可:
+ G5 O/ M( S5 Z n> latex(x^2+y^2=z^2);3 R5 w/ j1 Y6 f1 p1 M4 K
{x}^{2}+{y}^{2}={z}^{2}
+ B8 W6 q; P) V* \ 还可以将转换结果存为一个文件(LatexFile):( `" b$ d( j( W) v3 ^. I
> latex(x^2 + y^2 = z^2, LatexFile);
" O8 r' v" i7 m- v 再如下例:
0 [' V' h( D. J( J1 E5 n, p> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));: w! W5 v- J3 I
\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)
( G' k4 T* f2 O# k7 M( ]& G
( K; N; I+ W1 U# L |
zan
-
总评分: 体力 + 2
查看全部评分
|