Advertisement
Guest User

Untitled

a guest
Nov 20th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.92 KB | None | 0 0
  1. % Dormand Prince
  2.  
  3. % We are creating a function that approximates values of ODEs using two linear
  4. % combinations of seven different slopes. This function will approximate two
  5. % values for each iteration, one of 4th order and one of 5th based on weighted
  6. % averages. These values will be compared to increment size to determine the
  7. % most accurate value possible
  8.  
  9. % Parameters
  10. % ==========
  11. % f = f(t,y): The function f is the bivariate function (ODE) to be
  12. % approximated
  13. % t_rng: The range of input values
  14. % y0: The initial output value
  15. % h: The increment value between approximations.
  16. % eps_abs: The minimum absolute value of error required to terminate funtion
  17. %
  18. % Return Values
  19. % =============
  20. % t_out: A row vector of n amount equally spaced values from t0 to tfinal
  21. % y_out: A row vector of n amount of values where:
  22. % y_out(1) = y0
  23. % y_out(i) approximates the remaining output values
  24. %
  25. % Description
  26. % ==============
  27. % Initialize weighted variables
  28. % Define remaining variables
  29. % Iterate until t final is found
  30. % Calculate 7 DP slopes
  31. % Estimate 4th and 5th order values
  32. % Calculate scaling factor to interpret h
  33. % Find next t value
  34. % Determine if h is usable
  35. % Determine y_out if h is acceptable
  36. % If h doesnt work, half it
  37. % Update counter
  38.  
  39. function [t_out, y_out] = dp45(f, t_rng, y0, h, eps_abs)
  40.  
  41. if ~isa( f, 'function_handle' )
  42. throw( MException( 'MATLAB:invalid_argument', ...
  43. 'Invalid f: Not Funtion Handle' ) );
  44. end
  45. if ~all( size( t_rng ) == [1,2] )
  46. throw( MException( 'MATLAB:invalid_argument', ...
  47. 'Invalid t_rng: Not a 3D column vector' ) );
  48. end
  49.  
  50. if ~ismatrix(y0)
  51. throw( MException( 'MATLAB:invalid_argument', ...
  52. 'Invalid y0: Not a column vector' ) );
  53. end
  54.  
  55. [N,y0_col] = size(y0);
  56. if ~(y0_col == 1)
  57. throw( MException( 'MATLAB:invalid_argument', ...
  58. 'Invalid y0: Not a column vector ' ) );
  59. end
  60.  
  61. if ~isscalar( h )
  62. throw( MException( 'MATLAB:invalid_argument', ...
  63. 'Invalid h: Not a scalar' ) );
  64. end
  65.  
  66. if ~isscalar( eps_abs ) || eps_abs < 0
  67. throw( MException( 'MATLAB:invalid_argument', ...
  68. 'Invalid eps_abs: Not a positive scalar' ) );
  69. end
  70.  
  71. % Initialize weighted variables
  72. A = [ 0 0 0 0 0 0 0;
  73. 1 0 0 0 0 0 0;
  74. 1/4 3/4 0 0 0 0 0;
  75. 11/9 -14/3 40/9 0 0 0 0;
  76. 4843/1458 -3170/243 8056/729 -53/162 0 0 0;
  77. 9017/3168 -355/33 46732/5247 49/176 -5103/18656 0 0;
  78. 35/384 0 500/1113 125/192 -2187/6784 11/84 0]';
  79.  
  80. by = [5179/57600 0 7571/16695 393/640 -92097/339200 187/2100 1/40]';
  81. bz = [ 35/384 0 500/1113 125/192 -2187/6784 11/84 0 ]';
  82.  
  83. c = [0 1/5 3/10 4/5 8/9 1 1]';
  84.  
  85. % Define remaining variables
  86. t_out(1) = t_rng(1);
  87. y_out = y0;
  88. K = zeros( N,7);
  89. i = 1;
  90.  
  91. % Iterate until t final is found
  92. while t_out(i) < t_rng(2)
  93. %Calculate 7 DP slopes
  94. for m = 1:7
  95. K(:, m) = f(t_out(i) + h*c(m), y_out(:, i) + h*c(m)*K*A(:, m) );
  96. end
  97. %Estimate 4th and 5th order values
  98. y_t = y_out(:,i) + h*K*by;
  99. z_t = y_out(:,i) + h*K*bz;
  100.  
  101. e = norm(y_t - z_t);
  102. r = t_rng(2) - t_rng(1);
  103.  
  104. % Calculate scaling factor to interpret h
  105.  
  106. s = ((h*eps_abs)/((2*r*e)))^(1/4);
  107. %Find next t value
  108. %Determine if h is usable
  109. %Determine y_out if h is acceptable
  110. %If h doesnt work, half it
  111. %Update counter
  112. if s >= 2
  113. y_out(:,i+1) = z_t;
  114. t_out(i+1) = t_out(i) + h;
  115. h = h * 2;
  116. i = i + 1;
  117. elseif s >=1
  118. y_out(:,i+1) = z_t;
  119. t_out(i+1) = t_out(i) + h;
  120. i = i + 1;
  121. else
  122. h = h / 2;
  123. end
  124.  
  125. if (t_out(i) + h) > t_rng(2)
  126. h = (t_rng(2) - t_out(i));
  127. end
  128.  
  129. end
  130.  
  131. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement