Numerically solve a gamma parameter estimation - matlab

I am trying to numerically solve an equation using fzero in Matlab. It is part of a bigger exercise. I haven't posted much here so not sure how much background information you need about this exercise so will try to keep it short.
This is my code:
fun = #(a)log(a/xBar) + (1/n) * log(dataProd) + diff(gamma(a))/gamma(a);
x0 = 0.8014;
x = fzero(fun,x0)
These are the values:
n = 209
xBar is 0.6078
dataProd = 3.1554e-77
I get the following error message in Matlab:
Operands to the || and && operators must be convertible to logical
scalar values.
Error in fzero (line 306)
elseif ~isfinite(fx) || ~isreal(fx)
Any idea why I get this error message?

I would guess that, during the search for a solution, fzero tries to evaluate your function at a=0, leading to an infinity. To check if this is the case, either look and see if you can set the optimization parameter 'display' to 'iter', or something similar in your version of Matlab. Otherwise, you can simply move your function to a separate m-file and call disp(a) on the first line. That way you will be able to see what fzero is doing and which value of a is causing the problem.

Related

While loop error with Netwon-Raphson Method

I am trying to find use to Newton-Raphson method to find the roots. It does this by making a guess and then improving the guess after each iteration until you get one of the zeros.
Because the Newton-Raphson method quickly finds the zeros, it gives me a small error immediately and after two or three iterations max it should fail to meet the conditions of the while loop. However, the problem is that when I remove the semi-colon after "error" in my loop, I start getting fractions that should break the while loop, but its like Matlab doesn't know that 123/8328423 is less than 1. It continues to run until I manually force the program to stop running.
How do I fix this? I tried format long, format longe, and using double both in the command window, in the scrip file, and somewhere in the loop.
Thank you in advance for any tips, suggestions, or advice that may help!!
A = [1,2,-4;2,-2,-2;-4,-2,1;];
format longe
% syms x y z
% P = x^4 + 3*x^2*y^2-z^3+y+1;
% feval(symengine,'degree',P,x)
syms x
B = mateigenvalue(A);
f(x) = simplify(matdet(B));
x0 = 1;
error = 10;
while(error > .01)
x1 = x0 - f(x0)/(27*(x0)-3*(x0)^2);
error = abs(((f(x0)-f(x1))/f(x0))*100)
x0 = x1;
end
x0 = double(x0)
I reckon the main problem is with error.
It starts as double but inside the while-loop it turns into a symbolic variable and you can't easily compare symbolic variables with scalar values (the .01 in the while-loop condition).
Check in your workspace if error is symbolic (or type class(error) and check if sym is returned). I guess it is symbolic because a fraction is returned (123/8328423), as instead Matlab treats double values with decimals, not fractions.
If so, try doing (inside the while-loop) a conversion for error that is, under the line
error = abs(((f(x0)-f(x1))/f(x0))*100);
try putting
error=double(error);
So error will be temporarily converted in double and you can easily compare its value with .01 to check the while-loop condition.
Also, it is bad practice to call a variable error since error() is a built-in function in Matlab. By naming a variable error you cannot use the error() function. Same story goes for other built-in functions.

Matlab: Limit as t approaches positive and negative infinity?

I'm trying to write some code which would find the limit of a function as x approaches positive and negative infinity. The code I have so far is as follows:
pos = limit(exp(atan(x)), x = infinity)
neg = limit(exp(atan(x)), x = -infinity)
However, it gives me an error saying "invalid syntax at =. Possibly, a ), }, or ] is missing. When I looked at the Matlab documentation for how to compute a limit, they had this as their example:
limit((1 + 1/n)^n, n = infinity)
and this returned an answer of e. When I put this into my own Matlab, it gave me the same error, could anyone help? Is it possibly an error with my Matlab?
You've been looking at the wrong help. Such notation (and limit function) is used in MuPAD interface, not in the simple Matlab Command Window.
To use limit() in Matlab environment, you have to use symbolic variables and this is the correct help page.
In other words, to compute
limit((1 + 1/n)^n, n = infinity)
you have to declare a symbolic variable n
syms n
and then provide the correct syntax (ref. help)
limit((1 + 1/n)^n, n, inf)
and the result is (of course) exp(1), that is e.

MATLAB: Using FZERO on a function which has a vector output

I am working on my thesis and running in some programming problems in Matlab. I am trying to implement the ''golden Bisection Method'' to speed up my code. To this end, I've consulted the build in function FZERO.
So I am determining the difference between two vectors which are both (1x20).
Difference = Clmax_dist-cl_vec;
Clmax_dist comes from a semi-empirical method and cl_vec comes from the excecution of an external AVL.exe file.
Essentially, this difference depends only on one single variable AOA because the Clmax_dist vector is a constant. Hence, I am constantly feeding a new AOA value to the AVL.exe to obtain a new cl_vec and compare this again to the constant Clmax_dist.
I am iterating this until one of the element in the vector becomes either zero or negative. My loop stops and reveals the final AOA. This is a time consuming method and I wanted to use FZERO to speed this up.
However, the FZERO documentation reveals that it only works on function which has a scalar as input. Hence, my question is: How can I use FZERO with a function which has a vector as an output. Or do i need to do something totally different?
I've tried the following:
[Difference] = obj.DATCOMSPANLOADING(AOA);
fun=#obj.DATCOMSPANLOADING;
AOA_init = [1 20];
AOA_root = fzero(fun,AOA_init,'iter');
this gave me the following error:
Operands to the || and && operators must be convertible to logical scalar values.
Error in fzero (line 423)
while fb ~= 0 && a ~= b
Error in CleanCLmax/run (line 11)
AOA_root = fzero(fun,AOA_init,'iter');
Error in InitiatorController/moduleRunner (line 11)
ModuleHandle.run;
Error in InitiatorController/runModule (line 95)
obj.moduleRunner(ModuleHandle);
Error in RunSteps (line 7)
C.runModule('CleanCLmax');
The DATCOMSPANDLOADING function contains the following:
function [Difference] = DATCOMSPANLOADING(obj,AOA)
[Input]= obj.CLmaxInput; % Creates Input structure and airfoil list
obj.writeAirfoils(Input); % Creates airfoil coordinate files in AVL directory
[Clmax_dist,YClmax,Cla_mainsections] = obj.Clmax_spanwise(Input); % Creates spanwise section CLmax with ESDU method
[CLa] = obj.WingLiftCurveSlope(Input,Cla_mainsections); % Wing lift curve slope
[Yle_wing,cl_vec] = obj.AVLspanloading(Input,CLa,AOA); % Creates spanloading with AVL
Difference = Clmax_dist-cl_vec;
end
If I need to elaborate further, feel free to ask. And of course, Thank you very much.
fzero indeed only works on scalars. However, you can turn your criterion into a scalar: You are interested in AOA where any of the elements in the vector becomes zero, in which case you rewrite your objective function to return two output arguments: minDifference, which is min(Difference), and Difference. The first output, minDifference is the minimum of the difference, i.e. what fzero should try to optimize (from your question, I'm assuming all values start positive). The second output you'd use to inspect your difference vector in the end.

Numerical Triple integral where is the mistake?

I am trying to perform a numerical triple integral over s, gamma1, gamma2. The limits are (-inf +int), (0,+inf) and (gamma1,+inf) respectively. Please dont be scared from the shape of my function (its just a function of gamma1, gamma2, s)
The following is my code
syms s
syms gamma1
syms gamma2
fun=-(exp(-(28035689158432973*pi*gamma2^(2/3))/2305843009213693952)*
exp(-(pi*s*7120816246010697*i)/112589990684262400)*
(1/((pi*s*(4194304/gamma1^2 + 4194304/gamma2^2)*i)/(50*
(6144/gamma1 + 6144/gamma2)) + 1)^((3*(2048/gamma1 + 2048/gamma2)^2)
/(4194304/gamma1^2 + 4194304/gamma2^2)) - 1)
*(exp(-(pi^2*s*(log((-(gamma2*25*i)/(1024*pi*s))^(1/3) + 1)/3;
y=#(s,gamma1,gamma2)fun;
gamma2min=#(s,gamma1) gamma1;
prob=integral3(y,-inf,+inf,0,+inf,gamma2min,+inf)
I get the following error
Error using integralCalc/finalInputChecks (line 511)
Input function must return 'double' or 'single' values. Found 'sym'.
Any advice?
Thank you very much!
You can use quadgk to numerically integrate functions defined like
y=#(a,b,c) 1/abs(a^2+b^2+c^2+1);
(which I used to test my answer).
It's tricky because quadgk expects a function that takes vector input and returns a vector of function values, but you can get around it by using a lot of arrayfun's:
R=#(s,gamma1) quadgk(#(gamma2) arrayfun(#(k) y(s,gamma1,k),gamma2),gamma1,Inf)
S=#(s) quadgk(#(gamma1) arrayfun(#(k) R(s,k),gamma1),0,Inf)
T=quadgk(#(s) arrayfun(#(k) S(k),s),-Inf,Inf)
But! It's very slow, I wasn't patient enough to wait for the answer. So, replace the Inf and -Inf limits with 100 and -100, for example, and you will get an answer. Maybe try with 50 and -50 and see how much the solution changes by, if it changes very little then you can be confident the answer is quite accurate, otherwise you'll have to increase the number and wait longer! The faster your function decays the smaller the bounds you will be ale to get away with.

Matlab: nest fzero in fminsearch

I am trying to minimize with respect to a variable "y" a function that contains a parameter which must be calculated as a solution of an equality that contains "y" as well (say, y=-3; in my complete problem it is an equation with no analytic closed form solution, so I really need fzero).
Because of this, I include the fzero function in the argument of fminsearch:
fminsearch( #(y) 10*fzero(#(y) y+3, 0)) ;
I get the error:
Error using fminsearch (line 85)
The input to FMINSEARCH should be either a structure with
valid fields or consist of at least two arguments.
I obviously get the same error with:
f = fzero(#(y) y+3, 0);
fminsearch(#(y) 10*f);
Apparently the problem is that I cannot "nest" a fzero inside fminsearch.
Any idea about how to turn around this problem?
If you read the error message you got and look at the documentation of fminsearch you'll see that you need to call it with two input arguments. You call it with only one.
fminsearch( #(y) 10*fzero(#(x) x+3, 0), 0 )