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