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