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