How to numerically solve for the upper bound of a definite integral in Matlab? - matlab

Given the equation
For some given function f(x) where gamma is also given, how can you numerically solve for upper bound u in Matlab?
f(x) can be a placeholder for any model.
This is a root-finding and integration problem but with my lack of knowledge in Matlab, I'm still trying to figure out how it is done.
My initial solution is a brute force approach. Let's say we have
and gamma = 0.8, we can find the definite integral from -inf to u by extracting its integral from some very small value u, working our way up until we reach a result gamma = 0.8.
syms f(x)
f(x) = (1/(sqrt(6*pi)))*exp(-(x^2/6));
gamma = 0.8;
u = -10;
res = int(f,x,-Inf,u);
while double(res) <= gamma
u = u+0.1;
res = int(f,x,-Inf,u);
end
fprintf("u is %f", u);
This solution is pretty slow and will definitely not work all the time.
I set u = 10 because looking at the graph of the function, we don't really get anything outside the interval [-5, 5].

You can use MATLAB Symbolic Math Toolbox (an addon you might need to install).
That way you can define yourself a "true" unknow variable x (not an array of x-values) and later integrate from negative infinity:
syms f(x)
f(x) = exp(2*x) % an example function
gamma = int(f,x,-Inf,u)
This yields gamma as the integral from -Inf to u, after defining f(x) as a symbolic function and u as a scalar

Related

Solve a non-linear system of equations with differentiation in Matlab

I would like to solve a system of non-linear equations in Matlab with fsolve, but I also have to differentiate the functions with respect to two variables. Here is the problem in steps:
Step 1: I define the system of non-linear functions F:
function F = root2d(x)
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
end
Step 2: I want to find the derivative of F(1) with respect to x(1) and the derivative of F(2) with respect to x(2) such that:
function F = root2d(x)
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
f1_d=diff(F(1),x(1))
f1_d=diff(F(2),x(2))
end
Step 3: I want my function to be the original one plus the derivative:
function F = root2d(x)
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));
F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;
end
Step 4: In the main file I would use this function with fsolve to solve the system of non-linear equations for x(1) and x(2):
syms x
fun = #root2d;
x0 = [0,0];
x = fsolve(fun,x0);
root2d(x)
function F = root2d(x)
F(1) = (exp(-x(1)+2)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
F(2) = (exp(-x(2)+1)/(1+exp(-x(1)+2)+exp(-x(2)+1)));
f1_d=diff(F(1),x(1));
f1_d=diff(F(2),x(2));
F(1)=F(1)+f1_d;
F(2)=F(2)+f2_d;
end
Can you please help me, how can a rewrite my code in order to solve the derivatives and then calculate and solve the system? Calculation of the derivates by hand is not an option because later I have to develop this program and I will have about 100 equations instead of 2.
A fundamental problem that you're making is that you're solving this system numerically with fsolve but then mixing in symbolic math.
Since your functions, F don't seem to vary, their derivatives shouldn't either, so you can create them as symbolic functions and calculate their derivatives symbolically once:
syms x [1 2] real; % Create 1-by-2 symbolic vector
F = exp(-x+2)/(1+exp(-x(1)+2)+exp(-x(2)+1));
F_d(1) = diff(F(1),x(1));
F_d(2) = diff(F(2),x(2));
F = F+F_d; % Add derivatives to original functions
Then you can convert these to a numerical form and solve with fsolve:
root2d = matlabFunction(F,'Vars',{x}); % Convert symbolic function to vectorized numeric function
x0 = [0 0];
x = fsolve(root2d,x0)
root2d(x)
Note that fsolve only finds a single root (if it succeeds) for a given initial guess. It's strongly suggested that you plot your function to understand it's behavior and how many roots it may have. From my limited plotting it doesn't look like this function, as defined above, has any zeros. Separately, you should also look into the tolerance options for fsolve.
You can look into purely numerical (non-symbolic) methods to solve this, but you'll need properly calculate the derivative numerically. You might look into this approach for that.

Solve complex matrix equation

I have a complex equation involving matrices:
R = expm(X)*A + (expm(X)-I)*inv(X)*B*U;
where R, B and U are known matrices.
I is an identity matrix.
I need to solve for X. Is there any way to solve this in MATLAB?
If your equation is nonlinear and you have access to MATLAB optimization toolbox you can use the fsolve function (You can still use it for a linear equation, but it may not be the most efficient approach). You just need to reformat your equation into the form F(x) = 0, where x is a vector or a matrix. For example, if X is a vector of length 2:
Define your function to solve:
function F = YourComplexEquation(X)
Fmatrix = expm(X)*A + (expm(X)-I)*inv(X)*B*U - R
% This last line is because I think fsolve requires F to be a vector, not a matrix
F = Fmatrix(:);
Then call fsolve with an initial guess:
X = fsolve(#YourComplexEquation,[0;0]);

Solving a complex double-integral equation for a third variable

I'm trying to solve the following equation for the variable h:
F is the normal cumulative distribution function
f is the probability density function of chi-square distribution.
I want to solve it numerically using Matlab.
First I tried to solve the problem with a simpler version of function F and f.
Then, I tried to solve the problem as below:
n = 3; % n0 in the equation
k = 2;
P = 0.99; % P* in the equation
F = #(x,y,h) normcdf(h./sqrt((n-1)*(1./x+1./y)));
g1 = #(y,h)integral(#(x) F(x,y,h).*chi2pdf(x,n),0,Inf, 'ArrayValued', true);
g2 = #(h) integral(#(y) (g1(y,h).^(k-1)).*chi2pdf(y,n),0,Inf)-P;
bsolve = fzero(g2,0)
I obtained an answer of 5.1496. The problem is that this answer seems wrong.
There is a paper which provides a table of h values obtained by solving the above equation. This paper was published in 1984, when the computer power was not good enough to solve the equation quickly. They solved it with various values:
n0 = 3:20, 30:10:50
k = 2:10
P* = 0.9, 0.95 and 0.99
They provide the value of h in each case.
Now I'm trying to solve this equation and get the value of h with different values of n0, k and P* (for example n0=25, k=12 and P*=0.975), where the paper does not provide the value of h.
The Matlab code above gives me different values of h than the paper.
For example:
n0=3, k=2 and P*=0.99: my code gives h = 5.1496, the paper gives h = 10.276.
n0=10, k=4 and P*=0.9: my code gives h = 2.7262, the paper gives h = 2.912.
The author says
The integrals were evaluated using 32 point Gauss-Laguerre numerical quadrature. This was accomplished by evaluating the inner integral at the appropriate 32 values of y which were available from the IBM subroutine QA32. The inner integral was also evaluated using 32 point Gauss-Laguerre numerical quadrature. Each of the 32 values of the inner integral was raised to the k-1 power and multiplied by the appropriate constant.
Matlab seems to use the same method of quadrature:
q = integral(fun,xmin,xmax) numerically integrates function fun from xmin to xmax using global adaptive quadrature and default error tolerances.
Does any one have any idea which results are correct? Either I have made some mistake(s) in the code, or the paper could be wrong - possibly because the author used only 32 values in estimating the integrals?
This does work, but the chi-squared distribution has (n-1) degrees of freedom, not n as in the code posted. If that's fixed then the Rinott's constant values agree with literature. Or at least, the literature that isn't behind a paywall. Can't speak to the 1984 Wilcox.

parametric integration and numeric plotting of a 2D function

I am going to devise a 2D function as a probability density function, is which a function of two variables, i.e. f = f(x,n). Then, as the target is plotting the probability variation, the integration in related to parameter x should be taken into account. The t parameter is the variable planned to be the upper bound of the integration. It is suffice to say that n is the other tuning factor. Finally, with due attention to the considered meshgrid, the probability surface is supposed to be drawn.
My option for the integration process is the symbolic int function. But there is an error: Error using mupadmex
Here is my code:
clear;
syms x;
syms n;
syms t;
sigma = 1;
mu = 0;
[t,n] = meshgrid(0:0.01:20, 1:1:100);
f = (n./(2*sigma*sqrt(pi))).*exp(-((n.*x)./(2.*sigma)).^2);
ff = int(f, x, -inf, t);
mesh(n,t,ff);
And the error trace:
Error using mupadmex
Error in MuPAD command: The argument is invalid. [Dom::Interval::new]
Error in sym/int (line 153)
rSym = mupadmex('symobj::intdef',f.s,x.s,a.s,b.s,options);
Error in field (line 14)
ff = int(f, x, -inf, t);
Would you please helping me to overcome this tie?!
PS. I know that there are some ideas to do this stuff more numerically by integral function, but I am prone to handle this case by int function, if it is possible. Because this code should be used as a service by the other snippets and the generated ff parameter is completely deserving, however it won't be a closed form function.
Thanks in advance.
I have changed several details in your code, Ill try to explain all of them.
No need of defining symbolic variables that are not going to be symbolic.
code:
clear;
syms x;
sigma = 1;
mu = 0; % This is never used!
You want to integrate a function f(n,x) dx for different n. If you create a meshgrid of n (instead of a vector), you will have tons of repeated f(ni,x) that you are not going to use.
Just do:
t=(0:1:20);
n=(1:10:100);
% are you sure you dont want ((n.*x)-mu) here?
f = (n./(2*sigma*sqrt(pi))).*exp(-((n.*x)./(2.*sigma)).^2);
int does not accept a mesh of symbolic functions! (or I haven't managed to make it work...).
So put a couple of for's there!
for ii=1:length(n)
for jj=1:length(t)
ff(ii,jj) = int(f(ii), x, -inf, t(jj));
end
end
Now we DO want a meshgrid for the plot!
Like this:
[t,n] = meshgrid(t, n);
And you want to plot the numerical value, so use double() to convert from symbolic to numerical:
plot!:
mesh(n,t,double(ff));
Result (with low amount of points due to the obvious computational effort needed)

Fitting data in least square sense to nonlinear equation

I need help fitting data in a least square sense to a nonlinear function. Given data, how do I proceed when I have following equation?
f(x) = 20 + ax + b*e^(c*2x)
So I want to find a,b and c. If it was products, I would linearize the function by takin the natural logaritm all over the function but I can not seem to do that in this case.
Thanks
You can use the nlinfit tool, which doesn't require the Curve Fitting Toolbox (I don't think...)
Something like
f = #(b,x)(20 + b(1)*x + b(2)*exp(b(3)*2*x));
beta0 = [1, 1, 1];
beta = nlinfit(x, Y, f, beta0);
When MATLAB solves this least-squares problem, it passes the coefficients into the anonymous function f in the vector b. nlinfit returns the final values of these coefficients in the beta vector. beta0 is an initial guess of the values of b(1), b(2), and b(3). x and Y are the vectors with the data that you want to fit.
Alternatively, you can define the function in its own file, if it is a little more complicated. For this case, you would have something like (in the file my_function.m)
function y = my_function(b,x)
y = 20 + b(1)*x + b(2)*exp(b(3)*2*x);
end
and the rest of the code would look like
beta0 = [1, 1, 1];
beta = nlinfit(x, Y, #my_function, beta0);
See also: Using nlinfit in Matlab?
You can try the cftool which is an interactive tool for fitting data. The second part I don't quite understand. It may help if you describe it in more detail.