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