You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
978B

  1. #pragma once
  2. namespace rack {
  3. typedef void (*stepCallback)(float x, const float y[], float dydt[]);
  4. /** Solve an ODE system using the 1st order Euler method */
  5. inline void stepEuler(stepCallback f, float x, float dx, float y[], int len) {
  6. float k[len];
  7. f(x, y, k);
  8. for (int i = 0; i < len; i++) {
  9. y[i] += dx * k[i];
  10. }
  11. }
  12. /** Solve an ODE system using the 4th order Runge-Kutta method */
  13. inline void stepRK4(stepCallback f, float x, float dx, float y[], int len) {
  14. float k1[len];
  15. float k2[len];
  16. float k3[len];
  17. float k4[len];
  18. float yi[len];
  19. f(x, y, k1);
  20. for (int i = 0; i < len; i++) {
  21. yi[i] = y[i] + k1[i] * dx / 2.0;
  22. }
  23. f(x + dx / 2.0, yi, k2);
  24. for (int i = 0; i < len; i++) {
  25. yi[i] = y[i] + k2[i] * dx / 2.0;
  26. }
  27. f(x + dx / 2.0, yi, k3);
  28. for (int i = 0; i < len; i++) {
  29. yi[i] = y[i] + k3[i] * dx;
  30. }
  31. f(x + dx, yi, k4);
  32. for (int i = 0; i < len; i++) {
  33. y[i] += dx * (k1[i] + 2.0 * k2[i] + 2.0 * k3[i] + k4[i]) / 6.0;
  34. }
  35. }
  36. } // namespace rack