How to write a unit test - c++

everyone.
I'm new to unit testing and can't get the idea of it.
I have a module that have a process() function. Inside process() function module does a lot of non-trivial job. The task is to check module's output.
For example, there is a method calculateDistance() inside process() method that calculates distance value. Test requirement sounds like "check that module calculates distance..."
As I understand I have to:
Prepare input data
Call module's process() method
Calculate distance by hands
Get module's output value for distance
Compare this value to value calculated.
But it is easy for some trivial cases, for example some ariphmetical operations. But what if inside calculateDistance() there are lots of formulas. How should I calculate this distance's value? Should I just copy all source code from calculateDistance() function to the test's code to calculate this value from step 3?
Here is the source code example:
void process(PropertyList& propList)
{
m_properties = &propList;
...
for (int i = 0; i < m_properties.propertiesCount; i++)
{
calculateDistance();
}
}
void calculateDistance(int indx)
{
Property& property = m_properties->properties[indx];
property.distance = 0;
for (int i = 0; i < property.objectsCount - 1; i++)
{
property.distance += getDistanceBetweenObjs(i, i + 1);
}
}
int getDistanceBetweenObjects(indx1, indx2)
{
// here is some complex algorithm of calculating the distance
}
So, my question is: should I prepare input data where I know the resulting distance value and just compare this value to the output value? Or should I get input data structures, calculate distance value the same way as calculateDistance() method does (here is code duplication) and compare this value to the output distance?

But what if inside calculateSmth() there are lots of formulas.
Refactor the code and break out those formulas to separate functions and test them individually.

Related

most efficient way to have a if statement in C++

I am trying to do some Monte Carlo simulation, and as it is with this kind of simulation, it requires a lot of iterations, even for the smallest system. Now I want to do some tweaks with my previous code but it increases the wall time or running time, by 10 fold, which makes a week of calculations to more than two months. I wonder whether I am doing the most efficient way to do the simulation.
Before that, I was using a set of fixed intervals to get the properties of the simulations, but now I want to record a set of random intervals to get the system information as it is the most logical thing to do. However I don't know how to do it.
The code that I was using was basically something like that:
for(long long int it=0; it<numIterations; ++it)
{
if((numIterations>=10) && (it%1000==0))
{
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile1000, it);
}
}
As you see, before the tweaks made it was going through the simulation and only record the data, every 1000th iterations.
Now I want to do something like this
for(long long int it=0; it<numIterations; ++it)
{
for(int j = 1; j <= n_graph_points; ++j){
for (int i = 0; i < n_data_per_graph_points; ++i){
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j])) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}
}
}
}
In this part, the initial position array is just an array with lots of random numbers. The two for loop inside of each other checks every iteration and if the iterations is equal to that random number, it starts recording. I know this is not the best method as it is checking lots of iterations that are not necessary. But, I don't know how can I improve my code. I am a little helpless at this point, so any comment would be appreciated
This does not answer the implied question
[What is the] most efficient way to have [an] if statement in C++ (all of them should be equivalent), but
Supposing varying intervals between exports were logical, how do I code that adequately?
Keep a sane Monte Carlo control, initialise a nextExport variable to a random value to your liking, and whenever it equals nextExport, export and increase nextExport by the next random interval.
if (it == initial_position_array[j][i] || it == (initial_position_array[j][i] + delta_time_arr[j]))
you can use references for both expressions.(please use meaningful names as per your convinience)
int& i_p_a = initial_position_array[j][i];
int& i_p_a_d = (initial_position_array[j][i] + delta_time_arr[j]);
now you final if statement will be readable and maintainable.
if (it == i_p_a || it == i_p_a_d) {
exportedStates = system.GetStates();
Export2D(exportedStates, outputStatesFile, it);
}

c++ cplex access current solution to add constraint

i am trying to solve a LP-model in CPLEX using C++ and Concert Technology.
I want to implement constraints (the subtour elimination constraints, to be more specific) that needs to query the value of two of my variables in the current solution:
The variable array xvar is indicating the edges, yvar is representing the nodes.
I implement these constraints by solving n (= number of nodes) Min-Cut-Problems on a modified graph, which is constructed by adding an artificial source and an artifical sink and connect these to every node of the original graph.
From what i've read so far, do i need a lazy constraint or a callback or none of this?
This is where i create the model and get it solved, access the values of the variables in the solution etc:
// Step 2: Construct the necessary CPLEX objects and the LP model
IloCplex solver(env);
std::cout<< "Original Graph g: " <<std::endl;
std::cout<< net.g() <<std::endl;
MCFModel model(env, net);
// Step 3: Load the model into cplex and solve
solver.extract(model);
solver.solve();
// Step 4: Extract the solution from the solver
if(solver.getStatus() != IloAlgorithm::Optimal) throw "Could not solve to optimality!";
IloNumArray xsol ( env, net.g().nEdges() );
IloNumArray ysol ( env, net.g().nNodes() );
IloNumArray rsol ( env, net.g().nGroups() );
IloNumArray wisol ( env, net.g().nGroups() );
IloNum ksol;
NumMatrix wsol ( env, net.g().nGroups());
for(IloInt i = 0; i < net.g().nGroups(); i++){
wsol[i] = IloNumArray( env, net.g().nGroups() );
}
solver.getValues(xsol, model.xvar());
solver.getValues(ysol, model.yvar());
solver.getValues(rsol, model.rvar());
solver.getValues(wisol, model.wivar());
ksol=solver.getValue(model.kvar());
for (IloInt i = 0; i < net.g().nGroups(); i++){
wsol[i] = wisol;
}
// Step 5: Print the solution.
The constraint, i need the current values of the variables xvar and yvar for, is created here:
//build subset constraint y(S) -x(E(S))>= y_i
void MCFModel::buildSubsetCons(){
IloExpr lhs(m_env);
IloCplex cplex(m_env);
IloNumArray xtemp ( m_env, m_net.g().nEdges() );
IloNumArray ytemp ( m_env, m_net.g().nNodes() );
std::vector<Edge> mg_twin;
std::vector<int> mg_weights;
int mg_s;
int mg_t;
SGraph mgraph;
std::vector<int> f;
int nOrigEdges = m_net.g().nEdges();
int nOrigNodes = m_net.g().nNodes();
cplex.getValues(xtemp, m_xvar);
cplex.getValues(ytemp, m_yvar);
mgraph = m_net.g().mod_graph();
mg_s = mgraph.nNodes()-1;
mg_t = mgraph.nNodes();
std::cout<<"modified graph:"<<std::endl;
std::cout<<mgraph<<std::endl;
// fill the weight of original edges with 1/2*x_e
foreach_edge(e, m_net.g()){
mg_weights.push_back((xtemp[e->idx()])/2);
}
// fill the weight of the edges from artificial source with zero
for(int i=0; i<m_net.g().nNodes(); i++){
mg_weights.push_back(0);
}
// fill the weight of the edges to artificial sink with f(i)
// first step: calculate f(i):
//f.resize(m_net.g().nNodes());
foreach_node(i, m_net.g()){
foreach_adj_edge(e, i, m_net.g()){
f[i] = f[i] + xtemp[e->idx()];
}
f[i] = (-1)*f[i]/2;
f[i] = f[i] + ytemp[i];
}
// second step: fill the weights vector with it
for(int i=0; i<m_net.g().nNodes(); i++){
mg_weights.push_back(f[i]);
}
// calculate the big M = abs(sum_(i in N) f(i))
int M;
foreach_node(i, m_net.g()){
M = M + abs(f[i]);
}
// Build the twin vector of the not artificial edges for mgraph
mg_twin.resize(2*nOrigEdges + 2*nOrigNodes);
for(int i=0; i < nOrigEdges ; ++i){
mg_twin[i] = mgraph.edges()[nOrigEdges + i];
mg_twin[nOrigEdges + i] = mgraph.edges()[i];
}
//Start the PreflowPush for every node in the original graph
foreach_node(v, m_net.g()){
// "contract" the edge between s and v
// this equals to higher the weights of the edge (s,v) to a big value M
// weight of the edge from v to s lies in mg_weights[edges of original graph + index of node v]
mg_weights[m_net.g().nEdges() + v] = M;
//Start PreflowPush for v
PreflowPush<int> pp(mgraph, mg_twin, mg_weights, mg_s, mg_t);
std::cout << "Flowvalue modified graph: " << pp.minCut() << std::endl;
}
}
The Object pp is to solve the Min-Cut-Problem on the modified graph mgraph with artificial source and sink. The original graph is in m_net.g().
When i compile and run it, i get the following error:
terminate called after throwing an instance of 'IloCplex::Exception'
Aborted
It seems to me, that it is not possible to access the values of xvar and yvar like this?
I do appreciate any help since i am quite lost how to do this.
Thank you very much!!
Two things...
I. I strongly suggest you to use a try-catch to better understand CPLEX Exceptions. You could perhaps understand the nature of the exception like this. As a matter of fact, I suggest you a try-catch-catch setting, sort of:
try {
//... YOUR CODE ...//
}
catch(IloException& e) {
cerr << "CPLEX found the following exception: " << e << endl;
e.end();
}
catch(...) {
cerr << "The following unknown exception was found: " << endl;
}
II. The only way to interact with CPLEX during the optimization process is via a Callback, and, in the case of Subtour Elimination Constraints (SECs) you will need to separate both integer and fractional SECs.
II.1 INTEGER: The first one is the easiest one, an O(n) routine would help you identify all the connected components of a node solution, then you could add the subsequent cuts to prevent this particular SEC from appearing in other nodes. You could either enforce your cuts locally, i.e. only on the current sub-tree, using the addLocal() function, or globally, i.e. on the entire Branch-and-Cut tree, using the add() function. In any case, ALWAYS remember to add .end() to terminate the cut container. Otherwise you WILL have serious memory leak issues, trust me with this, lol. This callback needs to be a done via a Lazy Constraint Callback (ILOLAZYCONSTRAINTCALLBACK)
II.2 FRACTIONAL: The second one is by far more complex. The easiest way to make it work is to use Professor Lysgaard's CVRPSEP library. It is nowadays most efficient way of computing capacity cuts, Multistar, generalized multistar, framed capacity, strengthened comb and hypotour cuts. Additionally, is rather easy to link with any existing code. The linkage also needs to be embedded on the solution process, hence, a callback is also required. In this case, it would be a User Cut Callback (ILOUSERCUTCALLBACK).
One is glad to be of service
Y

knights tour in c++ using recursion

I have created a class Board which deals with 2d vectors specifically for this purpose. I am trying to solve the Knight's Tour. I want to print out the thing when it is done. Using the recursive voyagingKnight() function I find that it does not do anything, does not print the result. It seems that I would want to increment the step number for the recursive call but this is not working.
The vector argument incs is a 2d vector of increments for moving the knight, in each row a row move in the first colum and a column move in the second column.
Does anyone have any suggestions as to a flaw in my reasoning here?
The relevant code
bool voyaging_knight( Board &board, int i, int j, int steps ,vector< vector<int> > &increments)
{
if( !newplace(theboard, i, j) ) return false;
board.setval(i,j,step);
if( gone_everywhere( board, steps) )
{
cout <<"DONE" << endl;
board.showgrid();
return true;
}
int n;
int in, jn;
for(n=0; n<8; n++ )
{
in = i + increments[n][0];
jn = j + increments[n][1];
if( inboard(board, i, j)&& newplace(board,i,j) )
{
voyaging_knight( board, in, jn, steps+1 ,increments);
return true;
}
}
theboard.setval(i,j,-1);
}
Yes, change this:
voyagingKnight( theboard, inext, jnext, step+1 ,incs);
return true;
To this:
return voyagingKnight( theboard, inext, jnext, step+1 ,incs);
In addition, it seems that you need to return something (probably false) at the end of the function.
BTW, I'm assuming that you have all the entries in theboard initialized to -1.
I'm guessing that you want 1 continuous path made by horse movements on a (chess)-board found by backtracking. In that case you have to pass the board by value, so each path you take has its own instance to fill. By passing by reference, every path fills the same board, so you can never take all the steps.
Also you should pass a result by value and fill it with the positions you visited and return that from the recursive function, so each path has its own instance of resulting positions and by returning it, you end up with the final result.
You should not pass inc because that is just a helper container that doesn't change.
Make the board a global variable, and build up a sequence of visited squares in a global variable too. Make sure that when retracting each tentative step you undo any changes (square visited, last step of sequence). Call your knight's tour function, make it return success if it reaches the end, and do any output after finishing.
Package the whole shebang in a file or as a class, so as to not expose private details to prying eyes.

C++ do while loop

I have a vector holding 10 items (all of the same class for simplicity call it 'a'). What I want to do is to check that 'A' isn't either a) hiding the walls or b) hiding another 'A'. I have a collisions function that does this.
The idea is simply to have this looping class go though and move 'A' to the next position, if that potion is causing a collision then it needs to give itself a new random position on the screen. Because the screen is small, there is a good chance that the element will be put onto of another one (or on top of the wall etc). The logic of the code works well in my head - but debugging the code the object just gets stuck in the loop, and stay in the same position. 'A' is supposed to move about the screen, but it stays still!
When I comment out the Do while loop, and move the 'MoveObject()' Function up the code works perfectly the 'A's are moving about the screen. It is just when I try and add the extra functionality to it is when it doesn't work.
void Board::Loop(void){
//Display the postion of that Element.
for (unsigned int i = 0; i <= 10; ++i){
do {
if (checkCollisions(i)==true){
moveObject(i);
}
else{
objects[i]->ResetPostion();
}
}
while (checkCollisions(i) == false);
objects[i]->SetPosition(objects[i]->getXDir(),objects[i]->getYDir());
}
}
The class below is the collision detection. This I will expand later.
bool Board::checkCollisions(int index){
char boundry = map[objects[index]->getXDir()][objects[index]->getYDir()];
//There has been no collisions - therefore don't change anything
if(boundry == SYMBOL_EMPTY){
return false;
}
else{
return true;
}
}
Any help would be much appreciated. I will buy you a virtual beer :-)
Thanks
Edit:
ResetPostion -> this will give the element A a random position on the screen
moveObject -> this will look at the direction of the object and adjust the x and Y cord's appropriately.
I guess you need: do { ...
... } while (checkCollisions(i));
Also, if you have 10 elements, then i = 0; i < 10; i++
And btw. don't write if (something == true), simply if (something) or if (!something)
for (unsigned int i = 0; i <= 10; ++i){
is wrong because that's a loop for eleven items, use
for (unsigned int i = 0; i < 10; ++i){
instead.
You don't define what 'doesn't work' means, so that's all the help I can give for now.
There seems to be a lot of confusion here over basic language structure and logic flow. Writing a few very simple test apps that exercise different language features will probably help you a lot. (So will a step-thru debugger, if you have one)
do/while() is a fairly advanced feature that some people spend whole careers never using, see: do...while vs while
I recommend getting a solid foundation with while and if/else before even using for. Your first look at do should be when you've just finished a while or for loop and realize you could save a mountain of duplicate initialization code if you just changed the order of execution a bit. (Personally I don't even use do for that any more, I just use an iterator with while(true)/break since it lets me pre and post code all within a single loop)
I think this simplifies what you're trying to accomplish:
void Board::Loop(void) {
//Display the postion of that Element.
for (unsigned int i = 0; i < 10; ++i) {
while(IsGoingToCollide(i)) //check is first, do while doesn't make sense
objects[i]->ResetPosition();
moveObject(i); //same as ->SetPosition(XDir, YDir)?
//either explain difference or remove one or the other
}
}
This function name seems ambiguous to me:
bool Board::checkCollisions(int index) {
I'd recommend changing it to:
// returns true if moving to next position (based on inertia) will
// cause overlap with any other object's or structure's current location
bool Board::IsGoingToCollide(int index) {
In contrast checkCollisions() could also mean:
// returns true if there is no overlap between this object's
// current location and any other object's or structure's current location
bool Board::DidntCollide(int index) {
Final note: Double check that ->ResetPosition() puts things inside the boundaries.

Logic Help: comparing values and taking the smallest distance, while removing it from the list of "available to compare"

Okay, I have been set with the task of comparing this list of Photons using one method (IU) and comparing it with another (TSP). I need to take the first IU photon and compare distances with all of the TSP photons, find the smallest distance, and "pair" them (i.e. set them both in arrays with the same index). Then, I need to take the next photon in the IU list, and compare it to all of the TSP photons, minus the one that was chosen already.
I know I need to use a Boolean array of sorts, with keeping a counter. I can't seem to logic it out entirely.
The code below is NOT standard C++ syntax, as it is written to interact with ROOT (CERN data analysis software).
If you have any questions with the syntax to better understand the code, please ask. I'll happily answer.
I have the arrays and variables declared already. The types that you see are called EEmcParticleCandidate and that's a type that reads from a tree of information, and I have a whole set of classes and headers that tell that how to behave.
Thanks.
Bool_t used[2];
if (num[0]==2 && num[1]==2) {
TIter photonIterIU(mPhotonArray[0]);
while(IU_photon=(EEmcParticleCandidate_t*)photonIterIU.Next()){
if (IU_photon->E > thresh2) {
distMin=1000.0;
index = 0;
IU_PhotonArray[index] = IU_photon;
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
if (TSP_photon->E > thresh2) {
Float_t Xpos_IU = IU_photon->position.fX;
Float_t Ypos_IU = IU_photon->position.fY;
Float_t Xpos_TSP = TSP_photon->position.fX;
Float_t Ypos_TSP = TSP_photon->position.fY;
distance_1 = find distance //formula didnt fit here //
if (distance_1 < distMin){
distMin = distance_1;;
for (Int_t i=0;i<2;i++){
used[i] = false;
} //for
used[index] = true;
TSP_PhotonArray[index] = TSP_photon;
index++;
} //if
} //if thresh
} // while TSP
} //if thresh
} // while IU
Thats all I have at the moment... work in progress, I realize all of the braces aren't closed. This is just a simple logic question.
This may take a few iterations.
As a particle physicist, you should understand the importance of breaking things down into their component parts. Let's start with iterating over all TSP photons. It looks as if the relevant code is here:
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
...
if(a certain condition is met)
TSP_PhotonArray[index] = TSP_photon;
}
So TSP_photon is a pointer, you will be copying it into the array TSP_PhotonArray (if the energy of the photon exceeds a fixed threshold), and you go to a lot of trouble keeping track of which pointers have already been so copied. There is a better way, but for now let's just consider the problem of finding the best match:
distMin=1000.0;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
TSP_PhotonArray[index] = TSP_photon; // <-- BAD
index++; // <-- VERY BAD
}
}
This is wrong. Suppose you find a TSP_photon with the smallest distance yet seen. You haven't yet checked all TSP photons, so this might not be the best, but you store the pointer anyway, and increment the index. Then if you find another match that's even better, you'll store that one too. Conceptually, it should be something like this:
distMin=1000.0;
best_photon_yet = NULL;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
best_pointer_yet = TSP_photon;
}
}
// We've now finished searching the whole list of TSP photons.
TSP_PhotonArray[index] = best_photon_yet;
index++;
Post a comment to this answer, telling me if this makes sense; if so, we can proceed, if not, I'll try to clarify.