stperr.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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, 1998, 1999, 2005, 2008, Free
  6. * Software Foundation, Inc.
  7. */
  8. /*
  9. * find maximum errors
  10. *
  11. */
  12. #include "sys-defines.h"
  13. #include "ode.h"
  14. #include "extern.h"
  15. static double ssemax, abemax, acemax;
  16. static char *ssenam, *abenam, *acenam;
  17. void
  18. maxerr (void)
  19. {
  20. struct sym *sp, *dq;
  21. dq = symtab->sy_link;
  22. ssemax = abemax = acemax = 0.0;
  23. for (sp = dq; sp != NULL; sp = sp->sy_link)
  24. {
  25. if (ssemax < sp->sy_sserr)
  26. {
  27. ssemax = sp->sy_sserr;
  28. ssenam = sp->sy_name;
  29. }
  30. if (abemax < sp->sy_aberr)
  31. {
  32. abemax = sp->sy_aberr;
  33. abenam = sp->sy_name;
  34. }
  35. if (acmax < sp->sy_acerr)
  36. {
  37. acemax = sp->sy_acerr;
  38. acenam = sp->sy_name;
  39. }
  40. }
  41. }
  42. bool
  43. hierror (void) /* not enough accuracy */
  44. {
  45. double t = symtab->sy_val[0];
  46. if (t + tstep == t)
  47. {
  48. fprintf (stderr, "%s: %s\n", progname, "step size below lower limit");
  49. longjmp (mark, 1);
  50. }
  51. if (ssemax <= ssmax && abemax <= abmax && acemax <= acmax)
  52. return false;
  53. if (fabs(tstep) >= fabs(hmin))
  54. return true;
  55. if (sflag)
  56. return false;
  57. if (ssemax > ssmax)
  58. fprintf (stderr,
  59. "%s: relative error limit exceeded while calculating %.*s'\n",
  60. progname, NAMMAX, ssenam);
  61. else if (abemax > abmax)
  62. fprintf (stderr,
  63. "%s: absolute error limit exceeded while calculating %.*s'\n",
  64. progname, NAMMAX, abenam);
  65. else if (acemax > acmax)
  66. fprintf (stderr,
  67. "%s: accumulated error limit exceeded while calculating %.*s'\n",
  68. progname, NAMMAX, acenam);
  69. longjmp (mark, 1);
  70. /* doesn't return, but must keep unintelligent compilers happy */
  71. return false;
  72. }
  73. bool
  74. lowerror (void) /* more than enough accuracy */
  75. {
  76. if (ssemax < ssmin || abemax < abmin)
  77. if (fabs(tstep) <= fabs(hmax))
  78. return true;
  79. return false;
  80. }
  81. /*
  82. * interpolate to tstop in Runge-Kutta routines
  83. */
  84. #define PASTSTOP(stepvar) (t + 0.9375*stepvar > tstop && \
  85. t + 0.0625*stepvar < tstop)
  86. #define BEFORESTOP(stepvar) (t + 0.9375*stepvar < tstop && \
  87. t + 0.0625*stepvar > tstop)
  88. bool
  89. intpr (double t)
  90. {
  91. if (tstep > 0)
  92. if (!PASTSTOP(tstep))
  93. return false;
  94. if (tstep < 0)
  95. if (!BEFORESTOP(tstep))
  96. return false;
  97. if (tstep > 0)
  98. while (PASTSTOP(tstep))
  99. tstep = HALF * tstep;
  100. if (tstep < 0)
  101. while (BEFORESTOP(tstep))
  102. tstep = HALF * tstep;
  103. return true;
  104. }