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