我正在寫一個小程序來計算物理問題,但是我有從二維數組中刪除元素的問題。我正在編譯XCode(所以GDB)。不可重複的2D矢量問題
問題總是出現在walker.erase(walker.begin()+ loacationInArray)部分(在void diffuseWalkers函數中),並且總是在不同數量的函數調用之後出現。所以有時候,'熱化'循環可能會運行50次,有時會一直運行。我通常會得到一個EXC_BAD_ACCESS錯誤,偶爾會出現malloc錯誤。
任何幫助將不勝感激,因爲我已經嘗試了一切,真的不明白我做錯了什麼。我已經發布了下面的代碼。名爲'heliumHeader.h'的頭文件包含一些對我的問題並不重要的數學函數。
#include "heliumHeader.h"
void copyVectorInformation(vector<double>& walker, vector<double>& walkerTemp);
void diffuseWalker(double beta, double a, double alpha, int locationInArray, vector<double>& walker, double dt,
double& trialEnergy, int& numberOfWalkers, int targetNumberOfWalkers);
using namespace std;
int main(){
srand(time(NULL));
double s=0.; //inter-molecular distance
double beta = 0.15;
double alpha = 2.;
double dt=0.1;
int numberOfWalkers = 1; //number of particles
int targetNumberOfWalkers = numberOfWalkers;
//2D-vectors to hold information
vector<vector<double> > walker(numberOfWalkers,6);
//solve for a
double a = 1.;
for(int i=0; i<20;i++)
a = 1./(1.+exp(-s/a));
//set up sums
double localEnergy, trialEnergy, localEnergy2, trialEnergy2;
localEnergy = trialEnergy = localEnergy2 = trialEnergy2 = 0.;
//put the walkers randomly in space & get the energy of that configuration
for(int i=0; i<walker.size(); i++){
for(int j=0; j<6; j++)
walker[i][j]=randomPositiveNegative();
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);
}
localEnergy /= numberOfWalkers;
double beforeEnergy = localEnergy;
cout << "local energy of random " << localEnergy << endl;
trialEnergy = -2.903;
//move the walkers
for(int thermalisationCounter = 1; thermalisationCounter<1000; thermalisationCounter++){
for(int i=0; i<walker.size(); i++)
diffuseWalker(beta, a, alpha, i, walker[i], dt, trialEnergy, numberOfWalkers, targetNumberOfWalkers);
cout << thermalisationCounter << endl;
}
//recalculate the local energy
for(int i=0; i<walker.size(); i++){
for(int j=0; j<6; j++)
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);
}
localEnergy /= numberOfWalkers;
for(int numberOfSteps = 1; numberOfSteps<1000; numberOfSteps++){
for(int i=0; i<walker.size(); i++)
diffuseWalker(beta, a, alpha, i, walker[i], dt, trialEnergy, numberOfWalkers, targetNumberOfWalkers);
cout << numberOfSteps << endl;
}
//get initial energy of random positiions
for(int i=0; i<walker.size(); i++)
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);
localEnergy /= numberOfWalkers;
cout << "before energy " << beforeEnergy << " local energy " << localEnergy <<
" trial energy " << trialEnergy << " number " << numberOfWalkers << endl;
return 0;
}
void copyVectorInformation(vector<double>& walker, vector<double>& walkerTemp){
for(int i=0; i<6; i++)
walkerTemp[i] = walker[i];
}//end of copyVectorInformation
void diffuseWalker(double beta, double a, double alpha, int locationInArray, vector<double>& walker, double dt,
double& trialEnergy, int& numberOfWalkers, int targetNumberOfWalkers){
vector<double> driftFunction(6);
vector<double> walkerTemp(6); //temporary store of information
//copy the walker information over
copyVectorInformation(walker, walkerTemp);
//get the drift functions
calculateDriftFunctions(beta, alpha, a, walker, driftFunction);
//get the old local energy
double preMoveLocalEnergy = calculateEnergy(beta, alpha, a, walker);
//move the walker
for(int j=0; j<6;j++)
walker[j] += 0.5*dt*driftFunction[j] + randomGauss()*sqrt(dt);
//caclulate the local energy of the new position
double postMoveLocalEnergy = calculateEnergy(beta, alpha, a, walker);
//calculate the weight, q and branching ration s
double q = exp(-dt*(0.5*(postMoveLocalEnergy + preMoveLocalEnergy) - trialEnergy));
double s = q+randomPositive();
if(int(s)<1){
//kill the walker
walker.erase(walker.begin()+locationInArray);
numberOfWalkers--;
}
else{
//reproduce walker int(s) number of times
for(int k=0; k<int(s); k++){
walker.push_back(walker[locationInArray]);
numberOfWalkers++;
}
}
//update the trial energy
trialEnergy += 0.2*log((double)targetNumberOfWalkers/(double)numberOfWalkers);
}//end of diffuse walkers