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