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