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