Click here to Skip to main content
15,891,375 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi everybody!
I am a beginner in c++ and I need your help please. I implemented Euler's method for solving simple ODEs (y' = x - y, y(0)=1)and it is forward in time (from t=0 to t=1) and it worked well, my question is : I want to run this code backward in time (t=1 to t=0).

What do I have to change in my code?

C++
/* Euler for a set of first order differential equations */

#include <stdio.h>
#include <math.h>
#define dist 0.2               /* stepsize in t*/
#define MAX 1.0                /* max for t */
int N=1;

void euler(double x, double y[], double step); /* Euler function */

double f(double x, double y[], int i);          /* function for derivatives */

main()
{
    double t, y[N];
    int j;

    y[0]=1.0;                                       /* initial condition */

    for (j=0; j*dist<=MAX ;j++)                     /* time loop */
    {
       t=j*dist;
       printf("j =  %d,t = %f y[0] = %f\n", j,t, y[0]);
       euler(t, y, dist);
    }
}

void euler(double x, double y[], double step)
{
    double  s[N];      /* for euler */
    int i;

    for (i=0;i<N;i++)
    {     
        s[i]=step*f(x, y, i);
    }

    for (i=0;i<N;i++) 
        y[i]+=s[i];
}

double f(double x, double y[], int i)
{
    if (i==0) 
        return(x-y[0]);                 /* derivative of first equation */
}


Many thanks in advance!
Posted
Updated 2-May-11 6:20am
v4
Comments
OriginalGriff 2-May-11 10:51am    
Well, first off, you could try indenting it so it's readable, and using sensible names for your variables. Oh, and good comments are fashionable, too.
Niklas L 2-May-11 11:08am    
Fair enough. It smells homework.
CPallini 2-May-11 11:33am    
Looking at posted code (e.g. see function f definition) I wonder why you're confident it works well.
mora78 2-May-11 11:39am    
the above example is from ODE book so I know the results in advance but I want to know how to run this code backward in time because I need that at my work. by the way, the above example is a simple and it just a trial
Hans Dietrich 2-May-11 11:46am    
Take another look at your function f. If i is NOT equal to 0, what is returned?

1. This is more a question of algorithm than C++, since without knowledge of the Euler algorithm it's not easy to give a correct answer. You should have added 'algorithm' as a keyword.

2. Eulers method requires a starting value. Do you have the starting value for t=1.0? Or do you want to start at t=0.0 and run backward to t=-1.0?

3. Your function f() should always return a value. It currently does so only for i==0. Your compiler should have issued a warning about that - do not ignore it! Even though at the moment nothing bad happens, it will if you ever change your value for N!

Regarding your question, you only need to use a negative dist value and modify the for loop so that t gets decremented. Note that unless you really want your steps numbered in your printout, you do not need the variable j. For a loop from t=1.0 backwards to 0.0 you can define the for loop just like this:
#define dist -0.2
for (t = 1.0; t >= 0.0; t += dist) // as dist is negative you actually decrement t here
{
  printf(...);
  euler(...);
}


[edit: fixed the loop to run from 1.0 to 0.0]
[edit 2: fixed dist value to make sure euler() gets the correct, negative step value]
 
Share this answer
 
v3
Comments
mora78 2-May-11 11:59am    
many thanks, in the backward, t=1.0, y(t=1)=0.655
Stefan_Lang 2-May-11 12:10pm    
Updated solution: I said to use a negative dist value, so of course inthe for loop you still need to *add* that negative value, not subtract it. Also updated for actual range, 1.0 to 0.0
Its very unclear what you are calculating:
VB
y' = x - y
y' = dx/dy
dx = -y
dy = x

-y / x  = x - y
xy - y  = x²
y*(x-1) = x²
y       = x²/(x-1)
y' = x - x²/(x-1)
   = x² - x - x² / (x-1)
   = -x / (x-1)


The last line is your problem. The calculated values from your code are not correct.
Short table from Excel:
MSIL
x           y           y'
0.000000    0.000000    0.000000
0.100000    -0.011111   0.111111
0.200000    -0.050000   0.250000
0.300000    -0.128571   0.428571
0.400000    -0.266667   0.666667
0.500000    -0.500000   1.000000
0.600000    -0.900000   1.500000
0.700000    -1.633333   2.333333
0.800000    -3.200000   4.000000
0.900000    -8.100000   9.000000
1.000000    #DIV/0!   #DIV/0!


formula: y' = x - y
you want to set x = t and y = f(t), you should get the results above.
Regards.
 
Share this answer
 
Comments
Stefan_Lang 4-May-11 3:50am    
Several errors here:
1. you've tried to find the actual solution for this ODE, but the question refers to the Euler-algorithm, which only provides an approximation. OF COURSE the approximation will not yield the exact solution - you cannot compare these values.

2. Your solution is wrong. You just have to inject your solution into the original ODE to see that. Easier still: your solution does not fulfil the start condition: y(0)=1!

I'm not quite sure how you came by dx and dy, and why you think you can provide a solution without ever taking the start value into consideration. I haven't done ODEs in the last ~25 years, but some simple sanity checks never hurt.

3. The Euler algorithm always applies the same step size, using the previous values of x (or t in this case) and y as a starting point, so in the algorithm, starting from the second iteration, you'll have a different formula anyway. If you look at the program, there are no divisions involved, so there are no singularities (this, btw., should be another hint that your solution can't be right!)
Stefan_Lang 4-May-11 4:47am    
FYI, the general solution, before taking the start value into account, is: y=x-1+c*e^(-x), where c is a nonzero constant. The value of c must be 2 to fulfil the starting condition.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900