0001 function [f, df, d2f] = eval_nln_cost(om, x, name, idx)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 if nargin < 4
0027 idx = {};
0028 end
0029 nlc = om.nlc;
0030
0031 if nargin < 3
0032 f = 0;
0033 nx = om.var.N;
0034 if nargout > 1
0035 df = zeros(nx, 1);
0036 if nargout > 2
0037 d2f = sparse(nx, nx);
0038 end
0039 end
0040
0041 for k = 1:nlc.NS
0042 name = nlc.order(k).name;
0043 idx = nlc.order(k).idx;
0044 [N, fcn, vs] = om.params_nln_cost(name, idx);
0045 if N ~= 1
0046 error('@opt_model/eval_nln_cost: not yet implemented for vector valued functions');
0047 end
0048 xx = om.varsets_x(x, vs);
0049 if nargout == 3
0050 [fk, dfk, d2fk] = fcn(xx);
0051 elseif nargout == 2
0052 [fk, dfk] = fcn(xx);
0053 else
0054 fk = fcn(xx);
0055 end
0056
0057 f = f + fk;
0058
0059 if nargout > 1
0060 nk = length(dfk);
0061 if isempty(vs)
0062 if nk == nx
0063 df = df + dfk;
0064 if nargout > 2
0065 d2f = d2f + d2fk;
0066 end
0067 else
0068
0069 df(1:nk) = df(1:nk) + dfk;
0070 if nargout > 2
0071 d2fk_all_cols = sparse(nk, nx);
0072 d2fk_all_cols(:, 1:nk) = d2fk;
0073 d2fk_full = sparse(nx, nx);
0074 d2f(:, 1:nk) = d2f(:, 1:nk) + d2fk_all_cols';
0075 end
0076 end
0077 else
0078 jj = om.varsets_idx(vs);
0079 df(jj) = df(jj) + dfk;
0080 if nargout > 2
0081 d2fk_all_cols = sparse(nk, nx);
0082 d2fk_all_cols(:, jj) = d2fk;
0083 d2fk_full = sparse(nx, nx);
0084 d2f(:, jj) = d2f(:, jj) + d2fk_all_cols';
0085 end
0086 end
0087 end
0088 end
0089 else
0090 dims = size(nlc.idx.i1.(name));
0091 if ~isempty(idx) || prod(dims) == 1
0092 [N, fcn, vs] = om.params_nln_cost(name, idx);
0093 if N ~= 1
0094 error('@opt_model/eval_nln_cost: not yet implemented for vector valued functions');
0095 end
0096 xx = om.varsets_x(x, vs);
0097 if nargout == 3
0098 [f, df, d2f] = fcn(xx);
0099 elseif nargout == 2
0100 [f, df] = fcn(xx);
0101 else
0102 f = fcn(xx);
0103 end
0104 elseif nargout == 1
0105 done = 0;
0106 f = 0;
0107 idx = num2cell(ones(size(dims)));
0108 while ~done
0109 f = f + sum(om.eval_nln_cost(x, name, idx));
0110
0111
0112 D = length(dims);
0113 idx{D} = idx{D} + 1;
0114 for d = D:-1:2
0115 if idx{d} > dims(d)
0116 idx{d} = 1;
0117 idx{d-1} = idx{d-1} + 1;
0118 end
0119 end
0120 if idx{1} > dims(1)
0121 done = 1;
0122 end
0123 end
0124 else
0125 error('@opt_model/eval_nln_cost: general nonlinear cost set ''%s'' requires an IDX_LIST arg when requesting DF output', name)
0126 end
0127 end