function obj = objective_function(firstArg,funcName,evalLocs,obs,objName)
%OBJECTIVE_FUNCTION Calculates the objective function value of any input function and set of evaluation points.
% obj = objective_function(firstArg,funcName,evalLocs,obs,objName)
%
% Descriptions of Input Variables:
% firstArg: this will be either the string 'initialize', or an array of
% values that will be passed to the function for evaluation. Use
% 'initialize' prior to optimization to set the values of funcName, obs,
% and objName. Then, during either manual calibration or
% optimization, this variable, an array, will be passed to funcName along with vals.
% The output of this function will then be used, along with obs, to
% calculated the objective function value specified by objName.
% funcName: the name of the function to be evaluated. Input to this
% function must be of the form funcName(vals,[a,b,c...]) where a,b,and c
% are the parameters to be optimized.
% evalLocs: the points at which funcName will be evaluated.
% obs: 'observed' values at vals, to which the output of funcName will be
% compared.
% objName: name of the objective function to be used, current options are
% 'SSR': sum of squared residuals, and 'MAE': mean absolute error,
% and 'MPAE': mean percent absolute error, and 'LMAE': log mean
% absolute error
%
% Descriptions of Output Variables:
% obj: objective function value, a single scalar quantity
%
% Example(s):
% >> objective_function('initialize','gamma_distribution',obsLocs,obsVals,'MAE');
% followed by:
% >> objVal = objective_function([0.1,0.2]); this will evaluate
% 'gamma_distribution' with these two parameters at obsLocs, and return
% the mean absolute error objective function value by comparison to
% obsVals
%
% See also:
% Author: Anthony Kendall
% Contact: anthony [dot] kendall [at] gmail [dot] com
% Created: 2008-05-16
% Copyright 2008 Michigan State University.
%Update this list as new objective functions are added below
objOptions= {'mae','ssr','mpae','lmae'};
%data stores the function handles and evaluation data
persistent data
%Define the accepted objName values
if ischar(firstArg)
%Assert that there is an adequate number of inputs
error(nargchk(5,5,nargin,'struct'));
switch lower(firstArg)
case 'initialize'
%Return the function handle of the input function name, does
%not test for validity of the name
funcHandle = eval(['@',funcName]);
%Determine if the input objective function value is valid, and
%if so, return the function handle for that objective function
if any(strcmpi(objName,objOptions))
objHandle = eval(['@',lower(objName)]);
else
error('Unrecognized objective function name, see HELP');
end
data = struct('funcHandle',funcHandle,'eval',evalLocs,'obs',obs,'objHandle',objHandle);
otherwise
error('Unrecognized option for firstArg, see HELP')
end
else
%Assert that there is an adequate number of inputs
error(nargchk(1,1,nargin,'struct'));
%Evaluate the simulated values with the passed parameters
sim = data.funcHandle(data.eval,firstArg);
%Calculate the objective function value
obj = data.objHandle(sim,data.obs);
end
end
%Objective function evaluation options
function output = ssr(sim,obs)
output = sum((sim(:)-obs(:))^2);
end
function output = mae(sim,obs)
output = mean(abs(sim(:)-obs(:)));
end
function output = mpae(sim,obs)
output = mean(abs(sim(:)-obs(:))./obs(:));
end
function output = lmae(sim,obs)
output = mean(abs(log(sim(:)) - log(obs(:))));
end