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