Iteration and Interpolation

The problem is as follows:

Your task is to find the four solutions to the equation sin(x) = exp(-0.4x) in the region from zero to ten radians.

This is accomplished with iteration and interpolation.

The output from my program is shown below:

The 4 solutions to sin(x) = exp(-0.4x) starting from x = 0 are:

Solution No. 1:
x (iteration only) = 0.809 with an error of -5.77136e-005
x (with interpolation) = 0.808941 with an error of -2.32525e-008

Solution No. 2:
x (iteration only) = 2.811 with an error of 0.00024367
x (with interpolation) = 2.8107 with an error of -3.94877e-008

Solution No. 3:
x (iteration only) = 6.362 with an error of -0.000244374
x (with interpolation) = 6.36176 with an error of -8.23243e-009

Solution No. 4:
x (iteration only) = 9.402 with an error of 0.00048913
x (with interpolation) = 9.40151 with an error of -3.37411e-009


So far I have written coding to find the solution for the first iteration. I'm not sure how to use the range, (or how to show this in radians); also, my solution is not correct. Can anybody tell me what my problem is?

Lastly, should I use a for loop to show the 4 solutions, or is there something else I should be doing?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 //Iteration and Interpolation
//David Karayof
//October 25, 2013

#include <cmath>
#include <iostream>
using namespace std;

double Fx(double x);
double interp(double x, double step);

int main ()
{
  double x= 0, step = 0.001 ;

  while (Fx(x) > 0.0)
    x = x + step;

  cout << "\n x (iteration only) = " << x;
  cout << "\n with an error of " << Fx(x);

  x = interp(x,step);
  cout << "\n\n x (with interpolation) = " << x;
  cout << "\n with an error of " << Fx(x);

  cout << "\n\n";
  return 0;
}

double Fx(double x)
{
  return((sin(x)) - (exp(-0.4 * x)));
}

double interp(double x, double step)
{
  double ratio;

  ratio = - Fx(x-step)/Fx(x);

  return (x - step + ratio * step /(1 + ratio));
}
> I'm not sure how to use the range, (or how to show this in radians)

x is already in radians.


> should I use a for loop to show the 4 solutions

Yes. Loop from x = 0.0 to x < 10.0


> also, my solution is not correct.

Check the absolute value since you are always checking for 'greater than'

There is no one correct solution; play around with epsilon and see how the results change.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

double Fx(double x);
double interp(double x, double step);

int main ()
{
    const double epsilon = 0.001 ;
    const double incr = 0.5 ;

    const double max_radians = 10.0 ;

    for( double x = 0  ; x < max_radians ; x += incr )
    {
        const double step = 0.001 ;

        while( Fx(x) > epsilon ) x = x + step; // *** epsilon

        if( x < max_radians )
        {
            cout << "\n x (iteration only) = " << setprecision(4) << x;
            cout << setprecision(6) << " with an error of " << Fx(x) - epsilon ;

            x = interp(x,step);
            cout << "\n x (with interpolation) = " << x;
            cout << " with an error of " << Fx(x) ;

            cout << "\n\n";
        }
    }
}

double Fx(double x)
{
  return abs( (sin(x)) - (exp(-0.4 * x)) ); // *** abs
}

double interp(double x, double step)
{
  double ratio;

  ratio = - Fx(x-step)/Fx(x);

  return (x - step + ratio * step /(1 + ratio));
}

http://coliru.stacked-crooked.com/a/1dc36b1728981171
could you explain epsilon to me please? I'm not sure why it is relevant.

Also, what is "setprecision(4) and (6)? How does that work
> what is "setprecision(4) and (6)? How does that work

See: http://www.cplusplus.com/reference/ios/ios_base/precision/
and: http://www.cplusplus.com/reference/iomanip/setprecision/


> could you explain epsilon to me please? I'm not sure why it is relevant.

We are trying to find the root of a function by sampling at discrete intervals (in steps of 0.001 in the code above). Without an epsilon (an estimated, sufficiently small quantity), we can miss the root altogether.

Run this program, and the need for an epsilon would become apparent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <iomanip>
#include <cmath>

double Fx( double x )
{
    double temp = x - 3.00055 ;
    double temp2 = std::pow( temp* temp, 0.5 ) ;
    if( std::abs(temp) > 0.00001 ) temp2 = -temp2 ;
    return temp2 ;
}

int main()
{
    std::cout << std::fixed << std::setprecision(5) ;
    double x = 3.00055 ;
    std::cout << "x: " << x << "  Fx(x): " << Fx(x) << " (root)\n\n" ;

    std::cout << "now, iterating from 3.0000 in steps of 0.0001\n" ;

    bool found = false ;
    for( double x = 3.0000 ; x < 3.0010 ; x += 0.0001 )
    {
        if( Fx(x) >= 0.0 )
        {
            std::cout << "found the root!\n" ;
            found = true ;
            break ;
        }
        std::cout << "x: " << x << "  Fx(x): " << Fx(x) << '\n' ;
    }
    if( !found ) std::cout << "alas! we missed the root.\n" ;
}

http://coliru.stacked-crooked.com/a/92a6a846fca68541
Alright that makes more sense now... It's still returning the wrong error though, the function looks fine to me could it be my debugger?
Topic archived. No new replies allowed.