minFunc package usage - matlab

I have been using MATLAB fminunc function to solve my optimization problem. I want to try the minFunc package :
http://www.di.ens.fr/~mschmidt/Software/minFunc.html
When using fminunc, I defined a function funObj.m which gives me the objective value and the gradient at any point 'x'. It also takes in several external inputs say, {a,b,c} which are matrices. So the function prototype looks like :
function [objVal,G] = funObj(x,a,b,c)
I want to use the same setup in the minFunc package. From the examples, I figured this should work :
options.Method='lbfgs';
f = #(x)funObj(x,a,b,c);
x = minFunc(f,x_init,options);
But when I call this way, I get an error as:
Error using funObj
Too many output arguments.
What is the correct way to call minFunc for my case?
**EDIT : Alright, here is a sample function that I want to use with minFunc. Lets say I want to find the minimum of a*(b-x)^2, where a,b are scalar parameters and x being a scalar too. The MATLAB objective function will then look like :
function obj = testFunc(x,a,b)
obj = a*(b-x)^2;
The function call to minimize this using fminunc (in MATLAB ) is simply:
f = #(x)testFunc(x,a,b);
x = fminunc(f,x_init);
This gives me the minimum of x = 10. Now, How do I do the same using minFunc ?

"Note that by default minFunc assumes that the gradient is supplied, unless the 'numDiff' option is set to 1 (for forward-differencing) or 2 (for central-differencing)."
The error is because only one argument is returned by the function. You can either return the gradient as a second argument or turn on numerical differencing.

Agree with Mark. I think the simplest way to solve it is
minFunc(#testFunc, x_init, a, b, c)
In MATLAB temporary function can only have one return value. So f = #(x)testFunc(x,a,b); let your method drop gradient part every time. Because minFunc can accept extra paramters, you can pass a, b and c after x_init. I think this would work.

Related

vectorize a function with multiple variables

Consider the arbitrary function:
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput * secondInput;
end
Now imagine I want to map the above function to an array for the first input firstInput, while the second input secondInput is constant. For example, something like:
firstVariable = linspace(0., 1.);
plot(firstVariable, map(myFunc, [firstVariable , 0.1]))
where 0.1 is an arbitrary scalar value for the secondInput and firstVariable array is an arbitrary array for the firstInput.
I have looked into the arrayfun() function. However, I don't know how to include the constant variable. Plus it seems like the syntax between MATLAB and Octave are different, or maybe I'm mistaken. It is important for me to have a cross-compatible code that I can share with colleagues.
Assuming in the original function you were multiplying two scalars and you want to vectorise, then
function myFunc_ = myFunc(firstInput, secondInput)
myFunc_ = firstInput .* secondInput;
end
should work just fine.
Then plot it directly:
plot( firstVariable, myFunc(firstVariable , 0.1) )
I'm afraid the arbitrary examples given in the original question were too simplified and as a result, they do not represent the actual issue I'm facing with my code. But I did manage to find the right syntax that works inside Octave:
plot(firstVariable, arrayfun(#(tempVariable) myFunc(tempVariable, 0.1), firstVariable))
basically the
#(tempVariable) myFunc(tempVariable, 0.1)
creates what is so-called an anonymous function and the
arrayfun(<function>, <array>)
maps the function over the given array.

Operations with function handle in matlab

Could you please help me with the following issue: I have the following function handle:
r1 = #(lambda) b + lambda*(r - b); % r and b are vectors of return data
I want to find the optimal lambdas that set me a mean function to zero, for a given set of powers within that function. What I tried to do and didn't work, as it returns me an error for undefined operators for input arguments of type 'function_handle' is:
lambda0 = 0.3;
for a = 2:10 %power coefficient
S1(a) = fzero(mean((r - b)*r1.^(1/(a - 1))),lambda0);
end
Any suggestion as to how to go about this problem is highly appreciated! Thank you in advance.
fzero accepts a function handle as the first input. As you currently have it, you're trying to pass a statement as the first input. This statement can't even be properly evaluated because you are trying to perform numerical operations on a function handle (more on this in a bit).
You need to instead do something like this where we create a new function handle that evaluates the original function handle and performs the other operations you need.
S1(a) = fzero(#(lambda)mean((r - b)*r1(lambda).^(1/(a - 1))),lambda0);
Further Explanation
Performing operations on a function handle is not the same as performing them on the result.
So for example, if we had a function handle:
func = #(x)2*x;
If we evaluation this, by calling it with an input value for x
func(2)
4
This works as we would expect. If now we really want the value (2*x)^2, we could try to write it the way that you wrote your statement in your question
func2 = func^2;
We will get an error!
Undefined operator '^' for input arguments of type 'function_handle'.
This does not work because MATLAB attempts to apply the ^ operation to the function handle itself and not the value of the evaluated function handle.
Instead, we would need to create a new function handle that essentially wraps the other one and performs any additional options:
func2 = #(x)func(x)^2;
func2(2)
16
Bringing it Full-Circle
So if we go back to your question, you defined your anonymous function r1 like this.
r1 = #(lambda) b + lambda*(r - b); % r and b are vectors of return data
This all looks great. You have one input argument and you reference r and b from the parent workspace.
Now when you call fzero you try to perform operations on this function handle in hopes of creating a new function handle.
mean((r - b)*r1.^(1/(a - 1)))
Like we just showed this will result in a very similar error
Undefined operator .^ for input arguments of type 'function_handle'
So we need to wrap this into a new function.
newfunc = #(lambda)mean((r - b)*r1(lambda).^(1 / (a - 1)));
Now we can safely pass this to fzero.
result = fzero(newfunc, lambda0);

How to replace/modify something in a call to function 1 from within function 2 (both in their separate files)

The given task is to call a function from within another function, where both functions are handling matrices.
Now lets call this function 1 which is in its own file:
A = (1/dot(v,v))*(Ps'*Ps);
Function 1 is called with the command:
bpt = matok(P);
Now in another file in the same folder where function 1 is located (matok.m) we make another file containing function 2 that calls function 1:
bpt = matok(P);
What I wish B to do technically, is to return the result of the following (where D is a diagonal matrix):
IGNORE THIS LINE: B = (1/dot(v,v))*(Ps'*inv(D)*Ps*inv(D);
EDIT: this is the correct B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
But B should not "re-code" what has allready been written in function 1, the challenge/task is to call function 1 within function 2, and within function 2 we use the output of function 1 to end up with the result that B gives us. Also cause in the matrix world, AB is not equal to BA, then I can't simply multiply with inv(D) twice in the end. Now since Im not allowed to write B as is shown above, I was thinking of replacing (without altering function 1, doing the manipulation within function 2):
(Ps'*Ps)
with
(Ps'*inv(D)*Ps*inv(D)
which in some way I imagine should be possible, but since Im new to Matlab have no idea how to do or where even to start. Any ideas on how to achieve the desired result?
A small detail I missed:
The transpose shouldn't be of Ps in this:
B = (1/dot(v,v))*(Ps'*inv(D))*Ps*inv(D);
But rather the transpose of Ps and inv(D):
B = (1/dot(v,v))*(Ps*inv(D))'*Ps*inv(D);
I found this solution, but it might not be as compressed as it could've been and it seems a bit unelegant in my eyes, maybe there is an even shorter way?:
C = pinv(Ps') * A
E = (Ps*inv(D))' * C
Since (A*B)' = B'*A', you probably just need to call
matok(inv(D) * Ps)

auto derive arguments from base argument Matlab

I'm writing a function which have one value constant and others are derived in Matlab, I'm currently on that stage in which first argument is constant and others are derived,, but I want auto detection of constant and derived arguments.
Sample run is myfunc(7, #(b) -b,#(c) -c)
My function:
function p = myfunc(varargin)
a=varargin{1};
b=varargin{2};
c=varargin{3};
res = a-1;
p = [a b(a) c(a)];
end
What I wants is to input like myfunc(#(a) -a, 7,#(c) -c) or myfunc(#(a) -a, #(c) -c,7) are also possible.
You can see if a variable is an anonymous function using
isa(a,'function_handle')
or see if it is a number using
isa(a,'numeric')
so you could set up a switch or a series of if's based on what you get.

MATLAB- passing a function handle parameter into another function as a handle

Working on an assignment involving Genetic Algorithms (loads of headaches, loads of fun). I need to be able to test differing crossover methods and differing mutation methods, to compare their results (part of the paper I have to write for the course). As such, I want to just pass the function names into the Repopulate method, as function handles.
function newpop = Repopulate(population, crossOverMethod, mutationMethod)
...
child = crossOverMethod(parent1, parent2, #mutationMethod);
...
function child = crossOverMethod(parent1, parent2, mutationMethod)
...
if (mutateThisChild == true)
child = mutationMethod(child);
end
...
The key point here is like 3, parameter 3: how do I pass mutationMethod down another level? If I use the # symbol, I get told:
"mutationMethod" was previously used as a variable,
conflicting with its use here as the name of a function or command.
If I don't use the # symbol, then mutationMethod gets called, with no parameters, and is quite unhappy.
While I am aware that yes, I could just rewrite my code to make it work differently, I'm now curious as to how to make it actually work.
Any help is greatly appreciated.
Actually just dont use the # symbol, use it when you call the Repopulate function instead.
Example:
function x = fun1(a,m)
x = fun2(a,m);
end
function y = fun2(b,n)
y = n(b);
end
which we call as:
> fun1([1 2 3], #sum)
6
Refer to the documentation for Passing Function Handle Arguments
Note you can check if the argument is a function handle by: isa(m,'function_handle'). Therefore you can make your function Repopulate more flexible by accepting both a function handle and a function name as a string:
function x = fun(a,m)
if ischar(m)
f = str2func(m);
elseif isa(m,'function_handle')
f = m;
else
error('expecting a function')
end
x = fun2(a,f);
end
which now can be called both ways:
fun1([1 2 3], #sum)
fun1([1 2 3], 'sum')