C++ 不可重复二维向量问题
我正在写一个小程序来计算一个物理问题,但是我在从2D数组中删除元素时遇到了问题。我正在使用XCode(so GDB)进行编译 问题总是出现在walker.erase(walker.begin()+loacationInArray)部分(在void diffuseWalkers函数中),并且总是在不同数量的函数调用之后出现。所以有时候,“热化”循环可能会运行50次,其他时候它会一直运行。我通常会遇到EXC\u BAD\u访问错误,偶尔也会出现malloc错误 任何帮助都会非常感激,因为我已经尝试了所有的方法,真的看不出我做错了什么。我已经把代码贴在下面了。名为“heliumHeader.h”的头文件包含一些数学函数,这些函数对我的问题并不重要C++ 不可重复二维向量问题,c++,C++,我正在写一个小程序来计算一个物理问题,但是我在从2D数组中删除元素时遇到了问题。我正在使用XCode(so GDB)进行编译 问题总是出现在walker.erase(walker.begin()+loacationInArray)部分(在void diffuseWalkers函数中),并且总是在不同数量的函数调用之后出现。所以有时候,“热化”循环可能会运行50次,其他时候它会一直运行。我通常会遇到EXC\u BAD\u访问错误,偶尔也会出现malloc错误 任何帮助都会非常感激,因为我已经尝试了
#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
#包括“heliumHeader.h”
无效复制矢量信息(矢量和沃克、矢量和沃克特姆);
真空漫射沃克(双β,双a,双阿尔法,int-locationInArray,vector&walker,双dt,
双重和三重能量、int和numberOfWalkers、int targetNumberOfWalkers);
使用名称空间std;
int main(){
srand(时间(空));
双s=0;//分子间距离
双β=0.15;
双α=2。;
双dt=0.1;
int numberOfWalkers=1;//粒子数
int targetNumberOfWalkers=numberOfWalkers;
//用于保存信息的二维向量
矢量步行者(步行者数,6);
//解决问题
双a=1。;
对于(int i=0;i<p>),我认为你的问题在于向量的大小是动态的。当你调用时,看起来你在一个循环中。擦除。如果你擦除中间的东西,继续循环穿过这些元素,我就不会感到随机化的奇怪。 你有:
if(int(s)<1){
//kill the walker
walker.erase(walker.begin()+locationInArray);
numberOfWalkers--;
}
if(int(s)我认为您正在从错误的向量中删除。在主函数中walker
是一个2D向量。在diffuseWalker
中,您正在从传递到函数的walker
中删除,该函数是一个双精度的1D向量。您使用位置inarray
和减量numberwalkers
here对于1D walker来说没有意义-看起来你想从2D向量中删除它。我建议2D和1D向量使用不同的名称,以避免像这样的混淆。是的-非常感谢。这是真的,我删除了数组的diagnoal元素,这是我通过一个小得多的玩具示例I发现的n另一个程序
我通过向函数传递完整的2D向量来解决这个问题,因此当我擦除walker(walker.begin()+locationInArray)
时,迭代器引用walker[I][j]
向量的第一个索引“I
”。之前,我只是将它作为1D向量传递(本质上是“j
”索引块),我正在删除一个不存在的位置,如果“locationInArray
>=6”为0
(int(s) < 1)
//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;
}