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