EVAL_QUAD_COST Evaluates individual or full set of quadratic costs. F = OM.EVAL_QUAD_COST(X ...) [F, DF] = OM.EVAL_QUAD_COST(X ...) [F, DF, D2F] = OM.EVAL_QUAD_COST(X ...) [F, DF, D2F] = OM.EVAL_QUAD_COST(X, NAME) [F, DF, D2F] = OM.EVAL_QUAD_COST(X, NAME, IDX_LIST) Evaluates the cost function and its derivatives for an individual named set or the full set of quadratic costs for a given value of the optimization vector X, based on costs added by ADD_QUAD_COST. Example: [f, df, d2f] = om.eval_quad_cost(x) [f, df, d2f] = om.eval_quad_cost(x, name) [f, df, d2f] = om.eval_quad_cost(x, name, idx_list) See also OPT_MODEL, ADD_QUAD_COST, PARAMS_QUAD_COST.
0001 function [f, df, d2f] = eval_quad_cost(om, x, name, idx) 0002 %EVAL_QUAD_COST Evaluates individual or full set of quadratic costs. 0003 % F = OM.EVAL_QUAD_COST(X ...) 0004 % [F, DF] = OM.EVAL_QUAD_COST(X ...) 0005 % [F, DF, D2F] = OM.EVAL_QUAD_COST(X ...) 0006 % [F, DF, D2F] = OM.EVAL_QUAD_COST(X, NAME) 0007 % [F, DF, D2F] = OM.EVAL_QUAD_COST(X, NAME, IDX_LIST) 0008 % Evaluates the cost function and its derivatives for an individual named 0009 % set or the full set of quadratic costs for a given value of the 0010 % optimization vector X, based on costs added by ADD_QUAD_COST. 0011 % 0012 % Example: 0013 % [f, df, d2f] = om.eval_quad_cost(x) 0014 % [f, df, d2f] = om.eval_quad_cost(x, name) 0015 % [f, df, d2f] = om.eval_quad_cost(x, name, idx_list) 0016 % 0017 % See also OPT_MODEL, ADD_QUAD_COST, PARAMS_QUAD_COST. 0018 0019 % MP-Opt-Model 0020 % Copyright (c) 2008-2020, Power Systems Engineering Research Center (PSERC) 0021 % by Ray Zimmerman, PSERC Cornell 0022 % 0023 % This file is part of MP-Opt-Model. 0024 % Covered by the 3-clause BSD License (see LICENSE file for details). 0025 % See https://github.com/MATPOWER/mp-opt-model for more info. 0026 0027 if om.qdc.N 0028 done = 0; 0029 0030 %% collect cost parameters 0031 if nargin < 3 %% full set 0032 [Q, c, k, vs] = om.params_quad_cost(); 0033 N = 1; 0034 elseif nargin < 4 || isempty(idx) %% name, no idx provided 0035 dims = size(om.qdc.idx.i1.(name)); 0036 if prod(dims) == 1 %% simple named set 0037 [Q, c, k, vs] = om.params_quad_cost(name); 0038 N = om.getN('qdc', name); 0039 elseif nargout == 1 %% indexing required, recurse 0040 f = 0; %% initialize cumulative cost 0041 idx = num2cell(ones(size(dims))); %% initialize idx 0042 while ~done %% call eval_quad_cost() recursively 0043 f = f + sum(om.eval_quad_cost(x, name, idx)); 0044 0045 %% increment idx 0046 D = length(dims); 0047 idx{D} = idx{D} + 1; %% increment last dimension 0048 for d = D:-1:2 %% increment next dimension, if necessary 0049 if idx{d} > dims(d) 0050 idx{d} = 1; 0051 idx{d-1} = idx{d-1} + 1; 0052 end 0053 end 0054 if idx{1} > dims(1) %% check if done 0055 done = 1; 0056 end 0057 end 0058 else 0059 error('@opt_model/eval_quad_cost: quadratic cost set ''%s'' requires an IDX_LIST arg when requesting DF output', name) 0060 end 0061 else %% indexed named set 0062 [Q, c, k, vs] = om.params_quad_cost(name, idx); 0063 N = om.getN('qdc', name, idx); 0064 end 0065 0066 if ~done 0067 %% assemble appropriately-sized x vector 0068 xx = om.varsets_x(x, vs, 'vector'); 0069 0070 %% compute/assemble f 0071 if N == 1 %% f is scalar (Q is matrix, k is scalar) 0072 f = k; %% start with k term 0073 if ~isempty(c) 0074 f = f + c'*xx; %% add c term 0075 end 0076 if ~isempty(Q) %% add Q term 0077 f = f + (xx'*Q*xx)/2; 0078 end 0079 else %% f is vector (Q is vector or empty, k is vector or scalar) 0080 if isempty(c) %% Q, k terms only 0081 f = (Q .* xx.^2)/2 + k; 0082 else 0083 if isempty(Q) %% c, k terms only 0084 f = c .* xx + k; 0085 else %% Q, c, k terms 0086 f = (Q .* xx.^2)/2 + c .* xx + k; 0087 end 0088 end 0089 end 0090 0091 if nargout > 1 0092 %% compute/assemble df 0093 if ~isempty(c) 0094 df = c; %% start with c term 0095 else 0096 df = 0; %% start with nothing 0097 end 0098 if ~isempty(Q) 0099 if N == 1 %% f is scalar (Q is matrix, k is scalar) 0100 df = df + Q*xx; %% add Q term 0101 else %% f is vector (Q is vector or empty, k is vector or scalar) 0102 df = df + Q.*xx; %% add Q term 0103 end 0104 end 0105 0106 %% assemble d2f 0107 if nargout > 2 0108 if isempty(Q) 0109 nx = length(xx); 0110 if N == 1 %% f is scalar (Q is matrix, k is scalar) 0111 d2f = sparse(nx, nx); 0112 else %% f is vector (Q is vector or empty, k is vector or scalar) 0113 d2f = sparse(nx, 1); 0114 end 0115 else 0116 d2f = Q; 0117 end 0118 end 0119 end %% nargout > 1 0120 end %% ~done 0121 else 0122 f = 0; 0123 if nargout > 1 0124 % nx = length(x); 0125 % df = zeros(nx, 1); 0126 df = []; 0127 if nargout > 2 0128 % d2f = sparse(nx, nx); 0129 d2f = []; 0130 end 0131 end 0132 end