Computing integral with variable bounds in MATLAB - 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

Related

Why matlab gives fminsearch optimisation error?

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.

Integral in Matlab

I have 3 equations:
f = (exp(-x.^2)).*(log(x)).^2
g = exp(-x.^2)
h = (log(x)).^2
The interval is:
x = 0.05:10
I am able to correctly plot the equations but when I try to find an integral, it says that there is an error.
The code I used to find an integral is:
integral(f,0,Inf)
integral(g,0,inf)
integral(h,0,10)
The integrals for f and g are from 0 to infinity and the integral for h is from 0 to 10. None of my code to find integrals works.
You need to define f,g,h as functions like shown below. See documentation of integral(), it takes a function as its first argument. Matlab integral documentation
x = 0.05:10
f = #(x) (exp(-x.^2)).*(log(x)).^2
g = #(x) exp(-x.^2)
h = #(x) (log(x)).^2
integral(f,0,Inf) % 1.9475
integral(g,0,inf) % 0.8862
integral(h,0,10) % 26.9673
h = #(x) (log(x)).^2
This syntax is called anonymous functions, basically they are nameless functions. In above case it takes x as input and returns log(x) squared.
From now on h is a function and it can be used like this.
h(1) % will be equal 0
For more on anonymous functions refer to matlab anonymous functions guide:
Anonymous Functions

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.

Errors when using the Integral2 function in MATLAB

As far as I can tell, no one has asked this.
I've been asked to compute the double integral of a function, and also the same double integral but with the order of integration swapped (i.e: first integrate for dydx, then dxdy). Here is my code:
%Define function to be integrated
f = #(x,y) y^2*cos(x);
%First case. Integration order: dydx
ymin = #(x) cos(x);
I = integral2(f,ymin,1,0,2*pi)
%Second case. Integration order: dxdy
xmin = #(y) asin(y)+2*pi/2;
xmax = #(y) asin(y)-pi/2;
B = integral2(f,xmin,xmax,-1,1)
The error I'm getting is this:
Error using integral2 (line 71)
XMIN must be a floating point scalar.
Error in EngMathsA1Q1c (line 5)
I = integral2(f,ymin,1,0,2*pi)
I'm sure my mistake is something simple, but I've never used Integral2 before and I'm lost for answers. Thank you.
Per the integral2 documentation, the variable limits are given as the second pair of limits. So your first integral should be
% Define function to be integrated
f = #(x,y) y.^2.*cos(x);
% First case. Integration order: dydx
ymin = #(x) cos(x);
I = integral2(f,0,2*pi,ymin,1);
The set of constant limits always goes first, and Matlab assumes the first argument of f is associated with the first set of limits while the second argument of f is associated with the second set of limits, which may be a function of the first argument.
I point out that second part because if you wish to switch the order of integration, you also need to switch the order of the inputs of f accordingly. Consider the following example:
fun = #(x,y) 1./( sqrt(2*x + y) .* (1 + 2*x + y).^2 )
A nice little function that is not symmetric in its arguments (i.e., fun(x,y) ~= fun(y,x)). Let's integrate this over an elongated triangle in the first quadrant with vertices at (0,0), (2,0), and (0,1). Then integrating with dA == dy dx, we have
>> format('long');
>> ymax = #(x) 1 - x/2;
>> q = integral2(fun,0,2,0,ymax)
q =
0.220241017339352
Cool. Now let's integrate with dA == dx dy:
>> xmax = #(y) 2*(1-y);
>> q = integral2(fun,0,1,0,xmax)
q =
0.241956050772765
Oops, that's not equal to the first calculation! That's because fun is defined with x as the first argument and y as the second, but the previous call to integral2 is implying that y is the first argument to fun, and it has constant limits of 0 and 1. How do we fix this? Simply define a new function that flips the arguments:
>> fun2 = #(y,x) fun(x,y);
>> q = integral2(fun2,0,1,0,xmax)
q =
0.220241017706984
And all's right with the world. (Although you may notice small differences between the two correct answers due to the error tolerances of integral2, which can be adjusted via options per the documentation.)
The error states that you can't pass in a function for the limits of integration. You need to specify a scalar value for each limit of integration. Also, there are some errors in the dimensions/operations of the function. Try this:
%Define function to be integrated
f = #(x,y) y.^2.*cos(x);%changed to .^ and .*
%First case. Integration order: dydx
%ymin = #(x) cos(x);
I = integral2(f,-1,1,0,2*pi)%use scalar values for limits of integration
%Second case. Integration order: dxdy
%xmin = #(y) asin(y)+2*pi/2;
%xmax = #(y) asin(y)-pi/2;
B = integral2(f,0,2*pi,-1,1)% same issue, must use scalars

Taylor Method ODE

I am trying to implement the Taylor method for ODEs in MatLab:
My code (so far) looks like this...
function [x,y] = TaylorEDO(f, a, b, n, y0)
% syms t
% x = sym('x(t)'); % x(t)
% f = (t^2)*x+x*(1-x);
h = (b - a)/n;
fprime = diff(f);
f2prime = diff(fprime);
y(0) = y0,
for i=1:n
T((i-1)*h, y(i-1), n) = double(f((i-1)*h, y(i-1)))+(h/2)*fprime((i-1)*h, y(i-1))
y(i+1) = w(i) + h*T(t(i), y(i), n);
I was trying to use symbolic variables, but I don´t know if/when I have to use double.
I also tried this other code, which is from a Matlab function, but I do not understand how f should enter the code and how this df is calculated.
http://www.mathworks.com/matlabcentral/fileexchange/2181-numerical-methods-using-matlab-2e/content/edition2/matlab/chap_9/taylor.m
As error using the function from this link, I got:
>> taylor('f',0,2,0,20)
Error using feval
Undefined function 'df' for input arguments of type 'double'.
Error in TaylorEDO (line 28)
D = feval('df',tj,yj)
The f I used here was
syms t
x = sym('x(t)'); % x(t)
f = (t^2)*x+x*(1-x);
This is a numerical method, so it needs numerical functions. However, some of them are computed from the derivatives of the function f. For that, you need symbolic differentiation.
Relevant Matlab commands are symfun (create a symbolic function) and matlabFunction (convert a symbolic function to numerical).
The code you have so far doesn't seem salvageable. You need to start somewhere closer to basics, e.g., "Matlab indices begin at 1". So I'll fill the gap (computation of df) in the code you linked to. The comments should explain what is going on.
function [T,Y] = taylor(f,a,b,ya,m)
syms t y
dfs(1) = symfun(f, [t y]); % make sure that the function has 2 arguments, even if the user passes in something like 2*y
for k=1:3
dfs(k+1) = diff(dfs(k),t)+f*diff(dfs(k),y); % the idea of Taylor method: calculate the higher derivatives of solution from the ODE
end
df = matlabFunction(symfun(dfs,[t y])); % convert to numerical function; again, make sure it has two variables
h = (b - a)/m; % the rest is unchanged except one line
T = zeros(1,m+1);
Y = zeros(1,m+1);
T(1) = a;
Y(1) = ya;
for j=1:m
tj = T(j);
yj = Y(j);
D = df(tj,yj); % syntax change here; feval is unnecessary with the above approach to df
Y(j+1) = yj + h*(D(1)+h*(D(2)/2+h*(D(3)/6+h*D(4)/24)));
T(j+1) = a + h*j;
end
end
Example of usage:
syms t y
[T, Y] = taylor(t*y, 0, 1, 2, 100);
plot(T,Y)