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