Code to run script multiple times

29 ビュー (過去 30 日間)
Alice Shen
Alice Shen 2019 年 4 月 9 日
編集済み: per isakson 2019 年 4 月 12 日
I have two codes, one is a big system of equations (NFRO3), and one is a script that runs fsolve(NFRO3Script). How do I write a code that runs the script multiple times while changing one number in the original code each time? (basically, one of my equations is like f(50) = x(49) - .r and I want to change that r from in .001 increments from like .7 to 1 [r = .7:.001:1]). (the equations only converge for very specific r values and i don't want to manually test them)
  4 件のコメント
per isakson
per isakson 2019 年 4 月 9 日
So why did you write "fsolve(NFRO3Script)" in your question?
Alex Mcaulley
Alex Mcaulley 2019 年 4 月 9 日
for loop??

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

採用された回答

madhan ravi
madhan ravi 2019 年 4 月 9 日
編集済み: madhan ravi 2019 年 4 月 9 日
https://in.mathworks.com/help/matlab/math/parameterizing-functions.html - parameterize your function (by turning your script into a function file) [Make use of function! FUNCTION] and run a loop through it.
  5 件のコメント
madhan ravi
madhan ravi 2019 年 4 月 10 日
See the attached file. If your using version prior to 2016b you may need to save the function separately in the name of the function (I believe you know how to do it).
Alice Shen
Alice Shen 2019 年 4 月 10 日
wow this is an amazing code! Thank you so much, it's very easy to understand and use :)

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

その他の回答 (1 件)

per isakson
per isakson 2019 年 4 月 9 日
編集済み: per isakson 2019 年 4 月 9 日
Assumtions:
  1. NFRO3Rec is a function that "accepts a vector x and returns a vector F"
  2. r is not changed in your code
Alternate solutions:
  1. see Passing Extra Parameters ( recommended)
  2. make r global in NFRO3Rec and NFRO3Script (not recommended)
  3. use persistent according to the outline below (not tested)
  4. modify the code of NFRO3Rec.m (not recommended)
  5. and others, which I cannot think of
%% NFRO3Script
fun = @NFRO3Rec;
x0 = [(some guesses)];
for r = 0.7 : 0.001 : 1
NFRO3Rec( [], r );
x = fsolve( fun, x0 );
% assign x together with r to an array
x0 = x;
end
and
function F = NFRO3Rec( x, varargin )
persistent r
if isempty( r )
r = nan; % anything that will produce an error
end
if nargin == 2
r = varargin{1};
F = [];
return
end
% your code
f(50) = x(49) - r; % I assume the period, ".", is a typo
% more code
end
It's easier to test NFRO3Rec if it's in a separate file.
  8 件のコメント
Stephen23
Stephen23 2019 年 4 月 9 日
編集済み: Stephen23 2019 年 4 月 9 日
"The two first "embedd" the parameters values in the function handle. "
Nested functions do not have to "embed" any parameters in the function handle.
Why would it be necessary that "the function handle must be recreated in every iteration" for a nested function? I use nested function often for parameterizing functions, and I have not experienced any need to "recreate" the function handle just because a variable in the parent workspace has changed. That would entirely defeat the point of nested functions!
A nested function would also be simpler than using persistent (which requires special cases added to the objective function).
per isakson
per isakson 2019 年 4 月 11 日
編集済み: per isakson 2019 年 4 月 11 日
Yes, I was mistaken regarding nested function.
An even bigger mistake was that I answered the question without knowing that the documentation includes good solutions. I searched the documentation and added the link as an afterthought.
In this thread of comments I showed a somewhat better version of my "persistent" construct. And here is my current version (still missing error checking and documentation):
function F = objective_function_proxy( x, varargin )
%
% Syntax
% x = objective_function_proxy( x )
% x = objective_function_proxy( [], objective_function )
% x = objective_function_proxy( [], [], p1, p2, p3, ... )
persistent objective_function parameters
if isempty( objective_function )
parameters = {nan}; % something that will produce an error
objective_function = '';
end
if nargin == 2
objective_function = varargin{1};
F = [];
return
end
if nargin >= 3
parameters = varargin(2:end);
F = [];
return
end
F = feval( objective_function, x, parameters{:} );
end
Example of using objective_function_proxy()
%% NFRO3Script
fun = @objective_function_proxy;
x0 = [0;0];
opt = optimoptions('fsolve','Display','none');
Result = struct( 'x', cell(11,1), 'r', cell(11,1) );
jj = 0;
fun( [], 'NFRO3Rec' ); % set objective function
for r = 0.40 : 0.01 : 0.60
fun( [], [], r ); % set parameter value
x = fsolve( fun, x0, opt ); % call fsolve
jj = jj + 1;
Result(jj).r = r;
Result(jj).x = x;
x0 = x;
end
figure;
plot( [Result.r], [Result.x], 'd' );
where
function F = NFRO3Rec( x, r )
F(1) = exp(-exp(-(x(1)+x(2)))) - x(2)*(1+x(1)^2);
F(2) = x(1)*cos(x(2)) + x(2)*sin(x(1)) - r;
end
Comments:
  1. objective_function_proxy() doesn't contain any case specific code, i.e. no references to NFRO3.
  2. objective_function_proxy() should be possible to use in different cases without any modification.
  3. NFRO3Script includes two calls of objective_function_proxy(), but no code that depends on the inner workings of objective_function_proxy().
  4. The objective function, NFRO3Rec(), has no special code added.

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

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by