5

I have a small function, which is supposed to make a prediction based on a machine learning algorithm. The function wasn't working, so I put a print statement in to check on the value, and all of a sudden it started working. When I comment out the print line, it stops working again. Is there something I'm missing about why this would happen?

int makePrediction( const InstanceT & instance, bool biased ){
  double dotProduct = ( biased ? instance * _weights + _bias : instance * _weights ); 
  std::cout << "dotProduct = " << dotProduct << std::endl;
  return ( dotProduct > 0 ? 1 : -1 );
}

for some reason produces a different result then

int makePrediction( const InstanceT & instance, bool biased ){
  double dotProduct = ( biased ? instance * _weights + _bias : instance * _weights ); 
  return ( dotProduct > 0 ? 1 : -1 );
}

and to show that the results are different given the same inputs, I call this function with:

std::vector<InstanceT> _instances = populate_data() //this works for both versions
for ( int i = 0; i < _instances.size(); i++ ){
  std::cout << "prediction: " << makePrediction( _instances[i], true ) << std::endl;
}

Any thoughts?

Max
  • 99
  • 1
  • 7
  • Good question for codereview.stackexchange.com – P.T. Sep 26 '11 at 08:23
  • 2
    What do you mean by "wasn't working"? What was the expected and observed behaviour? Please specify the exact input and output. – Péter Török Sep 26 '11 at 08:26
  • std::endl usually flushes as well. Is your calling code producing output that depends on the state of cout's buffer? Seems unlikely. How different actually is the output; what is a correct rvalue of `makePrediction` and what does it give when it's wrong? – Nicholas Wilson Sep 26 '11 at 08:26
  • 8
    post complete (but minimal) code that exhibits the problem. post the results. explain what you expected instead. see this **[FAQ item](http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8)** about how to post. it was not made for SO but it applies here also. – Cheers and hth. - Alf Sep 26 '11 at 08:26
  • @P.T.: No, it's not. Code Review is for reviews of working code, not for "Why does this code produce unexpected/undefined behavior?" kind of questions. – sepp2k Sep 26 '11 at 08:27
  • 2
    Is your app multithreaded ? I/O can sometimes "resolve" concurrency problems because it introduces delays (maybe because of a mutex to write to the console, etc.). Of course, problems are just hidden, not resolved at all. –  Sep 26 '11 at 08:27
  • 2
    "Doesn't work" is not a good problem description. – n. m. could be an AI Sep 26 '11 at 08:29
  • Is the number very close to zero? The printing could have an effect if 80-bit excess precision is to blame, as it might cause the double to be stored to memory, changing its value. – Kerrek SB Sep 26 '11 at 08:44
  • @Kerrek SB: huh? a link or example for this? – Karoly Horvath Sep 26 '11 at 08:54
  • The number should not be close to zero. On one particular trial, the number was expected to be 185, and it was when printed, but when not printed, it apparently was less than or equal to zero, because the prediction was -1. – Max Sep 26 '11 at 09:02
  • @yi_H: There was a [related question](http://stackoverflow.com/questions/7517588/is-this-an-g-optimization-bug) recently. On x86, double computations are done in the FPU in 80 bits by default, which can sometimes lead to surprises. (Though apparently not in the present case.) – Kerrek SB Sep 26 '11 at 09:16
  • I've just tried it with long double, as suggested in the related forum, and unfortunately I get the same error. Making me even more worried is that if I remove the predicate statement for setting the dotProduct, and instead just use the "false" clause (because for now biased is always false), the problem reappears, even with the print statement in. – Max Sep 26 '11 at 09:20

1 Answers1

4

This often happens due to two reasons:

  1. Concurrency issues. If your program is multithreaded, you mask race conditions with debug output. Try a MT debugger like helgrind.
  2. Broken stacks. Try running valgrind on your program and see if it comes out clean.

These are, of course, pretty generic advices, but you'll have to specify your question better to get better advice :-).

thiton
  • 35,651
  • 4
  • 70
  • 100
  • The code is not multithreaded, so it shouldn't be a concurrency issue. And to answer some of the other commenters, about posting the results: essentially, given the same inputs (both parameters and also data members in the class being equal), the code produces both +1 and -1 with the print statement in, but only produces -1 when the print statement is out. – Max Sep 26 '11 at 08:56
  • 1
    @Max: I think you missed the main point of the commenters. Give a concrete example where it "fails". A code that I can compile and it will reproduce the problem. You have some ugly bug but if you don't put in effort nobody can help you. – Karoly Horvath Sep 26 '11 at 09:07
  • The trouble is, I don't know how to provide a good example, because this is part of a larger code structure, that relies on a data set from a separate file. I don't know how to produce a good example without including all of the code. – Max Sep 26 '11 at 09:09
  • 2
    well, the bug is in that larger codebase.. in the process of minimizing the example you can locate the bug. that's the whole point – Karoly Horvath Sep 26 '11 at 09:19
  • It turns out it was a problem with const correctness, and it was indeed in code outside of the original post. I tried to delete this post, but I was told that a moderator had to do so. – Max Sep 26 '11 at 09:48