Why matlab gives fminsearch optimisation error? - matlab

I have such an question, And I will do it in matlab. But, I get some errors:
Find the value of x ∈ [0, 1] that minimizes the largest eigenvalue of the matrix A(x) = xM +(1−x)P, where M is a 5×5 magic square and P is a 5 × 5 Pascal matrix.
My matlab code:
%Define Matrices
M = magic(5);
P = pascal (5);
% Define the variable x
syms x
%Define the given matrix A
>> A = x*M + (1-x)*P;
%Define the eigenvalue lambda as y;
syms y
%Find determinant of |A - lambda * I|
D = det (A - y*eye(5))
%Define Objective function
objective = #(y) y
%And Define the constraint
constraint = #(x,y) (-1)*D
%initial value x0 = (0:0.001:1);
%Minimization problem solving
x = fmincon(objective, constraint, x0)
I get this error;
Error using fmincon (line 221)
FMINCON requires the following inputs to be of data type double: 'X0'.
Or If I use another function: fminsearch
x = fminsearch(objective, constraint, x0)
In this case I get the following error:
Error using fminsearch (line 96)
FMINSEARCH accepts inputs only of data type double.
How can I deal with these errors ? Where is my mistake? How can I correct them?

I guess what you are looking for might be fminbnd, which helps to
Find minimum of single-variable function on fixed interval
n = 5;
M = magic(n);
P = pascal(n);
x = fminbnd(#(x) max(eig(x*M + (1-x)*P)),0,1);
such that
>> x
x = 0.79603

I suspect you did not show us the proper code, as you have sums there. I suspect you mean syms.
fmincon only works for numeric data, not symbolic data.

Related

MatLab Quadratic Equation With ln

How to solve the function f(x)=ln(x^2)-0.7=0 with a known Matlab command?
clc;clear all;close all;
f(x)=ln(x^2)-0.7=0
B=sqrt f(x)
You can use symbolic variables together with the solve function:
syms x;
eqn = log(x^2) - 0.7 == 0;
solve(eqn,x)
The above code will output:
ans =
exp(7/20)
-exp(7/20)
Since the equation is quadratic, the solver returns two distinct solutions (often people forget that quadratic equations may have two specular solutions, one positive and one negative).
If you want to retrieve the numerical values (for example, in order to calculate their sqrt value):
sol = solve(eqn,x);
num = double(sol)
num =
1.4191
-1.4191
Put the following code into a MATLAB script, name it "main.m".
function b=main
clc
x=solveF()
y=f(x)
b=sqrt(y)
end
function y=f(x)
y=log(x^2)-0.7
end
function x=solveF()
g = #(x) abs(f(x)-0)
x = fminsearch(g, 1.0)
end
Then run it as:
main
You will get the results:
x =
1.4190
y =
-3.4643e-05
b =
0.0000 + 0.0059i
ans =
0.0000 + 0.0059i
You can define equations in matlab as such:
f = #(x) log(x^2)-0.7;
B = #(x) sqrt(f(x));
If you want to find the value of x satisfying a constraint you can design a function that will be equal to zero when the constraint is respecte, then call fminsearch to find x:
f_constraint = #(x) abs(f(x)-0);
x_opt = fminsearch(f_constraint, 1.3); % function handle, initial estimate
In your example, B(x_opt) should be equal to zero. This is not exactly the case as fminsearch estimated a solution.

How to solve a differential equation with non-constant coefficient?

I have an equation like this:
dy/dx = a(x)*y + b
where a(x) is a non-constant (a=1/x) and b is a vector (10000 rows).
How can I solve this equation?
Let me assume you would like to write a generic numerical solver for dy/dx = a(x)*y + b. Then you can pass the function a(x) as an argument to the right-hand side function of one of the ODE solvers. e.g.
a = #(x) 1/x;
xdomain = [1 10];
b = rand(10000,1);
y0 = ones(10000,1);
[x,y] = ode45(#(x,y,a,b)a(x)*y + b,xdomain,y0,[],a,b);
plot(x,y)
Here, I've specified the domain of x as xdomain, and the value of y at the bottom limit of x as y0.
From my comments, you can solve this without MATLAB. Assuming non-zero x, you can use an integrating factor to get a 10000-by-1 solution y(x)
y_i(x) = b_i*x*ln(x) + c_i*x
with 10000-by-1 vector of constants c, where y_i(x), b_i and c_i are the i-th entries of y(x), b and c respectively. The constant vector c can be determined at some point x0 as
c_i = y_i(x0)/x_0 - b_i*ln(x0)

Computing integral with variable bounds in MATLAB

Consider the following MWE in MATLAB:
f = #(t) integral(#(x) x.^2,0,t);
integral(f,0,1);
This yields the error
Error using integral (line 85) A and B must be floating-point scalars.
(and a bit more). How do I fix this? Is this even possible? I think the problem is the variable upper bound.
If you want to use integral then set 'ArrayValued' to true otherwise t would be an invalid end point in integral(#(x) x.^2,0,t). So it would be:
f = #(t) integral(#(x) x.^2,0,t);
integral(f,0,1,'ArrayValued',true)
% ans =
% 0.0833
Alternately, since you're doing double integration, so use the function dedicated for this purpose i.e. integral2. For your example, it would be:
f = #(t,x) x.^2 ;
integral2(f,0,1,0, #(t) t)
% ans =
% 0.0833
If you have Symbolic Math Toolbox, you can also use int as int(expr,var,a,b) but it would be slower. For your case, it would be:
syms x t;
f = x.^2;
req = int(int(f,x,0,t),t,0,1); % It gives 1/12
req = double(req); % Convert to double if required

Plot symbolic equation using standard plot function in Matlab

In order to obtain a graphical representation of the behaviour of a fluid it is common practice to plot its streamlines.
For a given two-dimensional fluid with speed components u = Kx and v = -Ky (where K is a constant, for example: K = 5), the streamline equation can be obtained integrating the flow velocity field components as follows:
Streamline equation: ∫dx/u = ∫dy/v
The solved equation looks like this: A = B + C (where A is the solution of the first integral, B is the solution of the second integral and C is an integration constant).
Once we have achieved this, we can start plotting a streamline by simply assigning a value to C, for example: C = 1, and plotting the resulting equation. That would generate a single streamline, so in order to get more of them you need to iterate this last step assigning a different value of C each time.
I have successfully plotted the streamlines of this particular flow by letting matlab integrate the equation symbolically and using ezplot to produce a graphic as follows:
syms x y
K = 5; %Constant.
u = K*x; %Velocity component in x direction.
v = -K*y; %Velocity component in y direction.
A = int(1/u,x); %First integral.
B = int(1/v,y); %Second integral.
for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
eqn = A == B + C; %Solved streamline equation.
ezplot(eqn,[-1,1]); %Plot streamline.
hold on;
end
axis equal;
axis([-1 1 -1 1]);
This is the result:
The problem is that for some particular regions of the flow ezplot is not accurate enough and doesn't handle singularities very well (asymptotes, etc.). That's why a standard "numeric" plot seems desirable, in order to obtain a better visual output.
The challenge here is to convert the symbolic streamline solution into an explicit expression that would be compatible with the standard plot function.
I have tried to do it like this, using subs and solve with no success at all (Matlab throws an error).
syms x y
K = 5; %Constant.
u = K*x; %Velocity component in x direction.
v = -K*y; %Velocity component in y direction.
A = int(1/u,x); %First integral.
B = int(1/v,y); %Second integral.
X = -1:0.1:1; %Array of x values for plotting.
for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
eqn = A == B + C; %Solved streamline equation.
Y = subs(solve(eqn,y),x,X); %Explicit streamline expression for Y.
plot(X,Y); %Standard plot call.
hold on;
end
This is the error that is displayed on the command window:
Error using mupadmex
Error in MuPAD command: Division by zero.
[_power]
Evaluating: symobj::trysubs
Error in sym/subs>mupadsubs (line 139)
G =
mupadmex('symobj::fullsubs',F.s,X2,Y2);
Error in sym/subs (line 124)
G = mupadsubs(F,X,Y);
Error in Flow_Streamlines (line 18)
Y = subs(solve(eqn,y),x,X); %Explicit
streamline expression for Y.
So, how should this be done?
Since you are using subs many times, matlabFunction is more efficient. You can use C as a parameter, and solve for y in terms of both x and C. Then the for loop is very much faster:
syms x y
K = 5; %Constant.
u = K*x; %Velocity component in x direction.
v = -K*y; %Velocity component in y direction.
A = int(1/u,x); %First integral.
B = int(1/v,y); %Second integral.
X = -1:0.1:1; %Array of x values for plotting.
syms C % C is treated as a parameter
eqn = A == B + C; %Solved streamline equation.
% Now solve the eqn for y, and make it into a function of `x` and `C`
Y=matlabFunction(solve(eqn,y),'vars',{'x','C'})
for C = -10:0.1:10; %Loop. C is assigned a different value in each iteration.
plot(X,Y(X,C)); %Standard plot call, but using the function for `Y`
hold on;
end

Curve fitting using a equation that involves a integral that isnt possible to solve analytically?

I'm trying from 2 days to curve fit some data that I have using this equation
f = #(x) ((x.^4) .* exp(x)) ./((exp(x)-1).^2);
gama*x + 9*R*((x/a)^3)*quad(f,0,a/x);
Here x is independent variable and a is unknown, gama is known. I tried the following procedure with the most success.
function C=myquad(a,T)
C = zeros(size(T));
gama = 20 * 1e-3;
R = 8.314;
f = #(x) ((x.^4) .* exp(x)) ./((exp(x)-1).^2);
for n = 1:length(T)
C(n) = gama*T(n) + 9*R*((T(n)/a)^3)*quad(f,0,a/T(n));
end
>>fit(T_0,C_0,fittype('myquad(a,x)'));
It returned following error
??? NaN computed by model function, fitting cannot continue. Try using or tightening upper and lower bounds on coefficients.
Error in ==> fit at 443 errstr = handleerr( errid, errmsg, suppresserr );
No idea what to do. Please guide..
Find out why your function is returning NaN. NaN results from division of 0 by 0, or other causes.
Your function f(x) will compute 0/0 for x=0:
>> f = #(x) ((x.^4) .* exp(x)) ./((exp(x)-1).^2);
>> f(0)
ans =
NaN
Change your limits of integration so that you don't include 0, or re-define your function f to be better behaved at 0.