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