Gradient Calculation

Back to Problem Solutions forum

Leonid_Manieiev     2015-07-09 17:26:01

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!

Leonid_Manieiev     2015-07-09 17:34:39

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

OldProgrammer     2015-07-09 21:26:46

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.

Leonid_Manieiev     2015-07-09 22:42:34

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?

OldProgrammer     2015-07-10 10:56:52

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.

Leonid_Manieiev     2015-07-10 15:19:58

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.

TestUser     2015-07-10 16:23:25
User avatar

Why do you call round on angle? I remember this problem poorly but this looks strange - could it be the cause of discrepancy?

OldProgrammer     2015-07-10 16:32:09

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.

Leonid_Manieiev     2015-07-10 16:42:58

Thank you two for your replies. Ill try to change dt to smaller one.

OldProgrammer     2015-07-10 16:48:20

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?

Leonid_Manieiev     2015-07-10 20:59:33

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.

Rodion (admin)     2015-07-11 06:12:34
User avatar

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? :)

Leonid_Manieiev     2015-07-11 10:17:51

Sure, you can remove any part of my code :)

Dead Forest Foundation     2020-08-12 10:11:27
User avatar

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 :)

Rodion (admin)     2020-08-12 10:55:20
User avatar

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!

Dead Forest Foundation     2020-08-12 11:26:17
User avatar

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)

Please login and solve 5 problems to be able to post at forum