Double integral with variable limits over implicit function in MATLAB - matlab

I'm experiencing the problem because of variable limit and implicit funtion being together.
So let's simplify it to this:
s(y)=y - our "implicit" function
Int [Int(x*s(y)*dy, 1,x)*dx, 1, 2] - our double integral (which equals 9/8).
(So you can even separate in into 2 integral I_small= s(y)dy and I=I_small * x*dx)
All that I figured out:
1) I tried using quad2d (so there is no ploblem with variable limit) - but I can't put the root of implicit function in it . So it wotks for non-implicit function:
function main
quad2d(#myfun,1,2,1,#(x)x)
end
function value=myfun(x,y)
value=x.*y;
end
But for implicit I've tried that - and it doesn't work. I know there is something wrong with this code - matlab doesn't understand that argument "y" in function name and "y" in the function itself are the same. But don't know how to fix it.
function main
quad2d(#myfun,1,2,1,#(x)x)
end
function value=myfun(x,y)
f=#(s,y)s-y;
value=x.*fzero(#(s)f(y,s), 0.5);
end
2) This code solves the opposite I = s(x).*y and I can't understand how to switch x to y because fzero doesnt work if I place y in it instead of x(j)
function main
quad(#myfun, 0,1)
end
function z=myfun(x)
z=zeros(size(x));
f=#(x,s) s-x;
for j=1:length(x);
s(j)=fzero(#(s)f(x(j),s), 0.5);
h=#(y) (s(j).*y);
z(j)=quad(h,1,x(j));
end
end
3) I also tried the nested quads, but it only works with constant limits. Can't fiqure it out how instead of Upperlimit should I place #(x)x.
function main
quad(#(y)y.*first_int(2),1,2)
end
function value=first_int(UpperLimit)
value=quad(#(x)yfunction(x,1),1,UpperLimit);
end
function value=yfunction(x,l)
syms y;
f=#(x,y) l.*x-y;
for k=1:length(x)
value(k)=fzero(#(y)f(x(k),y), 0.5);
end
Could you guys help with that?

The command quad2d (as its modern and better counterpart integral2) requires that the function to be integrated accept matrices as inputs.
The function Z=FUN(X,Y) must accept 2D matrices X and Y of the same size and return a matrix Z of corresponding values.
On the other hand, fzero only solves one equation, not a whole bunch of them at once. So, in order for your implicit function to accept matrix inputs, it needs to be written with a loop:
function value = myfun(x,y)
f=#(s,y)s-y;
value = zeros(size(x));
for i=1:size(x,1)
for j=1:size(x,2)
value(i,j) = x(i,j)*fzero(#(s) f(y(i,j),s), 0.5);
end
end
end
Then quad2d(#myfun,1,2,1,#(x)x) or integral2(#myfun,1,2,1,#(x)x) will work.

Related

Calculating the numeric derivative

So i'm a little confounded by how to structure my problem.
So the assignment states as following:
Type a m-file numerical_derivative.m that performs numerical derivation. Use
it to calculate f'(-3) when f(x) = 3x^2 /(ln(1-x))
In the m-file you to use h = 10^-6 and have the following mainfunction:
function y = numericalderivative (f, x)
% Calculates the numerical value in the case of f in punk x.
% --- Input ---
% f: function handle f(x)
% x: the point where the derivative is calculated
% --- output ---
% y: the numerical derivative of f on the point x
If I want to save it as a file and run the program in matlab, does't it make it redundant to use handles then?
I won't give you the answer to your homework, but perhaps a simpler example would help.
Consider the following problem
Write a function named fdiff which takes the following two arguments:
A function f represented by a function handle which takes one argument,
and a point x which can be assumed to be in the domain of the f.
Write fdiff so that it returns the value f(x) - f(x-1)
Solution (would be in the file named fdiff.m)
function result = fdiff(f, x)
result = f(x) - f(x-1);
end
Example Use Cases
>> my_function1 = #(x) 3*x^2 /(log(1-x));
>> fdiff(my_function1, -3)
ans =
-10.3477
>> my_function2 = #(x) x^2;
>> fdiff(my_function2, 5)
ans =
9
What you've created with fdiff is a function which takes another function as an input. As you can see it doesn't just work for 3*x^2 /(log(1-x)) but any function you want to define.
The purpose of your assignment is to create something very similar, except instead of computing f(x) - f(x-1), you are asked write a function which approximates f'(x). Your use-case will be nearly identical to the first example except instead of fdiff your function will be named numericalderivative.
Note
In case it's not clear, the second example defines the my_function2 as x^2. The value returned by fdiff(my_function2, 5) is therefore 5^2 - 4^2 = 9.
When you make this as a function file and run this in MATLAB without any input arguments i.e., 'f' and 'x', it will give you the error: 'not enough input arguments'. In order to run the file you have to type something like numericalderivative (3x^2 /(ln(1-x)), 5), which gives the value of the numerical derivative at x = 5.
Functions and, in MATLAB function files are a simple implementation of the DRY programming method. You're being asked to create a function that takes a handle and an x file, then return the derivative of that function handle and that x value. The point of the function file is to be able to re-use your function with either multiple function handles or multiple x values. This is useful as it simply involves passing a function handle and a numeric value to a function.
In your case your script file or command window code would look something like:
func = #(x) (3*x^2)/log(1-x);
x = -3;
num_deriv = numericalderivative(func,x);
You should write the code to make the function numericalderivative work.

Matlab: Meaning of #(t)(costFunction(t, X, y)) from Andrew Ng's Machine Learning class

I have the following code in MATLAB:
% Set options for fminunc
options = optimset('GradObj', 'on', 'MaxIter', 400);
% Run fminunc to obtain the optimal theta
% This function will return theta and the cost
[theta, cost] = ...
fminunc(#(t)(costFunction(t, X, y)), initial_theta, options);
My instructor has explained the minimising function like so:
To specify the actual function we are minimizing, we use a "short-hand"
for specifying functions, like #(t)(costFunction(t, X, y)). This
creates a function, with argument t, which calls your costFunction. This
allows us to wrap the costFunction for use with fminunc.
I really cannot understand what #(t)(costFunction(t, X, y) means. What are the both ts are doing? What kind of expression is that?
In Matlab, this is called an anonymous function.
Take the following line:
f = #(t)( 10*t );
Here, we are defining a function f, which takes one argument t, and returns 10*t. It can be used by
f(5) % returns 50
In your case, you are using fminunc which takes a function as its first argument, with one parameter to minimise over. This could be called using
X = 1; y = 1; % Defining variables which aren't passed into the costFunction
% but which must exist for the next line to pass them as anything!
f = #(t)(costFunction(t, X, y)); % Explicitly define costFunction as a function of t alone
[theta, cost] = fminunc(f, 0, options);
This can be shortened by not defining f first, and just calling
[theta, cost] = fminunc(#(t)(costFunction(t, X, y)), 0, options);
Further reading
As mentioned in the comments, here is a link to generally parameterising functions.
Specifically, here is a documentation link about anonymous functions.
Just adding to Wolfie's response. I was confused as well and asked a similar question here:
Understanding fminunc arguments and anonymous functions, function handlers
The approach here is one of 3. The problem the anonymous function (1 of the 3 approaches in the link below) solves is that the solver, fminunc only optimizes one argument in the function passed to it. The anonymous function #(t)(costFunction(t, X, y) is a new function that takes in only one argument, t, and later passes this value to costFunction. You will notice that in the video lecture what was entered was just #costFunction and this worked because costFunction only took one argument, theta.
https://www.mathworks.com/help/optim/ug/passing-extra-parameters.html
I also had the same question. All thanks to the the link provided by Wolfie to understand paramterized and anonymous functions, I was able to clarify my doubts. Perhaps, you must have already found your answer but am explaining once again, for people who might develop this query in the mere future.
Let's say we want to derive a polynomial, and find its minimum/maximum value. Our code is:
m = 5;
fun = #(x) x^2 + m; % function that takes one input: x, accepts 'm' as constant
x = derive(fun, 0); % fun passed as an argument
As per the above code, 'fun' is a handle that points to our anonymous function, f(x)=x^2 + m. It accepts only one input, i.e. x. The advantage of an anonymous function is, one doesn't need to create a separate program for it. For the constant, 'm', it can accept any values residing in the current workspace.
The above code can be shortened by:
m = 5;
x = derive(#(x) x^2 + m, 0); % passed the anonymous function directly as argument
Our target is to find the global optimal,so i think the function here is to get a bounch of local minimal by change the alpha and compare with each other to see which one is the best.
to achive this you initiate the fminuc with value initial_theta
fminuc set t=initial_theta then compute CostFunction(t,X,y) which is equal to` CostFunction(initial_theta,X,y).you will get the Cost and also the gradient.
fminuc will compute a new_theta with the gradient and a alpha, then set t=new_theta and compute the Cost and gradient again.
it will loop like this until it find the local optimal.
Then it change the length of alpha and repeat above to get another optimal. At the end it will compare the optimals and return with the best one.

substituting my function in an expression

I have defined a function as mystep in matlab 2014b, which is the same as heaviside except for mystep(0) which is one instead of 0.5.
Now I would like to substitute my function using subs into an expression but it is not possible. Function is:
f(x) = heaviside(x) * x^2;
g(x) = subs(f(x) , heaviside(x) , mystep(x));
g(x) =
heaviside(x)
As you see, matlab does not do anything, but if I change mystep with dirac(x), it goes well.
g(x) = subs(f(x) , heaviside(x) , dirac(x))
g(x) =
dirac(x)
what should I do? is there any way to do this?
Any other help like showing a way to change the value of heaviside at origin in matlab 2014b might be useful.
The content of mystep
function Y = mystep(X)
%//This function is a user-defined unit step function, which has the exact
%//properties of matlab heaviside function except for the value of function
%//at zero that is defined as 1.
Y = heaviside(X);
if Y==0.5
Y=1;
end
Now I understand your problem. The mystep function you implemented is not compatible to symbolic math. If you try mystep(sym(x)) you will see it returns heaviside. That's because a symbolic variable compared to a constant is always false.
The best solution I see is to use this definition for mystep
syms x
mystep(x)=heaviside(x)+1/2-abs(heaviside(x)-.5);
g(x) = subs(f(x) , heaviside(x) , mystep(x));
Resulting in:
x^2*(heaviside(x) - abs(heaviside(x) - 1/2) + 1/2)
Which does not look nice but implements the intended behaviour.
I found the answer. I have to define a new function in which mystep = round(heaviside(x));
end

MATLAB Function (Solving an Error)

I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.

Is there any comparation operator applied for matrixs in Matlab, like the dot operator '.*', './', '.^'

I have function f like this
function z=f(x,y)
if(x<1 & y <1)
z=0;
else
z=1;
end
end
And a script
x=0:0.1:2;
y=0:0.1:2;
[X,Y]=meshgrid(x,y);
Z=f(X,Y);
mesh(X,Y,Z);
When running this script, I got this errors:
Z must be a matrix, not a scalar or vector.
It's because x and y here are two arrays, not scalar value. The script can run if I change the
function f looks like this:
function z = f( x,y )
for i=1:size(x,2)
for j=1:size(y,2)
if(x(i)<1 & y(j)<1)
z(i,j)=0;
else
z(i,j)=1;
end
end
end
end
The broblem is that the new function runs much slower than the first one. I don't know if there is any comparation operator applied for arrays in this case, like the ".*" operator used in this function
function z=f(x,y)
z=x.*y;
end
Thank you very much.
You're getting an error, because the function f(x,y) returns a scalar for z and mesh expects z to be a matrix. You can replace all of the functions and code above with a simple, fast vectorized solution, that uses logical indexing:
x=0:0.1:2;
y=0:0.1:2;
[X,Y]=meshgrid(x,y);
Z=ones(size(X));
Z(X(:)<1&Y(:)<1)=0;
mesh(X,Y,Z)
This produces the following figure
to quote Mr Mackey: for loops with indexed matrices are bad, mkay? It takes up a lot of time, mkay?
I will modify Yoda's code a notch for the sake of efficiency:
x=0:0.1:2;
y=0:0.1:2;
[X,Y]=meshgrid(x,y);
Z = ((X>1) | (Y>1))*1;
mesh(X,Y,Z);