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