ofstream doesn't write different data to two different files - c++

I'm having trouble using ofstream to write two different outputs to two different files at once. The program compiles and runs fine, and writes data to p1output.txt, but when I open p2output.txt, it is blank except for the first line with contents:
Time x1 x2 v1 v2 Energy Angular Momentum
If I delete the lines of code that write data to p1output.txt the program writes data correctly to p2output.txt. The only thing I can think of is that having two Leapfrog functions one after the other somehow prevents the second one from executing and printing out data. I don't know why this is or how to fix it - can anybody help?
Here is the code:
#include <iostream>
#include <cmath>
#include <fstream>
using namespace std;
#define D 2 // number of dimensions
struct particle
{
double x[D] ; // (x,y) coordinates
double v[D] ; // velocity
double F[D] ; // Force
double a[D] ; // acceleration
double GMm ; // gravitational parameter
double im ; // inverse mass
double PE ; // potential energy
double T ; // kinetic energy
double E ; // total energy
double J; // angular momentum
double r ; // distance from origin
};
void accel(particle &p_n) // acceleration of particle
{
for (int i=0; i<D; i++ )
{
p_n.a[i]=p_n.x[i]/(p_n.r*p_n.r*p_n.r) ;
}
}
void ForceEnergy(particle &p_n) //force and energy of particle
{
double R=0.0;
for(int i=0; i<D; i++)
{
R+=p_n.x[i]*p_n.x[i];
}
double r=sqrt(R);
p_n.PE=-p_n.GMm/r ; // PE of particle
p_n.r=r; // absolute distance of particle from origin
for(int i=0; i<D; i++)
{
p_n.F[i]=-p_n.GMm*p_n.x[i]/(p_n.r*p_n.r) ;
}
p_n.T=0.0;
for(int i=0; i<D; i++)
{
p_n.T+=0.5*p_n.v[i]*p_n.v[i]/p_n.im;
}
p_n.E=p_n.T+p_n.PE;
}
void VectorProduct(double x[],
double y[],
double z[],
int N) // finding the cross product of 2 vectors
{
double d[3], e[3];
for(int i=0; i<3; i++)
{
d[i]=0;
e[i]=0;
}
for(int i=0; i<N; i++)
{
d[i]=x[i];
e[i]=y[i];
}
z[0]=d[1]*e[2]-d[2]*e[1];
z[1]=d[2]*e[0]-d[0]*e[2];
z[2]=d[0]*e[1]-d[1]*e[0];
}
double VectorMag(double u[] ,
int n) // calculates magnitude of a vector
{
double vm=0;
for(int i=0; i<n; i++)
{
vm=vm+u[i]*u[i];
}
return sqrt(vm);
}
void AngMom(particle &p_n) // finding angular momentum about the origin
{
double z[3];
VectorProduct(p_n.x,
p_n.v,
z,
D);
p_n.J=VectorMag(z,3)/p_n.im;
}
void xchange(particle &p_n ,
double dt) // position increment
{
for(int i=0; i<D; i++)
{
p_n.x[i]+=dt*p_n.v[i] ;
}
}
void vchange(particle &p_n ,
double dt) // momentum increment
{
for(int i=0; i<D; i++)
{
p_n.v[i]+=dt*p_n.a[i] ;
}
}
void ParticleState(particle p_n ,
double t,
const char filename[]) // printing out the particle state
{
ofstream fxout;
fxout.open(filename,
ios::app);
if(fxout.good()==false)
{
cerr << "can't write to file " << filename << endl;
exit(0);
}
else
{
fxout << t << "\t" << p_n.x[0] << "\t" << p_n.x[1] << "\t"<< p_n.v[0] << "\t" << p_n.v[1] << "\t"<< p_n.E << "\t"<< p_n.J << endl;
fxout.close();
}
}
void Leapfrog(particle &p_n,
double dt,
double &t,
int N,
const char filename[])
{
while(t < N)
{
ParticleState(p_n,
t,
filename);
xchange(p_n,
dt*0.5); // position moved by a half-step
t+=0.5*dt;
accel(p_n); // computes acceleration at this position
vchange(p_n,
dt); // velocity moved by a full-step
xchange(p_n,
dt*0.5) ; // position moved by another half-step
t+=0.5*dt ;
}
}
int main()
{
particle p_1, p_2;
double dt=0.01; // time per step
double t=0.0; // start time
int N=1000; // number of time steps
p_1.im=0.02; p_2.im=0.5;
p_1.v[0]=0; p_2.v[0]=1;
p_1.v[1]=20; p_2.v[1]=20;
p_1.x[0]=4; p_2.x[0]=4;
p_1.x[1]=4; p_2.x[1]=4;
p_1.GMm=100;
p_2.GMm=100;
ForceEnergy(p_1);
accel(p_1);
AngMom(p_1);
ForceEnergy(p_2);
accel(p_2);
AngMom(p_2);
ofstream f1out;
f1out.open("p1output.txt");
f1out << "#Time" << "\t" << "x1" << "\t" << "x2" << "\t" << "v1" << "\t" << "v2" << "\t" << "Energy" << "\t" << "Angular Momentum" << endl;
f1out.close();
ofstream f2out;
f2out.open("p2output.txt");
f2out << "#Time" << "\t" << "x1" << "\t" << "x2" << "\t" << "v1" << "\t" <<"v2" << "\t" << "Energy" << "\t" << "Angular Momentum" << endl;
f2out.close();
Leapfrog(p_1,
dt,
t,
N,
"p1output.txt");
Leapfrog(p_2,
dt,
t,
N,
"p2output.txt");
return 0;
}

You taking "t" by reference.So when you write parameters for p2output.txt "t" is already greater than "N".So it not goes into while(t < N) loop.Try removing "&" from void Leapfrog(particle &p_n,
double dt,
double t,
int N,
const char filename[])

Related

Difference in accessing pixel by at and by data OpenCV

Today I observed one interesting thing: if I access image pixel using the function 'at' I received different result then if I access image pixel using image member 'data'.
Does anybody know why it happened?
int main()
{
double sigma = 1.0;
cv::Mat verticalGaussianKernel = getGaussianKernel(7, sigma);
printImg(verticalGaussianKernel);
return 0;
}
void printImg(cv::Mat &img)
{
cout << "---------//------\n";
if (img.empty())
{
cout << "Empty Image\n";
return;
}
for (int i = 0; i < img.size().height; i++)
{
for (int j = 0; j < img.size().width; j++)
{
cout << int(img.data[i * img.size().height + j]) << " " << img.at<double>(i, j) << endl;
}
cout << endl;
}
cout << "---------//------\n";
}
it code gives results:
data-------at
48------0.00443305
63------0.0540056
171-----0.242036
251-----0.39905
10------0.242036
12------0.0540056
84------0.00443305
Firstly I thought that values in data normalizing to 0-255, but the last string refute my guess
Your casting is wrong. The .data member is an uchar*, you're dereferencing it and casting that value (a single uchar) to int thats why you're not getting the correct values.
The proper way to do it would be to cast it to a double* and then dereferencing it. The following code does that.
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void printImg(cv::Mat &img) {
cout << "---------//------\n";
if (img.empty()) {
cout << "Empty Image\n";
return;
}
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
cout << reinterpret_cast<double *>(img.data)[i * img.cols + j]
<< " " << img.at<double>(i, j) << endl;
}
cout << endl;
}
cout << "---------//------\n";
}
int main() {
double sigma = 1.0;
cv::Mat verticalGaussianKernel = getGaussianKernel(7, sigma);
cout << verticalGaussianKernel << endl;
printImg(verticalGaussianKernel);
return 0;
}
Output:
[0.004433048175243745;
0.05400558262241448;
0.2420362293761143;
0.3990502796524549;
0.2420362293761143;
0.05400558262241448;
0.004433048175243745]
---------//------
0.00443305 0.00443305
0.0540056 0.0540056
0.242036 0.242036
0.39905 0.39905
0.242036 0.242036
0.0540056 0.0540056
0.00443305 0.00443305
You are reading the data as a char . Instead, read it as a double
int main()
{
double sigma = 1.0;
cv::Mat verticalGaussianKernel = getGaussianKernel(7, sigma);
printImg(verticalGaussianKernel);
return 0;
}
void printImg(cv::Mat &img)
{
cout << "---------//------\n";
if (img.empty())
{
cout << "Empty Image\n";
return;
}
for (int i = 0; i < img.size().height; i++)
{
for (int j = 0; j < img.size().width; j++)
{
cout << double(img.data[i * img.size().height*sizeof(double) + j*sizeof(double)]) << " " << img.at<double>(i, j) << endl;
}
cout << endl;
}
cout << "---------//------\n";
}

Output of neural network holds same values everytime

I am working on a very simple feed forward neural network to practice my programming skills. There are 3 classes :
Neural::Net ; builds the network, feeds forward input values (no backpropagation for the moment)
Neural::Neuron ; has characteristics of the neuron (index, output, weight etc)
Neural::Connection ; a structure-like class that randomizes the weights and hold the output, delta weight etc..
The program is very basic: I build the network with 2 hidden layers and randomized weights, then ask it to feed forward the same input values.
My problem is: It is expected that the program ends up with different output values after every run, yet the output are always the same. I tried placing markers everywhere to understand why it is calculating the same thing over and over again but I can't put my finger on the error.
Here is the code:
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <vector>
#include "ConsoleColor.hpp"
using namespace std;
namespace Neural {
class Neuron;
typedef vector<Neuron> Layer;
// ******************** Class: Connection ******************** //
class Connection {
public:
Connection();
void setOutput(const double& outputVal) { myOutputVal = outputVal; }
void setWeight(const double& weight) { myDeltaWeight = myWeight - weight; myWeight = weight; }
double getOutput(void) const { return myOutputVal; }
double getWeight(void) const { return myWeight; }
private:
static double randomizeWeight(void) { return rand() / double(RAND_MAX); }
double myOutputVal;
double myWeight;
double myDeltaWeight;
};
Connection::Connection() {
myOutputVal = 0;
myWeight = Connection::randomizeWeight();
myDeltaWeight = myWeight;
cout << "Weight: " << myWeight << endl;
}
// ******************** Class: Neuron ************************ //
class Neuron {
public:
Neuron();
void setIndex(const unsigned int& index) { myIndex = index; }
void setOutput(const double& output) { myConnection.setOutput(output); }
unsigned int getIndex(void) const { return myIndex; }
double getOutput(void) const { return myConnection.getOutput(); }
void feedForward(const Layer& prevLayer);
void printOutput(void) const;
private:
inline static double transfer(const double& weightedSum);
Connection myConnection;
unsigned int myIndex;
};
Neuron::Neuron() : myIndex(0), myConnection() { }
double Neuron::transfer(const double& weightedSum) { return 1 / double((1 + exp(-weightedSum))); }
void Neuron::printOutput(void) const { cout << "Neuron " << myIndex << ':' << myConnection.getOutput() << endl; }
void Neuron::feedForward(const Layer& prevLayer) {
// Weight sum of the previous layer's output values
double weightedSum = 0;
for (unsigned int i = 0; i < prevLayer.size(); ++i) {
weightedSum += prevLayer[i].getOutput()*myConnection.getWeight();
cout << "Neuron " << i << " from prevLayer has output: " << prevLayer[i].getOutput() << endl;
cout << "Weighted sum: " << weightedSum << endl;
}
// Transfer function
myConnection.setOutput(Neuron::transfer(weightedSum));
cout << "Transfer: " << myConnection.getOutput() << endl;
}
// ******************** Class: Net *************************** //
class Net {
public:
Net(const vector<unsigned int>& topology);
void setTarget(const vector<double>& targetVals);
void feedForward(const vector<double>& inputVals);
void backPropagate(void);
void printOutput(void) const;
private:
vector<Layer> myLayers;
vector<double> myTargetVals;
};
Net::Net(const vector<unsigned int>& topology) : myTargetVals() {
assert(topology.size() > 0);
for (unsigned int i = 0; i < topology.size(); ++i) { // Creating the layers
myLayers.push_back(Layer(((i + 1) == topology.size()) ? topology[i] : topology[i] + 1)); // +1 is for bias neuron
// Setting each neurons index inside layer
for (unsigned int j = 0; j < myLayers[i].size(); ++j) {
myLayers[i][j].setIndex(j);
}
// Console log
cout << red;
if (i == 0) {
cout << "Input layer (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else if (i < topology.size() - 1) {
cout << "Hidden layer " << i << " (" << myLayers[i].size() << " neurons including bias neuron) created." << endl;
myLayers[i].back().setOutput(1);
}
else { cout << "Output layer (" << myLayers[i].size() << " neurons) created." << endl; }
cout << white;
}
}
void Net::setTarget(const vector<double>& targetVals) { assert(targetVals.size() == myLayers.back().size()); myTargetVals = targetVals; }
void Net::feedForward(const vector<double>& inputVals) {
assert(myLayers[0].size() - 1 == inputVals.size());
for (unsigned int i = 0; i < inputVals.size(); ++i) { // Setting input vals to input layer
cout << yellow << "Setting input vals...";
myLayers[0][i].setOutput(inputVals[i]); // myLayers[0] is the input layer
cout << "myLayer[0][" << i << "].getOutput()==" << myLayers[0][i].getOutput() << white << endl;
}
for (unsigned int i = 1; i < myLayers.size() - 1; ++i) { // Updating hidden layers
for (unsigned int j = 0; j < myLayers[i].size() - 1; ++j) { // - 1 because bias neurons do not have input
cout << "myLayers[" << i << "].size()==" << myLayers[i].size() << endl;
cout << green << "Updating neuron " << j << " inside layer " << i << white << endl;
myLayers[i][j].feedForward(myLayers[i - 1]); // Updating the neurons output based on the neurons of the previous layer
}
}
for (unsigned int i = 0; i < myLayers.back().size(); ++i) { // Updating output layer
cout << green << "Updating output neuron " << i << ": " << white << endl;
const Layer& prevLayer = myLayers[myLayers.size() - 2];
myLayers.back()[i].feedForward(prevLayer); // Updating the neurons output based on the neurons of the previous layer
}
}
void Net::printOutput(void) const {
for (unsigned int i = 0; i < myLayers.back().size(); ++i) {
cout << blue; myLayers.back()[i].printOutput(); cout << white;
}
}
void Net::backPropagate(void) {
}
}
int main(int argc, char* argv[]) {
vector<unsigned int> myTopology;
myTopology.push_back(3);
myTopology.push_back(4);
myTopology.push_back(2);
myTopology.push_back(2);
cout << myTopology.size() << endl << endl; // myTopology == {3, 4, 2 ,1}
vector<double> myTargetVals= {0.5,1};
vector<double> myInputVals= {1, 0.5, 1};
Neural::Net myNet(myTopology);
myNet.feedForward(myInputVals);
myNet.printOutput();
return 0;
}
Edit: I figured that the bias neuron in the input layer was correctly set to output 1 while the ones in the hidden layers are set to 0 and I fixed that. But the outputs are still the same every run. I did the math on a sheet of paper and it works out. Here is the output (Color coded for clarity) :
I have expected the values to be random just like the weights. Shouldn't that be the case ? I am confused.
I found my mistake. I thought that rand() initialized its seed automatically. I knew it was a dumb thing. I added srand(time(NULL)); at the beginning of the program and now it works as it should.

Unresolved External Symbol with a particular function in c++

I got the error message like the following:
Unresolved External Symbol error with calculatewinner Candidate
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;
void headerforelection();
void getNamecalculatetotal(ifstream& in, string candidates[], double Votes[], double percentvotes[]);
void getNamecalculatetotal2(ifstream& in, string fname[], double Votes[], double percentvotes[]);
void allvotes(double []);
void Votesrecievedpercentage(ifstream& in, char Candidate[], double Votes[], string fname[], double percentvotes[]);
void Votesrecievedpercentage2(double Votes[], string fname[], double percentvotes[]);
void calculatewinner(string fname[], double Votes[]);
void headerforelection();
int main()
{
ifstream in = ifstream();
in.open("Votes.txt");
ofstream out = ofstream();
out.open("outputs.txt");
char winner();
char Candidate();
string fname[5];
double Votes[5];
double percentvotes[5];
double total = double();
headerforelection();
while (!in.eof())
{
getNamecalculatetotal(in, fname, Votes, percentvotes);
Votesrecievedpercentage2(Votes, fname, percentvotes);
}
allvotes(Votes);
calculatewinner(fname, Votes);
}
void getNamecalculatetotal(ifstream& in, string fname[], double Votes[], double percent[])
{
double total = double();
for (int i = 0; i < 5; i++)
{
in >> fname[i] >> Votes[i];
total = total + Votes[i];
}
for (int j = 0; j < 5; j++)
{
percent[j] = (Votes[j] / total) * 100;
}
}
void headerforelection()
{
std::cout << fixed << setfill(' ') << left << setw(10) << "Candidate"
<< right << setw(20) << setprecision(0) << "votes Recieved"
<< right << setw(20) << setprecision(2) << "% of Total Votes" << std::endl;
std::cout << endl;
}
void Votesrecievedpercentage2( double Votes[], string fname[], double percentvotes[])
{
for (int b = 0; b < 5; b++)
{
std::cout << fixed << setfill(' ') << left << setw(10) << fname[b]
<< right << setw(16) << setprecision(0) << Votes[b]
<< right << setw(16) << setprecision(2) << percentvotes << std::endl;
}
}
void allvotes(double Votes[])
{
double total = double();
for (int i = 0; i < 5; i++)
{
total = total + Votes[i];
}
std::cout << setfill(' ') << left << setw(22) << "Total" << setprecision(0) << total << std::endl;
}
void calculatewinner(string fname[], double Votes[])
{
{
int winner = 0;
for (int l = 0; l, 5; l++)
{
if (Votes[l] > Votes[winner])
{
winner = l;//3
}
}
}
char winner();
char Candidate();
std::cout << std::endl;
std::cout << Candidate << "Is The Winner" << fname << "." << std::endl;
}
First to answer your question, change these lines
char winner();
char Candidate();
everywhere in your code (in main as well as in calculatewinner) to the following:
char winner;
char Candidate;
By adding the paranthesis you are actually declaring a prototype to a function. Since you never define a function Candidate(void) the linker complains about the missing implementation. This would apply to char winner() also, but since you never use this "variable", the linker isn't concerned about this one.
Otherwise, your code is very broken. I am sure you are just learning C++, but your code is quite inconsistent in naming conventions as well as some other errors that should be addressed before doing something else.

Implementing Dijkstra's algorithm with vector of pointers

I'm working on a program involving Dijkstra's algorithm.
After searching long and far, I have only found help pertaining to Dijkstra's algorithm using Queues or Heaps, however, I am not using these. I have been tasked to used a vector of pointers to Vertex objects (a custom class I have defined).
I have attempted to convert the Queue pseudo code (from my textbook) to the best of my ability below:
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
However, when I attempt to compile, I keep receiving the following errors:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
I am trying to reduce the amount of Code in this post, but if need to be, my entire code is below:
Main.cpp:
#include "Vertex.h"
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;
void shortestPath(vector<Vertex> & v);
template <typename Comparable>
void insertionSort(vector<Comparable> & a);
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right );
///overload the less than operator in order to use the stl sort for vector
///print out the path for each vertex
int main()
{
/////READ ALL THE STUFF INTO THE GRAPH////
ifstream file;
file.open("graph.txt");
cout << "Opening file..." << endl;
if(!file)
{
cout << "System failed to open file.";
}
else
{
cout << "File successfully opened" << endl;
}
int numVertices;
int numEdges;
int num;
int adjacentVertex;
int weight;
file >> numVertices;
cout << "The number of vertices that are being read into the graph from the file: " << numVertices;
cout << endl;
vector<Vertex*> vertices;
//vector<Vertex> vertices(numVertices + 1);
Vertex * newVertex;
vertices.push_back(NULL);
cout << "SIZE: " << vertices.size() << endl;
cout << "NUM VERTICES: " << numVertices << endl;
for(int i=1;i < numVertices + 1; i++)
{
file >> numEdges;
cout << "At vertex " << i << " the number of edges is " << numEdges << endl;
newVertex = new Vertex();
//Using the i counter variable in the outer for loop to identify
//the what vertex what are currently looking at in order to read in the correct adjacent vertex and weight
cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
newVertex->setVertexNum(i);
//newVertex.setVertexNum(i);
for(int j=1;j<=numEdges;j++)
{
file >> adjacentVertex;
cout << "The adjacent vertex is: " << adjacentVertex << endl;
file >> weight;
cout << "The weight is: " << weight << endl;
cout << endl;
newVertex->setAdjacentVertex(adjacentVertex, weight);
}
//cout << "LENGTH OF VERTICES[i]: " << vertices.size() << endl;
vertices.push_back(newVertex);
}
file.close();
vector<Vertex*> sortedVertices = vertices;
insertionSort(sortedVertices);
cout << "SIZE: " << vertices.size() << endl;
for(int i=0;i<vertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << vertices[i]->getDV();
cout << endl;
cout << "Known Value: " << vertices[i]->getKnown();
cout << endl;
}
}
cout << "Sorted: " << endl;
for(int i=0;i<sortedVertices.size();i++)
{
cout << "V" << i << ": ";
cout << endl;
if(vertices[i] != NULL)
{
cout << "DV Value: " << sortedVertices[i]->getDV();
cout << endl;
cout << "Known Value: " << sortedVertices[i]->getKnown();
cout << endl;
}
}
//CALL THE SHORTEST PATH FUNCTION ON THE GRAPH/////
}
/*
const bool myFunction(const Vertex & x, const Vertex & y)
{
return (x.getDV() >= y.getDV());
}
*/
bool operator < (const Vertex & v1, const Vertex & v2)
{
return v1.getDV() > v2.getDV();
}
void Dijkstra(vector<Vertex*> & V, int startNum)
{
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0);
insertionSort(sortedVertices);
while(sortedVertices.size() != 0)
{
sortedVertices[sortedVertices.size() - 1]->setKnown(true);
sortedVertices.pop_back();
insertionSort(sortedVertices);
Vertex * v = V[1]; // Will always bring the first element off the list
v->setKnown(true);
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++)
{
int dist = getAdjacentVertices()[m].getWeight();
if((sortedVertices[1].getDV() + dist) < sortedVertices[m+1]->getAdjacentVertices()[m].getDV())
{
//WE WILL DECREASE THE VALUE HERE by finding the distance between two vertices
cout << "It works so far" << endl;
// BOOK has this, somehow need to change it: w.path = v
}
}
}
}
////////INSERTION SORT////////////
template <typename Comparable>
void insertionSort( vector<Comparable> & a )
{
for( int p = 1; p < a.size( ); ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > 0 && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
template <typename Comparable>
void insertionSort( vector<Comparable> & a, int left, int right )
{
for( int p = left + 1; p <= right; ++p )
{
Comparable tmp = std::move( a[ p ] );
int j;
for( j = p; j > left && tmp < a[ j - 1 ]; --j )
a[ j ] = std::move( a[ j - 1 ] );
a[ j ] = std::move( tmp );
}
}
Vertex.h:
#include "Edge.h"
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
class Vertex
{
private:
int vertexNum; //number of the vertex for identification purposes
int degree;
bool known;
vector<Edge> adjacentVertices; //vector of vertices that are adjacent to the vertex we are currently looking at
int dv; //distance
int pv; //previous vertex
Vertex *vertex;
public:
Vertex()
{
dv = INT_MAX;
known = false;
}
void setKnown(bool Known)
{
known = Known;
}
bool getKnown()
{
return known;
}
void setVertexNum(int VertexNum)
{
vertexNum = VertexNum;
}
void setDegree(int Degree)
{
degree = Degree;
}
vector<Edge> & getAdjacentVertices()
{
return adjacentVertices;
}
int getVertexNum()
{
return vertexNum;
}
int getDegree()
{
return degree;
}
int getDV() const
{
return dv;
}
int setDV(int Dv)
{
dv = Dv;
}
void setAdjacentVertex(int AdjacentVertex, int Weight)
{
Edge newEdge;
newEdge.setWeight(Weight);
newEdge.setAdjVertex(AdjacentVertex);
adjacentVertices.push_back(newEdge);
}
friend ostream & operator <<(ostream & outstream, Vertex *vertex)
{
outstream << vertex->getVertexNum() << endl;
outstream << vertex->getDegree() << endl;
outstream << vertex->getKnown() << endl;
vector<Edge> E = vertex->getAdjacentVertices();
for(int x=0;x<E.size();x++)
{
outstream << E[x].getAdjVertex() << endl;
outstream << E[x].getWeight() << endl;
}
return outstream;
}
friend bool operator < (const Vertex & v1, const Vertex & v2);
};
Edge.h:
#include <cstdlib>
class Edge
{
private:
int adjVertex; //represents the vertex that the edge leads to
int weight;
public:
Edge()
{
adjVertex = 0;
weight = 0;
}
void setWeight(int Weight)
{
weight = Weight;
}
void setAdjVertex(int adjacent)
{
adjVertex = adjacent;
}
int getAdjVertex()
{
return adjVertex;
}
int getWeight()
{
return weight;
}
};
From g++ to English:
Main.cpp: In function 'void Dijkstra(std::vector<Vertex*>&, int)':
Main.cpp:154:42: error: base operand of '->' has non-pointer type 'std::vector<Vertex*>'
Main.cpp:156:44: error: 'getAdjacentVertices' was not declared in this scope
Main.cpp:157:35: error: request for member 'getDV' in 'sortedVertices.std::vector<_Tp, _Alloc>::operator[]<Vertex*, std::allocator<Vertex*> >(1ul)', which is of pointer type '__gnu_cxx::__alloc_traits<std::allocator<Vertex*> >::value_type {aka Vertex*}' (maybe you meant to use '->' ?)
Main.cpp:157:99: error: '__gnu_cxx::__alloc_traits<std::allocator<Edge> >::value_type' has no member named 'getDV'
Explanation:
for(int m = 0; m < sortedVertices->getAdjacentVertices().size(); m++) <- this is 154. sortedVertices is not a pointer. It is a std::vector of some pointers.
int dist = getAdjacentVertices()[m].getWeight(); <- 156. What is getAdjacentVertices?
sortedVertices[1].getDV() <- 157 sortedVertices[1] is a pointer. Look at operator[]
sortedVertices[m+1]->getAdjacentVertices() is a vector of Edge. Edge does not have a getDV() method defined.
Is this really your code?
As an author you should not have trouble understanding the error messages. Those are simple mistakes, that took 5 minutes for a stranger to understand. You need to put more effort in understanding what you write, and what compiler tells you. Or get some sleep to get some focus.
I would also suggest to spend some time working out what std::vector really is and how to understand std::vector<Vertex*> vector_of_vertices; object.
vector<Vertex*> sortedVertices = V;
sortedVertices[startNum]->setDV(0)
Here you create variable of type vector<Vertex*> on the stack. This is not a pointer. This is a container containing pointers of type Vertex* and that's completely different. You use -> operator which is only used on pointers.

EXC_BAD_ACCESS at main method declaration

I'm trying to get some old C++ code up and running. I've gotten it to compile without error, but it immediately segfaults when I run, without entering main. When I use gdb to find out where things are going wrong, I find the following:
(gdb) run
Starting program: /Users/dreens/Documents/OH/extrabuncher2/ParaOHSB
Reading symbols for shared libraries +++. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00007fff5636581c
0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
13 int main(int argc, char *argv[]){
(gdb) backtrace
#0 0x000000010000151e in main (argc=1, argv=0x100000ad0) at ParaMainOHSlowerBuncher.cc:13
(gdb)
Does anyone know what could cause a memory access issue right at the start of the main method?
The code is rather large, but here is the file containing the main method. Could the included .hh and .cc files be a part of the problem? Should I attach them?
Thanks!
David
#include <iostream>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "MoleculeEnsemble.hh"
#include "SlowerForceLoadOH32.cc"
#include "SlowerForceLoadOH12.cc"
//#include "SlowerForceLoad3mmBuncher.cc"
#include "SlowerForceLoad4mmBuncher.cc"
using namespace std;
int main(int argc, char *argv[]){
//int main(){
cout << "Ahhhh!" << endl;
/******Parallel Crap********/
/*
int totalnodes = 0;
int mynode = 0;
MPI_Status status;
MPI_Init(&argv,&argc);
MPI_Comm_size(MPI_COMM_WORLD,&totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD,&mynode);
srand(time(NULL)*mynode);
*/
/******Distribution Parameters *******/
long MoleculeNumber = long(5e4);
double Xcenter = 0;
double Ycenter = 0;
double Zcenter = 0;
double DeltaX = 0.0015;
double DeltaY = 0.0015;
double DeltaZ = 0.01;
int FlatX = 1;
int FlatY = 1;
int FlatZ = 1;
double vXcenter = 0;
double vYcenter = 0;
double vZcenter = 406;
double Vcalc = 406;
double vZfinal = 0;
double DeltavX = 2;
double DeltavY = DeltavX;
double DeltavZ = 40;
int FlatvX = 0;
int FlatvY = 0;
int FlatvZ = 0;
int TimeArrayOnly = 0; //Outputs only Time Array
double TimeOffset = 0; //Adds valve-skimmer flight time to ToF array
/*******Overtone Parameters********/
int S = 1; //parameter S=Vz/Vswitch as defined by VDM et al.
int JILAOT = 0; //JILAOT is either 0 or 1, denoting whether or not to use special switching
/*******Hexapole Parameters********/
double VSD = 0.06;
double Voltage = 2000;
double HexRadius = .00268;
double HexStart = .0238;
double HexEnd = .083170;//0.089103;
double HexOn = 1e-6;
double HexOff = 203e-6;//224e-6; 212 for current data; Good = 243e-6 for 408m/s
double DeltaT = 1e-6;
double DeltaTSeqGen = 1e-9; //Need to use smaller time steps for finding the time sequence
double DetectionTime = HexOff; //Use to fake out hex code
double TriggerLatency = 0;//170e-9;
/*******Detection Parameters*******/
double DetectionPosition = double(0.9319);//0.257480; <- for viewing at 31.5 ||||| 0.9428; <-Mag trap(4stages), .9319 <-MagTrap(3Stages)
double IrisWidth = 0.008;//31.5 0.0023 //PostSlower.015;
double LaserRadius = .001;
/*****Bunching Paramaters******/
int BunchNumber = 0;
int NumberUsed = 0;
/*****Timing Variables*********/
time_t start, finish;
time( &start);
/*****Molecule Parameters******/
double mass =double(17*1.672e-27);
/******ToF Detection Arrays and Slowing Parameters *********/
double Phi = double(34.2);
double PhiEB = double(0);
int NumberOfStages = int(142/S); //Use 142 for Big machine
int EBStages = 3; //Larger Add-on stages at end of slower
double BuncherScale = 1;
double Time[int(1e7)];
int ToFSignal32[int(1e7)];
int ToFSignal12[int(1e7)];
double TimeArray[800];
double VExit[800];
double Average32[7];
double Average12[7];
int LOST[200];
/*************Finished ToF Detection Arrays and Slowing Parameters ********/
/******Force Arrays********/
int Xnumber = 111;
int Ynumber = 21;
int Znumber = 21;
int FLength = Xnumber*Ynumber*Znumber;
double AXxDT[FLength];
double AYxDT[FLength];
double AZxDT[FLength];
double AZxDTSeqGen[FLength];
SlowerForceLoadOH32(AZxDT, AYxDT, AXxDT); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
double DTovermass = DeltaT/mass;
for(int j = 0; j <FLength; j++){
AXxDT[j] = DTovermass*AXxDT[j];
AYxDT[j] = DTovermass*AYxDT[j];
AZxDT[j] = DTovermass*AZxDT[j];
AZxDTSeqGen[j] = DeltaTSeqGen*AZxDT[j]/DeltaT;
}
double AXxDT12[FLength];
double AYxDT12[FLength];
double AZxDT12[FLength];
SlowerForceLoadOH12(AZxDT12, AYxDT12, AXxDT12); //Note how Z and X are placed in this function. My matlab code calls the longitudnal dimension X, here it is Z
for(int j = 0; j <FLength; j++){
AXxDT12[j] = DTovermass*AXxDT12[j];
AYxDT12[j] = DTovermass*AYxDT12[j];
AZxDT12[j] = DTovermass*AZxDT12[j];
}
/********Load Extra Buncher Forces*********/
int XnumberEB = 251;
int YnumberEB = 41;
int ZnumberEB = 41;
int FLengthEB = XnumberEB*YnumberEB*ZnumberEB;
double AXxDTEB[FLengthEB], AYxDTEB[FLengthEB], AZxDTEB[FLengthEB], AZxDTSeqGenEB[FLengthEB];
SlowerForceLoad4mmBuncher(AZxDTEB, AYxDTEB, AXxDTEB);
for(int j = 0; j <FLengthEB; j++)
{
AXxDTEB[j] = DTovermass*AXxDTEB[j]/BuncherScale;
AYxDTEB[j] = DTovermass*AYxDTEB[j]/BuncherScale;
AZxDTEB[j] = DTovermass*AZxDTEB[j]/BuncherScale;
AZxDTSeqGenEB[j] = DeltaTSeqGen*AZxDTEB[j]/(DeltaT*BuncherScale);
}
/********* End All initiliazation ***************************/
/************Beginning Calculation *************************/
//Create Molecule Ensemble
MoleculeEnsemble Alice(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//MoleculeEnsemble Bob(MoleculeNumber,Xcenter,Ycenter,Zcenter,DeltaX,DeltaY,DeltaZ,FlatX,FlatY,FlatZ,vXcenter,vYcenter,vZcenter,DeltavX,DeltavY,DeltavZ,FlatvX,FlatvY,FlatvZ);
//Generate the Timing Sequence
Alice.TimeArrayGeneratorWithBuncher(Vcalc,Phi,PhiEB,TimeArray,VExit,AZxDTSeqGen,AZxDTSeqGenEB,HexOff,DeltaTSeqGen,BunchNumber,vZfinal,NumberUsed,NumberOfStages,S,EBStages);
/*if(mynode == 0){
cout << "Slowing utilized " << NumberUsed << " stages, yielding a final velocity of " << VExit[NumberUsed] << " m/s." << endl;
cout << endl;
for(int kk = 0; kk < NumberOfStages; kk++){cout << kk << " , " << TimeArray[kk] << " , " << VExit[kk] << endl;}
}*/
/*Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
if(TimeArrayOnly!=1)
{
//Fly the Ensemble through the hexapole
Alice.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(3/2), DetectionTime);
//Bob.HexapoleFlightOH(Voltage, HexRadius, HexStart, HexEnd, HexOn, HexOff, DeltaT, double(1/2), DetectionTime);
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl << endl;
*/
//Fly the Ensemble through the slower
Alice.SlowerFlight(LOST, Time, ToFSignal32, Phi, TimeArray, DeltaT, AXxDT, AYxDT, AZxDT, AXxDTEB, AYxDTEB, AZxDTEB, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages,S, TriggerLatency);
//Bob.SlowerFlight(LOST, Time, ToFSignal12, Phi, TimeArray, DeltaT, AXxDT12, AYxDT12, AZxDT12, Xnumber, Ynumber, Znumber, DetectionPosition, IrisWidth, LaserRadius, NumberOfStages, EBStages, S, TriggerLatency);
}
/**********Ending Calculation **********************/
//Alice.MoleculeEnsemble_Drawer();
/*
Alice.MoleculeEnsemble_Averager(Average32);
Bob.MoleculeEnsemble_Averager(Average12);
cout << "Processor: " << mynode << "\t" << sqrt(pow(Average32[3],2)+pow(Average32[4],2)) << ", " << sqrt(pow(Average12[3],2)+pow(Average12[4],2));
cout << " Mean = " << Average32[6] << ", " << Average12[6] << endl << endl;
*/
//Output ToF signal
if(TimeArrayOnly!=1)
{
for(int ii = 0; ii < int(1e7); ii++)
{
if(ToFSignal32[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal32[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal32[ii] << endl;
}
if(ToFSignal12[ii] > 0 && Time[ii] > 3e-3)
{
cout << Time[ii]+TimeOffset << "," << ToFSignal12[ii] << endl;
//+double(VSD/vZcenter)+38e-6 << "," << ToFSignal12[ii] << endl;
}
}
}
if(TimeArrayOnly==1)
{
for(int ii = 0; ii < NumberOfStages+EBStages+1; ii++)
{
cout << ii << "\t" << TimeArray[ii] << "\t" << VExit[ii] << endl;
//+double(VSD/vZcenter)+double(265e-6) << "\t" << VExit[ii] << endl;
}
}
/*for(int ii = 0; ii < NumberOfStages; ii++)
{
cout << ii << "\t" << LOST[ii] << endl;
}
*/
/*
MPI_Finalize();
*/
}
You're out of stack space.
You declare very large arrays in your code (over 10 million elements), which are all allocated on the stack. Instead of declaring the arrays statically, use dynamic memory allocation. So, instead of
double Time[int(1e7)];
write
double* Time;
Time = new double[int(1e7)];
and hope to have enough RAM in your computer :)