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