am.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* This file is part of the GNU plotutils package. */
  2. /*
  3. * Copyright (C) 1982-1994, Nicholas B. Tufillaro. All rights reserved.
  4. *
  5. * GNU enhancements Copyright (C) 1996, 1997, 2005, 2008, Free Software
  6. * Foundation, Inc.
  7. */
  8. /*
  9. * Adams-Moulton with constant step size
  10. */
  11. #include "sys-defines.h"
  12. #include "ode.h"
  13. #include "extern.h"
  14. #define PASTVAL (3) /* previous values, val[0] is current value */
  15. void
  16. am (void)
  17. {
  18. double t;
  19. double halfstep = HALF * tstep;
  20. double sconst = tstep / 24.0; /* step constant */
  21. double onesixth = 1.0 / 6.0;
  22. /* Runge-Kutta startup */
  23. for (it = 0, t = tstart; it <= PASTVAL && !STOPR; t = tstart + (++it) * tstep)
  24. {
  25. symtab->sy_value = symtab->sy_val[0] = t;
  26. field();
  27. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  28. {
  29. int j;
  30. for (j = it; j > 0; j--)
  31. {
  32. fsp->sy_val[j] = fsp->sy_val[j-1];
  33. fsp->sy_pri[j] = fsp->sy_pri[j-1];
  34. }
  35. fsp->sy_pri[0] = fsp->sy_prime;
  36. fsp->sy_val[0] = fsp->sy_value;
  37. }
  38. /* output */
  39. printq();
  40. if (it == PASTVAL)
  41. break; /* startup complete */
  42. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  43. {
  44. fsp->sy_k[0] = tstep * fsp->sy_prime;
  45. fsp->sy_value = fsp->sy_val[0] + HALF * fsp->sy_k[0];
  46. }
  47. symtab->sy_value = t + halfstep;
  48. field();
  49. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  50. {
  51. fsp->sy_k[1] = tstep * fsp->sy_prime;
  52. fsp->sy_value = fsp->sy_val[0] + HALF * fsp->sy_k[1];
  53. }
  54. symtab->sy_value = t + halfstep;
  55. field();
  56. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  57. {
  58. fsp->sy_k[2] = tstep * fsp->sy_prime;
  59. fsp->sy_value = fsp->sy_val[0] + fsp->sy_k[2];
  60. }
  61. symtab->sy_value = t + tstep;
  62. field();
  63. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  64. fsp->sy_k[3] = tstep * fsp->sy_prime;
  65. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  66. {
  67. fsp->sy_value = fsp->sy_val[0]
  68. + onesixth * (fsp->sy_k[0]
  69. + TWO * fsp->sy_k[1]
  70. + TWO * fsp->sy_k[2]
  71. + fsp->sy_k[3]);
  72. }
  73. }
  74. /* predictor - corrector */
  75. while (!STOPA)
  76. {
  77. /* Adams-Bashforth predictor */
  78. for (fsp = dqueue; fsp != NULL ; fsp = fsp->sy_link)
  79. {
  80. fsp->sy_value = fsp->sy_val[0]
  81. + (sconst) * (55 * fsp->sy_pri[0]
  82. -59 * fsp->sy_pri[1]
  83. +37 * fsp->sy_pri[2]
  84. -9 * fsp->sy_pri[3]);
  85. }
  86. symtab->sy_val[0] = symtab->sy_value = t = tstart + (++it) * tstep;
  87. field();
  88. /* Adams-Moulton corrector */
  89. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  90. {
  91. fsp->sy_value = fsp->sy_val[0]
  92. + (sconst) * (9 * fsp->sy_prime
  93. +19 * fsp->sy_pri[0]
  94. -5 * fsp->sy_pri[1]
  95. + fsp->sy_pri[2]);
  96. }
  97. field();
  98. /* cycle indices */
  99. for (fsp = dqueue; fsp != NULL; fsp = fsp->sy_link)
  100. {
  101. int j;
  102. for (j = PASTVAL; j > 0; j--)
  103. {
  104. fsp->sy_val[j] = fsp->sy_val[j-1];
  105. fsp->sy_pri[j] = fsp->sy_pri[j-1];
  106. }
  107. fsp->sy_val[0] = fsp->sy_value;
  108. fsp->sy_pri[0] = fsp->sy_prime;
  109. }
  110. /* output */
  111. printq();
  112. }
  113. }