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