Best way to minimize a function with a large vector variable? - matlab

I am trying to minimize a function that is a function of a 1x25 vector (weights_vector). In other words, I'm trying to find the values in the vector that minimize the function.
The function is defined by:
function weights_correct = Moo(weights_vector)
corr_matrix = evalin('base', 'corr_matrix');
tolerance = evalin('base', 'tolerance');
returns = evalin('base', 'returns');
weights_correct = weights_vector'*corr_matrix*weights_vector - tolerance*returns'*weights_vector;
end
On this function, I am calling:
weights_correct = fminsearch(#Moo, weights_vector);
This iterates until I see the error
"Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option."
Which leads me to believe that I'm not minimizing correctly. What's going on?

Use of evalin here is silly. Multiple calls to evalin will be inefficient for no reason. If you will make the effort to learn to use evalin for the wrong purpose, instead, make the effort to learn how to use function handles.
You need not even define an m-file, although you could do so. A simple function handle will suffice.
Moo = #(w_v) w_v'*corr_matrix*w_v-tolerance*returns'*w_v;
Then call a better optimizer. Use of fminsearch on a 25 variable problem is INSANE. The optimization toolbox is worth the investment if you will do optimization a lot.
weights_correct = fminunc(#Moo, weights_vector);
Or, you can do it all in one line.
weights_correct = fminunc(#(w_v) w_v'*corr_matrix*w_v-tolerance*returns'*w_v, weights_vector);
See that when you create the function handle here, MATLAB passes in the values of those arrays.
Finally, the problem with max function evals is a symptom of what you are doing. 25 variables is too much to expect convergence in any reasonable amount of time for fminsearch. You can change the limit of course, but better is to use the right tool to begin with.

You are exceeding the default number of function evaluations. You could change that using
weights_correct = fminsearch(#Moo, weights_vector, optimset('MaxFunEvals', num);
where num is some number you specify. The default is 200*numberOfVariables.
I am certainly not an expert, and please, somebody correct me, but 25 variables seems like a lot to ask for an optimization routine.

Related

MATLAB: how to discretize a function of 10 variables (currently using ndgrid and arrayfun)?

I have a function
function [output1 output2] = func(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10)
that I want to discretize. I am going to be performing optimization that involves this function and I think the optimization's efficiency would benefit from discretizing the function and then doing spline interpolation on the data instead of having to evaluate the continuous function. Essentially I would want a 10-D double for each of output1 and output2 that correlates with varying values of v1, v2, ... v10.
With infinite time and memory I would do the following:
n_pts = 100;
v1 = linspace(v1_min, v1_max, n_pts);
...
v10 = linspace(v10_min, v10_max, n_pts);
[v1g v2g ... v10g] = ndgrid(v1, v2, ... v10);
[output1, output2] = arrayfun(#func, v1g, v2g, ... v10g);
Time and memory (needed to execute ndgrid and arrayfun) obviously do not allow for this. Can anyone think of work-around, or is this problem of discretizing a function of 10 variables totally intractable?
You are on a totally wrong path. Assuming you had infinite memory, you would call your function 100^10 times in the last line. That would require a lot of time. No reasonable optimisation strategy would call your function that many times, that's the reason why all those complicated strategies are developed.
You may use your strategy to pre-compute computation intensive sub terms of your function. Replacing a very cost-intensive term with only three variables with a 100^3 lookup table might increase the performance significantly without using to much memory.

In Matlab, is there a way to take in a formula as parameter input?

This might seem like a strange thing to do, which it probably is. In my main (or how you call it in matlab) I would like to have all the information needed for the program to run. A change of variables or formulas should only happen in my main.
For example I would like to change the number of iterations and the formula of the hypothese in my main and let other function use these, instead of declaring them within the function themselves and having to edit it all over the place. The problem I face is not knowing how to do this properly for hypothese_formula and wonder if there is a better way of doing this?
function prog1()
iterations = 1;
hypothese_formula = x^2;
doSomethingWithFormulaAndIterations(hypothese_formula, iterations);
end
Practical: I would to do linear regression with a hypothesis of the formula and specific starting values of theta and don't want them to be hidden within a function. I don't know how to declare global formula's.
You can use anonymous functions.
function prog1()
iterations = 1;
hypothese_formula = #(x) x.^2
doSomethingWithFormulaAndIterations(hypothese_formula, iterations);
end

Number of outputs from constant anonymous function (anonymous function not known a priori)

This question may initially appear similar to this other question but my situation is a little bit different.
I have a function 'deriv' that takes a symbolic expression as its input, then takes the first derivative of that symbolic expression. That derivative is then converted into an anonymous function using matlabFunction(), and is then evaluated over an array of points. I also use the anonymous function later in some other code.
The problem I'm having is that sometimes the input symbolic expression happens to be linear, and thus the derivative is constant; therefore the anonymous function is also a constant. When I evaluate the anonymous function over the array of points, I only get one output instead of an array of outputs.
Here's some code showing what I'm doing. For the sake of simplicity here, let's assume that the symbolic input expressions will involve only one symbolic variable called q.
function[derivFun,derivVals] = deriv(input)
derivSym = diff(input,q);
derivFun = matlabFunction(derivSym,'vars',q);
evalPoints = [1;2;3;4;5]; %in my true application, a much larger array
derivVals = derivFun(evalPoints);
end
So if the input is q^2, then the output derivVals will be [2;4;6;8;10]. But if the input happens to be, say, 3*q, then derivVals will be 3 (just a single scalar). What I'd like is for derivVals to be [3;3;3;3;3].
That is, I'd like derivVals to be the same size as evalPoints even if the input function happens to be linear (or constant). And I don't know ahead of time what the input expression will be.
Can anyone give suggestions for a scheme that would do that? I understand that a constant anonymous function will just return a single constant scalar, regardless of the size of its input. What I'm hoping for is perhaps some way to recognize when the anonymous function is constant and then still cause derivVals to be the same size as evalPoints.
I know that I could use a for loop to evaluate derivFun for every row of evalPoints, but I'd like to avoid using such a loop if possible.
Thank you for your time and consideration.
I think that this is a slightly simpler solution. The issue is that you're using matlabFunction, which simplifies down the equations and doesn't allow much customization. However, you can create an anonymous function of an anonymous function. Just add the this line right after your matlabFunction line:
derivFun = #(evalPoints)derivFun(evalPoints)+zeros(size(evalPoints));
This only evaluates the original derivFun once. However, I do like you symvar solution (just remember that adding zeros is always better than multiplying ones).
Not 100% sure I got the problem correctly.
Would this solve your issue?:
if isscalar(derivVals)
derivVals = repmat(derivVals, size(evalPoints));
end

how to create a changing variable for fsolve

i want fsolve to calculate the output for different uc each time (increasing uc by 0.001 each time). each output from fsolve should be sent to a simulink model seperatly. so i set a loop to do so, but i believe that at the currenty constellation (if it will work)will just calculate 1000 different values? is there a way to send out the values seperately?
if not, how can i create a parameter uc. that goes from 0 to say 1000? i tried uc=0:0.001:1000, but again, the demension doen't seem to fit.
how do i create a function that takes the next element of a vector/matrix each time the function is called?
best regards
The general approach to iterating over an array of values and feeding them one-by-one into a series of evaluations of a function follows this form:
for ix = 0:0.1:10
func(arg1, arg2, ix)
end
See how each call to func includes the current value of ix ? On the first iteration ix==0, on the next ix==0.1 and so forth. You should be able to adapt this to your needs; in your code the loop index (which you call i) is not used inside the loop.
Now some un-asked-for criticism of your code. The lines
x0=[1,1,1];
y=x0(1);
u=x0(2);
yc=x0(3);
options=optimset('Display','off');
do not change as the loop iterations advance; they always return the same values whatever the value of the loop iterator (i in your code) may be. It is pointless including them inside the loop.
Leaving them inside the loop may even be a waste of a lot of time if Matlab decides to calculate them at every iteration. I'm not sure what Matlab does in this case, it may be smart enough to figure out that these values don't change at each iteration, but even if it does it is bad programming practice to write your code this way; lift constant expressions such as these out of loops.
It's not clear from the fragment you've posted why you have defined y, u and yc at all, they're not used anywhere; perhaps they're used in other parts of your program.

MATLAB: alternatives to calling feval in ode45

I hope I am on topic here. I'm asking here since it said on the faq page: a question concerning (among others) a software algorithm :) So here it goes:
I need to solve a system of ODEs (like $ \dot x = A(t) x$. The Matrix A may change and is given as a string in the function call (Calc_EDS_v2('Sys_EDS_a',...)
Then I'm using ode45 in a loop to find my x:
function [intervals, testing] = EDS_calc_v2(smA,options,debug)
[..]
for t=t_start:t_step:t_end)
[Te,Qe]=func_int(#intQ_2_v2,[t,t+t_step],q);
q=Qe(end,:);
[..]
end
[..]
with func_int being ode45 and #intQ_2_v2 my m-file. q is given back to the call as the starting vector. As you can see I'm just using ode45 on the intervall [t, t+t_step]. That's because my system matrix A can force ode45 to use a lot of steps, leading it to hit the AbsTol or RelTol very fast.
Now my A is something like B(t)*Q(t), so in the m-file intQ_2_v2.m I need to evaluate both B and Q at the times t.
I first done it like so: (v1 -file, so function name is different)
function q=intQ_2_v1(t,X)
[..]
B(1)=...; ... B(4)=...;
Q(1)=...; ...
than that is naturally only with the assumption that A is a 2x2 matrix. With that setup it took a basic system somewhere between 10 and 15 seconds to compute.
Instead of the above I now use the files B1.m to B4.m and Q1.m to B4.m (I know that that's not elegant, but I need to use quadgk on B later and quadgk doesn't support matrix functions.)
function q=intQ_2_v2(t,X)
[..]
global funcnameQ, funcnameB, d
for k=1:d
Q(k)=feval(str2func([funcnameQ,int2str(k)]),t);
B(k)=feval(str2func([funcnameB,int2str(k)]),t);
end
[..]
funcname (string) referring to B or Q (with added k) and d is dimension of the system.
Now I knew that it would cost me more time than the first version but I'm seeing the computing times are ten times as high! (getting 150 to 160 seconds) I do understand that opening 4 files and evaluate roughly 40 times per ode-loop is costly... and I also can't pre-evalute B and Q, since ode45 uses adaptive step sizes...
Is there a way to not use that last loop?
Mostly I'm interested in a solution to drive down the computing times. I do have a feeling that I'm missing something... but can't really put my finger on it. With that one taking nearly three minutes instead of 10 seconds I can get a coffee in between each testrun now... (plz don't tell me to get a faster computer)
(sorry for such a long question )
I'm not sure that I fully understand what you're doing here, but I can offer a few tips.
Use the profiler, it will help you understand exactly where the bottlenecks are.
Using feval is slower than using function handles directly, especially when using str2func to build the handle each time. There is also a slowdown from using the global variables (and it's a good habit to avoid these unless absolutely necessary). Each of these really adds up when using them repeatedly (as it looks like here). Store function handles to each of your mfiles in a cell array and either pass them directly to the function or use nested function for the optimization so that the cell array of handles is visible to the function being optimized. Personally, I prefer the nested method, but passing is better if you will use those mfiles elsewhere.
I expect this will get your runtime back to close to what the first method gave. Be sure to tell us if this was the problem or if you found another solution.