How can you plot a subfunction in matlab? - matlab

I can't figure out how to plot a subfunction of my program using plot.
main()
...
% this works
fplot('4 * (x^-12 - x^-6)', [0.98,2]);
% these and other combinations don't work
fplot('potential', [0.98,2]);
fplot('potential(x)', [0.98,2]);
plot(0.98:0.01:2, potential(x));
end
function v = potential(x)
v = 4 * (x^-12 - x^-6);
end
Could you please shed some light on how you should use plot to plot a subfunction if you don't want to write all of it. I'm sure I'll run into this problem again.

Passing a string to a function like fplot (or ode45 for that matter) will more than likely not work for local or nested functions since they will most likely leverage a function like str2func or feval. In both cases, the context in which the local or nested function is defined is hidden from fplot and ode45, and the function will not be found since it is not on the MATLAB the path.
The way to avoid this problem is to almost always use function handles. Function handles will bind the appropriate context data and everything will work as intended. Consider this example that will print the meta-information provided by the creation of the handle:
function [] = main()
potfun = #potential;
fplot(potfun, [0.98,2]);
% To see more clearly what information the handle has:
functions(potfun)
end
function v = potential(x)
v = 4 * (x.^-12 - x.^-6);
end
(I also switched to element-wise exponent operators, which is almost always a good idea.)
This prints the following struct from functions:
>> main
ans =
function: 'potential'
type: 'scopedfunction'
file: 'C:\main.m'
parentage: {'potential' 'main'}
As can be seen, the full needed context to call the subfunction ("scopefunction" apparently) from other functions is provided.

use arrayfun:
x = 0.98:00.1:2;
y = arrayfun(#(x)4 * (x^-12 - x^-6),x);
% or y = arrayfun(#(x)potential(x),x)
plot(x,y);
Or if the step is not important use the following code:
fplot(#(x)potential(x), [0.98, 2])

Related

How to write code to run a function and retrieve values from it

I am supposed to use a 2D Gaussian function which will have the following mathematical expression ๐บ(๐‘ฅ) = ๐‘’^(โˆ’(๐‘ฅโˆ’๐œ‡)^2/๐‘ ๐‘ก๐‘‘^2) and plot a graph of the function. ยต is the mean and std stands for the standard deviation, by the way. How would a write code to plug in values to the function and output the values of G(x) and x in to an array to be plotted?
I've tried looking at older code I've done for previous graph's I've made, but this function is much more complex than I've ever done.
The following anonymous function would work in your case
G = #(x,mu,sigma) exp(-((x-mu).^2)/(sigma^2));
x=-10:0.01:10;
plot(x,G(x,0.2,0.4));
Generically speaking, use the following method to call a function and return values:
Main Script
clc; clear; close all;
x = 0;
y = add_x(x);
Function Call
function y = add_x(x)
y = x+1;
end
Read more about function calling in the MATLAB Documentation.

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.

defining different cases for function im matlab (symfun)

i want to create a function (symfun), and i want to divide it to cases, i.e if t> then then answer will be a and if t<0 the answer will be b.
the thing is, that matlab wont allow me to put an if statements after a sym function.
>> l = symfun(0, [m]);
>> l(m) = if m>0 3
also i tried to create a function:
function [x1] = xt_otot_q3(t)
and tried to connect between the two functions:
>> l(m) = xt_otot_q3(m)
Conversion to logical from sym is not possible.
is there any way to break a symfun into cases?
Not sure that I understand what you want.
This code 'combines' the functions symfun and xt+otot_q3 defined below:
function test;
m=randn(4); % N(0,1) random numbers
l=xtotot_q3(symfun(0,m)) % combine xt_otot_q3 and symfun
l=symfun(0,xtotot_q3(m)) % combine symfun and xt_otot_q3
return
function lval=symfun(thr,rval);
lval=ones(size(rval)); % output, size of input, = 1
lval(rval<thr)=-1; % output = -1 if input < thr
return
function lval=xtotot_q3(rval);
lval=3*rval+1; % some function, in this case 3 * input + 1
return
You can save the whole bit as test.m and then call test from the matlab prompt. Maybe if you start with this then you can modify it to fit your needs.

Defining function in matlab which uses a function as a parameter

I want to define a function like this:
function f = f1(fun,a,b,c)
f = c*fun(a+b);
Here fun is some function that I will pass when I use the function f.
How can I do this in Matlab?
Have you tried it? The best way to learn a tool like matlab is to try things!
In fact, you don't even need to create an m-file function. I'll do it using a function handle here.
fun = #(x) sin(x);
f1 = #(f,a,b,c) c*f(a+b);
f1(fun,2,3,4)
ans =
-3.8357
I could have defined f1 as an m-file function too, but that would have required I save a file. Why bother?
What you are looking for is the function handle.
You can obtain the function handle of a function (in the following case, sqrt) by placing the "at" symbol ('#') in front of the function name:
a = 1;
b = 2;
c = 3;
fun = #sqrt; % obtain the function handle of sqrt()
f = f1(fun, a,b,c); % pass the function handle of sqrt() into your function f1().
When you use fun, it will be as if you are using the sqrt function.
For more details, you may also refer to another Stackoverflow question: function handle in MATLAB

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.