Group Abstract Group Abstract

Message Boards Message Boards

Solve an ODE using Runge-Kutta methods?

Hello All:

Hope everyone is doing well. I am attempting to create functions that use Runge-Kutta to solve an ODE. At the moment results are very close to exact solutions in a small example.

My question is in regards to the need of using "Evaluate Notebook" twice for getting good results after opening the notebook. Why is this happening(?)

Any advise is welcome!!! I highly appreciate your feedback letting me know my failures.

The attached file contains my attempts.

Attachments:
POSTED BY: Marcolino R-M
5 Replies

Re your point [14]: Using f as argument to RK4step and RK4 would have two advantages:

  1. You would not have to use the name f, which is currently hard-coded into RK4step and RK4, for your function prescribing the ODE's right-hand side. You could call it anything you like!
  2. It would make these function more like DSolve and NDSolve that are built into *Mathematica": in those two, the first argument is always the differential equation (or list consisting of differential equation and initial or boundary condtions) to be solved.

This would still not be quite like the built-in functions, in that the first argument would be just the name of a function (or, alternatively, a "pure function" expressed in a Function[....] expression or the equivalent abbreviation using # and &).

To be much more like the built-in functions, you would need to allow the first argument to be an entire "function expression" including variables, e.g., (in the case of a scalar ODE, for simplicity):

x^2 - y

But this makes coding RK4step and RK4 trickier, for you would also then need a new 2nd argument that is a list, in this example, {x, y}, of the names of the variables in that first argument.

POSTED BY: Murray Eisenberg

Professor Eisenberg:

Thanks again for taking the time to review my post. Attached a practice notebook with your guides. I am learning a lot from your insightful comments. Below are some notes from your post. Porting code from explicit to implicit iteration is beneficial and now I have a better understanding of it. Great leanings from you.

Thanks

Definition Of Function f:

[01] In f, argument x is used for non-homogeneous ODE or BVP.

[02] Defining f per your guidelines help clarify doubts on my side and makes its intent clear. Thanks!

Definition Of Function RK4:

[03] I realize the behavior of a variable, like k1, etc..., once an assignment occurs, hence impracticality for constant arrays. Thanks!

[04] It is clear your points on yn1. Thanks!

[05] It is clear also the comment on parameter m. Thanks!

[06] Great point on avoiding approximate use and how to maneuver with N. Thanks!

[07] Use of (**) is a habit that I should stop. Space helps. Thanks!

The Iteration: From Explicit Loop To Implicit Iteration

[08] The form you state RK4step is very clever and clear. Now I understand the type of changes. Thanks!

[09] The guides for stating NestList with RK4step is very clear. Looks like a controlled recursion. VERY HELPFUL. Thanks!

[10] Stating newRK4 gives new understanding on how to program. Thanks!

[11] Cleaning and customizing the output of lis is very helpful as well as insightful. I was expecting major difficulties. Thanks!

[12] The function nicerRK4 and RK4 are very compact and clear. Great learning from them. Thanks!

Printing A Nice Table Of Results:

[13] TableForm with RK4 does a straight job of showing results. Very useful. Thanks!

Further Refinements:

[14] Using f as argument to RK4step and RK4 is something that I am exploring. What would be the benefit(?)

[15] Input Checking is a good safeguard. Thanks for noting it.

Attachments:
POSTED BY: Marcolino R-M
POSTED BY: Murray Eisenberg

Professor Eisenberg:

Thanks a lot for taking the time to scrutinize the code and relay in writing your observations. I really appreciate your effort and feel thankful for it. Per your notes, I proceeded as follows:

[01] Clearly understood your point on evaluating cells one-by-one instead the entire notebook.

[02] I was not aware of the precedence's need during function declaration. This area is clear now.

[03] Currently I am investigating how to avoid using a "For" loop with other constructs (i.e. Table).

[04] Per your note, RK4 and f have been changed to return a result.

[05] Variable i removed from f since it was not being used.

[06] With your observations regarding precedence of functions and their return of values now can state code as: k1 = h f[x, yn], etc...

[07] Not using symbol, *, for multiplication helps in de-cluttering the code.

[08] In RK4 the inputs (x, y, m, h) are declared globally to accommodate variants of initial value problems.

[09] Coefficients declaration (i.e. k1,...) changed and this makes their intent more clear.

[10] With all your observations, the code have been changed and the need for TWICE evaluation is abolished!!!

Currently I will use your observations on a package to solve BVP. Please be sure that as I found setbacks, I will seek the advise of experts like you on this forum.

Thanks!!!

Attachments:
POSTED BY: Marcolino R-M

In general, it looks like you are treating a Mathematica notebook, and the Wolfram Language code used in it, as if it were a Matlab .m file and Matlab code. In contrast to a Matlab .m file, one does not ordinarily evaluate the entire notebook, but rather evaluate cells one-by-one, or in groups, as needed.

In your notebook, you are calling RK4 within the For loop before you define the function RK4. (Note also that RK4 calls the function f before you define f.) That is why you need to evaluate the entire notebook twice — unless, that is, you evaluate cells individually but in the order of defining f, defining RK4, and only then the For loop.

Aside from that, there are some issues with your code.

  • There is utterly no need for a For loop to print what you want. You should be able to do this with Table or similar constructs.
  • The function RK4 does not return a result as output (well, technically, it returns Null because the last expression within it ends with a semicolon.
  • Similarly, in the definition of f, you have no actual output but rather perniciously assign values to the (first two positions of) the global y.
  • In the definition of f, you have a local variable i which is not subsequently used, so why have it?
  • At several places in the definition of RK4 you simply invoke f at various input pairs but do nothing with them. For example, immediately after your list of local variables in Module, you have f[x, yn];. This evaluates f at the current values of x and yn and then in effect just throws that value of f away, because you don't assign it to anything; perhaps you really meant y = f[x, yn] there. And then you could simply set k1 = h f[x, yn].
  • This is a matter of taste, perhaps, but there is utterly no need to insert the symbol * to indicate multiplication; instead, just type a space between, e.g., h and y (so as not to confuse the product with a new symbol hy); Mathematica will provide an appropriate thin space there so it looks nice!
  • Your function RK4 takes as inputs an x , a yn, an m, and an h. Why, then, do you bother to define them globally at the beginning?
  • Inside RK4, the way you create the coefficients k1, k2, k3, k4 is unnecessarily verbose. This can be done much more succinctly — and clearly! — as follows:

    k1 = k2 = k3 = k4 = ConstantArray[0., m]
    
POSTED BY: Murray Eisenberg
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard