少女祈祷中...

做monte carlo很需要计算机的速度,除了寻找算法上的绝对优势之外,在代码上还能够有什么改进?结果显而易见。

预留空间+刷新整个动态数组需要67毫秒...

预留空间+刷新二维动态数组需要142毫秒...

1
构造改进版连续存储二维动态数组需要140毫秒...

11
vector初始化用掉1毫秒...

vector用resize来预留空间需要74毫秒...

5000000
vector如果用pushback需要2707毫秒...

5000000
刷新这个vector里面的所有值需要443毫秒...

使用vector的vector来pushback构造多维数组需要13131毫秒...

一个使用pair类型的vector来pushback需要12845毫秒...

#include <vector>
#include <ctime>
#include <iostream>
#include <fstream>
using namespace std;
 
 
void main(){
	ofstream flux("haaaaaaa.txt");
	double start, finish, duration;
	int N;
	int n;
	N=5000000;
	n=2;
 
 
	start   =   clock();
	double *temp= new double[N];
	for(int i=0;i<N;i++){
		temp[i]=99;
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"预留空间+刷新整个动态数组需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
 
	start   =   clock();
	double **temp1= new double *[n];
	for(int i=0;i<n;i++){
		temp1[i] = new double [N];
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<N;j++){
			temp1[i][j]=1;
		}
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"预留空间+刷新二维动态数组需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	flux<<temp1[1][100]<<endl;
 
	start   =   clock();
	double **temp2=new double *[n];
	temp2[0]= new double [N*n];
	for(int i=1;i<n;i++){
		temp2[i]=temp2[i-1]+N;
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<N;j++){
			temp2[i][j]=11;
		}
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"构造改进版连续存储二维动态数组需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	flux<<temp2[1][100]<<endl;
 
 
	start	=clock();
	vector<double> test;
	vector<pair<double,double>> test2;
	vector<vector<double>> test3;
	finish =clock();
	duration   =   (double)(finish   -   start); 
	flux<<"vector初始化用掉"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
 
	start   =   clock();
	test.resize(N,1);
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"vector用resize来预留空间需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	flux<<test.size()<<endl;
	test.clear();
 
	start   =   clock();
	for(int i=0;i<N;i++){
		test.push_back(1);
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"vector如果用pushback需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	flux<<test.size()<<endl;
	//test.clear();
 
	start   =   clock();
	for(int i=0;i<N;i++){
		test[i]=99;
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"刷新这个vector里面的所有值需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	test.clear();
 
	start   =   clock();
	for(int i=0;i<n;i++){
		for(int j=0;j<N;j++){
			test.push_back(99);
		}
		test3.push_back(test);
		test.clear();
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"使用vector的vector来pushback构造多维数组需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
	test.clear();
 
 
 
	start   =   clock();
	for(int i=0;i<N;i++){
		test2.push_back(make_pair(1,1));
	}
	finish   =   clock();  
	duration   =   (double)(finish   -   start); 
	flux<<"一个使用pair类型的vector来pushback需要"<<duration<<"毫秒..."<<endl<<endl<<endl<<endl;
 
 
 
	delete [] temp;
	for(int i=0;i<n;i++){
		delete [] temp1[i];
	}
	delete [] temp1;
	delete [] temp2[0];
	delete [] temp2;
	flux.close();
 
 
	char wengding;
	cin>>wengding;
 
};

Windows 7 64 bit Ultimate 7600_16385  + Visual Studio 2010 ultimate + MATLAB 2010 64bit + Office 2010 RTM professional 64bit

昨天重装了三次系统,折腾死我。今天终于爽了。这种廉价的幸福跟女人买新衣服的快感大概没有什么两样。第一次装64位的系统,感觉机器十分的快,磁盘性能好了很多。不过感觉总是不可靠的,很有可能是心理暗示。可惜的是光有4G内存,主板却只支持到3G,我是比较喜欢关闭虚拟内存的。总结一下遇到的问题:

  1. Windows 7 64 bit 占用硬盘相当的大。我的C盘原本只有24G,鉴于我什么软件都往C盘里面塞,即使是XP,到头来也只剩2G左右。装了win7之后我才发现C盘大小完全不够用,我便需要一个无损分区工具。Acronis 10我试过了,失败。搜到官方说法:11才会支持win7的。最终我找到个超级好用的win7下的分区工具:Partition Wizard。速度快的惊人,关键软件还是免费的。
  2. 这里有位内牛满面哥为了装vs2010,重装了9次系统。精神可嘉,可惜没有找到问题的症结所在。我前两次重装也是因为visual studio装不上去,需要不停重启。我分别尝试的win7 x86 和 x64 版本是7600_16384。结论就是换成16385就好了,并不是dell oem版本的原因,也不是破解的原因。
  3. 安装office 2010遇到1935这种错误的,绝对是.netframework的问题。好好装个3.5 sp1就可以解决问题。Vol版的可以使用那个延时180天的工具,我这个pro版只能用神key电话激活了。
  4. VS2010中工具》选项》项目和解决方案》C++目录的编辑功能已被否决。全局的设定这些目录需要在项目上点击右键》属性》配置属性》C++目录中设定。详见MSDN中的解释。
  5. 写程序时,原先要拷到system32文件夹下的那些dll现在要拷到SysWOW64文件夹。

嗯,穿新衣,安心工作。

如需转载,请注明来源:http://hi.baidu.com/yowsah/

GLUT 代表OpenGL Utility Tookit。Mark J.Kilgard 为了使OpenGL应用程序结构能够真正独立于窗口系统构思了GLUT库。

Freeglut是一个GLUT的开源实现。

本文介绍VS2008环境下的Freeglut 2.6.0配置:

1. 下载Freeglut:http://freeglut.sourceforge.net/http://prdownloads.sourceforge.net/freeglut/freeglut-2.6.0.tar.gz?download

2. 下载到的文件为freeglut-2.6.0.tar.gz,解压到任意目录,使用Visual Studio 2008打开freeglut-2.6.0\VisualStudio2008\freeglut.vcproj,使用Release执行编译。这时会生 成Release目录。

3. 将Release目录中的freeglut.dll复制到system32下。

4. 查找gl.h位置(默认在C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\gl),将freeglut-2.6.0\include\GL中的.h文件复制进去。

5.查找GlU32.Lib位置(默认在C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib),将Release目录下的freeglut.lib文件复制进去。

完成配置。

通过以下程序可测试是否成功并查看OpenGL版本:

#include <stdio.h>
#include <windows.h>
#include <gl/glut.h>
 
int main(int argc, char** argv)
{
glutInit(&argc,argv);
//显示模式初始化
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
//定义窗口大小
glutInitWindowSize(300,300);
//定义窗口位置
glutInitWindowPosition(100,100);
//创建窗口
glutCreateWindow("testgl");
const char* version = (const char*)glGetString(GL_VERSION);
printf("OpenGL 版本:%s\n", version);
glutMainLoop();
return 0;
}

下面的程序是利用OpenGL画公式 f(x)=\exp(-x)\cos(2\pi x) 的曲线:
转载自:http://blog.csdn.net/wangwei200508/archive/2008/03/09/2160189.aspx

// Draw the "dot plots" of a function
//P52 in <Computer Graphics Using OpenGL(Second Edition)>
 
#include<math.h>
#include<GL/glut.h>
 
const int screenWidth = 640;   // width of screen window in pixels
const int screenHeight = 480;  // height of screen window in pixels
GLdouble A,B,C,D; // values used for scaling and shifting
 
//----------Initialization--------------
void init(void)
{
    glClearColor(1.0,1.0,1.0,0.0); // Set white background color
    glColor3f(0.0f,0.0f,0.0f);    // Drawing color is black
    glPointSize(2.0);             // a 'dot' is 2 by 2 pixels
    glMatrixMode(GL_PROJECTION);  // Set "camera shape"
    glLoadIdentity();
    gluOrtho2D(0.0,(GLdouble)screenWidth,0.0,(GLdouble)screenHeight);
    // Set values used for scaling and shifting
    A = screenWidth/4.0;
    B = 0.0;
    C = D = screenHeight/2.0;
 
}
 
// --------Draw the "dot plots" of a function------
void dotPlots(void)
{
    glClear(GL_COLOR_BUFFER_BIT);       //clear the screen
    glBegin(GL_POINTS);
        for(GLdouble x = 0;x<4.0;x += 0.005)
        {
            GLdouble func = exp(-x) * cos(2*3.14159265*x);
            glVertex2d(A*x+B,C*func+D);
        }
    glEnd();
    // Draw a horizontal line
    glBegin(GL_LINES);
        glVertex2i(0,screenHeight/2);
        glVertex2i(screenWidth,screenHeight/2);
    glEnd();
    glFlush(); //send all output to display
}
 
//--------main-----------
void main(int argc,char** argv)
{
    glutInit(&argc, argv);  // Initialize the toolkit
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);  // Set display mode
    glutInitWindowPosition(100, 150);  // Set window pozition on screen
    glutInitWindowSize(screenWidth, screenHeight);      // Set window size
    glutCreateWindow("Dot plot of a Function"); // Open the screen window
    glutDisplayFunc(dotPlots); // Register redraw function 
    init();
    glutMainLoop();  // Go into a perpetual loop
//在上面的 dotPlot()中的for循环里做一些更改就可以画另一个函数图了
}

我以前用C++写程序做实验,为了让自己的数学结果能够可视化,总是把结果输出成文件,再用matlab来plot 2d图像。这无疑增加了工作量。怎么样可以在C++代码里面直接调用画图程序进行plot呢?Gnuplot这个软件给我们了C++的接口。 Gnuplot是一个强大的科学绘图软件,它甚至可以将Plot的图片直接转换成tex文件,这无疑是一名数学工作者的福音。Viktor Chyzhdzenka以gnuplot_i这个C的程序为基础,写了一个C++的绘图类。其原版代码在这里:http://ndevilla.free.fr/gnuplot/GNUPlot1.zip, 但我在编译使用中遇到了两个问题:

  1. 明明是windows系统,可是#ifdef WIN32 后面的语句却是灰色的。
  2. 程 序无法容易的找到Gnuplot的目录

经过修改,我将这个程序改得只适用于windows,另外Gnuplot里的 exe文件保证和VS2008里面的vcproj文件同目录即可。如果要发布文件,则和exe文件同目录即可。大家也可以自己阅读原版代码进行修改。再进 一步熟悉Gnuplot的用法之后,相信我们很容易可以为这个绘图类添加属于自己的成员函数。这里有一个Gnuplot的简单教程。

点我下载gnuplot_i头文件

点我申请115网盘

解压密码2000。

希望下载的人对速度有个反馈,merci。

装好了CLAPACK,试着用最小二乘法解了个10000*100阶矩阵乘以100*1阶矩阵等于10000*1阶矩阵的方程,瞬间出来结果,估计比matlab还要快一点。当然这只用转成100*100阶矩阵的QR分解问题。我自己写的代码,用的householer算法,这样的矩阵分解真的很 费时间,这实在是让人很沮丧,让人觉得我自己真的不会写程序。花了两三天自己写矩阵的类,结果还不令人满意。这也是为什么我转头研究这些库。
我 好好想一了想,首先并不用把所有的事情都揽到自己头上,非要代码100%都是自己的。已经有现成的很完美的解决方案,拿来用就是了,我只是做科学计算,数学实验的人,没必要浪费时间到没有意义的地方。其次,并不是代码的问题,代码的速度很大程度上取决于算法,手头讲线性代数这方面算法的书并不多,倒是一堆讲美式期权估价算法的文章。两周的实习也让我深刻的认识到算法的重要性远大于编程的技巧。
接下来的事情就是好好学习这些库的用法,以更加熟练的运用到自己的程序之中。LAPACK用起来很方便,几乎程序的源代码都在SRC目录,每个源文件里面都有函数的详细用法。但是为了实现一个方法, 却很难在那么多源文件里面选择是哪一个,尤其是对新手,对那些函数的命名规则不熟的人,真的是举步维艰。
这里是比较容易找到的官方的使用说明。
下面就 是这些函数的一些总结和索引,方便自己查阅和中文的搜索。
这里还包含一些其他的科学计算库中的函数索引。
这里可以可以查到大部分函数的用法,还带例子,可以说是福利了。

这里实际上有我在网络上找到的唯一的也是详尽的一个安装方法,可是依照它一步步做下来,最后的程序还是F5不了。其实是因为自己对Visual Studio实在很不熟的缘故,并不是安装步骤有问题。通过这里一篇简短的Levmar安装说明,我终于明白了是怎么回事。

打开CLAPACK-3.1.1-VisualStudio文件夹,先把\LIB\Win32的lib都删了,以免混淆

双击clapack.vcproj打开工程项目文件,下面的各编译步骤都编译成debug模式

依次编译F2CLIBS,tmglib,blas,CLAPACK,结果是在\LIB\Win32下依次生成了 libf2cd.lib,tmglibd.lib,BLASd.lib,clapackd.lib

工具->选项->项目和解决方案->vc++目录->包含文件处添加     \INCLUDE目录

工具->选项->项目和解决方案->vc++目录->库文件处添加        \LIB\Win32目录

项目属性->连接器->输入->附加依赖项libf2cd.lib BLASd.lib clapackd.lib tmglibd.lib

项目属性->连接器->输入->忽略特定库Libcmtd.lib

原来是Libcmtd.lib和MSVCRT.lib两个默认库和libf2cd.lib的冲突造成的链接问题。

详细的解释见这里:http://blog.csdn.net/pgmsoul/archive/2009/05/20/4203941.aspx

最后总结一下安装Library的方法:

  1. 像boost那样大多数都是直接可用的头文件的,可以直接设置\INCLUDE目录
  2. 而像CLAPACK这个和boost中有一些库,必须编译成Lib,然后设置成\LIB目录
  3. 测试库文件,编译或者运行出错的时候,记得查看日志,找出真正的错误原因

如此简单。