Defining function in matlab which uses a function as a parameter - matlab

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

Related

How to create a function to calculate g(1,2) g(2,3) g(1,3) for equations like this g(1)+g(2)+g(1)*g(2)?

I'm trying to create Matlab code to calculate these following equations in Matlab
g(1,2)=g(1)+g(2)+g(1)g(2)
g(1,3)=g(1)+g(3)+g(1)g(3)
g(2,3)=g(2)+g(3)+g(2)g(3)
and values of g(1), g(2),g(3) are available.
Where should I start to write such Matlab code?
One problem here appears to be that you have functions of one and two variables, but you're calling them the same thing (g). Let's call the function of one variable g and the function of two variables (that you want to create) f. Assuming the function g already exists, you can create f using an anonymous function like so:
f = #(x1, x2) g(x1)+g(x2)+g(x1)*g(x2);
And calling it like this:
result = f(1, 2);
is equivalent to:
result = g(1)+g(2)+g(1)*g(2);

How can you plot a subfunction in 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])

Create function with given number of input arguments

Here's the situation:
I need to create a function that takes a function handle fun which is of CONSTANT input-length (that is nargin(fun)>=0), does some transformation on the inputs and then calls fun.
Pseudo-Code:
function g = transformFun(fun)
n = nargin(fun);
g = #(v_1, ..., v_n) ...
% ^ NOT REAL MATLAB - THE MAIN PROBLEM
fun(someCalculationsWithSameSizeOfOutput(v_1,...v_n){:});
% CAN BE ACHIEVED WITH TEMPORARY CELL IN HELPER FUNCTION ^
end
Now the problem: the output function's handle (g = transformFun(concreteFun)) is then passed to other code that relies on the fact that the function is of constant length (assumes nargin(g)>=0), thus a variable-input-length function is unacceptable (the "easy" solution).
This transformation is called with many functions with every possible number of arguments (n is unbounded), so covering a finite number of possibilities is also not possible.
Is there a (simple?) way to achieve that?
[I've searched the internet for a few hours and could only come up with a nasty hack involving the deprecated inline function, which I couldn't make work; maybe I have the wrong terminology].
So typically you could use varargin to handle this sort of thing, but since you need nargin(g) to return the actual number of inputs it's a little trickier.
You could use str2func to create the anonymous function as a string and then convert it to a function handle.
% Create a list or arguments: x1, x2, x3, x4, ...
args = sprintf('x%d,', 1:nargin(func));
args(end) = '';
% Place these arguments into a string which indicates the function call
str = sprintf('#(%s)fun(someCalculationsWithSameSizeOfOutput(%s))', args, args);
% Now create an anonymous function from this string
g = str2func(str);
Based on the attrocity above, it may be worth considering an alternative way of dealing with your function handles.

Variable or function undefined

I am trying to implement following in MATLAB,
n1 = 6;
n2 = 1;
n3=0.1;
global ps
ps=zeros(3,15);
[R,t,d]=model(n1,n2,n3);
ps=R;
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],#cons);
function f = Obj(x)
f = x(1)^2+x(2)^3+x(3)^4;
function [c, ceq] = cons(x)
c=[];
ceq(1) = sum(ps(1,:))*x(1)+sum(ps(2,:))*x(2)+sum(ps(3,:))*x(3) - (sum(d(1,:)));
ceq(2) = sum(x) - 4;
I'm getting following error, what is wrong here?
variable or function 'ps' undefined
You don't need to and definitelty should not use global variables for this. It is a very bad habit and inefficient to boot. Any time you think about using global you should ask yourself if there is another way and search for it. It is only in the very very rare case that globals are needed/helpful (usually in large codebases such as toolboxes).
In your case, you should pass your ps variable in as a parameter by creating an anonymous function. First define your cons function like this so that it takes in a parameter argument:
function [c, ceq] = cons(x,ps)
Then create the anonymous function with one input (x) and one captured parameter (the variable ps, which needs to be defined before this):
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],#(x)cons(x,ps));
Alternatively you can save a handle to the anonymous function and pass that in:
cfun = #(x)cons(x,ps);
[x, fval] = fmincon(#Obj,[1/3,1/3, 1/3],[],[],[],[],[],[],cfun);
Here's a blog post from The MathWorks with other bad habits.
I cannot run your lines of code, but I think you have to put
global ps
in your function cons to inform Matlab that you are referring to the global ps. More information on global variables can be found here: http://www.mathworks.de/de/help/matlab/ref/global.html
EDIT: For a cleaner design, you should take into account horchler's advice: https://stackoverflow.com/a/20721808/3060323

Parameter passing to function handle

I have a function and I want to each time change its input and integrate over a certain interval. For example, I first write an m file:
function y = myfun(x)
y = 1 ./ (x.^3 - 2*x - 5);
Now I want to integrate functions like myfun(x-2) or myfun(2*x). Does anyone know how I should pass them? Integral(myfun(x-2),a,b) creates an error.
Thanks
I suggest calling integral on a handle for your function as below:
h1 = #(x)myfun(x);
h2 = #(x)myfun(x-2);
h3 = #(x)myfun(x.^2);
integral(h1,a,b);
integral(h2,a,b);
integral(h3,a,b);
This should trick the integral function into thinking that you are just defining myfun as a function of x while allowing you to pass whatever expression you want to it. You could also pass additional parameters this way, such as:
h = #(x)myfun(x, params);
integral(h,a,b);
Where params could be a list of parameters that you use in your definition of myfun.
I hope that helps.
EDIT: I tested this on a server that I have access to which does have the integral function and it seemed to work. Hopefully this answers your question.