竞赛:| 全国大学生数模竞赛 | 全国研究生数模竞赛 | 全国大学生电工数模竞赛 | 美国"MCM/ICM" 竞赛 |
 资讯:| 数学理论 | 交叉学科 | 基础教育 | 考研数学 | 学术动态 | 编程交流 | 网络安全 | 经验技巧 |
 下载:| 数 学 篇 | 算 法 篇 | 建 模 篇 | 编 程 篇 | 数 据 篇 | 软 件 篇 | 考 研 篇 | 交叉学科 |
 视频:| 大学数学 | 大学英语 | 计 算 机 | 法律课程 | 政治课程 | 经济管理 | 数学建模 | 高考数学 |
 功能:| 矩阵论坛 | 学校协会 | 挑 战 赛 | 人才招聘 | 数学问吧 | "MC"理工浏览器 | "MCQ"即时通讯 |

 
会员中心
社区论坛
加入收藏
联系我们
您现在的位置: 数学中国 >> 资讯无限 >> 数学理论 >> 数学分支 >> 正文
【字体:           
 
第一章  Maple基础
作者:佚名    文章来源:本站原创    点击数:    更新时间:2006-8-30


 
第一章  Maple基础 

1 初识计算机代数系统Maple
1.1 Maple简说
1980年9月, 加拿大Waterloo大学的符号计算机研究小组成立, 开始了符号计算在计算机上实现的研究项目, 数学软件Maple是这个项目的产品. 目前, 这仍是一个正在研究的项目.
Maple的第一个商业版本是1985年出版的. 随后几经更新, 到1992年, Windows系统下的Maple 2面世后, Maple被广泛地使用, 得到越来越多的用户. 特别是1994年, Maple 3出版后, 兴起了Maple热. 1996年初, Maple 4问世, 1998年初, Maple 5正式发行. 目前广泛流行的是Maple 7以及2002年5月面市的Maple 8.
Maple是一个具有强大符号运算能力、数值计算能力、图形处理能力的交互式计算机代数系统(Computer Algebra System). 它可以借助键盘和显示器代替原来的笔和纸进行各种科学计算、数学推理、猜想的证明以及智能化文字处理.
Maple这个超强数学工具不仅适合数学家、物理学家、工程师, 还适合化学家、生物学家和社会学家, 总之, 它适合于所有需要科学计算的人.
1.2 Maple结构
Maple软件主要由三个部分组成: 用户界面(Iris)、代数运算器(Kernel)、外部函数库(External library). 用户界面和代数运算器是用C语言写成的, 只占整个软件的一小部分, 当系统启动时, 即被装入, 主要负责输入命令和算式的初步处理、显示结果、函数图象的显示等. 代数运算器负责输入的编译、基本的代数运算(如有理数运算、初等代数运算等)以及内存的管理. Maple的大部分数学函数和过程是用Maple自身的语言写成的, 存于外部函数库中. 当一个函数被调用时, 在多数情况下, Maple会自动将该函数的过程调入内存, 一些不常用的函数才需要用户自己调入, 如线性代数包、统计包等, 这使得Maple在资源的利用上具有很大的优势, 只有最有用的东西才留驻内存, 这保证了Maple可以在较小内存的计算机上正常运行. 用户可以查看Maple的非内存函数的源程序, 也可以将自己编的函数、过程加到Maple的程序库中, 或建立自己的函数库.
1.3 Maple输入输出方式
为了满足不同用户的需要, Maple可以更换输入输出格式: 从菜单“Options | Input Display和Out Display下可以选择所需的输入输出格式.
Maple 7有2种输入方式: Maple语言(Maple Notation)和标准数学记法(Standard Math Notation). Maple语言是一种结构良好、方便实用的内建高级语言, 它的语法和Pascal或C有一定程度的相似, 但有很大差别. 它支持多种数据操作命令, 如函数、序列、集合、列表、数组、表, 还包含许多数据操作命令, 如类型检验、选择、组合等. 标准数学记法就是我们常用的数学语言.
启动Maple, 会出现新建文档中的“[>”提示符, 这是Maple中可执行块的标志, 在“>”后即可输入命令, 结束用“;”(显示输出结果)或者“:”(不显示输出结果). 但是, 值得注意的是, 并不是说Maple的每一行只能执行一句命令, 而是在一个完整的可执行块中健入回车之后, Maple会执行当前执行块中所有命令(可以是若干条命令或者是一段程序). 如果要输入的命令很长, 不能在一行输完, 可以换行输入, 此时换行命令用“shift+Enter”组合键, 而在最后一行加入结束标志“;”或“:”, 也可在非末行尾加符号“\”完成.
Maple 7有4种输出方式: Maple语言、格式化文本(Character Notation)、固定格式记法(Typeset Notation)、标准数学记法(Standard Math Notation). 通常采用标准数学记法.
Maple会认识一些输入的变量名称, 如希腊字母等. 为了使用方便, 现将希腊字母表罗列如下,输入时只需录入相应的英文,要输入大写希腊字母, 只需把英文首字母大写:  
 
3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0    
alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu   
3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0  3.0    
nu xi omicron pi rho sigma tau upsilon phi chi psi omega 
有时候为了美观或特殊需要,可以采用Maple中的函数或程序设计方式控制其输出方式,如下例:
> for i to 10 do
printf("i=%+2d and i^(1/2)=%+6.3f", i, eval(sqrt(i)));
od;
i=+1 and i^(1/2)=+1.000i=+2 and i^(1/2)=+1.414i=+3 and i^(1/2)=+1.732i=+4 and i^(1/2)=+2.000i=+5 and i^(1/2)=+2.236i=+6 and i^(1/2)=+2.449i=+7 and i^(1/2)=+2.646i=+8 and i^(1/2)=+2.828i=+9 and i^(1/2)=+3.000i=+10 and i^(1/2)=+3.162
+2d的含义是带符号的十进位整数,域宽为2. 显然,这种输出方式不是我们想要的,为了得到更美观的输出效果,在语句中加入换行控制符“\n”即可:
> for i to 10 do
printf("i=%+2d and i^(1/2)=%+6.3f\n", i, eval(sqrt(i)));
od;
i=+1 and i^(1/2)=+1.000
i=+2 and i^(1/2)=+1.414
i=+3 and i^(1/2)=+1.732
i=+4 and i^(1/2)=+2.000
i=+5 and i^(1/2)=+2.236
i=+6 and i^(1/2)=+2.449
i=+7 and i^(1/2)=+2.646
i=+8 and i^(1/2)=+2.828
i=+9 and i^(1/2)=+3.000
i=+10 and i^(1/2)=+3.162
再看下例:将输入的两个数字用特殊形式打印:
> niceP:=proc(x,y)
printf("value of x=%6.4f, value of y=%6.4f",x,y);
end proc;
 
> niceP(2.4,2002.204);
value of x=2.4000, value of y=2002.2040
1.4 Maple联机帮助
学会寻求联机帮助是掌握一个软件的钥匙. Maple有一个非常好的联机帮助系统, 它包含了90%以上命令的使用说明. 要了解Maple的功能可用菜单帮助“Help”, 它给出Maple内容的浏览表, 这是一种树结构的目录表, 跟有…的词条说明其后还有子目录, 点击这样的词条后子目录就会出现(也可以用Tab键和up, down选定). 可以从底栏中看到函数命令全称, 例如, 我们选graphics…, 出现该条的子目录, 从中选2D…, 再选plot就可得到作函数图象的命令plot的完整帮助信息. 一般帮助信息都有实例, 我们可以将实例中的命令部分拷贝到作业面进行计算、演示, 由此可了解该命令的作用.
在使用过程中, 如果对一个命令把握不准, 可用键盘命令对某个命令进行查询. 例如, 在命令区输入命令“?plot”(或help(plot);), 然后回车将给出plot命令的帮助信息, 或者将鼠标放在选定的要查询的命令的任何位置再点击菜单中的“Help”即可.
2  Maple的基本运算
2.1 数值计算问题
算术是数学中最古老、最基础和最初等的一个分支, 它研究数的性质及其运算, 主要包括自然数、分数、小数的性质以及他们的加、减、乘、除四则运算. 在应用Maple做算术运算时, 只需将Maple当作一个“计算器”使用, 所不同的是命令结束时需加“;”或“:”.
在Maple中, 主要的算术运算符有“+”(加)、“–”(减)、“*”(乘)、“/”(除)以及“^”(乘方或幂,或记为**), 算术运算符与数字或字母一起组成任意表达式, 但其中“+”、“*”是最基本的运算, 其余运算均可归诸于求和或乘积形式. 算述表达式运算的次序为: 从左到右, 圆括号最先, 幂运算优先, 其次是乘除,最后是加减. 值得注意的是, “^”的表达式只能有两个操作数, 换言之, 3.0 是错误的, 而“+”或“*”的任意表达式可以有两个或者两个以上的操作数.
Maple有能力精确计算任意位的整数、有理数或者实数、复数的四则运算, 以及模算术、硬件浮点数和任意精度的浮点数甚至于矩阵的计算等等. 总之, Maple可以进行任意数值计算.
但是, 任何软件或程序毕竟只是人们进行科学研究的一种必要的辅助, 即便它有很多优点, 但也有它的局限性, 为了客观地认识数学软件、认识Maple, 下面通过两个简单例子予以说明.
第一个简单的数值计算实例想说明Maple数值计算的答案的正确性:  
> 3!!!;
2601218943565795100204903227081043611191521875016945785727541837850835631156947382240678577958130457082619920575892247259536641565162052015873791984587740832529105244690388811884123764341191951045505346658616243271940197113909845536727278537099345629855586719369774070003700430783758997420676784016967207846280629229032107161669867260548988445514257193985499448939594496064045132362140265986193073249369770477606067680670176491669403034819961881455625195592566918830825514942947596537274845624628824234526597789737740896466553992435928786212515967483220976029505696699927284670563747137533019248313587076125412683415860129447566011455420749589952563543068288634631084965650682771552996256790845235702552186222358130016700834523443236821935793184701956510729781804354173890560727428048583995919729021726612291298420516067579036232337699453964191475175567557695392233803056825308599977441675784352815913461340394604901269542028838347101363733824484506660093348484440711931292537694657354337375724772230181534032647177531984537341478674327048457983786618703257405938924215709695994630557521063203263493209220738320923356309923267504401701760572026010829288042335606643089888710297380797578013056049576342838683057190662205291174822510536697756603029574043387983471518552602805333866357139101046336419769097397432285994219837046979109956303389604675889865795711176566670039156748153115943980043625399399731203066490601325311304719028898491856203766669164468791125249193754425845895000311561682974304641142538074897281723375955380661719801404677935614793635266265683339509760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
上述运算结果在IBM PC机(1G, 128M)上计算只需要0.01秒, 得到如此复杂的结果(1747位), 一个自然的问题是: 答案正确吗?
为了回答这个问题, 我们借助于数值分析方法, 由Stiring公式
3.0
可得: 3.0 , 前三位数字与Maple输出结果相同, 且两者结果均为1747位. 另外, 在720!的计算中, 5的因子的个数为:  
3.0
这些5与足够多的2相乘将得到178个0, 而Maple的输出结果中最后178位数为零. 由此, 可以相信Maple结果的正确性.
另一个例子则想说明Maple计算的局限性:  
 3.0
Maple在处理问题时, 为了避免失根, 从不求算术式的近似值, 分数则化简为既约分数. 因此, 在Maple中很容易得到:  
3.0
显然这是错误的. 这一点可以从代数的角度予以分析.
不妨设3.0 , 则3.0 , 即3.0 , 显然3.0 有3个结果, -2是其实数结果.
另一方面, 设3.0 , 则3.0 , 即:
3.0
显然3.0 有6个结果, -2、2是其实数结果.
这个简单的例子说明了Maple在数值计算方面绝对不是万能的, 其计算结果也不是完全正确的, 但是, 通过更多的实验可以发现: Maple只可能丢失部分结果, 而不会增加或很少给出完全错误的结果(如上例中Maple的浮点数结果皆为 ). 这一点提醒我们, 在利用Maple或其他任何数学软件或应用程序进行科学计算时, 必须运用相关数学基础知识校验结果的正确性.
尽管Maple存在缺陷(实际上, 任何一个数学软件或程序都存在缺陷), 但无数的事实说明Maple仍然不失为一个具有强大科学计算功能的计算机代数系统. 事实上, Maple同其他数学软件或程序一样只是科学计算的一个辅助工具, 数学基础才是数学科学中最重要的.
2.1.1 有理数运算
作为一个符号代数系统, Maple可以绝对避免算术运算的舍入误差. 与计算器不同, Maple从来不自作主张把算术式近似成浮点数, 而只是把两个有公因数的整数的商作化简处理. 如果要求出两个整数运算的近似值时, 只需在任意一个整数后加“.”(或“.0”), 或者利用“evalf”命令把表达式转换成浮点形式, 默认浮点数位是10 (即: Digits:=10, 据此可任意改变浮点数位, 如Digits:=20).
> 12!+(7*8^2)-12345/125;
 
> 123456789/987654321;
 
> evalf(%);
 
> 10!; 100*100+1000+10+1; (100+100)*100-9;
 
 
 
> big_number:=3^(3^3);
 
> length(%);
 
上述实验中使用了一个变量“big_number”并用“:=”对其赋值, 与Pascal语言一样为一个变量赋值用的是“:=”. 而另一个函数“length”作用在整数上时是整数的十进制位数即数字的长度. “%”是一个非常有用的简写形式, 表示最后一次执行结果, 在本例中是上一行输出结果. 再看下面数值计算例子:  
    1)整数的余(irem)/商(iquo)
命令格式:  
irem(m,n);        #求m除以n的余数
irem(m,n,'q');    #求m除以n的余数, 并将商赋给q
iquo(m,n);        #求m除以n的商数
iquo(m,n,'r');    #求m除以n的商数, 并将余数赋给r
其中, m, n是整数或整数函数, 也可以是代数值, 此时, irem保留为未求值.
> irem(2002,101,'q'); # 求2002除以101的余数, 将商赋给q
 
> q; #显示q
 
> iquo(2002,101,'r'); # 求2002除以101的商, 将余数赋给r
 
> r; #显示r
 
> irem(x,3);
 
2)素数判别(isprime)
素数判别一直是初等数论的一个难点, 也是整数分解问题的基础. Maple提供的isprime命令可以判定一个整数n是否为素数. 命令格式: isprime(n);
    如果判定n可分解, 则返回false, 如果返回true, 则n“很可能”是素数.
> isprime(2^(2^4)+1);
 
> isprime(2^(2^5)+1);
 
上述两个例子是一个有趣的数论难题。形如3.0 的数称为Fermat数, 其中的素数称为Fermat素数, 显然, F0=3、F1=5、F2=17、F3=257、F4=65537都是素数. Fermat曾经猜想所有的Fn都是素数, 但是Euler在1732年证明了F5=641•6700417不是素数. 目前, 这仍是一个未解决的问题, 人们不知道还有没有Fermat素数, 更不知道这样的素数是否有无穷多.
3) 确定第i个素数(ithprime)
若记第1个素数为2,判断第i个素数的命令格式: ithprime(i);   
> ithprime(2002);
 
> ithprime(10000);
 
4) 确定下一个较大(nextprime)/较小(prevprime)素数
当n为整数时,判断比n稍大或稍小的素数的命令格式为:  
nextprime(n); 
prevprime(n);
> nextprime(2002);
 
> prevprime(2002);
 
5) 一组数的最大值(max)/最小值(min)
命令格式: max(x1,x2,…,xn);   #求x1,x2,…,xn中的最大值
             min(x1,x2,…,xn);   #求x1,x2,…,xn中的最小值
> max(1/5,ln(3),9/17,-infinity);
 
> min(x+1,x+2,y);
 
6)模运算(mod/modp/mods)
命令格式:  e mod m;    # 表达式e对m的整数的模运算
modp(e,m);  # e对正数m的模运算
mods(e,m);  # e对m负对称数(即 -m)的模运算
`mod`(e,m);  # 表达式e对m的整数的模运算, 与e mod m等价
值得注意的是, 要计算i^n mod m(其中i是一整数), 使用这种“明显的”语法是不必要的, 因为在计算模m之前, 指数要先在整数(可能导致一个非常大的整数)上计算. 更适合的是使用惰性运算符“&^”即: i &^n mod m, 此时, 指数运算将由mod运算符智能地处理. 另一方面, mod运算符的左面优先比其他运算符低, 而右面优先高于+和-, 但低于*和/.
> 2002 mod 101;
 
> modp(2002,101);
 
> mods(49,100);
 
> mods(51,100);
 
> 2^101 mod 2002;  # 同 2 &^101 mod 2002;
 
7)随机数生成器(rand)
命令格式:  
rand( );    #随机返回一个12位数字的非负整数
rand(a..b);  #调用rand(a..b)返回一个程序, 它在调用时生成一个在范围[a, b]内的随机数
> rand();
 
> myproc:=rand(1..2002):
> myproc();
 
> myproc();
 
    注意, rand(n)是rand(0..n-1)的简写形式.
2.1.2 复数运算
复数是Maple中的基本数据类型. 虚数单位i在Maple中用I表示. 在运算中, 数值类型转化成复数类型是自动的, 所有的算术运算符对复数类型均适用. 另外还可以用Re( )、Im( )、conjugate( )和argument( )等函数分别计算实数的实部、虚部、共轭复数和幅角主值等运算. 试作如下实验:  
> complex_number:=(1+2*I)*(3+4*I);
 
> Re(%);Im(%%);conjugate(%%%);argument(complex_number);
 
 
 
 
值得注意的是上行命令中均以“;”结束, 因此不能将命令中的2个%或3个%(最多只能用3个%)改为1个%, 因为%表示上一次输出结果, 若上行命令改为“,”结束, 则均可用1个%.
为了在符号表达式中进行复数运算, 可以用函数evalc( ), 函数evalc把表达式中所有的符号变量都当成实数, 也就是认为所有的复变量都写成3.0 的形式, 其中a、b都是实变量. 另外还有一些实用命令, 分述如下:  
1) 绝对值函数
命令格式: abs(expr); 
当expr为实数时,返回其绝对值,当expr为复数时,返回复数的模.
> abs(-2002);    #常数的绝对值
 
> abs(1+2*I);   #复数的模
 
> abs(sqrt(3)*I*u^2*v);  #复数表达式的绝对值
 
> abs(2*x-5);   #函数表达式的绝对值
 
2)复数的幅角函数
命令格式:   argument(x);  #返回复数x的幅角的主值
> argument(6+11*I);
 
> argument(exp(4*Pi/3*I));
 
3)共轭复数
命令格式:   conjugate(x);  #返回x的共轭复数
> conjugate(6+8*I);
 
> conjugate(exp(4*Pi/3*I));
 
2.1.3 数的进制转换
数的进制是数值运算中的一个重要问题. 而在Maple中数的进制转换非常容易, 使用convert命令即可.
命令格式:   convert(expr, form, arg3, ...);   
其中, expr为任意表达式, form为一名称, arg3, ... 可选项.
下面对其中常用数的转换予以概述. 而convert的其它功能将在后叙章节详述.
    1)基数之间的转换
命令格式:  
convert(n, base, beta);      #将基数为10的数n转换为基数为beta的数
    convert(n, base, alpha, beta);#将基数为alpha的数字n转换为基数为beta的数
> convert(2003,base,7); #将10进制数2002转换为7进制数, 结果为: (5561)7
 
> convert([1,6,5,5],base,7,10); #将7进制数5561转换为10进制数
 
> convert(2002,base,60);       #将十进制数2002转换为60进制数, 得33(分钟)22(秒)
 
    2)转换为二进制形式
命令格式: convert(n, binary);
其功能是将十进制数n转换为2进制数. 值得注意的是, 数可以是正的, 也可以是负的, 或者是整数, 或者是浮点数, 是浮点数时情况较为复杂.
> convert(2002,binary);  
 
> convert(-1999,binary);
 
> convert(1999.7,binary);
 
3)转换为十进制形式
其它数值转换为十进制的命令格式为:  
convert(n, decimal, binary);   #将一个2进制数n转换为10进制数
    convert(n, decimal, octal);    #将一个8进制数n转换为10进制数
    convert(string, decimal, hex);  #将一个16进制字符串string转换为10进制数
> convert(11111010010, decimal, binary);   
 
> convert(-1234, decimal, octal);          
 
> convert("2A.C", decimal, hex);         
 
4) 转换为16进制数
将自然数n转换为16进制数的命令格式为: convert(n, hex);  
> convert(2002,hex);  convert(1999,hex);
 
 
5)转换为浮点数
命令格式: convert(expr, float);
注意, convert/float命令将任意表达式转换为精度为全局变量Digits的浮点数, 且仅是对evalf的调用.
> convert(1999/2002,float);
 
> convert(Pi,float);
 
2.2 初等数学
    初等数学是数学的基础之一, 也是数学中最有魅力的一部分内容. 通过下面的内容我们可以领略Maple对初等数学的驾驭能力, 也可以通过这些实验对Maple产生一些感性认识.
2.2.1 常用函数
作为一个数学工具, 基本的数学函数是必不可少的, Maple中的数学函数很多, 现例举一二如下:  
指数函数: exp
一般对数: log[a]
自然函数: ln
常用对数: log10
平方根: sqrt
绝对值: abs
三角函数: sin、cos、tan、sec、csc、cot
反三角函数: arcsin、arccos、arctan、arcsec、arccsc、arccot
双曲函数: sinh、cosh、tanh、sech、csch、coth
反双曲函数: arcsinh、arccosh、arctanh、arcsech、arccsch、arccoth
贝赛尔函数: BesselI、BesselJ、BesselK、BesselY
Gamma函数: GAMMA
误差函数: erf
函数是数学研究与应用的基础之一, 现通过一些实验说明Maple中的函数的用法及功能.
1) 确定乘积和不确定乘积
命令格式: product(f,k); 
product(f,k=m..n); 
product(f,k=alpha);
product(f,k=expr);
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—包含k的任意表达式.
> product(k^2,k=1..10);   #计算3.0 关于1..10的连乘
 
> product(k^2,k);         #计算3.0 的不确定乘积
 
> product(a[k],k=0..5);    #计算ai(i=0..5)的连乘
 
> product(a[k],k=0..n);    #计算ai(i=0..n)的连乘
 
> Product(n+k,k=0..m)=product(n+k,k=0..m);   #计算(n+k)的连乘, 并写出其惰性表达式
 
> product(k,k=RootOf(x^3-2));     #计算3.0 的三个根的乘积
 
    product命令计算符号乘积, 常常用来计算一个公式的确实或不确实的乘积. 如果这个公式不能求值计算, Maple返回3.0 函数. 典型的例子是:  
> product(x+k,k=0..n-1);
 
如果求一个有限序列值的乘积而不是计算一个公式, 则用mul命令. 如:  
> mul(x+k,k=0..3);
 
2)指数函数
计算指数函数exp关于x的表达式的命令格式为: exp(x);
> exp(1);
 
> evalf(%);
 
> exp(1.29+2*I);
 
> evalc(exp(x+I*y));
 
3)确定求和与不确定求和sum
命令格式: sum(f,k); 
sum(f,k=m..n); 
sum(f,k=alpha);
sum(f,k=expr);
其中, f—任意表达式, k—乘积指数名称, m,n—整数或任意表达式, alpha—代数数RootOf,     expr—不含k的表达式.
> Sum(k^2,k=1..n)=sum(k^2,k=1..n);
 
> Sum(k^3,k=1..n)=sum(k^3,k=1..n);
 
> Sum(k^4,k=1..n)=sum(k^4,k=1..n);
 
> Sum(1/k!,k=0..infinity)=sum(1/k!,k=0..infinity);
 
> sum(a[k]*x[k],k=0..n);
 
> Sum(k/(k+1),k)=sum(k/(k+1),k);
 
> sum(k/(k+1),k=RootOf(x^2-3));
 
sum函数可计算一个公式的确定和与不确定和, 如果Maple无法计算封闭形式, 则返回未求值的结果. 值得注意的是, 在sum命令中将f和k用单引号括起来, 可避免过早求值. 这一点在某些情况下是必需的.
> Sum('k','k'=0..n)=sum('k','k'=0..n);

如果计算一个有限序列的值, 而不是计算一个公式, 可用add命令. 如:  
> add(k,k=1..100);
 
尽管sum命令常常用于计算显式求和, 但在程序设计中计算一个显式和应该使用add命令.
另外, sum知道各种求和方法, 并会对各类发散的求和给出正确的结果, 如果要将求和限制为收敛求和, 就必须检查显式的收敛性.
3)三角函数/双曲函数
命令格式:   sin(x);   cos(x);   tan(x);   cot(x);   sec(x);   csc(x);
          sinh(x);  cosh(x);  tanh(x);  coth(x);  sech(x);  csch(x);
其中, x为任意表达式.
值得注意的是三角函数/双曲函数的参数以弧度为单位. Maple提供了利用常见三角函数/双曲函数恒等式进行化简和展开的程序, 也有将其转化为其它函数的命令convert.
> Sin(Pi)=sin(Pi);
 
> coth(1.9+2.1*I);
 
> expand(sin(x+y));     #展开表达式
 
> combine(%);        #合并表达式
 
> convert(sin(7*Pi/60),'radical');
 
> evalf(%);
 
但有趣的是, combine只对sin, cos有效, 对tan, cot竟无能为力.
4)反三角函数/反双曲函数
命令格式: arcsin(x);   arccos(x);   arctan(x);   arccot(x);   arcsec(x);   arccsc(x);
     arcsinh(x);  arccosh(x);  arctanh(x);  arccoth(x);  arcsech(x);  arccsch(x);  
arctan(y,x);
其中, x, y为表达式. 反三角函数/反双曲函数的参数必须按弧度计算.
算子记法可用于对于反三角函数和反双曲函数. 例如, sin@@(-1)求值为arcsin.
> arcsinh(1);
 
> cos(arcsin(x));
 
> arcsin(1.9+2.1*I);
 
5)对数函数
命令格式: ln(x);           #自然对数
log[a](x);        #一般对数
log10(x);        #常用对数
一般地, 在ln(x)中要求x>0. 但对于复数型表达式x, 有:  
3.0  (其中, 3.0 )
> ln(2002.0);
 
> ln(3+4*I);
 
> evalc(%);    # 求出上式的实部、虚部
 
> log10(1000000);
 
> simplify(%);   #化简上式
 
2.2.2 函数的定义
Maple是一个计算机代数系统, 带未知或者已知字母变量的表达式是它的基本数据形式. 一个简单的问题是, 既然表达式中可以包含未知变量, 那么它是不是函数呢?试看下面一个例子:  
> f(x):=a*x^2+b*x+c;
 
可以看出, Maple接受了这样的赋值语句, 但f(x)是不是一个函数呢?要回答这个问题,一个简单的方法是求函数值:  
> f(x),f(0),f(1/a);
 
由上述结果可以看出, 用赋值方法定义的f(x)是一个表达式而不是一个函数, 因为f(x)不能把所定义的“自变量”或者“参数”转换成别的变量或表达式. 但从赋值“过程”可以看出, f(x)虽然也算是一个“函数”, 但却是一个没有具体定义的函数:  
> print(f);
 
事实上, 我们所做的赋值运算, 只不过是在函数f的记忆表(remember table)中加入了f(x)在x上的值, 当我们把自变量换作0或1/a时, f(x)的记忆表中没有对应的表项, 所以输出结果就是抽象的表达式.
在Maple中, 要真正完成一个函数的定义, 需要用算子(也称箭头操作符):  
> f:=x->a*x^2+b*x+c;
 
> f(x),f(0),f(1/a);
 
多变量的函数也可以用同样的方法予以定义, 只不过要把所有的自变量定成一个序列, 并用一个括号“()”将它们括起来(这个括号是必须的, 因为括号运算优先于分隔符“,”).
> f:=(x,y)->x^2+y^2;
 
> f(1,2);
 
> f:=(x,y)->a*x*y*exp(x^2+y^2);
 
综上所述, 箭头操作符定义函数的方式一般为:  
一元函数: 参数->函数表达式
多多函数: (参数序列)->函数表达式
无参数函数也许不好理解, 但可以用来定义常函数:  
> E:=()->exp(1);
 
> E();
 
> E(x);
 
另一个定义函数的命令是unapply,其作用是从一个表达式建立一个算子或函数.
定义一个表达式为expr的关于x的函数f的命令格式为:  f:=unapply(expr, x);         
定义一个表达式为expr的关于x,y,…的多元函数f的命令格式为:  f:=unapply(expr, x, y, …);    
> f:=unapply(x^4+x^3+x^2+x+1,x);
 
> f(4);
 
> f:=unapply(x*y/(x^2+y^2),x,y);
 
> f(1,1);
 
借助函数piecewise可以生成简单分段函数:
> abs(x)=piecewise(x>0,x,x=0,0,x<0,-x);
 
清除函数的定义用命令unassign.
> unassign(f);
> f(1,1);
 
除此之外, 还可以通过程序设计方式定义函数(参见第6章).
定义了一个函数后, 就可以使用op或nops指令查看有关函数中操作数的信息. nops(expr)返回操作数的个数, 函数op的主要功能是获取表达式的操作数,其命令格式为:
op(expr);         
op(i, expr);        
op(i .. j, expr);     
nops(expr);
如果函数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的类型.
命令op(i .. j, expr); 执行的结果是expr的第i到第j个操作数, i..j中含负整数时的情形同上.
命令op(expr); 等价于op(1..nops(expr), expr);
特别地, 当op函数中i为列表[a1, a2, ..., an], 则op([a1, a2, ..., an], expr); 等价于op(an, op(..., op(a2, op(a1, e))...));
而当expr为一般表达式时,nops(expr)命令返回的是表达式的项数, 当expr是级数时返回级数每一项的系数和指数的总和.
> expr:=6+cos(x)+sin(x)*cos(x)^2;
 
> op(expr);
 
> nops(expr);
 
> p:=x^2*y+3*x^3*z+2;
 
> op(1,p);
 
> op(1..nops(p),p);
 
> op(op(2,p));
 
> u:=[1,4,9];
 
> op(0,u);
 
> s:=series(sin(x),x=1,3);
 
> op(0,s);
  
> nops(s);
 
下面一个有趣的例子说明了Maple在处理算术运算时的“个性”:
> op(x*y*z);
 
> op(x*y*z+1);
 
2.2.3 Maple中的常量与变量名
为了解决数学问题, 一些常用的数学常数是必要的. Maple系统中已经存储了一些数学常数在表达式序列constants中:  
> constants;
 
为了方便使用, 现将上述常数的具体含义列示如下:  
 
常    数 名 称 近似值   
圆周率3.0  Pi 3.1415926535   
Catalan常数3.0  Catalan 0.9159655942   
Euler-Mascheroni常数3.0  gamma 0.5772156649   
3.0  infinity  

需要注意的是, 自然对数的底数e未作为一个常数出现, 但这个常数是存在的, 可以通过exp(1)来获取.
在Maple中, 最简单的变量名是字符串, 变量名是由字母、数码或下划线组成的序列, 其中第一个字符必须是字母或是下划线. 名字的长度限制是499个字符. 在定义变量名时常用连接符“.”将两个字符串连接成一个名. 主要有三种形式: “名.自然数”、“名.字符串”、“名.表达式”.
值得注意的是, 在Maple中是区分字母大小写的. 在使用变量、常量和函数时应记住这一点. 数学常量3.0 用Pi表示, 而pi则仅为符号3.0 无任何意义. 如g, G, new_term, New_Team, x13a, x13A都是不同的变量名.
在Maple中有一些保留字不可以被用作变量名:  
by      do      done     elif     else     end        fi        for     
from    if       in       local     od     option    options     proc        
quit    read     save     stop     then     to        while      D
Maple中的内部函数如sin, cos, exp, sqrt, ……等也不可以作变量名.
另外一个值得注意的是在Maple中三种类型引号的不同作用:  
`  `:   界定一个包含特殊字符的符号, 是为了输入特殊字符串用的;   
'  ':   界定一个暂时不求值的表达式;   
"  ":   界定一个字符串, 它不能被赋值.
2.2.4 函数类型转换          
函数类型转换是数学应用中一个重要问题, 譬如, 将三角函数转换成指数函数, 双曲函数转换成指数函数, 等等. 在Maple中, 实现函数类型转换的命令是convert. 命令格式: 
    convert(expr, form);        #把数学式expr转换成form的形式
convert(expr, form, x);      #指定变量x, 此时form只适于exp、sin、cos
convert指令所提供的三角函数、指数与函数的转换共有exp等7种:  
(1) exp: 将三角函数转换成指数
(2) expln: 把数学式转换成指数与对数
(3) expsincos: 分别把三角函数与双曲函数转换成sin、cos与指数的形式
(4) ln: 将反三角函数转换成对数
(5) sincos: 将三角函数转换成sin与cos的形式, 而把双曲函数转换成sinh与cosh的形式
(6) tan: 将三角函数转换成tan的形式
(7) trig: 将指数函数转换成三角函数与对数函数
> convert(sinh(x),exp);   #将sinh(x)转换成exp类型
 
> convert(cos(x)*sinh(y),exp);
 
> convert(cos(x)*sinh(y),exp,y);
 
> convert(exp(x)*exp(x^(-2)),trig);
 
> convert(arcsinh(x)*cos(x),expln);
 
> convert(cot(x)+sinh(x),expsincos);
 
> convert(arctanh(x),ln);
 
convert在有理式的转换中也起着重要的作用. 在有关多项式运算的过程中, 利用秦九韶算法可以减少多项式求值的计算量. 在Maple中, 可以用函数convert将多项式转换为这种形式, 而cost则可以获取求值所需的计算量. 注意: cost命令是一个库函数, 第一次调用时需要使用with(codegen)加载. 例举如下:  
> with(codegen):
> p:=4*x^4+3*x^3+2*x^2-x;
 
> cost(p);
 
> convert(p,'horner');  #将展开的表达式转换成嵌套形式
 
> cost(%);
 
同样, 把分式化成连分式(continued fraction)形式也可以降低求值所需的计算量.
> (1+x+x^2+x^3)/p;
 
> cost(%);
 
> convert(%%,'confrac',x);
 
> cost(%);
 
在某些场合下(比如求微分、积分时), 把分式化成部分分式(partial fraction)也就是几个最简分式的和式的形式也可以简化运算, 但简化程度不及连分数形式.
> convert(%%, 'parfrac',x);
 
> cost(%);
 
而把分数转换成连分数的方法为:
> with(numtheory):
> cfrac(339/284);
 
2.2.5 函数的映射—map指令
在符号运算的世界里, 映射指令map可以说是相当重要的一个指令, 它可以把函数或指令映射到这些结构里的元素, 而不破坏整个结构的完整性. 命令格式为:
map(f, expr);      #将函数f映射到expr的每个操作数
map(f, expr, a);    #将函数f映射到expr的每个操作数, 并取出a为f的第2个自变量
map(f, expr, a1, a2,…, an); #将函数f映射到expr的每个操作数, 并取a1~an为f的第2~n+1个自变量
map2(f, a1, expr, a2, …, an);    #以a1为第1个自变量, expr的操作数为第2个自变量, a2为
第3个自变量…, an为第n+1个自变量来映射函数f
> map(f,x1+x2+x3+x4,a1,a2,a3,a4);
 
> f:=x->sqrt(x)+x^2;
 
> map(f,[a,b,c]);
 
> map(h, [a,b,c],x,y);
 
> map(convert,[arcsinh(x/2),arccosh(x/2)],ln);
 
> map(x->convert(x,exp),[sin(x),cos(x)]);
 
上式的映射关系可通过下式理解:
> [convert(sin(x),exp),convert(cos(x),exp)];
 
> restart:
map2(f,a1,x1+x2+x3+x4,a2,a3,a4);
 
> map2(max,k,[a,b,c,d]);
 
再看下面示例:  
> L:=[seq(i,i=1..10)];
 
> nops(L);
 
> sqr:=(x)->x^2;
 
> map(sqr,L);
 
> map((x)->x+1,L);
 
> map(f,L);
 
> map(f,{a,b,c});
 
> map(sqr,x+y*z);
 
> M:=linalg[matrix](3,3,(i,j)->i+j);
 
> map((x)->1/x,M);
 
3 求 值
3.1 赋值
在Maple中, 不需要申明变量的类型, 甚至在使用变量前不需要将它赋值, 这是Maple与其它高级程序设计语言不同的一点, 也正是Maple符号演算的魅力所在, 这个特性是由Maple与众不同的赋值方法决定的. 为了理解其赋值机制, 先看下面的例子.
> p:=9*x^3-37*x^2+47*x-19;
 
> roots(p);
 
> subs(x=19/9,p);
 
在这个例子中, 第一条语句是一个赋值语句, 它的作用是把变量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;”这样的简单语句即可验证.
3.2 变量代换
在表达式化简中, 变量代换是一个得力工具. 我们可以利用函数subs根据自己的意愿进行变量代换, 最简单的调用这个函数的形式是这样的:  
subs ( var = repacedment, expression);
调用的结果是将表达式expression中所有变量var出现的地方替换成 replacement.
> f:=x^2+exp(x^3)-8;
 
> subs(x=1,f);
 
> subs(x=0,cos(x)*(sin(x)+x^2+5));
 
    由此可见, 变量替换只得到替换后的结果, 而不改变表达式的内容, 而且Maple只对替换的结果进行化简而不求值计算, 如果需要计算, 必须调用求值函数evalf. 如:  
> evalf(%);
 
变量替换函数subs也可以进行多重的变量替换, 以两重代换为例:  
subs (var1 = repacedment1, var2 = repacedment2, expression)
调用的结果和按从左到右的顺序连续两次调用是一样的, 也就是先将expression中的var1替换成replacement1, 再将其结果中的var2替换成replacement2, 把这种替换称作顺序替换;    与此相对, 还可以进行同步替换, 即同时将expression中的var1替换成replacement1, 而var2替换成replacement2. 同步替换的调用形式为:  
subs ( {var1 = repacedment1, var2 = repacedment2 }, expression)
下面通过例子说明这几种形式的替换.
> subs(x=y,y=z,x^2*y);              (顺序替换)
 
> subs({x=y,y=z},x^2*y);            (同步替换)
 
> subs((a=b,b=c,c=a),a+2*b+3*c);   (顺序替换)
 
> subs({a=b,b=c,c=a},a+2*b+3*c);    (轮  换)
 
> subs({p=q,q=p},f(p,q));             (互  换)
 
3.3 假设机制
Maple是一种计算机代数语言, 显然, 很多人会尝试用Maple(或其他计算机代数语言)解决分析问题. 但由于分析问题与处理问题的考虑方法不同, 使得问题的解决存在某些困难. 例如考虑方程3.0 的解. 如果k是实数, 结果显然是x=1, 但如果k是3.0 的复根, 为了保证解x=1的正确性, 必需添加附带条件: 也就是当3.0 时x=1. 这是一个对结果进行正确分析的例子. 然而从代数的角度考虑这个问题时就会把k当作不定元, 此时k没有值, 从方程两端去除k的多项式是合法的, 只要这个多项式不是零多项式即可(这一点是可以保证的, 因为其所有系数不全为0). 在此情况下x=1就不需要任何附加条件. 计算机代数系统经常采用这种分析的观点.
在Maple中, 采用分析观点解决这类带有一定附加条件的实用工具是函数assume, 其命令格式为: assume(x, prop);
函数assume界定了变量与变量之间的关系式属性. assume最普遍的用法是assume(a>0), 该语句假设符号a为一个正实常数; 若假定某一符号c为常数,使用命令assume(c,constant); 另一方面, assume可以带多对参数或多个关系式. 当给定多个参数时, 所有假定均同时生效. 例如, 要定义a0);”后再写“assume(x<0);”也不会产生矛盾.
> Int(exp(-s*t),t=0..infinity);
 
> value(%);
Definite integration: Can't determine if the integral is convergent.
Need to know the sign of --> s
Will now try indefinite integration and then take limits.
 
> assume(s>0);
> Int(exp(-s*t),t=0..infinity);
 
> value(%);
 
3.4 求值规则
在多数情况下, Maple的求值规则设计为做用户期望的事情, 但要做到这一点很困难,因为不同的人在相同的情形下会有不同的期望. 在大多数情况下, 全局变量被完全求值, 局部变量被一层求值. 而由符号' '界定一个暂时不求值的表达式, 单步求值仅去掉引号, 不作计算, 这也是允许取消指定名字或清除变量的原因. 如下例:  
> x:=y;
 
> y:=z;
 
> z:=3;
 
> x;
 
> y;
 
> x:='x';
 
> x;
 
> y;
 
对于不同的问题, Maple设计了不同的求值命令. 现分述如下:  
1) 对表达式求值
命令格式: eval(e, x=a);  #求表达式e在x=a处的值
             eval(e, eqns); #对方程或方程组eqns求值
             eval(e);      #表达式e求值到上面两层
             eval(x,n);    #给出求值名称的第n层求值
> p:=x^5+x^4+x^3+x^2+x+73;
 
> eval(p,x=7);
 
> P:=exp(y)+x*y+exp(x);
 
> eval(P,[x=2,y=3]);
 
    当表达式在异常点处求值时, eval会给一个错误消息. 如下:  
> eval(sin(x)/x,x=0);
Error, numeric exception: division by zero
    下面再看使用eval进行全层求值或者对名称几层求值的示例:  
> a:=b: b:=c: c:=x+1:
> a;              #默认的全层递归求值
 
> eval(a);        #强制全层递归求值
 
> eval(a,1);       #对a一层求值
 
> eval(a,2);       #对a二层求值
 
> eval(a,3);       #对a三层求值
 
> eval(a,4);       #对a四层求值
 
    2) 在代数数(或者函数)域求值
命令格式: evala(expr);       # 对表达式或者未求值函数求值
             evala(expr,opts);   #求值时可加选项(opts)
所谓代数数(Algebraic number)就是整系数单变量多项式的根, 其范围比有理数大, 真包含于实数域, 也就是说任意实数都是整系数多项式的根(如3.0 就不是任何整系数多项式的根). 另一方面, 代数数也不是都可以表示成为根式的, 如多项式3.0 的根就不能表示成为根式的形式.
代数数的计算, 算法复杂, 而且相当费时. 在Maple中, 代数数用函数RootOf()来表示. 如3.0 作为一个代数数, 可以表示为:  
> alpha:=RootOf(x^2-3,x);
 
> simplify(alpha^2);
 
在Maple内部, 代数数3.0 不再表示为根式, 而在化简时, 仅仅利用到3.0 这样的事实. 这里, Maple用到一个内部变量_Z. 再看下面一个例子,其中alias是缩写的定义函数,而参数lenstra指lenstra椭圆曲线方法:
> alias(alpha=RootOf(x^2-2)):
> evala(factor(x^2-2,alpha),lenstra);
 
> evala(quo(x^2-x+3,x-alpha,x,'r'));
 
> r;
 
> simplify(%);
 
3) 在复数域上符号求值
操纵复数型表达式并将其分离给出expr的实部和虚部的函数为evalc, 命令格式为:
evalc(expr);  
evalc假定所有变量表示数值, 且实数变量的函数是实数类型. 其输出规范形式为: expr1+I*expr2.
> evalc(sin(6+8*I));
 
> evalc(f(exp(alpha+x*I)));
 
> evalc(abs(x+y*I)=cos(u(x)+I*v(y)));
 
4) 使用浮点算法求值
浮点算法是数值计算的一种基本方法,在任何情况下均可以对表达式expr使用evalf命令计算精度为n的浮点数(n=Digits), 如果n缺省, 则取系统默认值, 命令格式为: evalf(expr, n);    
> evalf(Pi,50);   
 
> evalf(sin(3+4*I));  
 
> evalf(int(sin(x)/x,x=0..1),20);
 
5) 对惰性函数求值
把只用表达式表示而暂不求值的函数称为惰性函数, 除了第一个字母大写外, Maple中的惰性函数和活性函数的名字是相同的. 惰性函数调用的典型用法是预防对问题的符号求值, 这样可以节省对输入进行符号处理的时间, 而value函数强制对其求值. 对任意代数表达式f求值的命令格式为: value(f);  
> F:=Int(exp(x),x);
 
> value(%);
 
> f:=Limit(sin(x)/x,x=0);
 
> value(%);
 
另外, 将惰性函数的大写字母改为小写字母亦即可求值. 如下例:  
> Limit(sin(x)/x,x=0)=limit(sin(x)/x,x=0);
 
4 数据结构
Maple中有许多内建的与FORTRAN、C或Pascal不同的数据结构. 主要的数据结构有序列(sequence)、列表(list)、集合(set)、代数数( algebraic number)、未求值或惰性函数调用、表(table)、级数(series)、串(string)、索引名(index)、关系(relation)、过程体(process)以及整数(integer)、分数(fraction)、浮点数(float)、复数(complex number)等数据结构, 而矩阵(matrix)在Maple中表示为阵列, 是一种特殊的表.
4.1 数据类型查询
在Maple中, 用whattype指令来查询某个变量的数据类型或特定类型, 命令格式为:
whattype(expr)        # 查询expr的数据类型
type(expr, t)           # 查询expr是否为t类型, 若是则返回true, 否则返回false
> whattype(12);
 
> whattype(Pi);
 
> type(1.1,fraction);
 
> whattype(1.1);
 
4.2 序列, 列表和集合
4.2.1 序列
所谓序列(Sequence), 就是一组用逗号隔开的表达式列. 如:  
> s:=1,4,9,16,25;
 
> t:=sin,com,tan,cot;
 
一个序列也可以由若干个序列复合而成, 如:  
> s:=1,(4,9,16),25;
 
> s,s;
 
而符号NULL表示一个空序列. 序列有很多用途, 如构成列表、集合等. 事实上, 有些函数命令也是由序列构成. 例如:  
> max(s);
 
> min(s,0,s);
 
值得注意的是, op和nops函数命令不适用于序列, 如op(s)或nops(s)都是错误的, 如果要使用op(s)或nops(s)前应先把序列s置于列表中.
> s:=1, 2, abc, x^2+1, `hi world`, Pi, x -> x^2, 1/2, 1;
 
> op(s);
Error, wrong number (or type) of parameters in function op
> nops(s);
Error, wrong number (or type) of parameters in function nops
> op([s]);
 
> nops([stuff]);
 
函数seq是最有用的生成序列的命令, 通常用于写出具有一定规律的序列的通项, 命令格式为:  
seq(f(i), i=m..n);  # 生成序列f(m), f(m+1), …, f(n) (m,n为任意有理数)
seq(f(i), i=expr);  # 生成一个f映射expr操作数的序列
seq(f(op(i,expr)), i=1..nops(expr));  # 生成nops(expr)个元素组成的序列
> seq(i^2,i=1..10);
 
> seq(ithprime(i),i=1..20);
 
> seq(i^3,i=x+y+z);
 
> seq(D(f),f=[sin,cos,tan,cot]);
 
> seq(f(op(i,x1+x2+x3+x4)),i=1..nops(x1+x2+x3+x4));
 
获得一个序列中的特定元素选用操作符[  ], 如:  
> seq(ithprime(i),i=1..20);
 
> %[6],%[17];
 
4.2.2 列表
列表(list), 就是把对象(元素)放在一起的一种数据结构, 一般地, 用方括号[  ]表示列表. 如下例:  
> l:=[x,1,1-z,x];
 
> whattype(%);
 
空列表定义为[ ].
但下述两个列表是不一样的, 因为对于列表而言, 次序是重要的:  
> L:=[1,2,3,4];
 
> M:=[2,3,4,1];
 
4.2.3 集合
集合(set)也是把对象(元素)放在一起的数据结构, 与列表不同的是集合中不可以有相同的元素(如果有, Maple也会自动将其当作同一个元素), 另外, 集合中的元素不管次序. 一般地, 用花括号表示集合.
> s:={x,1,1-z,x};
 
> whattype(%);
 
空集定义为{ }.
函数nop返回列表或集合的元素数, 而op则可返回其第I个元素.
> op(1,s);
 
> s[1];
 
> op(1..3,s);
 
> s[1..3];
 
函数member可以判定元素是否属于一个列表或集合, 如果属于, 返回true, 否则返回false.
> member(1+x,s);
 
可以通过下述方法在列表中增减元素:  
> t:=[op(s),x];
 
> u:=[s[1..5],s[7..nops(s)]];
 
Maple中集合的基本运算有交(intersect)、并(union)、差(minus):  
> A:={seq(i^3,i=1..10)};B:={seq(i^2,i=1..10)};
 
 
> A intersect B;
 
> A union B;
 
> A minus B;
 
4.3 数组和表
在Maple中, 数组(array)由命令array产生, 其下标变量(index)可以自由指定. 下标由1开始的一维数组称为向量(vector), 二维以上的数组称为矩阵(matrix). 数组的元素按顺序排列, 任意存取一数组的元素要比列表或序列快的多. 区分一个数据结构是数组还是列表要用“type”命令.
    表(table)在建立时使用圆括号, 变量能对一个表赋值, 但一个在存取在算子中的未赋值变量会被自动地假定是表, 表的索引可以成为任意Maple表达式. 表中元素的次序不是固定的.
> A:=array(1..4);
 
> for i from 1 to 4 do A[i]:=i: od:
> eval(A);
 
> type(A,array);
 
> type(A,list);
 
> T:=table();
 
> T[1]:= 1;
 
> T[5]:= 5;
 
> T[3]:= 3;
 
> T[sam]:=sally;
 
> T[Pi]:=exp(1);
 
> x:='x';
 
> T[(1+x+x^3)*sin(x)] := 0;
 
> eval(T);
 
> T[3]:='T[3]';
 
> eval(T);
 
4.4 其他数据结构
串在Maple中是很重要的, 他们主要用于取名字和显示信息. 一个Maple的串可以作为变量名, 它们中的大多数是简单的、不需要加引号的串, 但是如果变量名中包含/. 例如“diff/T”则必须把变量名用引号括起来.
索引名是像Database[1,2,drawer]或A[3]这样的对象, 在使用索引前不需要直接建立表, 如果不得不做, Maple会自动建立表. 索引名通常被用于矩阵和向量. 为了保证Maple建立表的正确次序, 建议在赋值前直接建立.
> x:=T[3];
 
> eval(T);
 
> T[5]:=y;
 
> eval(T);
 
由此可见, Maple并不直接建立T的表, 直到给T[5]赋了值.    
数值数据结构(整数、分数、有理数、浮点数、硬件浮点数和复数等)在它们的使用中是大量透明的. 浮点数是有传染性的, 这意味着如果数值结构中有一个是浮点数, 则整个结构自动转换为浮点数.
4.5 数据类型转换和合并
convert是一个功能强大的类型转换函数, 它可以实现列表和数组的类型转换:  
> L:=[1,2,3,4];
 
> type(L,list);
 
> A:=convert(L,array);
 
> type(A,list);
 
> type(A,array);
 
另一个有用的函数zip则可把两个列表或向量合并:  
>L:=[seq(i,i=1..10)];
 
> Sqr:=(x)->x^2;
 
> M:=map(sqr,L);
 
> LM:=zip((x,y)->[x,y],L,M);
 
> map(op,LM);
 
5 Maple高级输入与输出操作
Maple提供了良好的接口来编辑与计算数学式. 许多时候, 我们可能需要把Maple的运算结果输出到一个文件中, 或者在一个文本编辑器里先编好一个较大的Maple程序, 再将它加载到Maple的环境里.
5.1 写入文件
5.1.1 将数值数据写入到一个文件
如果Maple的计算结果是一长串的数值串行或数组, 而想把它写到一个文件时, 用writedata命令.
若Maple的计算结果data为集合、矩阵、列表、向量等形式时, 将其写入名为filename的文件时命令格式为: writedata("filename", data);
> with(linalg):
> M:=matrix(3,3,[1,2,3,4,5,6,7,8,9]);
 
> writedata("e:\\filename.txt",M);
而将结果附加在一个已存在的文件后时,使用命令: writedata[APPEND]("filename", data);
> W:=matrix(2,2,[1,2,3,4]);
 
> writedata[APPEND]("e:\\filename.txt",W);
需要注意的是, 这里的APPEND是必需的, 否则W结果将会覆盖M结果.
另外, 若想将结果显示在屏幕上时, 用命令: writedata('terminal', data);
> writedata[APPEND]("e:\\filename.txt",W);
> writedata('terminal',M);
1            2            3          
4            5            6          
7            8            9   
5.1.2 将Maple语句写入一个文件
如果所要写入文件的是表达式、函数的定义或者是一个完整的程序, 则使用命令save, 写入一个或多个语句的命令格式分别如下:
save name, "filename";
save name1, name2, …, "filename";
若filename的扩展名为.m, 则Maple会以内定的格式储存, 若扩展名为.txt, 则以纯文本文件储存. 以内定的格式储存的文件作纯文本编辑器无法读取, 但在大多数情况下, 它会比纯文本文件的加载速度更快, 且文件容量小.
> myfunc:=(k,n)->sum(x^k/k!,x=1..n);
 
> myresult:=myfunc(6,8);
 
> save myfunc,myresult,"e:\\test.m";
调用已存m文件用命令read. 试看下述实验:
> restart:
> myfunc(6,8);
 
> read "e:\\test.m";
> myfunc(6,8);
 
> myresult;
 
    而存为txt文件时则将整个语句存为一个文件:
> save myfunc,myresult,"e:\\test.txt";
> restart: read"e:\\test.txt";
 
 
5.2 读取文件
在Maple里最常用的两个读取文件的命令, 一个是读取数值数据, 另一个是是读取Maple的指令.
5.2.1 读取数值数据
如果想把大量的数据导入Maple里进行进一步的运算或者要运用大量的实验数据在Maple环境绘图时, 可以用readdata( )命令完成.
从filename文件里读取n行数据时使用命令: readdata("filename",n);
以指定的格式读取数据时使用命令: readdata("filename",[tyep1,type2,…]);
> readdata("e:\\filename.txt",3);
 
    读取filename的前三列, 第一列为整数形式, 第二、三列为浮点数形式:
> readdata("e:\\filename.txt",[integer,float,float]);
 
下面再看一个运用大量的实验数据在Maple环境绘图的实验:
> mypts:=[seq([x/1000,cos(x^2/100000)],x=1..1000)]:
> writedata("e:\\data.txt",evalf(mypts));
> dots:=readdata("e:\\data.txt",100):
> nops(dots);
 
> dots[1..4];
 
> plot(dots,style=line);

5.2.2 读取Maple的指令
在编写程序时, 在普通软件中先编好程序再将其读入Maple环境中常常比直接在Maple中编写更为方便. 如果要将程序代码或Maple指令加载用read命令:
read "filename";
如下例:
> reatart:
> myfunc:=(a::list)->add(i,i=a);
 
> avg:=(a::list)->myfunc(a)/nops(a);
 
> save myfunc,avg,"e:\\function.m";
> restart:
> read "e:\\function.m";
> myfunc([1,2,3,4,5,6,7,8,9]);
 
> avg([1,2,3,4,5,6,7,8,9]);
 
5.3 与其它程序语言的连接
5.3.1 转换成FORTRAN或C语言
调用codegen程序包中的fortran命令可以把Maple的结果转换成FORTRAN语言:
> with(codegen,fortran):
f:= 1-2*x+3*x^2-2*x^3+x^4;
 
> fortran(%);
      t0 = 1-2*x+3*x**2-2*x**3+x**4
 > fortran(f,optimized);
      t2 = x**2
      t6 = t2**2
      t7 = 1-2*x+3*t2-2*t2*x+t6
> fortran(convert(f,horner,x));
      t0 = 1+(-2+(3+(-2+x)*x)*x)*x
而codegen程序包中的C命令可以把Maple结果转换成C语言格式:
> with(codegen,C):
f:=1-x/2+3*x^2-x^3+x^4;
 
> C(f);
      t0 = 1.0-x/2.0+3.0*x*x-x*x*x+x*x*x*x;
> C(f,optimized);
      t2 = x*x;
      t5 = t2*t2;
      t6 = 1.0-x/2.0+3.0*t2-t2*x+t5;
optimized命令表示要对转换的表达式进行优化, 如果不加此可选参数, 则直接对表达式进行一一对应的转换.
5.3.2 生成LATEX
Maple可以把它的表达式转换成LATEX, 使用latex命令即可:
> latex(x^2+y^2=z^2);
{x}^{2}+{y}^{2}={z}^{2}
    还可以将转换结果存为一个文件(LatexFile):
> latex(x^2 + y^2 = z^2, LatexFile);
    再如下例:
> latex(Int(1/(x^2+1),x)=int(1/(x^2+1),x));
\int \! \left( {x}^{2}+1 \right) ^{-1}{dx}=\arctan\left( x \right)

文章录入:views63    责任编辑:madio  
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    推 荐 文 章
    更多内容
     
    热 门 文 章  
    更多内容
     

    费马小定理
    相 关 文 章
    更多内容
     
    没有相关文章
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |