Back to Problem Solutions forum
Hi everyone.
Im trying to solve Gradient Calculation. Here is my code on C++:
//... I removed unnecessary parts of code to prevent spoiling solution - Admin :)
//... thanks to Leonid for allowing this!
double calcFunc(double A, double B, double C, double x, double y)
{
return pow((x - A), 2) + pow((y - B), 2) + C * exp(- pow((x + A), 2) - pow((y + B), 2));
}
It looks like Im doing something wrong, because I get wrong angels in output? I think that my problem is because Im using dt = 0.1 like in example. Do i have to use it at all? Can someone give me a hint, please.
Thanks!
Answer that I should get: 222 246 211 212 234 254 19 214 172 234 244 254 175 213
Answer that I get: 42 69 27 34 56 76 175 31 -8 55 67 76 -6 29
atan2 returns values from the set { -PI < x < PI }.
Your code needs to analyse the signs of your x and y values and add an appropriate constant to put them in the correct range.
See the following for how to work out to relate the x and y values to the angle. https://www.mathsisfun.com/algebra/trig-four-quadrants.html
There are other possibilities for the small differences e.g. you could use a system defined value for PI e.g. MPI and adjust how the code rounds values.
Your code needs to analyse the signs of your x and y values and add an appropriate constant to put them in the correct range.
What kind of constant do you mean?
Apologies I can see now that my response is confusing. Let me try again.
Anyway, atan2 can return negative angles so the result won't be in the range 0 - 360 degrees in those cases. Adding an appropriate constant value should bring it into the correct range.
If you look at the link I gave, angles start at the x-axis on the graph and increase anti-clockwise from 0 - 360.
However, negative angles in range -PI - 0 are mirror image of angles from 0 to PI. The code needs to adjust for this.
I hope this helps.
Well, if I understand you currectly, I should change calcGradient function like this:
double calcGradient(double res, double resX, double resY)
{
double angle = round(atan2((resY - res) / 0.1, (resX - res) / 0.1) * 180.0 / PI);
if(angle < 0)
return 180-angle;
else return 180+angle;
}
I run my programm and get: 222 249 207 214 236 256 355 211 188 235 247 256 186 209
Close to correct answer, but still not correct.
Why do you call round
on angle
? I remember this problem poorly but this looks strange - could it be the cause of discrepancy?
To get more accurate numbers e.g. 246 instead of 249, you need to use a much smaller step size. 0.1 is not sufficient.
I've messed up on the theory again and I'd need to think about that bit - sorry.
Thank you two for your replies. Ill try to change dt to smaller one.
Regarding the theory:
Negative angles go in the wrong direction i.e. 0 down to -PI is clockwise not anti-clockwise. So, -10 degrees becomes 350 degrees.
Also, the problem specifies descent so, instead of going up the gradient line, one goes the opposite way - that changes the angle.
As an example, think of the line y = x. In ascent that has angle 45 degrees. What is it in the opposite direction?
Finally. I got the right answer. If anyone is interested here is the code of calcGradient function:
double calcGradient(double res, double resX, double resY)
{
double angle = round(atan2((resY - res) / 0.0001, (resX - res) / 0.0001) * 180.0 / PI);
return angle+180;
}
TestUser, sorry, I forgot to answer to your question. I call round on angle because problem asked for angle, rounded to whole integers.
Ah, yes, sorry for silly question about rounding. That's cool you was able to get through it and thanks to OldProgrammer for help!
Wouldn't you mind if we remove unnecessary parts of the code from your first post now? I mean, to prevent spoiling solutions in the forum? :)
Sure, you can remove any part of my code :)
Hello All! Please pay special attention about function that we have!
For two hours I could not understand what the problem was, until I saw this in my code:
... + C * Math.exp(- Math.pow((x - A), 2) - Math.pow((y - B), 2)); // instead x + A, x + B
I was too lazy to write the expression in brackets again and I just copied it from the left side of the formula. Stupid(
Be careful and good luck :)
He-he, we are programmers :) If I'm paid $1 every time I make some mistake due to lack of attention, I would be millionaire already!
I was sure that I did everything right and was about to turn to this thread for help. But in the first message I saw that something was wrong)