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

+252
View File
@@ -0,0 +1,252 @@
%% I. Matlab Introduction
%% 1. Vector
% Exercise 1
x = [1, 2, 3, 4, 5];
result1 = x(3) + x(2)
% Exercise 2
x_col = [1; 2; 3; 4; 5];
x_transposed = x_col'
% Exercise 3
a_sum = sum(1:100)
% Exercise 4
syms x y
f = x + y;
f_val = subs(f, [x, y], [1, 2])
% Exercise 5
% a) sum from 1 to 10
syms n
s1 = symsum(n, n, 1, 10)
% b) sum of n^2 from 1 to 5
s2 = symsum(n^2, n, 1, 5)
%% 2. Matrix
% Exercise 1a
% Define element by element
A1 = [0 0 0; 0 0 0; 0 0 0];
% Define using zeros
A2 = zeros(3,3);
% Exercise 1b
A = zeros(3);
A = A + diag([1 1 1])
% Exercise 1c
B = A'
% Exercise 1d
add = A + B
sub = A - B
mul_matrix = A * B
mul_elem = A .* B
% Remark: A*B is matrix multiplication, A.*B is element-wise
% Exercise 1e
A2x2 = A;
A2x2(3,:) = [];
A2x2(:,3) = [];
A2x2
B2x2 = B;
B2x2(1,:) = [];
B2x2(:,1) = [];
B2x2
% Exercise 1f
A(1:3)
A(1:3,1)
A(:,1)
%% 3. Function
% Exercise 1
function m = mean_vector(v)
m = sum(v)/length(v);
end
% Application
x = 1:3:100;
m_val = mean_vector(x)
% Exercise 2
function roots = quadratic_solver(a, b, c)
D = b^2 - 4*a*c;
roots = [(-b + sqrt(D))/(2*a), (-b - sqrt(D))/(2*a)];
end
% Application
roots_val = quadratic_solver(1, 2, -3)
%% 4. If else structure
% Exercise 1
n = 5;
if n > 1
m = n + 1;
else
m = n - 1;
end
m
n = -5;
if n > 1
m = n + 1;
else
m = n - 1;
end
m
% Exercise 2
x = 5;
if x > 0 && x < 10
y = 4*x;
elseif x > 10 && x < 40
y = 10*x;
elseif x > 40 || x < 0
y = x;
end
y
x = -5;
if x > 0 && x < 10
y = 4*x;
elseif x > 10 && x < 40
y = 10*x;
elseif x > 40 || x < 0
y = x;
end
y
x = 20;
if x > 0 && x < 10
y = 4*x;
elseif x > 10 && x < 40
y = 10*x;
elseif x > 40 || x < 0
y = x;
end
y
% Exercise 3: Electricity bill
kWh = 350;
price = 0; % cant even initialize bru
if kWh > 400
price = (kWh-400)*2.587 + 100*2.503 + 100*2.242 + 100*1.786 + 50*1.533 + 50*1.484;
elseif kWh > 300
price = (kWh-300)*2.503 + 100*2.242 + 100*1.786 + 50*1.533 + 50*1.484;
elseif kWh > 200
price = (kWh-200)*2.242 + 100*1.786 + 50*1.533 + 50*1.484;
elseif kWh > 100
price = (kWh-100)*1.786 + 50*1.533 + 50*1.484;
elseif kWh > 50
price = (kWh-50)*1.533 + 50*1.484;
else
price = kWh * 1.484;
end
price
%% 5. For loop
% Exercise 1a: sum of squares
sum_sq = 0;
for i = 1:1000
sum_sq = sum_sq + i^2;
end
sum_sq
% Exercise 1b: 20!
fact = 1;
for i = 1:20
fact = fact * i;
end
fact
% Exercise 1c: Series
sum_alt = 0;
for i = 1:2:1003
sum_alt = sum_alt + ((-1)^((i-1)/2)) * (1/i);
end
sum_alt
% Exercise 1d: π approximation
sum_pi = 0;
for k = 1:1000
sum_pi = sum_pi + 1/((2*k-1)^2);
end
pi_squared_over_8 = sum_pi
approx_pi = sqrt(8 * sum_pi)
% Exercise 2a: Combination function
function c = combination(n, k)
c = factorial(n)/(factorial(k)*factorial(n-k));
end
comb_val = combination(5, 3)
% Exercise 2b: Permutation function
function p = permutation(n, k)
p = factorial(n)/factorial(n-k);
end
perm_val = permutation(5, 3)
%% 6. While loop
% Exercise 1a: Count numbers from 1 to N
N = 5;
i = 1;
while i <= N
disp(i)
i = i + 1;
end
% Exercise 1b: Count odd numbers from 1 to N
i = 1;
while i <= N
if mod(i,2) == 1
disp(i)
end
i = i + 1;
end
% Exercise 2: Sum sqrt(2i-1) until > 20
i = 1;
S = 0;
while S <= 20
S = S + sqrt(2*i - 1);
i = i + 1;
end
S
i
% Exercise 3: Doubling investment
investment = 1;
years = 0;
while investment < 2
investment = investment * 1.1;
years = years + 1;
end
years
%% 7. Graphics
% Exercise 1a: Linear plot
x = linspace(-5,5,100);
y1 = x + 1;
plot(x, y1)
% Exercise 1b: Line style and color
plot(x, y1, '--r')
% Exercise 1c: Plot second function
hold on
y2 = -x + 2;
plot(x, y2, ':b')
hold off
% Exercise 1d: Add title and labels
title('Linear Functions')
xlabel('x')
ylabel('y')
legend('y = x+1', 'y = -x+2')
+127
View File
@@ -0,0 +1,127 @@
%% I. MATLAB FUNCTION
%% 1. Solve / fzero
% (a) Exact solution: 67x + 32 = 0
syms x
sol_exact = solve(67*x + 32 == 0, x)
% (b) Numerical solution to 15 places
format long
f = @(x) 67*x + 32;
sol_numeric = fzero(f, -1)
% (c) x^3 + p*x + q = 0
syms x p q
sol_cubic = solve(x^3 + p*x + q == 0, x)
% (d) e^x = 8x - 4
syms x
eqn = exp(x) == 8*x - 4;
% Plotting to identify real solutions
fplot(@(x) exp(x), [-2, 2]); hold on;
fplot(@(x) 8*x - 4, [-2, 2]);
legend('e^x','8x-4');
grid on;
title('Graph of e^x and 8x-4 to visualize intersection points');
% Solving numerically
f = @(x) exp(x) - (8*x - 4);
sol1 = fzero(f, 0) % Guess from plot
%% 2. Plot
% (a) y = x^3 - x for x in [-4, 4]
x = linspace(-4, 4, 1000);
y = x.^3 - x;
figure
plot(x, y); grid on; title('y = x^3 - x');
% (b) y = tan(x/2) for x in [-pi, pi], clip y in [-10, 10]
x = linspace(-pi, pi, 1000);
y = tan(x/2);
figure
plot(x, y);
axis([-pi pi -10 10]);
title('y = tan(x/2)');
% (c) y1 = e^(-x/2), y2 = x^4 - x^2 for x in [-1.5, 1.5]
x = linspace(-1.5, 1.5, 1000);
y1 = exp(-x/2);
y2 = x.^4 - x.^2;
figure
plot(x, y1, 'b', x, y2, 'r--');
legend('e^{-x/2}', 'x^4 - x^2');
title('Overlay of two functions');
%% II. MATLAB NUMERICAL METHODS
%% 1. Bisection Method
% Function file already given above as bisection.m
% Exercise 1: sqrt(2), f(x) = x^2 - 2
f = @(x) x^2 - 2;
[root1, fx1, ea1, iter1] = bisection(f, 1, 2, 0.05)
% Exercise 2: ln(x^2) = 0.7 --> f(x) = log(x^2) - 0.7
f = @(x) log(x^2) - 0.7;
[root2, fx2, ea2, iter2] = bisection(f, 0.5, 2, 100, 3)
% Exercise 3: x^2 + 2x - 3 = 0
f = @(x) x^2 + 2*x - 3;
[root3, fx3, ea3, iter3] = bisection(f, 0, 2)
%% 2. Newton-Raphson Method
% f.m file
% function y = f(x)
% y = x^3 + x - 3;
% df.m file
% function y = df(x)
% y = 3*x^2 + 1;
% Exercise 1: Solve x^3 + x - 3 = 0
f = @(x) x^3 + x - 3;
df = @(x) 3*x^2 + 1;
x0 = 1; tol = 1e-8; max_iter = 20;
x = x0;
for i = 1:max_iter
x_new = x - f(x)/df(x);
err = abs((x_new - x)/x_new);
x = x_new;
fprintf('Iter %d: x = %.15f, f(x) = %.15f\n', i, x, f(x));
if err < tol
break
end
end
% Exercise 2: f(x) = x^10 - 1, x0 = 0.5
f = @(x) x^10 - 1;
df = @(x) 10*x^9;
x = 0.5;
X_history = x;
for i = 1:20
x_new = x - f(x)/df(x);
X_history(end+1) = x_new;
if abs((x_new - x)/x_new) < 1e-8
break
end
x = x_new;
end
fprintf('Final approx root: %.15f\n', x);
% Plot convergence
figure;
plot(0:length(X_history)-1, X_history, '-o');
xlabel('Iteration');
ylabel('x');
title('Newton-Raphson convergence for x^{10} - 1');
% Exercise 3: Solve x^2 + 2x - 3 = 0
f = @(x) x^2 + 2*x - 3;
df = @(x) 2*x + 2;
x = 1;
for i = 1:20
x_new = x - f(x)/df(x);
fprintf('Iter %d: x = %.10f, f(x) = %.10f\n', i, x_new, f(x_new));
if abs((x_new - x)/x_new) < 1e-8
break
end
x = x_new;
end
+438
View File
@@ -0,0 +1,438 @@
%% Labwork 3: Solving Linear Systems
%% V. Gauss Elimination
%% Exercise 1: Solve the system of linear equations:
%%
%
% 3x1 + 2x2 = 18
% -x1 + 2x2 = 2
%
% a) Graphical Method
% (As the graph is provided in the lab, this part focuses on creating the plot in MATLAB)
% Define the equations as functions to plot
eq1 = @(x1) (18 - 3*x1) / 2;
eq2 = @(x1) (2 + x1) / 2;
% Create the x1 vector for plotting
x1_vals = 0:0.1:6; % Range of x1 values
% Calculate the corresponding x2 values
x2_eq1 = eq1(x1_vals);
x2_eq2 = eq2(x1_vals);
% Plot the equations
figure; % Create a new figure
plot(x1_vals, x2_eq1, 'b-', 'LineWidth', 2); % Plot the first equation (blue line)
hold on; % Hold the current plot to add the second equation
plot(x1_vals, x2_eq2, 'r-', 'LineWidth', 2); % Plot the second equation (red line)
% Add labels and title
xlabel('x1');
ylabel('x2');
title('Graphical Solution of Linear Equations');
legend('3x1 + 2x2 = 18', '-x1 + 2x2 = 2');
axis([0 6 0 9]); % Set the axis limits to match the lab's graph
grid on; % Add grid lines
hold off; % Release the plot hold
% Mark the solution point (x1=4, x2=3) as given in the lab
plot(4, 3, 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k'); % Black circle for the solution
text(4.2, 3.2, 'Solution: (4, 3)'); % Label the solution
% b) Naive Gauss Elimination Method
% (Code provided in the lab)
function x = GaussNaive(A, b)
% GaussNaive: naive Gauss elimination
% x = GaussNaive(A, b): Gauss elimination without pivoting.
% input:
% A = coefficient matrix
% b = right hand side vector
% output:
% x = solution vector
[m, n] = size(A);
if m ~= n, error('Matrix A must be square'); end
nb = n + 1;
Aug = [A b]; % Augmented matrix
% forward elimination
for k = 1:n-1
for i = k+1:n
factor = Aug(i, k) / Aug(k, k);
Aug(i, k:nb) = Aug(i, k:nb) - factor * Aug(k, k:nb);
end
end
% back substitution
x = zeros(n, 1);
x(n) = Aug(n, nb) / Aug(n, n);
for i = n-1:-1:1
x(i) = (Aug(i, nb) - Aug(i, i+1:n) * x(i+1:n)) / Aug(i, i);
end
end
% Define the coefficient matrix A and the right-hand side vector b
A = [3 2; -1 2];
b = [18; 2];
% Solve using the GaussNaive function
x_naive = GaussNaive(A, b)
%% Exercise 2: Solve the system of linear equations:
%%
%
% 2x + y - z = 8
% -3x - y + 2z = -11
% -2x + y + 2z = -3
%
% a) Using inv or mldivide in Matlab
% Define the coefficient matrix A and the right-hand side vector b
A = [2 1 -1; -3 -1 2; -2 1 2];
b = [8; -11; -3];
% Solve using inv
x_inv = inv(A) * b
% Solve using mldivide (backslash operator \) - RECOMMENDED
x_mldivide = A \ b
% b) Use the function GaussPivot.m
% (Code provided in the lab)
function x = GaussPivot(A, b)
% GaussPivot: Gauss elimination pivoting
% x = GaussPivot(A, b): Gauss elimination with pivoting.
% input:
% A = coefficient matrix
% b = right hand side vector
% output:
% x = solution vector
[m, n] = size(A);
if m ~= n, error('Matrix A must be square'); end
nb = n + 1;
Aug = [A b];
% forward elimination
for k = 1:n-1
% partial pivoting
[big, i] = max(abs(Aug(k:n, k)));
ipr = i + k - 1;
if ipr ~= k
Aug([k, ipr], :) = Aug([ipr, k], :);
end
for i = k+1:n
factor = Aug(i, k) / Aug(k, k);
Aug(i, k:nb) = Aug(i, k:nb) - factor * Aug(k, k:nb);
end
end
% back substitution
x = zeros(n, 1);
x(n) = Aug(n, nb) / Aug(n, n);
for i = n-1:-1:1
x(i) = (Aug(i, nb) - Aug(i, i+1:n) * x(i+1:n)) / Aug(i, i);
end
end
% Solve using GaussPivot
x_pivot = GaussPivot(A, b)
% c) Modify the code above to Gauss Elimination without Pivoting
function x = GaussNaive_modified(A, b)
% GaussNaive_modified: Gauss elimination without pivoting (modified from GaussPivot).
% input:
% A = coefficient matrix
% b = right hand side vector
% output:
% x = solution vector
[m, n] = size(A);
if m ~= n, error('Matrix A must be square'); end
nb = n + 1;
Aug = [A b];
% forward elimination (WITHOUT PIVOTING)
for k = 1:n-1
for i = k+1:n
factor = Aug(i, k) / Aug(k, k);
Aug(i, k:nb) = Aug(i, k:nb) - factor * Aug(k, k:nb);
end
end
% back substitution
x = zeros(n, 1);
x(n) = Aug(n, nb) / Aug(n, n);
for i = n-1:-1:1
x(i) = (Aug(i, nb) - Aug(i, i+1:n) * x(i+1:n)) / Aug(i, i);
end
end
% Solve using GaussNaive_modified
x_naive_mod = GaussNaive_modified(A, b)
% d) Explain the code
% (Explanation embedded in the comments within the code above)
%% VI. LU Decomposition
%% Exercise 3: LU decomposition
%%
%
% 2x + y - z = 8
% -3x - y + 2z = -11
% -2x + y + 2z = -3
%
% a) Using function lu in Matlab
% Define A and b (same as before)
A = [2 1 -1; -3 -1 2; -2 1 2];
b = [8; -11; -3];
% Perform LU decomposition
[L, U, P] = lu(A);
% Solve Ly = Pb
y = L \ (P * b);
% Solve Ux = y
x_lu_matlab = U \ y
% b) Use the function LU_pivot.m code
% (Code provided in the lab)
function [L, U, P] = LU_pivot(A)
% LU_pivot: LU decomposition with pivoting
[n, ~] = size(A);
L = eye(n);
P = eye(n);
U = A;
for j = 1:n
[pivot, m] = max(abs(U(j:n, j)));
m = m + j - 1;
if m ~= j
U([m, j], :) = U([j, m], :); % interchange rows m and j in U
P([m, j], :) = P([j, m], :); % interchange rows m and j in P
if j >= 2
L([m, j], 1:j-1) = L([j, m], 1:j-1); % interchange rows m and j in columns 1:j-1 of L
end
end
for i = j+1:n
L(i, j) = U(i, j) / U(j, j);
U(i, :) = U(i, :) - L(i, j) * U(j, :);
end
end
end
% Perform LU decomposition using LU_pivot
[L_pivot, U_pivot, P_pivot] = LU_pivot(A);
% Solve Ly = Pb
y_pivot = L_pivot \ (P_pivot * b);
% Solve Ux = y
x_lu_pivot = U_pivot \ y_pivot
% c) Change the code of LU with pivoting in LU_pivot.m to LU non-pivoting code
function [L, U] = LU_nopivot(A)
% LU_nopivot: LU decomposition without pivoting
[n, ~] = size(A);
L = eye(n);
U = A;
for j = 1:n
for i = j+1:n
L(i, j) = U(i, j) / U(j, j);
U(i, :) = U(i, :) - L(i, j) * U(j, :);
end
end
end
% Perform LU decomposition without pivoting
[L_nopivot, U_nopivot] = LU_nopivot(A);
% Solve Ly = b
y_nopivot = L_nopivot \ b; % No pivoting, so use original b
% Solve Ux = y
x_lu_nopivot = U_nopivot \ y_nopivot
% d) Comparison and explain the difference between LU_pivot.m and mylup.m code:
% (Explanation provided as comments below)
function [L, U, P] = mylup(A)
% MYLUP LU DECOMPOSITION WITH PIVOTING
[n, m] = size(A);
C = zeros(n, n+1);
% initialize
C(1:n, 1:n) = A;
C(1:n, n+1) = (1:n)';
% main algorithm
for j = 1:n-1
if (sum(C(1:n, j)) == 0)
error('mylup:input', 'The solution is not determined.');
end
[~, i] = max(abs(C(1:n, j)));
if (i ~= j)
tt = C(i, 1:n+1);
C(i, 1:n+1) = C(j, 1:n+1);
C(j, 1:n+1) = tt;
end
for i = j+1:n
t = C(i, j) / C(j, j);
C(i, j) = t;
C(i, j+1:n) = C(i, j+1:n) - t * C(j, j+1:n);
end
end
% refine the results
PP = C(1:n, n+1);
Z = C(1:n, 1:n);
L = tril(C, -1);
U = triu(C);
P = zeros(n, n);
for i = 1:n
L(i, i) = 1;
P(i, PP(i)) = 1;
end
end
% Differences between LU_pivot.m and mylup.m:
% - LU_pivot.m is more straightforward, directly manipulating U, L, and P.
% - mylup.m uses an augmented matrix C to keep track of row permutations,
% which can be less intuitive but might be optimized for certain implementations.
% - Both achieve the same goal: LU decomposition with partial pivoting.
% - mylup.m includes a check for a column of zeros, raising an error if found.
%% VII. Common
%% Exercise 1: Create a vector x that:
%%
%
% - is a column vector
% - has all integer value elements from 1 to 20 respectively from the top.
%
% Create the column vector x
x = (1:20)'; % Or x = [1:20]';
% a) Create a vector y that has the same length and size as x's but all entries is 1.
% Create the vector y
y = ones(size(x));
% b) Calculate vector z that is the sum of x and y
% Calculate the vector z
z = x + y;
% c) Calculate the dot product between x and y
% Calculate the dot product
dot_product_xy = dot(x, y); % Or sum(x .* y);
% d) Increment the first, the 5th, the 16th and the last element of z by 3
% Increment the specified elements
z([1, 5, 16, end]) = z([1, 5, 16, end]) + 3;
% e) After step d, multiply those elements with 6.
% Multiply the incremented elements by 6
z([1, 5, 16, end]) = z([1, 5, 16, end]) * 6;
%% Exercise 2: Create a matrix A that:
%%
%
% - has size of 3*3
% - all the entries is 1
%
% Create the matrix A
A = ones(3, 3);
% a) Create matrix b that is transpose of A
% Create the matrix B
B = A'; % Or B = transpose(A); Since A is all ones, A' == A, but this is the general way
% b) Compute sum of A and B
% Compute the sum of A and B
sum_AB = A + B;
% c) Compute A*B and B*A
% Compute A * B and B * A
AB = A * B;
BA = B * A;
% d) Increment all the elements of A by 2.
% Increment all elements of A
A = A + 2;
%% Exercise 3: Give a MATLAB expression that multiplies two vectors to obtain:
% (a) the matrix
% 1 2 3 4 5
% 1 2 3 4 5
% 1 2 3 4 5
% Create the vectors to produce the matrix
vec1a = ones(3, 1);
vec2a = 1:5;
% Matrix (a)
matrix_a = vec1a * vec2a;
% (b) the matrix
% 0 0 0
% 1 1 1
% 2 2 2
% 3 3 3
% 4 4 4
% Create the vectors to produce the matrix
vec1b = (0:4)';
vec2b = ones(1, 3);
% Matrix (b)
matrix_b = vec1b * vec2b;
%% Exercise 4: Create filled 2-D patches
% a) Create matrices x and y.
% Then plot the filled region in red as the figure below using fill in Matlab.
% Define the x and y coordinates for the patches
x_red1 = [0 4 0];
y_red1 = [4 2 2];
x_red2 = [2 4 2];
y_red2 = [0 0 1];
% Create the plot
figure;
fill(x_red1, y_red1, 'c');
hold on;
fill(x_red2, y_red2, 'y');
hold off;
% Add labels and title
xlabel('x');
ylabel('y');
title('Filled 2D Patches');
+434
View File
@@ -0,0 +1,434 @@
%% Labwork 5: Linear Programming, Numerical Integration, Symbolic Math, Numerical Differentiation
%% 1. Linear Programming
%% Exercise 1: Gas Processing Plant Maximization Problem
% (a) Develop a linear programming formulation to maximize the profits for this operation.
% Let x1 = quantity of regular gas produced (in tons)
% Let x2 = quantity of premium gas produced (in tons)
% Objective Function (Maximize Profit):
% Max P = 150*x1 + 175*x2
% Constraints:
% 1. Raw Gas Constraint: 7*x1 + 11*x2 <= 77 (m^3/week)
% 2. Production Time Constraint: 10*x1 + 8*x2 <= 80 (hr/week)
% 3. Regular Gas Storage Constraint: x1 <= 9 (tons)
% 4. Premium Gas Storage Constraint: x2 <= 6 (tons)
% 5. Non-negativity Constraints: x1 >= 0, x2 >= 0
% (b) Minimization of the problem above using function: linprog in Matlab
% linprog solves minimization problems: min (f'*x) such that A*x <= b, Aeq*x = beq, lb <= x <= ub
% To convert our maximization problem (Max P = 150*x1 + 175*x2) to minimization:
% Min -P = -(150*x1 + 175*x2)
f = [-150; -175]; % Coefficients of the objective function for minimization
% Inequality constraints (A*x <= b)
A = [7 11; % Raw gas
10 8]; % Production time
b = [77; 80]; % Resource availability
% No equality constraints (Aeq, beq are empty or not used)
Aeq = [];
beq = [];
% Lower bounds (lb) and Upper bounds (ub) for x1 and x2
lb = [0; 0]; % Non-negativity constraints
ub = [9; 6]; % Storage constraints (x1 <= 9, x2 <= 6)
% Solve the linear programming problem
options = optimoptions('linprog', 'Display', 'off'); % Suppress iteration display
[x_opt, fval_opt, exitflag, output] = linprog(f, A, b, Aeq, beq, lb, ub, options);
fprintf('--- 1. Linear Programming (linprog) ---\n');
fprintf(' Optimal production of Regular Gas (x1): %.4f tons\n', x_opt(1));
fprintf(' Optimal production of Premium Gas (x2): %.4f tons\n', x_opt(2));
fprintf(' Maximum Profit: $%.2f\n', -fval_opt); % Negative of fval_opt because we minimized -P
% (c) Demonstrate the feasible solution space using the graphical solution of a linear programming problem.
% Hint: use linspace and meshgrid and plot
figure;
hold on;
xlabel('Regular Gas (x1)');
ylabel('Premium Gas (x2)');
title('Feasible Region and Optimal Solution for Gas Production');
grid on;
axis equal; % Ensures equal scaling on both axes
% Define range for plotting
x1_plot = linspace(0, 10, 200); % x1 from 0 to slightly above max possible
x2_plot = linspace(0, 10, 200); % x2 from 0 to slightly above max possible
% Plot constraints as lines (and shade feasible region)
% Constraint 1: 7*x1 + 11*x2 <= 77 => x2 <= (77 - 7*x1) / 11
plot(x1_plot, (77 - 7*x1_plot) / 11, 'DisplayName', 'Raw Gas Constraint (7x1 + 11x2 <= 77)', 'LineWidth', 1.5);
% Constraint 2: 10*x1 + 8*x2 <= 80 => x2 <= (80 - 10*x1) / 8
plot(x1_plot, (80 - 10*x1_plot) / 8, 'DisplayName', 'Production Time Constraint (10x1 + 8x2 <= 80)', 'LineWidth', 1.5);
% Constraint 3: x1 <= 9 (vertical line)
plot([9 9], [0 10], 'DisplayName', 'Storage Constraint (x1 <= 9)', 'LineWidth', 1.5);
% Constraint 4: x2 <= 6 (horizontal line)
plot([0 10], [6 6], 'DisplayName', 'Storage Constraint (x2 <= 6)', 'LineWidth', 1.5);
% Non-negativity constraints are implicit by starting x1_plot and x2_plot from 0
% Shade the feasible region (more complex for general cases, but for this 2D, we can draw a polygon)
% Find vertices of the feasible region
% (0,0)
% Intersection of x1=0 and x2=6 => (0,6)
% Intersection of x2=6 and 7x1 + 11x2 = 77 => 7x1 + 66 = 77 => 7x1 = 11 => x1 = 11/7 approx 1.57, (1.57, 6)
% Intersection of 7x1 + 11x2 = 77 and 10x1 + 8x2 = 80
% Multiply first by 8, second by 11:
% 56x1 + 88x2 = 616
% 110x1 + 88x2 = 880
% Subtracting first from second: 54x1 = 264 => x1 = 264/54 = 4.8889
% Then 10*(264/54) + 8x2 = 80 => 8x2 = 80 - 2640/54 = (4320-2640)/54 = 1680/54 => x2 = 1680/(54*8) = 1680/432 = 3.8889
% So, (4.8889, 3.8889)
% Intersection of 10x1 + 8x2 = 80 and x2=0 => x1 = 8
% Intersection of x1=9 and x2=0 => (9,0)
% Vertices to consider for feasible region:
% (0,0), (0, 6), (11/7, 6), (4.8889, 3.8889), (8, 0), (9, 0)
% We need to find the intersection of all binding constraints.
% The relevant vertices forming the feasible polygon (convex hull) are:
% (0,0)
% (0, 6) -- intersection of x1=0 and x2<=6
% (11/7, 6) ~= (1.5714, 6) -- intersection of 7x1 + 11x2 = 77 and x2=6
% (4.8889, 3.8889) -- intersection of 7x1 + 11x2 = 77 and 10x1 + 8x2 = 80
% (8, 0) -- intersection of 10x1 + 8x2 = 80 and x2=0
% (9, 0) -- intersection of x1=9 and x2=0
% It looks like the effective polygon vertices are (0,0), (0, 6), (11/7, 6), (4.8889, 3.8889), (8, 0)
feasible_x = [0, 0, 11/7, 264/54, 8];
feasible_y = [0, 6, 6, 1680/432, 0];
fill(feasible_x, feasible_y, [0.8 0.9 1], 'DisplayName', 'Feasible Region', 'FaceAlpha', 0.5); % Light blue
% Plot the optimal solution found by linprog
plot(x_opt(1), x_opt(2), 'ro', 'MarkerSize', 10, 'LineWidth', 2, 'MarkerFaceColor', 'r', 'DisplayName', 'Optimal Solution');
text(x_opt(1) + 0.2, x_opt(2) + 0.2, sprintf('(%.2f, %.2f)', x_opt(1), x_opt(2)), 'Color', 'r');
xlim([0 9.5]); % Adjust axis limits to focus on feasible region
ylim([0 7]);
legend('Location', 'best');
hold off;
%% 2. Numerical Integration
% Function definition
% fx = 0.2 + 25x - 200x2 + 675x3 - 900x4 + 400x5
f_integrand = @(x) 0.2 + 25*x - 200*x.^2 + 675*x.^3 - 900*x.^4 + 400*x.^5;
% Integration limits
a_int = 0;
b_int = 0.8;
% For trapz and cumtrapz, we need discrete points
num_points = 100; % Number of points for discretization
x_discrete = linspace(a_int, b_int, num_points);
y_discrete = f_integrand(x_discrete);
fprintf('\n--- 2. Numerical Integration ---\n');
%% (a) Use Matlab trapz function to estimate the integral above from 0 to 0.8
integral_trapz = trapz(x_discrete, y_discrete);
fprintf(' (a) Integral using trapz: %.8f\n', integral_trapz);
%% (b) Use the trapezoidal function in Matlab, cumtrapz. Compare the difference between two functions
% cumtrapz calculates the cumulative integral
cumulative_integral_cumtrapz = cumtrapz(x_discrete, y_discrete);
% The last value of cumtrapz should be equal to trapz for the whole interval
integral_cumtrapz_full = cumulative_integral_cumtrapz(end);
fprintf(' (b) Full integral using cumtrapz (last value): %.8f\n', integral_cumtrapz_full);
fprintf(' Difference between trapz and cumtrapz (full integral): %.8e\n', abs(integral_trapz - integral_cumtrapz_full));
fprintf(' Comment: trapz computes the total integral over the given range, while cumtrapz returns\n');
fprintf(' a vector where each element is the integral from the start point to that x-value.\n');
fprintf(' The last value of cumtrapz should conceptually match the result of trapz.\n');
%% (c) Use the simpson function in Matlab, quad
% The 'quad' function is largely superseded by 'integral' in modern MATLAB.
% 'integral' is more robust and generally preferred.
integral_quad_simpson = integral(f_integrand, a_int, b_int);
fprintf(' (c) Integral using integral (quad replacement): %.8f\n', integral_quad_simpson);
%% (d) Use the quadrature function quadadapt (custom function)
% Define the custom quadadapt and quadstep functions as local functions
% or ensure they are in separate .m files on your path.
% Function: q = quadadapt(f,a,b,tol,varargin)
% Recursive subfunction: q = quadstep(f,a,b,tol,fa,fc,fb,varargin)
% Custom quadadapt function (embed here for MLX, or ensure separate file)
% If this were a separate .m file, you'd only need the definition once.
% For MLX, define them inline.
% Make sure 'f' is a function handle.
integral_quadadapt = quadadapt(f_integrand, a_int, b_int);
fprintf(' (d) Integral using custom quadadapt: %.8f\n', integral_quadadapt);
% Embedded Custom Functions (for the .mlx file)
function q = quadadapt(f,a,b,tol,varargin)
% Evaluates definite integral of f(x) from a to b
if nargin < 4 || isempty(tol),tol = 1.e-6;end
c = (a + b)/2;
fa = feval(f,a,varargin{:});
fc = feval(f,c,varargin{:});
fb = feval(f,b,varargin{:});
q = quadstep(f, a, b, tol, fa, fc, fb, varargin{:});
end
function q = quadstep(f,a,b,tol,fa,fc,fb,varargin)
% Recursive subfunction used by quadadapt.
h = b - a; c = (a + b)/2;
fd = feval(f,(a+c)/2,varargin{:});
fe = feval(f,(c+b)/2,varargin{:});
q1 = h/6 * (fa + 4*fc + fb); % Simpson's Rule for the whole interval [a,b]
q2 = h/12 * (fa + 4*fd + 2*fc + 4*fe + fb); % Simpson's Rule for two sub-intervals [a,c] and [c,b]
if abs(q2 - q1) <= tol
q = q2 + (q2 - q1)/15; % Adaptive Simpson's correction
else
qa = quadstep(f, a, c, tol, fa, fd, fc, varargin{:});
qb = quadstep(f, c, b, tol, fc, fe, fb, varargin{:});
q = qa + qb;
end
end
%% 3. Symbolic Integration and Differentiation
fprintf('\n--- 3. Symbolic Integration and Differentiation ---\n');
%% a. Define the following function using syms: fx = x2 ex - 5x3
% Compute the integral, and the first and second derivatives of the above function
% symbolically
syms x_sym
f_sym_a = x_sym^2 * exp(x_sym) - 5*x_sym^3;
% Compute the integral
integral_f_sym_a = int(f_sym_a, x_sym);
% Compute the first derivative
first_deriv_f_sym_a = diff(f_sym_a, x_sym);
% Compute the second derivative
second_deriv_f_sym_a = diff(f_sym_a, x_sym, 2);
fprintf(' (a) Original function f(x): %s\n', char(f_sym_a));
fprintf(' Symbolic Integral of f(x): %s\n', char(integral_f_sym_a));
fprintf(' Symbolic First Derivative of f(x): %s\n', char(first_deriv_f_sym_a));
fprintf(' Symbolic Second Derivative of f(x): %s\n', char(second_deriv_f_sym_a));
%% b. Define the following function using syms: fxyz = x2 ey - 5z2
% Compute the integral with respect to x and second derivative with respect
% to z
syms x_sym y_sym z_sym
f_sym_b = x_sym^2 * exp(y_sym) - 5*z_sym^2;
% Compute the integral with respect to x
integral_f_sym_b_x = int(f_sym_b, x_sym);
% Compute the second derivative with respect to z
second_deriv_f_sym_b_z = diff(f_sym_b, z_sym, 2);
fprintf('\n (b) Original function f(x,y,z): %s\n', char(f_sym_b));
fprintf(' Symbolic Integral of f(x,y,z) with respect to x: %s\n', char(integral_f_sym_b_x));
fprintf(' Symbolic Second Derivative of f(x,y,z) with respect to z: %s\n', char(second_deriv_f_sym_b_z));
%% 4. Numerical Differentiation
% Re-use the function f(x) from Exercise 2 for numerical differentiation
% fx = 0.2 + 25x - 200x2 + 675x3 - 900x4 + 400x5
f_num_diff = @(x) 0.2 + 25*x - 200*x.^2 + 675*x.^3 - 900*x.^4 + 400*x.^5;
% Define a range for x to calculate derivatives
x_range_diff = 0:0.01:0.8; % A finer step for numerical differentiation
y_range_diff = f_num_diff(x_range_diff);
fprintf('\n--- 4. Numerical Differentiation ---\n');
%% a. Use Matlab diff function to differentiate the function f(x) from Ex2
% When used on arrays, diff calculates discrete differences. dy/dx approx diff(y)./diff(x)
% First derivative
dydx_numerical = diff(y_range_diff) ./ diff(x_range_diff);
% The resulting derivative array is one element shorter than the original array.
% The x-values for the derivative are typically taken as the midpoints of the original x-intervals.
x_deriv_plot = (x_range_diff(1:end-1) + x_range_diff(2:end))/2;
figure;
plot(x_deriv_plot, dydx_numerical, 'b-', 'DisplayName', 'Numerical Derivative (diff)');
hold on;
xlabel('x');
ylabel('f''(x)');
title('Numerical Differentiation using diff()');
grid on;
%% b. Comparison of the exact derivative with numerical estimates
syms x_sym_diff
f_sym_diff_exact = 0.2 + 25*x_sym_diff - 200*x_sym_diff^2 + 675*x_sym_diff^3 - 900*x_sym_diff^4 + 400*x_sym_diff^5;
exact_deriv_f_sym = diff(f_sym_diff_exact, x_sym_diff);
% Convert symbolic derivative to a numeric function handle
exact_deriv_func = matlabFunction(exact_deriv_f_sym);
% Calculate exact derivative values over the same x range
exact_deriv_values = exact_deriv_func(x_deriv_plot); % Use x_deriv_plot for comparison
plot(x_deriv_plot, exact_deriv_values, 'r--', 'DisplayName', 'Exact Derivative');
legend('show');
hold off;
% Calculate average absolute difference
avg_abs_diff = mean(abs(dydx_numerical - exact_deriv_values));
fprintf(' (b) Average absolute difference between numerical (diff) and exact derivative: %.4e\n', avg_abs_diff);
%% c. Use forward function
% y = vector containing function values x = vector containing increments p =
% point number where to calculate d = derivative of y at point p Custom forward
% difference function (embed here or ensure separate file) function d = forward(y,x,p)
% d = (y(p+1)-y(p))/(x(p+1)-x(p)); end
% Test a point, e.g., at x=0.4 (which is at index 41 if step is 0.01 from 0)
test_point_index = find(x_range_diff == 0.4);
if isempty(test_point_index) || test_point_index == length(x_range_diff)
test_point_index = floor(length(x_range_diff)/2); % Fallback to middle if 0.4 not exact or is last point
fprintf(' Warning: Exact x=0.4 not found or is last point for forward diff. Using index %d.\n', test_point_index);
end
forward_deriv_at_point = forward(y_range_diff, x_range_diff, test_point_index);
exact_deriv_at_point = exact_deriv_func(x_range_diff(test_point_index));
fprintf('\n --- Numerical Differentiation (Custom Methods) ---\n');
fprintf(' (c) Forward difference at x=%.2f (index %d): %.8f (Exact: %.8f)\n', ...
x_range_diff(test_point_index), test_point_index, forward_deriv_at_point, exact_deriv_at_point);
%% d. Use backward function
% function d = backward(y,x,p) d = (y(p)-y(p-1))/(x(p)-x(p-1)); end
% Test a point, e.g., at x=0.4 (index 41)
% Ensure p is not the first element
if test_point_index == 1
test_point_index_bwd = 2; % Use second element for backward diff
else
test_point_index_bwd = test_point_index;
end
backward_deriv_at_point = backward(y_range_diff, x_range_diff, test_point_index_bwd);
exact_deriv_at_point_bwd = exact_deriv_func(x_range_diff(test_point_index_bwd));
fprintf(' (d) Backward difference at x=%.2f (index %d): %.8f (Exact: %.8f)\n', ...
x_range_diff(test_point_index_bwd), test_point_index_bwd, backward_deriv_at_point, exact_deriv_at_point_bwd);
%% e. Use central function
% function d = central(y,x,p) d = (y(p+1)-y(p-1))/(x(p+1)-x(p-1)); end
% Test a point, e.g., at x=0.4 (index 41)
% Ensure p is not the first or last element
if test_point_index == 1
test_point_index_central = 2; % Use second element for central diff
elseif test_point_index == length(x_range_diff)
test_point_index_central = length(x_range_diff) - 1; % Use second to last element
else
test_point_index_central = test_point_index;
end
central_deriv_at_point = central(y_range_diff, x_range_diff, test_point_index_central);
exact_deriv_at_point_central = exact_deriv_func(x_range_diff(test_point_index_central));
fprintf(' (e) Central difference at x=%.2f (index %d): %.8f (Exact: %.8f)\n', ...
x_range_diff(test_point_index_central), test_point_index_central, central_deriv_at_point, exact_deriv_at_point_central);
fprintf('\n Comment: Central difference formula generally provides a more accurate approximation\n');
fprintf(' of the derivative than forward or backward differences for a given step size.\n');
% --- Embedded Custom Functions (for the .mlx file) ---
% These functions are defined here to be self-contained within the .mlx
% For production code, it's usually better to have them in separate .m files.
% Custom linear_regression function (from Lab 4B, Ex 1a)
function [a0, a1, r2] = linear_regression(x, y)
if length(x) ~= length(y)
fprintf('The independent and the dependent variables should have same number of elements\n');
a0 = NaN; a1 = NaN; r2 = NaN;
return;
else
n = length(x);
end
X = mean(x); Y = mean(y);
x = reshape(x, 1, []);
y = reshape(y, 1, []);
Sxy = sum((x - X) .* (y - Y));
Sxx = sum((x - X).^2);
if Sxx == 0
a1 = NaN; a0 = NaN; r2 = NaN;
fprintf('Cannot perform regression: all x values are the same.\n');
return;
end
a1 = Sxy / Sxx;
a0 = Y - a1 * X;
Syy = sum((y - Y).^2);
if Sxx == 0 || Syy == 0
r = NaN;
else
r = Sxy / sqrt(Sxx * Syy);
end
r2 = r^2;
xp = linspace(min(x), max(x), 2);
yp = a0 + a1 * xp;
figure; % Create new figure for this plot
plot(x, y, 'o', xp, yp, 'b-');
xlabel('Independent Variable (x)');
ylabel('Dependent Variable (y)');
title('Linear Regression Fit (from linear_regression.m)');
grid on;
end
% Custom PVSSR function (from Lab 4B, Ex 2)
% NOTE: This function is expected to be in a subfolder like './lab4/PVSSR.m'
% For this MLX, I'll include its code definition as if it were there.
% If you actually have it in a separate file, ensure MATLAB's path includes it.
% function f = PVSSR(a, x, y)
% R = 82.05;
% T = 303;
%
% if length(x) ~= length(y)
% fprintf('The two data must have the same length\n');
% f = NaN;
% return;
% end
%
% n = length(x);
%
% yp_model = zeros(1, n);
% for j = 1:n
% yp_model(j) = R * T * (1 + a(1)/x(j) + a(2)/x(j)^2) / x(j);
% end
%
% y = reshape(y, 1, []);
% yp_model = reshape(yp_model, 1, []);
%
% f = sum((y - yp_model).^2);
% end
% this is now at ./ as it is a common function
% Custom forward difference function (from Lab 5, Ex 4c)
function d = forward(y,x,p)
d = (y(p+1)-y(p))/(x(p+1)-x(p));
end
% Custom backward difference function (from Lab 5, Ex 4d)
function d = backward(y,x,p)
d = (y(p)-y(p-1))/(x(p)-x(p-1));
end
% Custom central difference function (from Lab 5, Ex 4e)
function d = central(y,x,p)
d = (y(p+1)-y(p-1))/(x(p+1)-x(p-1));
end
+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');