How do I edit a loop to be able to store the variables and outputs used in each loop in a way which can be graphed?

28 ビュー (過去 30 日間)
I have an assignment where I need to collect multiple outputs from a loop utilizing in order to create a graph with all of the outputs. I am struggling with setting up the loop to change a variable (R) every loop while storing the previous outputs in a way which can be used with the function and loop we were given. I have to do this using two different methods that use different matlab functions and different loops structures, but my issue applies to both.
I attempted to define R as an array including all of the different values I needed outputs for, but it returned errors at the function when I tried to run it due to the dimensions not agreeing.
D = 0.3
D = 0.3000
k = 0.0002
k = 2.0000e-04
R = 10^4:10^5:10^8
R = 1×1000
10000 110000 210000 310000 410000 510000 610000 710000 810000 910000 1010000 1110000 1210000 1310000 1410000 1510000 1610000 1710000 1810000 1910000 2010000 2110000 2210000 2310000 2410000 2510000 2610000 2710000 2810000 2910000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
xarray = 0
% Define the function and its derivative
f = @(x) (1/sqrt(x))+(2*log((k/(3.7*D))+(2.51/(R*sqrt(x))))) ; % Function f(x)
df = @(x) -((1000 * R * k + 18574 * D) * sqrt(x) + 9287 * D) / (2000 * R * k * x^2 + 18574 * D * x^(3 / 2)); % First derivative f'(x)
===== Newton’s Method with Convergence Rate =====
Iter x_n f(x_n) Error Conv. Rate
% Newton's Method Parameters
x0 = 0.01; % Initial guess
tol = 1e-4; % Tolerance
max_iter = 100; % Maximum iterations
fprintf('\n===== Newton’s Method with Convergence Rate =====\n');
fprintf('%5s %12s %12s %12s %12s %12s\n', ...
'Iter', 'x_n', 'f(x_n)', 'Error', 'Conv. Rate');
iter = 0; % Iteration counter
error = Inf; % Initial large error
prev_error = NaN; % Previous error for convergence rate
while error > tol
iter = iter + 1;
% Compute next approximation
x_new = x0 - f(x0) / df(x0);
% Compute error
error = abs(x_new - x0);
% Compute convergence rate
if iter > 2
conv_rate = log(error / prev_error) / log(prev_error / prev_prev_error);
else
conv_rate = NaN; % Not enough data to compute rate
end
% Print iteration details
fprintf('%5d %12.6f %12.6f %12.6f %12.6f\n', ...
iter, x0, f(x0), error, conv_rate);
% Update values for next iteration
prev_prev_error = prev_error;
prev_error = error;
x0 = x_new;
% Stopping condition
if abs(error) < tol
break;
end
end
Error using /
Matrix dimensions must agree.

Error in solution>@(x)(1/sqrt(x))+(2*log((k/(3.7*D))+(2.51/(R*sqrt(x))))) (line 6)
f = @(x) (1/sqrt(x))+(2*log((k/(3.7*D))+(2.51/(R*sqrt(x))))) ; % Function f(x)
% Display final result
fprintf('\nApproximate Root: %.6f\n', x0);
fprintf('Total Iterations: %d\n', iter);
The function being used involved multiple loops/iterations to reach a final result, so I am not sure where or how I can repeatedly store the outputs (in this case, x_new or x0 I think) without affecting any part of the code in the next iteration. The code runs properly and gives an output when R is not an array. I am looking to use values for R between 10^4 and 10^8.
I am very inexperienced with Matlab so I am very sorry if I used any incorrect terms, if my question is confusing, or if I included too much of my code. Thank you all in advance.

採用された回答

Torsten
Torsten 2025 年 2 月 24 日 20:53
編集済み: Torsten 2025 年 2 月 24 日 21:07
Be careful here. In correlations for friction factors, log is usually meant as log to the basis of 10, not the natural logarithm.
D = 0.3;
k = 0.0002;
r = 10^4:10^5:10^8;
x0 = 0.01;
for i = 1:numel(r)
R = r(i);
% Define the function and its derivative
f = @(x) (1/sqrt(x))+(2*log((k/(3.7*D))+(2.51/(R*sqrt(x))))) ; % Function f(x)
df = @(x) -((1000 * R * k + 18574 * D) * sqrt(x) + 9287 * D) / (2000 * R * k * x^2 + 18574 * D * x^(3 / 2)); % First derivative f'(x)
% Newton's Method Parameters
%x0 = 0.01; % Initial guess
tol = 1e-4; % Tolerance
max_iter = 100; % Maximum iterations
%fprintf('\n===== Newton’s Method with Convergence Rate =====\n');
%fprintf('%5s %12s %12s %12s %12s %12s\n', ...
% 'Iter', 'x_n', 'f(x_n)', 'Error', 'Conv. Rate');
iter = 0; % Iteration counter
error = Inf; % Initial large error
prev_error = NaN; % Previous error for convergence rate
while error > tol
iter = iter + 1;
% Compute next approximation
x_new = x0 - f(x0) / df(x0);
% Compute error
error = abs(x_new - x0);
% Compute convergence rate
if iter > 2
conv_rate = log(error / prev_error) / log(prev_error / prev_prev_error);
else
conv_rate = NaN; % Not enough data to compute rate
end
% Print iteration details
%fprintf('%5d %12.6f %12.6f %12.6f %12.6f\n', ...
% iter, x0, f(x0), error, conv_rate);
% Update values for next iteration
prev_prev_error = prev_error;
prev_error = error;
x0 = x_new;
% Stopping condition
if abs(error) < tol
break;
end
end
X0(i) = x0;
end
plot(r,X0)
% Display final result
%fprintf('\nApproximate Root: %.6f\n', x0);
%fprintf('Total Iterations: %d\n', iter);
  2 件のコメント
Antonios
Antonios 2025 年 2 月 24 日 21:11
Thank you very much! This worked for me!
Torsten
Torsten 2025 年 2 月 24 日 21:15
編集済み: Torsten 2025 年 2 月 24 日 21:17
And don't forget to replace "log" by "log10" in your code (and adjust the derivative accordingly).
You can even get an analytical solution for x in terms of the LambertW function:
Section "Solving" under

サインインしてコメントする。

その他の回答 (1 件)

Matt J
Matt J 2025 年 2 月 24 日 20:56
編集済み: Matt J 2025 年 2 月 24 日 21:15
D = 0.3
k = 0.0002
Rvalues = 10^4:10^5:10^8;
nR=numel(Rvalues);
X=nan(1,nR);
for i=1:nR
R=Rvalues(i);
% Define the function and its derivative
f = @(x) (1/sqrt(x))+(2*log((k/(3.7*D))+(2.51/(R*sqrt(x))))) ; % Function f(x)
df = @(x) -((1000 * R * k + 18574 * D) * sqrt(x) + 9287 * D) / (2000 * R * k * x^2 + 18574 * D * x^(3 / 2)); % First derivative f'(x)
X(i)=doNewton(x0,f,df);
end
function x0=doNewton(f,df)
% Newton's Method Parameters
x0 = 0.01; % Initial guess
tol = 1e-4; % Tolerance
max_iter = 100; % Maximum iterations
fprintf('\n===== Newton’s Method with Convergence Rate =====\n');
fprintf('%5s %12s %12s %12s %12s %12s\n', ...
'Iter', 'x_n', 'f(x_n)', 'Error', 'Conv. Rate');
iter = 0; % Iteration counter
error = Inf; % Initial large error
prev_error = NaN; % Previous error for convergence rate
while error > tol
iter = iter + 1;
% Compute next approximation
x_new = x0 - f(x0) / df(x0);
% Compute error
error = abs(x_new - x0);
% Compute convergence rate
if iter > 2
conv_rate = log(error / prev_error) / log(prev_error / prev_prev_error);
else
conv_rate = NaN; % Not enough data to compute rate
end
% Print iteration details
fprintf('%5d %12.6f %12.6f %12.6f %12.6f\n', ...
iter, x0, f(x0), error, conv_rate);
% Update values for next iteration
prev_prev_error = prev_error;
prev_error = error;
x0 = x_new;
% Stopping condition
if abs(error) < tol
break;
end
end
% Display final result
fprintf('\nApproximate Root: %.6f\n', x0);
fprintf('Total Iterations: %d\n', iter);
end

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品


リリース

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by