Not able to solve fzero with array by for-loop
3 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Jakub Szekely
am 30 Mai 2022
Kommentiert: dpb
am 30 Mai 2022
Hello everybody,
I'm working on my thesis and I got stuck for few hours/days on this:
- Having implicit function with array (15x1) with one vairable (results needed for all array positions)
I've spend few hours running through this forum (attempt on solving my issue by seen examples is the second/lower code) and I am starting to become hopeless. How to properly do it?
Working fzero code with my equation (everything is a scalar besides the lambdaCH_030_4h and Mach030_4h is unknow) I would write it seperatly (write the loop by hand), but I need it for even bigger arrays and multiple other equations.
lambdaCH_030_4h = ones(1,15)' ; %example
c_int = 0.7576
kappa = 1.4
fcn = @(Mach030_4h) ...
((-1)*lambdaCH_030_4h(1,1) + c_int * ...
(( (1 - sqrt(1-(Mach030_4h^2))) / (1 + sqrt(1-(Mach030_4h^2))) ).^(1/2)) * ...
( ((sqrt( (kappa+1) / (kappa-1) )) + sqrt(1-(Mach030_4h^2)) )/ ...
((sqrt( (kappa+1) / (kappa-1) )) - sqrt(1-(Mach030_4h^2)) )) ...
.^((1/2) * ( sqrt( (kappa + 1) / (kappa - 1) ) ))) ;
Mach030_4h = fzero(fcn,0) ;
My try on getting results for all lambdaCH_030_4h, but with no luck.
fcn = @(Mach030_4h) ...
((-1)*lambdaCH_030_4h + c_int * ...
(( (1 - sqrt(1-(Mach030_4h^2))) / (1 + sqrt(1-(Mach030_4h.^2))) ).^(1/2)) * ...
( ((sqrt( (kappa+1) / (kappa-1) )) + sqrt(1-(Mach030_4h.^2)) )/ ...
((sqrt( (kappa+1) / (kappa-1) )) - sqrt(1-(Mach030_4h.^2)) )) ...
.^((1/2) * ( sqrt( (kappa + 1) / (kappa - 1) ) ))) ;
Mach030_4h_V = zeros(1,15)' ;
for i = 1:length(lambdaCH_030_4h)
Mach030_4h_V(i,1) = fzero( @(Mach030_4h) fcn(Mach030_4h,lambdaCH_030_4h(i,1)),0.1) ;
end
This one gets as an error Too many arguments.
Different way I tired to achieve this:
for i = 1:length(lambdaCH_030_4h)
fcn = @(Mach030_4h) ...
((-1)*lambdaCH_030_4h(i,1) + c_int * ...
(( (1 - sqrt(1-(Mach030_4h^2))) / (1 + sqrt(1-(Mach030_4h(i,1).^2))) ).^(1/2)) * ...
( ((sqrt( (kappa+1) / (kappa-1) )) + sqrt(1-(Mach030_4h(i,1).^2)) )/ ...
((sqrt( (kappa+1) / (kappa-1) )) - sqrt(1-(Mach030_4h(i,1).^2)) )) ...
.^((1/2) * ( sqrt( (kappa + 1) / (kappa - 1) ) ))) ;
Mach030_4h_V(i,1) = fzero( fcn,0.1) ;
end
This one gets this error message: Index in position 1 exceeds array bounds. Index must not exceed 1.
Any help would be greatly welcome!
Thanks in advance!!
4 Kommentare
dpb
am 30 Mai 2022
You CAN do what you tried to do with slightly different syntax, but it's MUCH cleaner this way.
To use an array inside the anonymous function would require the second argument anyway to pass the indexing variable that you left out...it doesn't know anything about the for loop; an anonymous function uses static copies of the workspace variables it references AT_THE_TIME_IT_IS_DEFINED and those are unchanged no matter what happens to the same variables afterwards. Only redefiing the function with a different set of variable values will change what happens inside the anonymous function.
Hence, to use it in the loop without passing the second variable, you would define the variable "lambda" as the array value, execute the lines of code that redefine FCN and then sic fzero() on the new result. Much more efficient to pass the constant.
Again, the range of the function as it's written seems very limited to produce real values -- I would also strongly suggest it is too complicated for an anonymous function -- use an m-file and define intermediary values for the various pieces that are used multiple times and then reference those in the long equation.
Then, eliminate about half the superfluous parentheses so the code is legible...
Akzeptierte Antwort
Jakub Szekely
am 30 Mai 2022
Bearbeitet: Jakub Szekely
am 30 Mai 2022
1 Kommentar
dpb
am 30 Mai 2022
That's identically what @Torsten and I told you to do in only a slightly altered incarnation -- his solution deserves being "Accepted" and acknowledged.
You'll note my comment to rewrite the function as an m-file -- I'd certainly have taken it several steps further than that, but ugly is in the eye of the beholder.
If this is, however, thesis or similar project, it desires a far better presenation.
Weitere Antworten (1)
Torsten
am 30 Mai 2022
Bearbeitet: Torsten
am 30 Mai 2022
To see where the problem with fzero is, I suggest you first plot your function for a reasonable value of lambdaCH_030_4h:
c_int = 0.7576;
kappa = 1.4;
lambdaCH_030_4h = 1.0;
fcn = @(Mach030_4h,lambdaCH_030_4h) ...
((-1)*lambdaCH_030_4h + c_int .* ...
(( (1 - sqrt(1-(Mach030_4h.^2)))./ (1 + sqrt(1-(Mach030_4h.^2))) ).^(1/2)).* ...
( ((sqrt( (kappa+1) / (kappa-1) )) + sqrt(1-(Mach030_4h.^2)) )./ ...
((sqrt( (kappa+1) / (kappa-1) )) - sqrt(1-(Mach030_4h.^2)) )) ...
.^((1/2).* ( sqrt( (kappa + 1) / (kappa - 1) ) ))) ;
Mach030_4h = 0.1:0.01:5.0;
plot(Mach030_4h,fcn(Mach030_4h,lambdaCH_030_4h))
Here you see that fzero cannot succeed since your function has no zero (at least in the range I specified).
Once you have found a reasonable range for lambdaCH_030_4h, you can use fsolve:
c_int = 0.7576;
kappa = 1.4;
lambdaCH_030_4h = some array;
fcn = @(Mach030_4h,lambdaCH_030_4h) ...
((-1)*lambdaCH_030_4h + c_int .* ...
(( (1 - sqrt(1-(Mach030_4h.^2)))./ (1 + sqrt(1-(Mach030_4h.^2))) ).^(1/2)).* ...
( ((sqrt( (kappa+1) / (kappa-1) )) + sqrt(1-(Mach030_4h.^2)) )./ ...
((sqrt( (kappa+1) / (kappa-1) )) - sqrt(1-(Mach030_4h.^2)) )) ...
.^((1/2).* ( sqrt( (kappa + 1) / (kappa - 1) ) ))) ;
guess = 1.0;
for i = 1:numel(lambdaCH_030_4h)
fun = @(Mach030_4h) fcn(Mach030_4h,lambdaCH_030_4h(i));
sol(i) = fsolve(fun,guess);
guess = sol(i);
end
0 Kommentare
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!