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