一直都有人问讨论有关于 Perl 与数学的问题。有时候一些 perl 玩家问如何使用 perl 做一些高级数学的工作。另一方面,一些数学家又反过来问如何利用 perl 来帮助完成他们本身的工作。所以,现在我提供一些方便的参考文献,比较和说明一些常用的 perl 数学模块,以及对 perl 有用的软件。它并不是完整的Perl数学编程手册,而只是对于一些常用的数学模块和软件的简要综述。我忽略了 bioperl 以及生物信息学的内容,因为他们涵盖范围太广,无法简单地称之为“数学”。
一般来说,如果你在 CPAN 上搜索与数学相关的模块,那么你应该从以下关键字入手: Math::×, Statistics::×, 以及 AI::× ,Algorithm::×, Cript::×, Date::, Graph::, GraphViz::, Inline::, 等等。 GNU项目也是
寻找 perl 扩展模块的好地方。
Perl数学模块及其相关软件
以下列举了一些有关于数学的 perl 模块及软件:
模块/软件
|
类型
|
可用性
|
评论
|
通用模块,perl 与 C 语言的接口
|
任何操作系统
|
可能不是你用 perl 做数学的第一选择
|
|
矩阵代数以及数值分析
|
Inline::Octave 无法从ActiveState获得。 Octave 可以在任何操作系统运行
|
Matlab的开源版本,运行快,语法简单。Octave 可以交互式的使用,或用做脚本语言。其他类似的商业软件有:Gauss,APL等。
|
|
通用工程数学库
|
任何操作系统
|
特征系统(Eigensystem)仅适用与实对称矩阵。
|
|
线性编程
|
ActiveState perl 没有,LP solve则有 DOS 的版本。
|
免费,但 LP Solve 可能不再持续维护了。类似的商用软件有:CPLEX,Lindo,Minos,AMPL等。
|
|
数论
|
任何操作系统
|
很适合密码学分析
|
|
矩阵代数(仅适用用于实数)
|
任何操作系统
|
纯 Perl 代码实现,特征系统仅用于实对称矩阵
|
|
Perl 数据语言(Perl Data Language)
|
最新版本为2.4.0,windows预编译版2.3.1。
|
为 perl 提供更多的数学语法
|
|
Statistical software
|
任何操作系统
|
语法比较
我们来比较一下这些模块和软件的语法。我们以运算一个2×2矩阵与一个向量的乘积为例,以下是它们各自的语法。
模块/软件
|
代码
|
Math::Cephes
|
use Math::Cephes::Matrix qw(mat); $a = mat [[1, 2], [3, 4]]; $b = [1, 1]; print "@{$a->mul($b)}"; # print "3 7" |
Math::RealMatrix
|
use Math::MatrixReal; $a = Math::MatrixReal->new_from_rows( [[1, 2], [3, 4]] ); $b = Math::MatrixReal->new_from_cols( [ [1, 1] ] ); print $a*$b; # print "[ 3.000000000000E+000 ] # [ 7.000000000000E+000 ]" |
PDL
|
use PDL; $a = pdl [[1, 2],[3, 4]]; $b = pdl [[1], [1]]; print $a x $b; # print "[ # [3] # [7] # ]" |
Octave
|
>> a = [1, 2; 3, 4]; >> b = [1; 1]; >> a*b ans = 3 7 |
R
|
> a = matrix(c(1,2,3,4), ncol=2, byrow=T) > b = matrix(c(1,1), ncol=1) > a%*%b [,1] [1,] 3 [2,] 7 |
仅就数学上来说,以上这些模块和软件的语法看起来都相当简洁。不过 Octave 和 R 比 perl 还是要好懂的多了。许多数学语言的一个突出特点是它们的“向量操作”以及“下标操作”。
具个例子来讲,例如现在我们要从一个矩阵中,提取一个子矩阵。
实例:提取一个子矩阵
模块/软件
|
代码
|
Math::Cephes
|
use Math::Cephes::Matrix qw(mat); $mat = mat [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; $mat = $mat->coef; for my $i (1..2) { # 0 first index print "@{$mat->[$i]}[1..2]\n"; } # print "5 6 # 8 9" |
Math::RealMatrix
|
use Math::MatrixReal; $mat = Math::MatrixReal->new_from_rows( [[1, 2, 3] [4, 5, 6] [7, 8, 9] ) for my $i (2..3 { firs ndex fo ..3) { |
PDL
|
use PDL; $mat = pdl [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; print $mat->slice("1:2,1:2"); # 0 first index # print "[ # [5 6] # [8 9] # ]" |
Octave
|
mat = [1,2,3; 4,5,6; 7,8,9]; mat(2:3, 2:3) ans = 5 6 8 9 |
R
|
> mat = matrix(1:9, ncol=3, byrow=T) > mat[2:3, 2:3] [,1] [,2] [1,] 5 6 [2,] 8 9 |
向量的串行运算是一个非常不错的功能. 考虑一下下面的有关于 R 的源码:
> vec = 1:10
> vec
[1] 1 2 3 4 5 6 7 8 9 10
> vec %% 2
[1] 1 0 1 0 1 0 1 0 1 0
> vec[vec %% 2 == 1]
[1] 1 3 5 7 9
> vec[vec %% 2 == 1] + 1
[1] 2 4 6 8 10
我们刚才在前面也提到了 Pari,但它只是一个自成体系的模块。我们来看一个 Pari 的例子。
#! /usr/local/bin/perl -w
use strict;
# -----------------------------------------------------------
# RSA algorithm -- assymetrical\public-key cryptography
# -----------------------------------------------------------
use Math::Pari qw(gcd PARI) ;
# -----------------------------------------------------------
# m -- message
my $m = 'Perl' ;
print "original: $m\n" ;
my $tmpl = 'C*' ;
my @m = unpack($tmpl, $m) ; # string -> unsigned char values
print "coded: @m\n" ;
# n = pq -- in RSA, p & q = prime, each 1024 bits/308 digits long
my $p = PARI("prime(".int(rand 50).")") ;
my $q = PARI("prime(".int(rand 50).")") ;
my $n = $p*$q ; # $n = Pari's obj
# choose a random number r, s.t.
# 1 < r < (p-1)(q-1) = b
# gcd(r, b) = 1 -- relative prime
my $b = ($p-1)*($q-1) ;
my $r ;
do {$r = int rand $b ; } until (gcd($r,$b) == 1) ;
$r = PARI $r ;
# rk = 1 mod (p-1)(q-1) -- k = private key; (n, r) public
my $k = (1/$r)%$b ; # Pari's math operators, since vars = Pari
# encrypt -- c = (m ^ r) mod n
my @c ;
map { $c[$_] = ($m[$_]**$r)%$n } 0..$#m ; # Perl: ** for power
print "ciphered: @c\n" ;
# decrypt -- m = (c ^ k) mod n
my @d ;
map { $d[$_] = PARI("($c[$_]^$k)%$n") } 0..$#c ; # Pari: ^ for power
print "deciphered: @d\n" ;
print "decoded: " . pack($tmpl, @d) . "\n" ;
__END__
original: Perl
coded: 80 101 114 108
ciphered: 18431 6512 5843 7236
deciphered: 80 101 114 108
decoded: Perl
</font></tt>
有时侯 perl 和数学软件之间并没有直接的相互接口,但是那些软件可以通过命令行来运行,于是我们就可以利用命令行界面来操作他们。以下是 perl 与 R 之间的一个例子:
<tt class="code"><font size="-1">#! /usr/local/bin/perl -w
use strict ;
R("getwd()");
sub R {
my $Rpath = "C:\R\rw\bin\" ;
my $Rcmd = $Rpath . "rterm --vanilla --quiet --slave" ;
my $Rscript = shift ;
$Rscript =~ s/(\r|;\r)/ ;/gm ;
$Rscript =~ s/<-/=/gm ; # \r or <- will break "echo"
return `echo $Rscript | $Rcmd` ;
}
如果你只有 DOS LP Solce 的可执行程序,那么你也可以这样操作:
my $dir = 'D:\tmp\prog\math\lp32';
my $lp_solve = "d:\mydir\lp_solve.exe";
my $lpfile = "d:\mydir\model.lp";
(my $lp = << " EOF") =~ s/^\s+//gm;
min: 8 x1 + 15 x2 ;
c1: 10 x1 + 21 x2 > 156 ;
c2: 2 x1 + x2 > 22 ;
EOF
open OUTFILE, "+>$lpfile";
print OUTFILE $lp;
close OUTFILE;
$output = qx($lp_solve < $lpfile);
$output =~ s/\r//gm;
print $lp;
print $output;
system("del $lpfile");
这也是为什么 Perl 被成为“胶水语言”的原因。
评测
人们做数学的时候往往很关心速度,所以我们来做些评测。
use strict;
use warnings;
my ($a1,$a2,$a3,$ref);
for my $x (0..20) {
for my $y (0..20) {
$ref->[$x][$y] = rand 100;
}
}
use Math::Cephes::Matrix qw(mat);
$a1 = mat $ref;
use Math::MatrixReal;
$a2 = Math::MatrixReal->new_from_rows( $ref );
use PDL;
use PDL::Slatec;
$a3 = pdl $ref;
use Benchmark qw(cmpthese);
cmpthese(100,
{
cephes=>sub{$a1->inv()},
matrixreal=>sub{$a2->inverse()},
pdl=>sub{matinv($a3)}
}
);
__END__
Rate matrixreal cephes pdl
matrixreal 5.28/s -- -94% -99%
cephes 83.3/s 1479% -- -87%
pdl 625/s 11744% 650% --
注意,对于任何编译的数学模块,编译的方式将对计算速度有着非常大的影响。关于此,你可以在这里找到Octave 和 R 以及其他一些数学工具的评测。
假如你不太清楚 Perl 和其他数学软件与模块如何写作来完成一个项目,以下是一些提示(但不是规定)。
流程
|
Perl
|
数学模块/软件
|
评论
|
数据存储
|
N/A
|
N/A
|
很多人用电子表格存储数据。不过可能用数据库会更好些,比如Oracle,MySQL,MS SQL等等。这部分工作和 Perl 和数学工具都关系不太大。 |
数据存取
|
是
|
可能
|
这部分工作是“插入”,“更新”和“删除”数据。你可能会用DBI 来做这件事。如果你的数学软件可以直接完成这些数据操作的工作,那部分就不再需要 Perl 了。
|
数据操作
|
YES
|
可能
|
数据操作的意思是以正确的格式获取原始数据以用于数据分析。比如从 log 文件中提取一系列的时间,把一些格式混乱的文本文件转换为 CSV 文件,等等。当这项工作变得复杂的时候,Perl 可能比直接操作电子表格或者数学软件方便得多,同时你可能会用到很多正则表达式。
|
数据分析
|
可能
|
是
|
在做复杂数学运算的时候, Perl 没有 C 那么快的速度,也没有 Octave 或其他数学模块那样简单的语法,所以数据分析的部分常常是由专业的数学软件完成的。当然,如果你大部分工作都是用的 Perl,而你需要的数学又相对简单,那么再去求助专业软件就可能是杀鸡用牛刀了。
|
生成报表
|
是
|
可能
|
一些数据库(如Oracle)或数学/统计学软件(比如SAS)提供“报表生成器”。如果这些能够满足你的要求,那么你就用它好了。但是如果你需要更复杂的报告,Perl 可能是你的选择。 你经常会用 Perl 来创建 HTML 格式的报告(比其他格式如 PDF 要简单得多),然后将 HTML 再转换成其他格式,比如 WORD 或 PDF。有些人会更关心 XML。XML实际上是展示数据的一种方法,但不是用来做视觉上的数据展示。用设计与开发的术语来说,XML 可能更接近于数据存储,而离数据报表更远。数据存储的工作是你应该在整个项目早期考虑的事情,而不是在数据汇报的时候。 |
越来越多的人,通过互联网来获取数据,例如 XML 等格式,然后对这些数据进行分析(股票数据,DNA 数据,等等)。
|
Perl
|
数学模块/软件
|
可能用到的工具
|
XML 获取
|
是
|
可能
|
|
数据处理
|
是
|
可能
|
正则表达式
|
数据分析
|
可能
|
是
|
前面提到的软件或工具
|
汇总报告
|
是
|
可能
|
相关推荐
它包括perl二进制文件,编译器(gcc)+相关工具,所有外部库(加密,数学,图形,xml等),所有捆绑的数据库客户端以及对Strawberry Perl的期望。 在Linux和大多数类似UNIX的系统(包括Mac OS X)下,perl与系统...
"Perl函数全集"是Perl学习者的重要参考资料,它包含了Perl语言中众多内置函数的详细解释和示例,对于深入理解Perl的功能和提升编程技能非常有帮助。 在Perl中,函数是可重用的代码块,用于执行特定的任务。以下是...
- **科学计算**:尽管不是主要用途,Perl 也可以用于简单的数学计算和数据分析。 #### 三、Perl安装方法 ##### 对于 Windows 用户: 1. 访问 [ActiveState]...
11. **数值计算与数学算法**:Perl可以处理复杂的数学运算,包括复数、矩阵、高精度计算等,这在科学计算和工程应用中十分常见。 12. **优化与贪心策略**:在解决实际问题时,Perl可以用于实施贪婪算法和动态规划等...
### 关于利用Perl脚本产生状态机的Verilog代码与DC脚本 #### 摘要 在电子设计自动化(EDA)领域,特别是在数字电路设计过程中,状态机的设计与实现是一项核心任务。状态机(Finite State Machine, FSM)是描述数字...
### Perl教程概述与基本概念 #### 一、Perl简介 Perl是一种高级编程语言,全称为Practical Extraction and Report Language,即实用的提取和报告语言。它最初由Larry Wall开发,并持续由他进行更新和维护。Perl的...
通过将Perl与生物信息学结合,专业人员能够开发出更智能、更高效的解决方案,推动生命科学的进步。 ### 部分内容解读: 虽然提供的部分内容中包含了一些无法解析的符号和乱码,但从可识别的部分来看,这部分内容...
Perl6允许开发者直接在REPL中输入表达式来尝试基本的数学运算,如加法、减法、乘法、除法以及取模等。这本书通过例子展示了如何进行这些基本的数值运算,并要求学习者自己尝试这些运算来观察结果。 字符串是编程中...
9. **系统交互**:Perl可以方便地与操作系统进行交互,执行外部命令,管理进程等。书中给出了如何使用`system`和`backticks`进行系统调用的实例。 10. **网络编程**:Perl同样适用于网络编程,可以创建客户端和...
在数学计算领域,Perl同样表现出色,能够处理各种数值运算,包括浮点数的加减乘除。本文将详细探讨如何使用Perl来实现浮点格式数据的运算,并解释浮点数的组成——指数(exponent)和小数部分(mantissa)。 浮点数在...
Strawberry Perl 5.30.1 windows x64 MSI (2019.11.22发布) ...它包括perl二进制文件,编译器(gcc)+相关工具,所有外部库(加密,数学,图形,xml等),所有捆绑的数据库客户端以及您对Strawberry Perl的所有期望。
2. **字符串与数字操作**:详细介绍了如何在Perl中处理字符串与数字(标量数据)。 3. **高级标量数据操作与运算符**:进一步深入探讨了更复杂的标量数据管理方法以及各种运算符的应用。 4. **列表与数组处理**:...
Perl拥有大量的内置函数,涵盖了数学、字符串、文件处理、系统调用等多个领域,如: - 数学函数:abs(绝对值)、int(取整)、sqrt(平方根)、rand(随机数)。 - 字符串函数:length(长度)、substr(子串)、...
2. **数据格式化与输出**:在描述中提到,Perl脚本会根据既定格式输出数据。这意味着你需要处理从Excel中读取的值,可能包括数字、日期、字符串等,并将其转换为所需的格式。例如,你可能需要将日期从Excel的内置...
** 对于复杂的数学计算和图形界面设计,Perl不如专门的语言或工具。 #### 1.3 如何获取Perl? - **什么是CPAN?** CPAN是Comprehensive Perl Archive Network的缩写,是Perl模块的中央仓库,提供了大量免费的扩展库...
<br/>因为 Perl 既强大又好用,所以它被广泛地用于日常生活的方方面面,从宇航工程到分子生物学,从数学到语言学,从图形处理到文档处理,从数据库操作到网络管理。很多人用 Perl 进行快速处理那些很难分析或...
整型是最常见的简单变量类型,可以进行数学运算,例如将数值分配给变量$x,然后进行比较或计算。需要注意的是,虽然Perl中的整数在内部可能存储为浮点数,但在大多数情况下,整型操作不会受到影响。 此外,Perl还...