以下のコードを実行すると、このエラーが表示されます。
Segmentation fault (core dumped)
理由がわかりません。
#ifndef DQMCBASE__H
#define DQMCBASE__H
const double pi=3.141592645;
#define rnd() ((double)rand())/ RAND_MAX
/**
* The basic walker class. This class serves the purpose of providing
* a structure that can be reused by inheriting.
*/
class DQMCWalker {
double _x; ///< dummy variable to implement basic 1D Harmonioscillator example.
This variable will be removed in future versions.
double _timeStep; ///< is the timestep in between to simultanious simulations
public:
DQMCWalker();
~DQMCWalker();
/**
* implements a normal distribution that can be used for the walking
* process defined in
* @see WalkNormal()
*
* @param variance the variance of the distribution.
* @param meanvalue the mean value of the distribution.
*
* @return A double distributed according to a normal distribution.
*/
double NormalDistribution(double variance, double meanvalue);
/**
* a virtual function that describes the walking process of the walker.
*
* @return returns 0, always.
*/
virtual int WalkNormal();
virtual double Potential();
virtual double Weight(double);
int Copy(DQMCWalker);
double SetDeltaT(double);
double GetDeltaT();
};
/* *
* The simulation class is a basic class that implements the basic features of walking, branching
* TODO
*/
template <class walker>
class DQMCSimulation {
walker* _walkers;
walker* _copies;
double _refE;
double _timeStep;
int _population;
int _max_walkers;
int _last_pop,_cur_pop,_nCopies;
public:
/**
* The constructor is used to define the simulation parameters of an instance. It takes two parameters,
* namely, the number of walkers and the time step in between two iterations.
*
* @param n the number of walkers used in the simulation.
* @param dt the time step in between two iterations.
*/
DQMCSimulation(int n, double dt);
~DQMCSimulation();
/**
* This function is used to perform one iteration. Every time this function is called
* a walkers are move according to the implementation of DQMCWalker::Walk(), next the
* reference energy is calculted according to the formula
* TODO
* and lastly, a birth-death process is performed.
*/
int Iterate();
double GetReferenceEnergy();
walker* WalkerArray();
};
#endif
ここまでは DQMCBase.h ファイルに埋め込むことができます
/* DQMCBase.cpp */
#include <iostream>
#include<math.h>
#include<stdlib.h>
#include<ctime>
//#include <DQMCBase.h>
using namespace std;
DQMCWalker::DQMCWalker() {
_timeStep=0.1;
_x=0.0;
}
DQMCWalker::~DQMCWalker() {
_x=0.0;
}
double DQMCWalker::NormalDistribution(double variance=1.0, double meanvalue=0.0) {
int samples=12;
double res = 0.0;
for(int i=0;i<samples;i++)
res +=rnd();
res = (res - samples*0.5)*sqrt(variance)+meanvalue;
return res;
}
int DQMCWalker::WalkNormal() {
_x+=NormalDistribution(1.0,0.0)*sqrt(_timeStep);
return 0;
}
double DQMCWalker::Potential() {
return 0.5*_x*_x;
}
double DQMCWalker::Weight(double refE) {
return exp(-(Potential()-refE)*_timeStep);
}
int DQMCWalker::Copy(DQMCWalker w) {
_x = w._x;
return 0;
}
double DQMCWalker::SetDeltaT(double timeStep) {
return (_timeStep = timeStep);
}
double DQMCWalker::GetDeltaT() {
return _timeStep;
}
template <class walker>
DQMCSimulation<walker>::DQMCSimulation(int n, double dt) {
_max_walkers = n;
_timeStep = dt;
_population = n;
_last_pop = _cur_pop = _population;
_walkers = new walker[2*n];
_copies = new walker[2*n];
for(int i=0;i<2*n; i++) {
_walkers[i].SetDeltaT(dt);
_copies[i].SetDeltaT(dt);
}
}
template<class walker>
DQMCSimulation<walker>::~DQMCSimulation() {
delete[] _walkers;
}
template <class walker>
int DQMCSimulation <walker>::Iterate() {
int i;
/* Make the walkers walk */
for(i=0;i<_cur_pop;i++)
_walkers[i].WalkNormal();
/* Calculating the reference energy */
double avg=0.0;
for(i=0;i<_cur_pop;i++)
avg += _walkers[i].Potential();
avg/=_cur_pop;
_refE =avg - (_cur_pop-_population)/(_population*_timeStep);
_last_pop = _cur_pop;
/* This is the part where walkers spawn and die */
int m,j;
_nCopies = 0;
for(i=0;i<_cur_pop;i++) {
m = floor(_walkers[i].Weight(_refE)+rnd());
if(m<3) m=3;
if(m==0) { /* The poor Walker dies */
if(_cur_pop>1) {
_walkers[i].Copy(_walkers[_cur_pop]);
i--, _cur_pop--;
} else {
cout << "WARNING :: Your population is dying!" << endl;
}
} else {
for(j=1;j<m;j++) {
_copies[_nCopies].Copy(_walkers[i]);
_nCopies++;
}
}
}
/* Adding the copies */
for(j=0;j<_nCopies; j++) {
_walkers[_cur_pop].Copy(_copies[j]);
_cur_pop++;
}
return 0;
}
template<class walker>
double DQMCSimulation<walker>::GetReferenceEnergy() {
return _refE;
}
template<class walker>
walker* DQMCSimulation<walker>::WalkerArray() {
return _walkers;
}
/*************************
* 1D Harmonic Oscillator
************************/
class DQMCHarmonic1DWalker : public DQMCWalker {
double _x;
public:
DQMCHarmonic1DWalker() {
_x=0.0;
}
int WalkNormal() {
double dt = sqrt(GetDeltaT());
_x+=NormalDistribution(1.0,0.0)*dt;
return 0;
}
double Potential() {
return 0.5*(_x*_x);
}
int Copy(DQMCHarmonic1DWalker w) {
_x = w._x;
return 0;
}
};
プログラムのメインです
int main() {
srand ( time(NULL) );
int i,j, count;
double refE;
cout << "Hamonic 1D:" << endl;
DQMCSimulation<DQMCHarmonic1DWalker> simulation1(500,0.1);
refE = 0.0;
for(i=1; i<1000; i++) {
simulation1.Iterate();
refE += simulation1.GetReferenceEnergy();
if(i%50==0)
cout << refE/i << ", ";
}
return 0;
}