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
Related
I have N functions in MATLAB and I can define them using strcat, num2str and eval in a for loop. So without defining by hand I am able to define N functions. Let N=4 and let them be given as follows:
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
Now I add these four functions and I can do this by hand as follows:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x));
Here I can do it by hand because I know that N=4. However, in general I never know how many functions I will have. For all cases I cannot write a new function.
Is there any way to do this automatically? I mean if I give N=6 I am expecting to see MATLAB giving me this:
f=#(x)(f1(x)+f2(x)+f3(x)+f4(x)+f5(x)+f6(x));
Whenever I give N=2 then I must have the function f, defined as follows:
f=#(x)(f1(x)+f2(x));
How can we do this?
First of all, you should read this answer that gives a series of reasons to avoid the use of eval. There are very few occasions where eval is necessary, in all other cases it just complicates things. In this case, you use to dynamically generate variable names, which is considered a very bad practice. As detailed in the linked answer and in further writings linked in that answer, dynamic variable names make the code harder to read, harder to maintain, and slower to execute in MATLAB.
So, instead of defining functions f1, f2, f3, ... fN, what you do is define functions f{1}, f{2}, f{3}, ... f{N}. That is, f is a cell array where each element is an anonymous function (or any other function handle).
For example, instead of
f1=#(x) a1*x+1;
f2=#(x) a2*x+1;
f3=#(x) a3*x+1;
f4=#(x) a4*x+1;
you do
N = 4;
a = [4.5, 3.4, 7.1, 2.1];
f = cell(N,1);
for ii=1:N
f{ii} = #(x) a(ii) * x + 1;
end
With these changes, we can easily answer the question. We can now write a function that outputs the sum of the functions in f:
function y = sum_of_functions(f,x)
y = 0;
for ii=1:numel(f)
y = y + f{ii}(x);
end
end
You can put this in a file called sum_of_functions.m, or you can put it at the end of your function file or script file, it doesn't matter. Now, in your code, when you want to evaluate y = f1(x) + f2(x) + f3(x)..., what you write is y = sum_of_functions(f,x).
Say that I have the following function
function y = f(x,a)
if nargin < 2
a = 2;
end
y = x.^2 - a;
end
I have another function which finds the root through Newton's method. Say that this is how I call upon the method :
newton(#f,#df,x0)
If I run the newton function with the supplied arguments, then it will only run for the default value of a = 2.
I was wondering if it is possible to some how specify a default parameter for a function when sending it through a function handle. Like this for instance
newton(#f(a),#df,x0)
If you mean this newton, then it expects a univariate function. You can still use your bivariate function f, but you have to be tricky: you need to define a new, anonymous function, and use your variable a as parameter to that:
a = 3; %or any other specific value, have to be set before calling newton
newton(#(x) f(x,a),#df,x0)
If you find that more transparent, you can also do it in a separate step:
f_uni = #(x) f(x,a); %defines f_uni(x), "a" is a parameter to it
newton(f_uni,#df,x0);
Note that in this case f_uni is already a function handle, so you don't have to (and mustn't) put a # before it.
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.
Is it possible to use an anonymous function as an event function in Matlab. What I want to do is basically
opt = odeset('Events', #(t,y) (deal(y(end)-t^2,1,0)));
[T,Y] = ode45(#odefun,[tstart tend],y0,opt);
However, this returns an error complaining that the number of outputs to deal must be matched exactly. Is there some other way to make the anonymous function return multiple arguments?
I noticed this post looking for the answer to the same question. This means that for some people the question may be still valid. Since finally I found the solution by myself, I'd like to give a little bit "outdated" answer.
Actually, yes - it's possible but not straightforward. Try this:
evnt_fun = #(t, f)subsref({'some stop condition', 1, 0}, struct('type', '{}', 'subs', {{':'}}));
I'm not able to fully check the backward-compatibility of the code. However, it works with R2011 and later MATLAB versions.
No, you can't do it. Anonymous functions in Matlab only ever return one value.
Instead, you could define a thin wrapper around deal and pass your wrapper as a handle:
function [a b c] = wrapper(t,y)
[a b c] = deal('some stop condition', 1, 0);
end
opt = odeset('Events', #wrapper);
[T, Y] = ode45(#odefun, [tstart tend], y0, opt);
Also (this is very late in the game to be adding to this, but this frustrates me). Here is a solution with nested functions:
function [ dealfunchandle ] = dealwithit( arrayfunc )
% Takes as input an event function of (t,z) that returns a 3 array (in same order as event syntax).
function [a, b, c] = dealfunc(t,z)
output = arrayfunc(t,z);
a = output(:,1);
b = output(:,2);
c = output(:,3);
end
dealfunchandle = #dealfunc;
end
This function only has to be written once (handy if you have to use lots of different event functions). This can be used to generate an anonymous event function within the code as follows:
arrayfunc = #(t,y) [y(1), 0, 1];
events = dealwithit(arrayfunc);
opts = odeset('Events', events);
And then ode45 as per normal.
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