一、GSL介绍
GNU科学计算函数库GSL(GNU Scientific Library)是一个强大的C/C++数值计算函数库,它是一个自由软件,是GNU项目软件的一个部分,遵循GPL协议。GSL是一个为C和C++程序员提供的科学数值运算库。该科学计算库异常强大,函数库提供了大量的数值计算程序,如随机函数、特殊函数和拟合函数等等,整个函数库大约有1000多个函数,几乎涵盖了科学计算的各个方面。提供了如下方面的支持:
Complex Numbers Roots of Polynomials Special Functions
Vectors and Matrices Permutations Sorting
BLAS Support Linear Algebra Eigensystems
Fast Fourier Transforms Quadrature Random Numbers
Quasi-Random Sequences Random Distributions Statistics
Histograms N-Tuples Monte Carlo Integration
Simulated Annealing Differential Equations Interpolation
Numerical Differentiation Chebyshev Approximation Series Acceleration
Discrete Hankel Transforms Root-Finding Minimization
Least-Squares Fitting Physical Constants IEEE Floating-Point
Discrete Wavelet Transforms Basis splines
该函数库的主页是:http://www.gnu.org/software/gsl/gsl.html。不过遗憾的是原始GSL并不支持不支持windows平台,可所幸的是有人做了GSL在windows上的移植工作,详见http://gnuwin32.sourceforge.net/packages/gsl.htm,目前版本是1.8。
二、下载gsl
1、从http://gnuwin32.sourceforge.net/packages/gsl.htm下载Complete package, except sources和Sources两个exe文件。
这是gsl最新版本的下载地址(感谢shaw博友提供):http://gladman.plushost.co.uk/oldsite/computing/gnu_scientific_library.php
三、安装
1、 首先从http://gnuwin32.sourceforge.net/packages/gsl.htm下载的两个文件gsl-1.8.exe和gsl-1.8-src.exe,默认安装就行。
四、设置Visual studio编译环境
4.1 对于visual studio 2010
1、生成lib文件。发现安装目录lib下并没有libgsl.lib,libgslcblas.lib这两个文件,倒是有两个扩展名为def和a(linux下库文件包格式)的文件,因此必须进行转换。
l 开始菜单,点击运行,输入cmd。
l 先将lib.exe的所在目录(vs安装目录下Microsoft Visual Studio \VC\bin)加入到系统/用户环境变量path中,以便在命令行下可以执行lib,进入gsl库的lib目录下依次输入以下两条语句:
lib /machine:i386 /def:libgsl.def
lib /machine:i386 /def:libgslcblas.def
注:如果执行这两条命令时提示不支持lib命令,则从vs安装vc\bin目录下拷贝lib.exe到libgsl.def所在目录即可。
默认是不能运行的,缺少几个文件。把Microsoft Visual Studio 8\Common7\IDE 里面的spdb80.dll,mspdbcore.dll,
mspdbsrv.exe,msobj80.dll复制到上面的bin文件夹里。
如果报错error:cannot excute link.exe,则在命令行界面执行vc/bin下vcvars32.bat脚本文件,应该能顺利执行lib命令。
再看lib目录下,发现有了libgsl.lib,libgslcblas.lib这两个文件。
2、将x:\Program Files\GnuWin32l\bin中的libgsl.dll和libgslcblas.dll复制到x:\VC\Bin;将\include整个Gsl目录复制到\VC\include下;\lib目录下的所有.lib文件全部复制到\VC\Lib下。
(如果这样添加了其实下面指定的前两个都不需要,因为在系统中已经有了这些文件,但不建议按这种方法指定,这样会使系统VC库中的东西非常混乱,强烈建议使用下面这种指定路径的方法!!)
在Project -> tracking-> Configuration Properties -> C/C++ -> General -> Additional Include Directories 中增加头文件路径。
在Project -> tracking -> Configuration Properties -> C/C++ -> General -> Additional Library Directories 中增加库文件路径。
在Project -> tracking -> Configuration Properties -> Linker -> Input -> Additional Dependencies 中增加所依赖的库文件libgsl.lib和libgslcblas.lib。
重要tips:需要在c/c++的command line里添加 /D "GSL_DLL"
(注:Project -> tracking -> Configuration Properties ->C/C++->Command line)
3、 新建一个工程用于测试,。然后在该项目的project-properties-configuration properties-linker-input,在additional dependencies中加入你用到的库文件,如libgsl.lib libgslcblas.lib,用空格隔开。
4.2 对于vc6.0
生成lib文件:发现安装目录lib下并没有libgsl.lib,libgslcblas.lib这两个文件,倒是有两个扩展名为def和a(linux下库文件包格式)的文件,因此必须进行转换。
这里可以直接用windows命令行,在命令行中切换到D:\GSL\GnuWin32\lib
lib /machine:i386 /def:libgsl.def
lib /machine:i386 /def:libgslcblas.def
运行以上命令后再看lib目录下,发现有了libgsl.lib,libgslcblas.lib这两个文件,这就对了,进入下一步。
将D:\GSL\GnuWin32\bin中的libgsl.dll和libgslcblas.dll复制到..\VC\Bin下;
将D:\GSL\GnuWin32\include目录下的整个gsl文件夹拷贝到..\VC\include下;
将D:\GSL\GnuWin32\lib目录下的所有.lib文件全部复制到..\VC98\Lib下。
新建一个VC6工程用于测试,然后进入项目->属性->连接器->输入,在“附加依赖项”一栏加入库文件 libgsl.lib libgslcblas.lib,用空格隔开,并在
Project setting->C++->Project Options加入/D "GSL_DLL",并点击OK
五、测试Gsl函数库(一)
#define GSL_DLL //如果程序用到gsl的动态链接库,一定要加这句,否则连接时报错“access violation。。。。。”
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spline.h>
#include <conio.h>
int main (void)
{
int i;
double xi, yi, x[10], y[10];
printf ("#m=0,S=2\n");
for (i = 0; i < 10; i++)
{
x[i] = i + 0.5 * sin (1.0*i);
y[i] = i + cos (i * i*1.0);
printf ("%g %g\n", x[i], y[i]);
}
printf ("#m=1,S=0\n");
{
gsl_interp_accel *acc = gsl_interp_accel_alloc ();//a gsl_interp_accel object, which is a kind of iterator for interpolation lookups. It caches the previous value of an index lookup. When the subsequent interpolation point falls in the same interval its index value can be returned immediately.创建一个gsl_interp_accel类型的指针并初始化,该类型对象可以加速对数组元素的遍历。
//equivalent to the corresponding gsl_interp functions but maintain a copy of this data in the gsl_spline object. This removes the need to pass both xa and ya as arguments on each evaluation. 下面这两个函数功能等同于普通的调用gsl_interp。。。相应函数,但效率较高,不必每计算一个插值点就把x和y传过去一遍。
gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, 10);
gsl_spline_init (spline, x, y, 10);
for (xi = x[0]; xi < x[9]; xi += 0.01)
{
yi = gsl_spline_eval_r(spline, xi, acc);//求x=xi时对应的插值yi。
printf ("%g %g\n", xi, yi);
}
gsl_spline_free (spline);
gsl_interp_accel_free (acc);
}
getch();
return 0;
}
======================================================================================
测试程序(二)
#define GSL_DLL
#include <gsl/gsl_spline.h>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <gl/glut.h>
#include <gl/gl.h>
void Display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
const size_t n = 4;
double x[] = {0,0.333336,0.666666,1};
double y[] = {0,0.5,0.9,0};
gsl_interp* interps[3] = {NULL,NULL,NULL};
interps[0] = gsl_interp_alloc(gsl_interp_linear,n);
interps[1] = gsl_interp_alloc(gsl_interp_polynomial,n);
interps[2] = gsl_interp_alloc(gsl_interp_cspline,n);
gsl_interp_init(interps[0],x,y,n);
gsl_interp_init(interps[1],x,y,n);
gsl_interp_init(interps[2],x,y,n);
gsl_interp_accel* acc = gsl_interp_accel_alloc();
glBegin(GL_LINE_STRIP);
for(double t=0.0; t<=1.025; t+=0.025)
{
glColor3f(1,0,0);
glVertex3f(t,gsl_interp_eval_r(interps[0],x,y,t,acc),0.0);
}
glEnd();
glBegin(GL_LINE_STRIP);
for(double t=0.0; t<=1.025; t+=0.025)
{
glColor3f(0,1,0);
glVertex3f(t,gsl_interp_eval_r(interps[1],x,y,t,acc),0.0);
}
glEnd();
glBegin(GL_LINE_STRIP);
for(double t=0.0; t<=1.025; t+=0.025)
{
glColor3f(0,0,1);
glVertex3f(t,gsl_interp_eval_r(interps[2],x,y,t,acc),0.0);
}
glEnd();
gsl_interp_accel_free(acc);
gsl_interp_free(interps[0]);
gsl_interp_free(interps[1]);
gsl_interp_free(interps[2]);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(512,512);
glutCreateWindow("GSL Interpolation");
glutDisplayFunc(Display);
glClearColor(1,1,1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1,-1,0);
glScalef(2,2,1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,512,512);
glLineWidth(4.0);
glutMainLoop();
return 0;
}运行结果:
说明Gsl函数库已经可以使用了。