@author:armylau
@date:2004-8-12
一.起因
安装和使用blitz++时经常遇到问,查看了ccboy写的《VC++ _NET 2003 –安装和使用Boost 1_30和Blitz++0_6 》,但他写的不详细, Blitz的官方文档也不清楚, 只好自己来, 花了不少时间才初步弄清楚。
二.Blitz简介
大家知道Fortran是公认的科学计算编程语言,大量数值计算库都是基于fortran的,如lapack. 而blitz++则为科学计算人员提供了面向对象的C++的数值计算程序库, 速度能与fortran77/90匹配.
用过matlab的人知道, matlab是一种基于矩阵的第四代语言,它将每个变量都视作矩阵,赋值起来比起c/c++/java等主流语言起来非常方便,而blitz++也提供了这种矩阵的强大操作,而且性能比起matlab要快很多,这是因为两种的语言特性所决定的.
Blitz++最新的版本中提供了数组和向量(即矩阵),随机数产生器,小向量和矩阵.
值得注意的是,与其它数值计算包相比较, blitz是非常有个性的,它不求高大全,如它并没有提供所有的矩阵操作功能,如求特征向量,FFT分析等.它的特点在于面向对象、数组操作语法和模板操作(But the main focus of blitz is on array syntaxand stencil operations)[4]。矩阵操作功能,想起STL中的VALARRY了吗?VALARRAY中的功能这里都实现和加强了。这个在测试项目MT1中可以初步显示.
三.安装与测试
1) 安装Blitz++-0.7通用代码
首先要安装最原始的代码包,源代码是跨平台的,只要blitz支持.
在http://www.oonumerics.org/blitz/ 下只有0.6版本的,最新的版本是0.7,在http://sourceforge.net/project/showfiles.php?group_id=63961 .解压缩,如到C:\vc\Blitz++-0.7
2) 安装Blitz-VS.NET1.5 -FOR vs.net2003项目
如果想blitz能在VS.net下使用, 就要定义相应的宏, 使用相应的头文件, lib和blitz++提供的类就行. 而宏定义,Lib的编译项目文件,这些工作Julian Cummings已经为我们做好.在blitz++的主页上查看supported platforms,看到blitz for vs.net,循提示去到blitz在sourceforge的cvs下查找,在cvs目录下 http://cvs.sourceforge.net/viewcvs.py/blitz/blitz , 下载两个文件: Blitz-VS.NET.zip和README-VS.NET.txt,我下载时的这两个文件的最新版本分别是1.6和1.1
将blitz-VS.NET zip解压缩,它的主目录与C:\vc\Blitz++-0.7的相同,我们假设它为C:\vc\Blitz-VS.NET1.6,目录结构如下:
Blitz
Blitz-Testsuite
Blitz-Library.ncb
Blitz-Library.sln
Blitz-Library.suo
blitz\里面是config.h, 它定义了blitz相关的宏变量, 如BZ_HAVE_COMPLEX, BZ_HAVE_STL等等, 这是每个项目必须用到的.
blitz目录里面还有一个VC项目文件, 这个项目是用来生成blitz.lib文件的,稍后我们将提到如何设置生成。
3) 生成blitz.lib
启动vs.net2003,设置: 工具->选项->项目->VC++目录, 在”包含文件”中添加blitz-0.7的路径 (即cl中的 /I 参数),如C:\vc\blitz。 下图为我的配置
使用vs.net2003打开为C:\vc\Blitz-VS.NET1.6\blitz\ blitz.vcproj,如上所述,我们正是用这个项目来产生blitz.lib的.它所使用的源文件就是Blitz++-0.7\src\globals.cpp, 因为代码原作者为了保持代码的唯一份,所以没有包括到这个for vs.net的压缩包中, 你要将原Blitz++目录下的src目录拷贝到这里.如将C:\vc\Blitz++-0.7\src拷贝到 C:\vc\Blitz-VS.NET1.6\src
编译生成blitz.lib.编译时会出现错误提示,如error PRJ0019:工具从”copying blitz_d.lib..”不必理会,这是blitz的BUG,在DEBUG或release目录下已经生成了我们所需的文件,debug版本的为blitz_d.lib, release版本的为blitz.lib.
此时,为了以后的版本都能使用此lib文件,我们可以配置一下全局选项:
首先在\Blitz-VS.NET1.6\下新建一lib目录,将blitz.lib和blitz_d.lib拷贝进去. 在工具->选项->项目->VC++目录->库文件下添加我们lib的路径
4) 编译和测试blitz-testsuit
用vs.net2003打开Blitz-Library.sln, 里面包括了54个测试用例.
将Blitz++-0.7下的testsuite目录拷贝到Blitz-VS.NET1.6,原因也是为了保持代码的唯一性,据作者所说[4].
要确认这点, 可以打开项目配置文件vsproj,用文本编辑器如notepad打开, 查看
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File
RelativePath="..\..\testsuite\ctors.cpp">
</File>
</Filter>
</Files>
确定项目选项输入库为blitz_d.lib或blitz.lib
编译,执行.1) 如测试ABA1, 这是求数组的最大值的测试
源代码为:
#include
BZ_USING_NAMESPACE(blitz)
int main()
{
Array<double,1> psiElem(3);
psiElem =
-0.121990517304243,-0.099118834514638,-0.164750336116265;
double psi_max = blitz::max(psiElem);
cout << "psiElem = " << psiElem << endl;
cout << "psi_max = " << psi_max << endl;
}
结果为:
psiElem = 3
[ -0.121991 -0.0991188 -0.16475 ]
psi_max = -0.0991188
2) 测试MT1 – 主要测试矩阵赋值与操作语法,index的使用等等.
源码:
#include
BZ_USING_NAMESPACE(blitz)
#if 0
BZ_DECLARE_STENCIL2(kinEnergy,A,B)
B=Laplacian3D(A);
BZ_END_STENCIL_WITH_SHAPE(shape(-1,-1,-1),shape(1,1,1))
typedef complex<double> T_num;
typedef Array array3d;
int main()
{
const int N=5;
array3d A(N,N,N);
array3d B(N,N,N);
// Fill a three-dimensional array with a Gaussian function
firstIndex i;
secondIndex j;
thirdIndex k;
float midpoint = 15/2.;
float c = - 1/3.0;
A = exp(c * (sqr(i-midpoint) + sqr(j-midpoint)
+ sqr(k-midpoint)));
applyStencil(kinEnergy(), A, B);
Array out_view(B.data(),shape(N*N*N));
cout << out_view;
}
#endif
BZ_DECLARE_STENCIL2(footprint,A,B)
B = Laplacian2D4(A);
BZ_END_STENCIL_WITH_SHAPE(shape(-2,-2),shape(+2,+2))
int main()
{
int N = 9;
Array<double,2> A(N,N), B(N,N);
A = 0;
A(4,4) = 1;
applyStencil(footprint(), A, B);
cout << B(Range(2,6),Range(2,6)) << endl;
}
结果为:
5 x 5
[ 0 0 -1 0 0
0 0 16 0 0
-1 16 -60 16 -1
0 0 16 0 0
0 0 -1 0 0 ]
五.在自己的项目中使用
一个很简单的例子,
新建个人项目后,注意以下几件事:
1. 添加了lib或正确配置了lib的路径 :将blitz.lib拷贝到项目下或在项目属性中配置好引用路径.
2. 添加了config.h, 将原来我们编译blitz.lib的宏定义文件拷贝过来.
3. 使用了using namespace blitz
4. 正确使用blitz的库对象
#include "stdafx.h"
#include "config.h"
#include
#include
using namespace blitz;
int main()
{
complex<int> c(4,8);
cout << c << endl;
Array<int,2> ar(2,2) ;
ar = 1,1,
2,2;
cout << ar <
}
在编译时,各种配置都要非常小心,一不小心就会出错,按照以上的步骤一步一步来,应该不会有太大的错误,有任何问题或建议,可与我联系armylau@163.com
六.参考文献:
1. [blitz] blitz官方主页,文档
2. [IBM] C 和 C++ 的矩阵库-评估和比较 Meschach、Cooperware 矩阵和 Blitz.htm http://www-900.ibm.com/developerWorks/cn/linux/other/matrix/index.shtml
3. [ccboy] ccboy写的VC++ _NET 2003 –安装和使用Boost 1_30和Blitz++0_6
4. [Julian C.]emails