Numerically integrate in Matlab without requiring vector input - matlab

The following is a generalisation of my problem
function E = FunctionIntegration(S)
I = #(f) log(det(4 * S(f)));
E = integral(I, -pi, pi)
S is a function handle that takes scalar input f and returns a matrix. When I try and run this function I get a Inner matrix dimensions must agree error.
I understand that integral requires the function I to take vector input and that's where the problem lies but in this case I don't see a way of accommodating that as I must then pass this vector to function S which returns a matrix. Is there a way around this?
Note an example of S could be:
S = #(f) [f 0; 0 1]
Obviously in this case the integral is easy to do analytically but the function S can be any scalar to matrix transformation.

Your problem is that integral passes an array of values to I. But your I only expects a scalar. Try this:
function E = functionIntegration(S)
I = #(x) arrayfun(#(f) log(det(4 * S(f))), x);
E = integral(I, -pi, pi);
end
I've wrapped your integrand into a call to arrayfun which will loop over the array passed in by integral and calculates the integrand for each entry:
>> S = #(x) x * eye(3, 3);
>> functionIntegration(S)
ans =
28.8591 + 9.8696i

Related

Multiplication Error in Integral Function in MATLAB

I want to write a function which uses a combination of sin(x) and cos(x) functions and then integrate it to get a scalar value as a result. However, when I run the code I got an error which says that dimensions of the matrices do not match in the integral function but they actually match. I an multiplying a 1x2 matrix with a 2x1 matrix. I am supposed to get a scalar value for the multiplication. Can you help please?
y = zeros(2,2);
y(1,1) = 100;
y(1,2) = 5;
y(2,1) = 200;
y(2,2) = 10;
fun = #(x) ([sin(x) cos(x)] * [y(:,1) - y(:,2)]);
q = integral(fun,0,Inf);
I found a solution to this problem. Instead of using matrices, I converted the function to a scalar form. This way it doesn't give a multiplication error.
fun = #(x) sin(x)*(y(1,1)-y(1,2)) + cos(x)*(y(2,1)-y(2,2));

Matlab integrate of fitted "linearinterp" returning error "First input argument must be a function handle"

Trying to get the integral of some experimentally collected data.
After using the envelope and abs functions I'm using the fit function to get the equation I wish to integrate (unfortunately 'poly' isn't giving a close enough fit to the data):
[yupper,ylower] = envelope(signal,1000,'peak');
dat = abs(yupper);
f = fit(x,dat,'linearinterp');
Then when I try
q = integral(f,3e4,9e4);
I get the error:
Error using integral (line 82) First input argument must be a function
handle.
Error in findenergyfromfitcurve (line 10) q = integral(f,3e4,9e4);
I thought f was a (mathematical) function, don't understand what the error is telling me. When I try using 'poly3' incase it's the linearinterp messing things up I still get that error.
TIA
f is a function but its type is cfit not function handle.
integral() function requires function handle, what you can do
is transform cfit into function handle before taking the
integral
The code is as follows
x = rand(5,1);
dat = rand(5,1);
f = fit(x,dat,'linearinterp');
% Create a new function handle
f = #(x)f(x);
q = integral(f, 3e4,9e4, 'ArrayValued', 1)
2) What does the ... 'Array valued', 1) do as well? It didn't work
till I put that in so it must do something
f is a piecewise function, the following illustration is based on the assumption that f is a 2-piecewise linear function, but it can be used for n-piecewise function as well.
The task for fit() function is finding the parameters :
a
b
c
d
k
In terms of code f looks like
function y = f(x,a,b,c,d,k)
% PIECEWISELINE A line made of two pieces
% that is not continuous.
y = zeros(size(x));
% This example includes a for-loop and if statement
% purely for example purposes.
for i = 1:length(x)
if x(i) < k
y(i) = a.* x(i) + b;
else
y(i) = c.* x(i) + d;
end
end
end
To plot a function handle, just use fplot(f)
Here is the graph for f
To sum up, f probably has more than one expression, that's why I set
'ArrayValued' to true so that integral() function knowns f
has more than one expression, omitting it means f has a single
expression which is not true.

Integral piecewise function matlab

I am trying to integrate a function F which is defined as:
function F
x = -3:0.1:3;
F = zeros(1, length(x));
for i = 1:length(x)
if (1.4<= x(i)) && (x(i) <= 1.6)
F(i) = x(i).^2;
else
F(i) = 2;
end
end
end
but the integral function gives me an error saying that there are too many arguments. I think the problem that the function is defined as a points?
The problem with your function, is that integral has no way to pass the arguments you supply to your function F. The function doesn't know that it can just pull certain elements from the vector you created. If you rewrite your function such that for an input (or x value), the output of F is returned, then integral will work as you need given two values to integrate between.

differentiate a function in matlab

how can I differentiate a function in matlab? I tried with:
syms x;
f = 3x^2 + 2;
A = diff(f);
disp(A);
My problem is now I want to give x a value after (for example A(x = 1) and I don't know how.
First, there's an error in your code, you can't imply multiplication, you need to write 3*x^2 rather than 3x^2.
Also, in case you feed the function a vector rather than scalar, you should use element-wise operations (including a . before powers, multiplication etc.) so this becomes 3*x.^2.
Other than that, 2 options:
syms x;
f = 3*x.^2 + 2;
1) define A like you did and use subs to substitute x for, say, 1.
A = diff(f);
subs(A,x,1);
2) define A as an anonymous function and call it more easily.
A = #(y) subs(diff(f),x,y)
Now A can be easily called with different values
A(1)
ans = 6
A(2)
ans = 12
Links to documentation on element-wise ops, subs and anonymous functions:
https://uk.mathworks.com/help/matlab/matlab_prog/array-vs-matrix-operations.html
https://uk.mathworks.com/help/symbolic/subs.html
https://uk.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html
Modify your code like this:
syms x;
f = 3*x^2 + 2; % You missed a * here
A(x) = diff(f); % This creates a symfun
A(1) % This gives the value of A at x=1
You need the matlabfunction function.
matlabFunction Generate a MATLAB file or anonymous function from a sym

trouble with fmincon in MATLAB

I'm trying to use fmincon in MATLAB and not quite sure what the heck the problem is. My function is:
function f = myfun(x4)
f = (C * x4 - d) .^ 2;
end
and I call it like this:
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(#myfun,x0,[],[],[],[],lb,[]);
but when I run it I get
??? Error using ==> mtimes
Inner matrix dimensions must agree.
However, I checked and C is 112x3, and d is 112x1, and x4 is not initialized at all because that's what I'm trying to solve for. If I create a "dummy" x4 I can run
(C * x4 - d) .^ 2
without a problem.
Any thoughts? I realize this is the same as using lsqr or rather lsqlin with a lb of 0, which is also equivalent to lsqnonneg, but that's the point: I'm trying to verify results from those methods in different ways.
There are several issues here.
First, you need to learn how to pass in those parameters that are not optimized. The function myfun cannot see C and d, as functions have their own workspaces, unless they are nested functions.
Next, since you are computing a linear least squares subject to constraints, you need to return a sum of squares. fmincon needs a scalar objective. It does not understand what to do when you return a vector.
Personally, I would not even bother defining an explicit m-file. Define this using a function handle. So perhaps you might try this objective:
myfun = #(x4) norm(C*x4 - d);
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(myfun,x0,[],[],[],[],lb,[]);
The function handle can see the value of C and d, so once the handle is created, those variables are carried along inside the function handle workspace.
Notice that I used norm to compute the sum of squares, in fact, here a sqrt of a sum of squares. But where the sum of squares is minimized, then so is the sqrt of that number. Its a bit cleaner looking with norm.
Another option is to use a version of myfun that explicitly passes in the value of C and d. Here I've given myfun arguments, then essentially created a function handle wrapper around myfun. You could have done that with an m-file version of myfun too.
myfun = #(x4,C,d) norm(C*x4 - d);
lb = zeros(3, 1);
x0 = [10; 10; 10];
[x4, fvalx4, exitflagx4, outputx4, lambdax4] = fmincon(#(x4) myfun(x4,C,d),x0,[],[],[],[],lb,[]);
The function that you pass to fmincon should return a scalar value. In your function it returns a 112-by-1 vector. Maybe you need to change
f = (C * x4 - d) .^ 2;
to
f = sum((C * x4 - d) .^ 2);