Example Code

Fixing the RK4 ODE solver for many single-step iterations

Code and Documents

Attachment

Problem:

Initial function parsing in the 4th order Runge Kutta method takes about 10x the amount of time it takes to run a simulation step. This doesn't matter all that much when your t_end - t_start >> h, but when they're close, for example when t_end = t_start + h, the parsing step takes up almost 90% of execution time, even though it may be doing the same thing every time.

My solution:

Keep a queue that holds the 5 most recently parsed functions. If the incoming function matches any of the functions we already have, use that instead of reparsing.

Here is the new parser:

It replaces Gmath.lvlib:Runge Kutta Check.vi. The difference is in the two new VI's: "RK4 Parse.vi" and "RK4 Append to Parsed Function Queue.vi"

In RK4 Parse.vi, we check our parsed function queue to see if the incoming function matches any of the ones we currently have:

Here, "clear function queue" is a debugging input used to show how continuously reparsing is detrimental.

And in "RK4 Append to Parsed Function Queue.vi" we actually add functions to the queue:

As I said before, people who are using this VI to do a bunch of simulation steps all at once will not notice many benefits. But if you're in a situation where you need to continually see the results of your simulation to alter the function itself, for example if you have a max() in your system of ODEs, this will have performance increases of 50-90%.

I've attached an lvproj where you can check this out yourself. See "RK4 test.vi" in the attached zip to see how much the parser affects execution time when running single-steps. The RK4_optimized VI is similar to the one already available in Gmath.lvlib, with an added debugging feature "clear function queue" to demonstrate what happens when reparsing. If you run the "RK4 test" with and without "always reparse", you will see the clear jump in execution time between the first iteration and the latter iterations. Run "RK4 extended test" to see how, on average, the parsing step takes a significant portion of the execution time.

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Contributors