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