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