Advertisement
Guest User

Untitled

a guest
Jan 19th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MatLab 8.48 KB | None | 0 0
  1. %% Caller 'script'
  2. function caller
  3. close all
  4.  
  5. % solving problem #2 - defined as BVP
  6.  
  7. % define the BVP, we chose boundary conditions in such way that out known
  8. % exact solution would be usable as reference
  9. TSPAN   = [0.001 1];                                                            %first I define a TSPAN
  10. YL      = exactSol2(TSPAN(1));                                              %value of exact solution at left side of TSPAN
  11. YR      = exactSol2(TSPAN(2));                                              %value of exact solution at right side of TSPAN
  12. % BC      = [YL(1) YR(1);NaN NaN];                                            %boundary conditions (NxN matrix)
  13. % BC      = [NaN NaN;YL(2) YR(2)];                                            %boundary conditions (NxN matrix)
  14. % BC      = [YL(1) NaN;NaN YR(2)];                                            %boundary conditions (NxN matrix)
  15. BC      = [NaN YR;NaN YL];                                            %boundary conditions (NxN matrix)
  16. nSteps  = 20;                                                               %define number of steps to be used in solver
  17.  
  18. % create initial guess for the BVP solver
  19. % Y0Guess = [YL(1) 0.9];                                                      %Y0 = [2/3 1]; - corresponding initial condition
  20. Y0Guess = [0.01 YR(2)];
  21.  
  22. [TOUT,YOUTBVP4]  =   bvp4M(@problem2,TSPAN,BC,Y0Guess,nSteps);
  23.  
  24. figure
  25. plot(TOUT,exactSol2(TOUT));hold on;
  26. plot(TOUT,YOUTBVP4,'s');
  27. legend('xExact','yExact','xBVP4','yBVP4','Location','Best')
  28. axis tight
  29. title('Solution of problem 2','FontSize',18,'FontWeight','Bold')
  30. end
  31.  
  32. %% Methods
  33.  
  34. % boundary value problem solver (4th order)
  35. function [TOUT,YOUT] = bvp4M(ODEFUN,TSPAN,BC,Y0G,nSteps)
  36. % ODEFUN ... handle to a function defining the solved SODE
  37. % TPSAN  ... time span for the independent variable
  38. % BC     ... boundary condition (I need to have N BC for system of N ODE)
  39. % Y0G    ... initial guess for the initial condition
  40. % nSteps ... number of steps to use in embedded ODE solver, implicitely
  41. %            defines the step length and is much easier to implement
  42. %
  43. % note: step length, h = (TSPAN(1)-TSPAN(2))/nSteps
  44.  
  45. % transpose BC - writing it in rows is more natural, but for the solution
  46. % structure, it is better to have it in columns
  47. BC = BC';
  48.  
  49. % allocate variables
  50. TOUT = linspace(min(TSPAN),max(TSPAN),nSteps);                              %I can create this vector right away
  51.  
  52. % resave missing initial conditions in a special variable
  53. Y0Miss = Y0G(isnan(BC(1,:)));
  54.  
  55. % find suitable initial condition (the missing ones)
  56. Y0Miss = newtonM(@getReziduals,Y0Miss);                                     %at the time, call with built in pars is enough
  57.  
  58. % get together the found conditions with what is known
  59. Y0G(isnan(BC(1,:))) = Y0Miss;
  60.  
  61. % get the actual solution
  62. [t,YOUT] = rk4M(ODEFUN,TSPAN,Y0G,nSteps);
  63.  
  64. % nested functions
  65.     function rez = getReziduals(X)
  66.         IC       = Y0G;IC(isnan(BC(1,:))) = X;                              %construct initial condition
  67.         [t,YVOL] = rk4M(ODEFUN,TSPAN,IC,nSteps);
  68. %         rez = YVOL(end,~isnan(BC(2,:))) - BC(2,~isnan(BC(2,:)));            %subtract only defined boundary conditions
  69.         rez = (YVOL(end,~isnan(BC(2,:))) - BC(2,~isnan(BC(2,:))))./...      %why does this work better?
  70.             abs(BC(2,~isnan(BC(2,:))));
  71.         rez = rez';                                                         %I need to return a column vector for newton
  72.     end
  73.  
  74. end
  75.  
  76. % Runge-Kutta method (4th order)
  77. function [TOUT,YOUT] = rk4M(ODEFUN,TSPAN,Y0,nSteps)                         %with tspan we input time step (not adaptive)
  78. % calculate needed the step length
  79. H = (max(TSPAN)-min(TSPAN))/nSteps;                                         %I will end exactly in TEND BUT H is not pretty
  80.  
  81. % allocate variables
  82. TOUT = linspace(min(TSPAN),max(TSPAN),nSteps);                              %I can create this vector right away
  83. YOUT = zeros(nSteps,numel(Y0));                                             %but I can only allocate this
  84.  
  85. % save initial condition
  86. TOUT(1) = min(TSPAN);YOUT(1,:) = reshape(Y0,1,numel(Y0));
  87.  
  88. for i = 2:nSteps
  89.    k1 = H*reshape(feval(ODEFUN,TOUT(i-1),YOUT(i-1,:)),1,numel(Y0));
  90.    k2 = H*reshape(feval(ODEFUN,TOUT(i-1)+0.5*H,YOUT(i-1,:)+0.5*k1),1,numel(Y0));
  91.    k3 = H*reshape(feval(ODEFUN,TOUT(i-1)+0.5*H,YOUT(i-1,:)+0.5*k2),1,numel(Y0));
  92.    k4 = H*reshape(feval(ODEFUN,TOUT(i-1)+1*H,YOUT(i-1,:)+1*k3),1,numel(Y0));
  93.    YOUT(i,:) = YOUT(i-1,:) + 1/6*(k1+k4) + 1/3*(k2+k3);
  94. end
  95. end
  96.  
  97. % Newtons method
  98. function [X,FVAL] = newtonM(FUN,X0,OPT)                                     %n-dimensional newton method
  99. % n-dimensional newtons method for solving of SNAE
  100. %
  101. % FUN ... function handle to a mapping defining the set of eqs F(x) = 0
  102. %     ... FUN has to return a column vector
  103. % X0  ... initial guess
  104. % OPT ... optional variable containing options for the solution
  105. %     ... OPT has to have a structure of [eps,maxiter]
  106. % eps ... optional argument, set precision, default: eps = 1e-4;
  107. % maxiter optional argument, maximal number of iterations,
  108. %         default: maxiter = 20
  109. %
  110. %
  111.  
  112. % basic input check
  113. if nargin < 2
  114.     error('My:Err1','Not enough input arguments')
  115. elseif nargin == 2
  116.     eps     = 1e-4;
  117.     maxiter = 20;
  118. elseif nargin == 3
  119.     eps     = OPT(1);
  120.     maxiter = OPT(2);
  121. else
  122.     error('My:Err2','Too many input arguments')
  123. end
  124.  
  125. if size(feval(FUN,X0),1) ~= numel(X0) || size(feval(FUN,X0),2) ~= 1
  126.     error('My:Err3','FUN has to return a column vector of size N')
  127. end
  128.  
  129. % auxiliary input processing
  130. X0   = reshape(X0,numel(X0),1);                                             %transform X0 to a column vector
  131.  
  132. % define auxiliary variables
  133. k       = 0;                                                                %iteration counter
  134. delta   = eps+1;                                                            %precision check
  135. XOLD    = X0;
  136.  
  137. % write out 0-th iteration
  138. fprintf(1,'k = %03d | Xk = [',k);
  139. for j = 1:numel(XOLD)
  140.     fprintf(1,'%12.3e ',XOLD(j));
  141. end
  142. fprintf(1,'] | delta = %1.3e\n',delta);
  143.  
  144. % calculation cycle itself
  145. while k < maxiter && delta >= eps                                          %goal precision or maxiter not reached
  146.     % calculate the next iteration
  147.     JAC = jacobiM(FUN,XOLD);                                                %get Jacobi matrix at given point
  148.     DX  = JAC\-feval(FUN,XOLD);                                              %get DX
  149.     XNEW= XOLD + DX;                                                        %currently undumped newton
  150.     % precision check
  151.     delta = norm(XNEW-XOLD);                                                %is this OK?
  152. %     delta = norm(feval(FUN,XNEW)-feval(FUN,XOLD));                          %alternative
  153.     % update the solution
  154.     XOLD= XNEW;
  155.     k   = k+1;
  156.     fprintf(1,'k = %03d | Xk = [',k);
  157.     for j = 1:numel(XOLD)
  158.         fprintf(1,'%12.3e ',XOLD(j));
  159.     end
  160.     fprintf(1,'] | delta = %1.3e\n',delta);
  161. end
  162.  
  163. % check the result
  164. if delta < eps
  165.     fprintf(1,'\nCONVERGED\n');
  166. else
  167.     warning('My:Wrng1','Newton did not converge, solution might be inacurate')
  168. end
  169.  
  170. % assign output variables
  171. X   = XOLD;
  172. FVAL= feval(FUN,XOLD);
  173.  
  174. % nested functions - yes, it is a possibility in MATLAB
  175.     function JAC = jacobiM(FUN,X)
  176.     % function that returns a jacobian of a mapping FUN at X
  177.     % FUN is a function handle (passed from newtonM, X is a point
  178.         h   = 1e-3;                                                         %step for numerical derivation
  179.         JAC = zeros(numel(X));                                              %allocate the output matrix
  180.         for i = 1:numel(X)
  181.             e_i      = zeros(numel(X),1);e_i(i) = 1;                        %create a vector of zeros with 1 at i-th place
  182.             JAC(:,i) = (feval(FUN,X+e_i*h) - feval(FUN,X))./h;              %forward calculation of a first derivative
  183.         end
  184.     end
  185. end
  186.  
  187. %% Problem definitions
  188.  
  189. % second equation to be solved (x in R2)
  190. function dxdt = problem2(t,x)                                               %%I do not need to input t -> ~
  191.  
  192. dxdt = zeros(numel(x),1);                                                   %allocate space for output (general)
  193. fi=1;
  194. dxdt(1) = (-2/t)*x(2)+fi^2*x(1);
  195. dxdt(2) = x(2);
  196. %problem specific
  197. end
  198.  
  199. % exact solution to the problem 2
  200. function xExact = exactSol2(t)
  201.  
  202. xExact = zeros(numel(t),2);
  203. fi=1;
  204. % xExact(:,1) = exp(t) - exp(-2*t)./3;
  205. % xExact(:,2) = exp(-t);
  206. xExact(:,1)=1./t .*(exp(t*fi)-exp(-t*fi))/(exp(fi)-exp(-fi));
  207. xExact(:,2)=1./t .*(exp(t*fi)-exp(-t*fi))/(exp(fi)-exp(-fi));
  208. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement