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