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