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