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