You're pretty close. What you have to do is place all of the parameters that you want to optimize into a single vector . Also, inside the residual function you want to minimize, the inputs must also be in a vector. Therefore, a, b, c would be passed in as a vector into your residual function, and input1, input2, input3 are constant and don't change over the evolution of the search. These are also vectors of the same length.
Therefore, you really just have to do this. First, change your residual function so that it accepts a vector parameter of inputs:
function residual = CalculateResidual(x, input1, input2, input3)
%for example
a = x(1); b = x(2); c = x(3); %// Change here
residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end
Now, just call fminsearch normally but specifying a vector of parameters as the starting position:
X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC]);
The first input is a function that you are trying to minimize. In this case, we provide a handle to CalculateResidual with input1, input2, input3 all being static. This is required because the function you want to minimize for fminsearch can only accept a signature with one input argument - namely the parameters to be optimized at a certain iteration. You then specify the initial starting points as a vector.
Once you have that, then you should be solid! You would then unwrap the parameters from the output and assign them to a,b,c, so:
a = X(1); b = X(2); c = X(3);
To piece it all together, your code would look like this:
function [a,b,c] = SolveForParameters(input1, input2, input3)
%finds the parameters a, b, and c by minimizing the function CalculateResidual
startA = 3;
startB = 1;
startC = 0;
X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC]);
a = X(1); b = X(2); c = X(3); %// Final assignment
end
function residual = CalculateResidual(x, input1, input2, input3)
%for example
a = x(1); b = x(2); c = x(3); %// Change here
residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end
Running the above code with input1 = sin(1:10), input2 = cos(1:10), input3 = tan(1:10) gives me the following a,b,c given the start positions:
>> format long g;
>> [a,b,c] = SolveForParameters(1:10, 11:20, 21:30)
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: -5.127366
a =
2.6014e-06
b =
325.4224
c =
-2.0911
You get that exit warning because we couldn't quite minimize the residuals given the default number of iterations. You can increase the total number of iterations by increasing the number of function evaluations and maximum iterations the optimization routine takes. That can be done with optimset. Therefore, let's change your code slightly:
function [a,b,c] = SolveForParameters(input1, input2, input3)
%finds the parameters a, b, and c by minimizing the function CalculateResidual
startA = 3;
startB = 1;
startC = 0;
%// New - Change optimization options
options = optimset('fminsearch');
options.MaxFunEvals = 10000;
options.MaxIter = 10000;
%// New - also include options for optimization
X = fminsearch(@(x) CalculateResidual(x, input1, input2, input3), [startA;startB;startC], options);
a = X(1); b = X(2); c = X(3); %// Final assignment
end
function residual = CalculateResidual(x, input1, input2, input3)
%for example
a = x(1); b = x(2); c = x(3); %// Change here
residual = (sum(input1*(a-b)) + sum(input2)*sqrt(a*1.5)*a) / (sum(input3+b) + sum(input2/log(sum(input1))/(a+c)));
end
Doing options = optimset('fminsearch'); generates the default parameters used in fminsearch. We then override the defaults by changing the number of function evaluations and number of iterations to 10000. We also provide this as an additional parameter to fminsearch to let the function know we are providing some changes to the default parameters for the optimization routine.
By doing this, we now get:
>> [a,b,c] = SolveForParameters(1:10, 11:20, 21:30)
a =
7.4210e-07
b =
325.4225
c =
-2.0911
input1, input2andinput3all static? That is, do these change over time?... or are they constant during the optimization? You didn't specify what these parameters are.