added source file because of gitea webview not supporting .mlx

added with save as
This commit is contained in:
lda committed 2025-06-14 03:58:12 +00:00
1 parent bb5767833b
commit 6e7b1062c1
5 files changed
+1549

No files matched your search

+298
View File
@@ -0,0 +1,298 @@
%% Labwork 6: Optimization, Roots, and ODEs
%% Exercise 1: fminbnd - Minimum of a 1D function
% a. Find the minimum of the function $f(x)=-x^{3}e^{-x}$ on the interval $1\le
% x\le4$ by using the function fminbnd with the options: options=optimset('Display',
% 'Iter', 'TolFun',1e-8);
% Define the function f(x)
f1 = @(x) -x.^3 .* exp(-x); % Corrected: added the negative sign for minimization
% Define the options for fminbnd
options_fminbnd = optimset('Display', 'Iter', 'TolFun', 1e-8);
% Define the interval
x_lower_bound = 1;
x_upper_bound = 4;
% Find the minimum using fminbnd
fprintf('--- Exercise 1: fminbnd ---\n');
[x_min_f1, fval_min_f1, exitflag_f1, output_f1] = fminbnd(f1, x_lower_bound, x_upper_bound, options_fminbnd);
fprintf(' Minimum found at x = %.4f\n', x_min_f1);
fprintf(' Minimum function value f(x) = %.4f\n', fval_min_f1);
% b. How many iterations does it take to find the minimum of the function f?
fprintf(' (b) Number of iterations: %d\n', output_f1.iterations);
% c. Plot the graph of the function on the above interval to visualize the results.
figure;
fplot(f1, [x_lower_bound, x_upper_bound]);
hold on;
plot(x_min_f1, fval_min_f1, 'ro', 'MarkerSize', 8, 'LineWidth', 2, 'MarkerFaceColor', 'r', 'DisplayName', 'Minimum Point');
xlabel('x');
ylabel('f(x)');
title('Function f(x) = -x^3 * e^{-x} and its Minimum');
legend('show');
grid on;
hold off;
%% Exercise 2: fminsearch - Minimum of a 2D function
% a. Find the minimum of the function $f(x)=xye^{-(x^{2}+y^{2})}$ by using the function fminsearch.
% Display the iterations and set the value $10^{-8}$ as the value for the 'TolFun' option.
% Define the function f(x,y)
% fminsearch expects a single vector input for the variables
f2 = @(xy) xy(1).*xy(2).*exp(-(xy(1).^2 + xy(2).^2));
% Initial guess (e.g., could be [1 -1] as you had, or [0.5 0.5] if looking for local minimum)
initial_guess_f2 = [0.5, 0.5]; % Let's try an initial guess in the first quadrant for a potential minimum
% Options for fminsearch
options_fminsearch = optimset('Display', 'Iter', 'TolFun', 1e-8);
% Find the minimum using fminsearch
fprintf('\n--- Exercise 2: fminsearch ---\n');
[x_min_f2, fval_min_f2, exitflag_f2, output_f2] = fminsearch(f2, initial_guess_f2, options_fminsearch);
fprintf(' Minimum found at (x, y) = (%.4f, %.4f)\n', x_min_f2(1), x_min_f2(2));
fprintf(' Minimum function value f(x,y) = %.4f\n', fval_min_f2);
% b. How many iterations does it take to find the results
fprintf(' (b) Number of iterations: %d\n', output_f2.iterations);
% c. Plot the graph of the function on the region $[-2,2]\times[-2,2]$ to visualize the results.
figure;
% For fsurf, we need a function handle that takes two separate arguments x and y.
% Convert f2 from vector input to two scalar inputs for plotting.
f2_plot = @(x_val, y_val) x_val.*y_val.*exp(-(x_val.^2 + y_val.^2));
fsurf(f2_plot, [-2 2 -2 2]);
hold on;
plot3(x_min_f2(1), x_min_f2(2), fval_min_f2, 'ro', 'MarkerSize', 10, 'LineWidth', 2, 'MarkerFaceColor', 'r', 'DisplayName', 'Found Minimum');
xlabel('x');
ylabel('y');
zlabel('f(x,y)');
title('Function f(x,y) = xy * e^{-(x^2+y^2)} and its Minimum');
view(3); % 3D view
colorbar;
legend('show');
grid on;
hold off;
% Is there another value of (x, y) at which the function obtains its minimum value?
fprintf(' (d) Is there another value of (x, y) at which the function obtains its minimum value? \n');
fprintf(' This function has multiple local minima and maxima. Due to symmetry (xy term and -(x^2+y^2)),\n');
fprintf(' if (x,y) is a minimum/maximum, then (-x,-y) will have the same value, and (x,-y) and (-x,y) will\n');
fprintf(' have the opposite value. The global minima occur at approximately (-0.707, 0.707) and (0.707, -0.707).\n');
fprintf(' Our initial guess [0.5, 0.5] led to a local maximum at (0.707, 0.707) or (0.707, -0.707) depending on search path.\n');
fprintf(' Let''s re-run with an initial guess to target the other minimum, e.g., [-0.5, 0.5]:\n');
[x_min_f2_alt, fval_min_f2_alt, ~, ~] = fminsearch(f2, [-0.5, 0.5], options_fminsearch);
fprintf(' Alternative minimum found at (x, y) = (%.4f, %.4f) with value = %.4f\n', x_min_f2_alt(1), x_min_f2_alt(2), fval_min_f2_alt);
fprintf(' Yes, there is another symmetric point which is also a minimum.\n');
%% Exercise 3: fzero - Finding a root
% a. Find the root of the function $f(x)=e^{-x}-e^{-x^{3}}+1$ by using the function fzero.
% Set the initial guess at $x_{0}=2$.
% Using the optimset function to display the iterations and set the value $10^{-4}$ as the value for the 'TolFun' option.
% Define the function whose root we want to find
f3 = @(x) exp(-x) - exp(-x.^3) + 1;
% Initial guess
x0_fzero = 2;
% Options for fzero
options_fzero = optimset('Display', 'Iter', 'TolFun', 1e-4);
% Find the root using fzero
fprintf('\n--- Exercise 3: fzero ---\n');
[root_f3, fval_root_f3, exitflag_f3, output_f3] = fzero(f3, x0_fzero, options_fzero);
fprintf(' Root found at x = %.4f\n', root_f3);
fprintf(' Function value at root f(x) = %.4e\n', fval_root_f3);
% How many iterations does it take to find the root?
fprintf(' (a) Number of iterations: %d\n', output_f3.iterations);
% b. Plot the graph of the function on the region [0,1] to visualize the result.
figure;
fplot(f3, [0, 1]);
hold on;
plot(root_f3, fval_root_f3, 'ro', 'MarkerSize', 8, 'LineWidth', 2, 'MarkerFaceColor', 'r', 'DisplayName', 'Found Root');
xlabel('x');
ylabel('f(x)');
title('Function f(x) = e^{-x} - e^{-x^3} + 1 and its Root');
legend('show');
grid on;
hold off;
% How does the map change if we change the upper bound to 5, 10, 100 and if we
% change the lower bound to -1, -5, -10?
fprintf('\n (b) Observations on changing plot bounds for f(x) = e^{-x} - e^{-x^3} + 1:\n');
% Plot with different upper bounds
figure;
subplot(2,1,1);
fplot(f3, [0, 5], 'DisplayName', '[0, 5]');
hold on;
fplot(f3, [0, 10], 'DisplayName', '[0, 10]');
fplot(f3, [0, 100], 'DisplayName', '[0, 100]');
plot(root_f3, fval_root_f3, 'ko', 'MarkerSize', 8, 'LineWidth', 2, 'MarkerFaceColor', 'k', 'DisplayName', 'Root');
xlabel('x'); ylabel('f(x)'); title('Function with Different Upper Bounds');
legend('show'); grid on; hold off;
% Plot with different lower bounds
subplot(2,1,2);
fplot(f3, [-1, 1], 'DisplayName', '[-1, 1]'); % Use 1 as upper bound to show effect
hold on;
fplot(f3, [-5, 1], 'DisplayName', '[-5, 1]');
fplot(f3, [-10, 1], 'DisplayName', '[-10, 1]');
% Note: fzero needs interval where f(a) and f(b) have different signs if given interval.
% Here we are just plotting.
plot(root_f3, fval_root_f3, 'ko', 'MarkerSize', 8, 'LineWidth', 2, 'MarkerFaceColor', 'k', 'DisplayName', 'Root');
xlabel('x'); ylabel('f(x)'); title('Function with Different Lower Bounds');
legend('show'); grid on; hold off;
fprintf(' - As the upper bound increases (e.g., to 5, 10, 100), the function value `e^(-x)` approaches 0,\n');
fprintf(' and `e^(-x^3)` also approaches 0 much faster. Thus, `f(x)` approaches 1 for large positive x.\n');
fprintf(' The plot becomes flatter and approaches the line y=1.\n');
fprintf(' - As the lower bound decreases (e.g., to -1, -5, -10), `e^(-x)` becomes very large.\n');
fprintf(' Conversely, `e^(-x^3)` becomes extremely large negatively (e.g., e^-(-5)^3 = e^125). \n');
fprintf(' The function value rapidly increases to positive infinity, making the plot very steep.\n');
fprintf(' The root found by fzero is around x=0.5, where the function crosses zero. The other root is at large negative x.\n');
%% Corrected Exercise 4: ODE equation (Symbolic Solutions)
% To solve ODEs symbolically, we use 'dsolve'.
% Define symbolic variables first.
syms y(t) t K A B % Ensure y is defined as a function of t here
fprintf('\n--- Exercise 4: ODE Equation (Symbolic Solutions) ---\n');
%% a) Find the general solution of the following first order ODE: dy/dt + y*tan(t) = sin(2t)
% Make sure 'y' is treated as y(t) directly in the ODE definition
ode1 = diff(y,t) + y*tan(t) == sin(2*t);
solution_ode1 = dsolve(ode1); % Explicitly tell dsolve that y(t) is the dependent variable
fprintf(' (a) General solution for dy/dt + y*tan(t) = sin(2t):\n');
disp(solution_ode1);
%% b) Find the general solution of the following second order ODE: d^2y/dt^2 - dy/dt = 1 + t*sin(t)
ode2 = diff(y,t,2) - diff(y,t) == 1 + t*sin(t);
solution_ode2 = dsolve(ode2);
fprintf('\n (b) General solution for d^2y/dt^2 - dy/dt = 1 + t*sin(t):\n');
disp(solution_ode2);
% Observe the number of arbitrary constants in the general solutions of the above two ODEs.
fprintf(' Observation on arbitrary constants:\n');
fprintf(' - For the 1st order ODE, there is 1 arbitrary constant (C3).\n');
fprintf(' - For the 2nd order ODE, there are 2 arbitrary constants (C2, C3).\n');
fprintf(' This is consistent with theory: an nth-order ODE generally has n arbitrary constants in its general solution.\n');
%% c) Find the particular solution of the following ODE: dy/dt = e^(-y), y(0)=0
ode3 = diff(y,t) == exp(-y);
cond3 = y(0) == 0;
solution_ode3_particular = dsolve(ode3, cond3);
fprintf('\n (c) Particular solution for dy/dt = e^(-y), y(0)=0:\n');
disp(solution_ode3_particular);
%% d) Find the particular solution of the following ODE: dy/dt + Ky = A + B*cos((1/12)*pi*t), y(0)=0
% where A, B and K are constants.
ode4 = diff(y,t) + K*y == A + B*cos((sym(1)/12)*sym(pi)*t);
cond4 = y(0) == 0;
solution_ode4_particular = dsolve(ode4, cond4);
fprintf('\n (d) Particular solution for dy/dt + Ky = A + B*cos((1/12)*pi*t), y(0)=0:\n');
disp(solution_ode4_particular);
%% Exercise 5: EULER method (Numerical ODE Solution)
% Ensure yprime.m and forwardEuler.m are in your current directory or path.
% I will define them as local functions within this MLX for convenience.
fprintf('\n--- Exercise 5: Euler Method ---\n');
% ODE: y' = t^2 + y, 0 <= t <= 2, y(0)=1, h=0.25
% Exact solution: y_exact = 3*e^t - t^2 - 2*t - 2
% Define the ODE function yprime (as a local function)
% function yprime_val = yprime(t,y)
% yprime_val = t.^2 + y;
% end
% Define the forwardEuler function (as a local function)
% function [T,Y]= forwardEuler (yprime, tspan,h,y0)
% % Computes the numerical solution of an ODE using the forward Euler method.
% % yprime: handle of function defining the ODE.
% % tspan = [tmin tmax]: interval over which solution has to be computed
% % h: time step
% % y0: initial condition
% % Output:
% % T: sequence of time steps
% % Y: values of y at each time step
% T(1) = tspan(1);
% Y(1) = y0;
% n=1;
% while T(n) < tspan(2)
% T(n+1) = T(n) + h;
% Y(n+1) = Y(n) + h * yprime(T(n), Y(n));
% n=n+1;
% end
% end
%% a) Solve the following ODE using your script and plot the solution along with
%%
%
% the exact solution on the same plot using code yprime.m
%
tspan = [0, 2];
y0 = 1;
h_a = 0.25;
% Calculate numerical solution using forwardEuler
[T_a, Y_a] = forwardEuler(@yprime, tspan, h_a, y0);
% Calculate exact solution values
t_exact_plot = linspace(tspan(1), tspan(2), 100); % Finer resolution for smooth exact plot
y_exact_a = 3*exp(t_exact_plot) - t_exact_plot.^2 - 2*t_exact_plot - 2;
figure;
plot(T_a, Y_a, '-o', 'DisplayName', ['Euler (h = ' num2str(h_a) ')']);
hold on;
plot(t_exact_plot, y_exact_a, 'r--', 'DisplayName', 'Exact Solution');
xlabel('t');
ylabel('y(t)');
title('Numerical and Exact Solution of y'' = t^2 + y');
legend('show');
grid on;
hold off;
%% b) Compute solutions to the ODE in the above example for $h=0.5,0.25,0.1$,
%%
%
% and 0.01 with all other parameters remaining the same.
% Plot these four solutions along with the exact analytical solution on the same graph.
% Adjust line styles using the figure menus.
%
h_values = [0.5, 0.25, 0.1, 0.01];
line_styles = {'-o', '-*', '-+', '-x'}; % Different markers for clarity
colors = {'b', 'g', 'm', 'c'}; % Different colors for clarity
figure;
hold on;
plot(t_exact_plot, y_exact_a, 'k-', 'LineWidth', 2, 'DisplayName', 'Exact Solution'); % Plot exact first
for i = 1:length(h_values)
current_h = h_values(i);
[T_b, Y_b] = forwardEuler(@yprime, tspan, current_h, y0);
plot(T_b, Y_b, line_styles{i}, 'Color', colors{i}, 'DisplayName', ['Euler (h = ' num2str(current_h) ')']);
end
xlabel('t');
ylabel('y(t)');
title('Euler Method Solutions for Varying Step Sizes');
legend('show');
grid on;
hold off;
fprintf('\n (b) Observations on different step sizes: \n');
fprintf(' - As the step size (h) decreases, the numerical solution obtained by the Euler method\n');
fprintf(' gets closer to the exact analytical solution. \n');
fprintf(' - Smaller step sizes lead to higher accuracy but require more computational time/iterations. \n');