[37] | 1 | function sys=double(X) |
---|
| 2 | %DOUBLE Returns current numerical value |
---|
| 3 | %bajs i bajs |
---|
| 4 | % Author Johan Löfberg |
---|
| 5 | % $Id: double.m,v 1.1 2006/08/10 18:00:19 joloef Exp $ |
---|
| 6 | |
---|
| 7 | solution = yalmip('getsolution'); |
---|
| 8 | lmi_variables = X.lmi_variables; |
---|
| 9 | opt_variables = solution.variables; |
---|
| 10 | |
---|
| 11 | % Definition of nonlinear variables |
---|
| 12 | [mt,variabletype] = yalmip('monomtable'); |
---|
| 13 | nonlinears = lmi_variables(find(variabletype(X.lmi_variables))); |
---|
| 14 | |
---|
| 15 | if ~isempty(solution.values) |
---|
| 16 | if max(lmi_variables) <= length(solution.values) & isempty(nonlinears) |
---|
| 17 | if ~any(isnan(solution.values(lmi_variables(:)))) |
---|
| 18 | % Yihoo, we can do this really fast by |
---|
| 19 | % re-using the old values |
---|
| 20 | sys = X.basis*[1;solution.values(lmi_variables(:))]; |
---|
| 21 | if X.typeflag==10 |
---|
| 22 | sys = eig(full(reshape(sys,X.dim(1),X.dim(2)))); |
---|
| 23 | else |
---|
| 24 | sys = full(reshape(sys,X.dim(1),X.dim(2))); |
---|
| 25 | end |
---|
| 26 | return |
---|
| 27 | end |
---|
| 28 | end |
---|
| 29 | end |
---|
| 30 | |
---|
| 31 | % Okey, we could not do it really fast... |
---|
| 32 | |
---|
| 33 | % Definition of nonlinear variables |
---|
| 34 | allextended = yalmip('extvariables'); |
---|
| 35 | allevaluators = yalmip('evalVariables'); |
---|
| 36 | allextended = union(allextended,allevaluators); |
---|
| 37 | |
---|
| 38 | if isempty(nonlinears) & isempty(allextended) & all(ismembc(lmi_variables,solution.variables)) |
---|
| 39 | |
---|
| 40 | % speed up code for simple linear case |
---|
| 41 | values = solution.values; |
---|
| 42 | if isempty(solution.values) |
---|
| 43 | values = sparse(solution.variables,ones(length(solution.variables),1),solution.optvar,size(mt,1),1); |
---|
| 44 | %values = zeros(size(mt,1),1); |
---|
| 45 | %values(solution.variables) = solution.optvar; |
---|
| 46 | yalmip('setvalues',values); |
---|
| 47 | else |
---|
| 48 | if any(isnan(solution.values(lmi_variables(:)))) |
---|
| 49 | values = sparse(solution.variables,ones(length(solution.variables),1),solution.optvar,size(mt,1),1); |
---|
| 50 | % values = zeros(size(mt,1),1); |
---|
| 51 | % values(solution.variables) = solution.optvar; |
---|
| 52 | yalmip('setvalues',values); |
---|
| 53 | end |
---|
| 54 | end |
---|
| 55 | |
---|
| 56 | sys = X.basis*[1;values(lmi_variables(:))]; |
---|
| 57 | if X.typeflag==10 |
---|
| 58 | sys = eig(full(reshape(sys,X.dim(1),X.dim(2)))); |
---|
| 59 | else |
---|
| 60 | sys = full(reshape(sys,X.dim(1),X.dim(2))); |
---|
| 61 | end |
---|
| 62 | |
---|
| 63 | return |
---|
| 64 | end |
---|
| 65 | |
---|
| 66 | % All double values |
---|
| 67 | values(size(mt,1),1)=nan;values(:)=nan; |
---|
| 68 | values(solution.variables) = solution.optvar; |
---|
| 69 | |
---|
| 70 | % Evaluate the extended operators |
---|
| 71 | if ~isempty(allextended) |
---|
| 72 | extended_variables = find(ismembc(X.lmi_variables,allextended)); |
---|
| 73 | if ~isempty(extended_variables) |
---|
| 74 | for i = 1:length(extended_variables) |
---|
| 75 | extvar = lmi_variables(extended_variables(i)); |
---|
| 76 | extstruct = yalmip('extstruct',extvar); |
---|
| 77 | |
---|
| 78 | for k = 1:length(extstruct.arg) |
---|
| 79 | if isa(extstruct.arg{k},'sdpvar') | isa(extstruct.arg{k},'constraint') |
---|
| 80 | extstruct.arg{k} = double(extstruct.arg{k}); |
---|
| 81 | end |
---|
| 82 | end |
---|
| 83 | |
---|
| 84 | switch extstruct.fcn |
---|
| 85 | |
---|
| 86 | case 'sort' |
---|
| 87 | [w,loc] = sort(extstruct.arg{1}); |
---|
| 88 | if extstruct.arg{2}.isthisloc |
---|
| 89 | val = loc(extstruct.arg{2}.i); |
---|
| 90 | else |
---|
| 91 | val = w(extstruct.arg{2}.i); |
---|
| 92 | end |
---|
| 93 | |
---|
| 94 | case 'semivar' |
---|
| 95 | % A bit messy, since it not really is a nonlinear |
---|
| 96 | % operator. semivar(1) does not return 1, but a new |
---|
| 97 | % semivar variable... |
---|
| 98 | val = values(getvariables(extstruct.var)); |
---|
| 99 | |
---|
| 100 | case 'geomean' % Not 100% MATLAB consistent (Hermitian case differ) |
---|
| 101 | val = extstruct.arg{1}; |
---|
| 102 | if ~any(any(isnan(val))) |
---|
| 103 | [n,m] = size(val); |
---|
| 104 | if n == m |
---|
| 105 | if issymmetric(val) |
---|
| 106 | val = max(0,real(det(val)))^(1/n); |
---|
| 107 | else |
---|
| 108 | val = geomean(val); |
---|
| 109 | end |
---|
| 110 | else |
---|
| 111 | val = geomean(val); |
---|
| 112 | end |
---|
| 113 | else |
---|
| 114 | val = nan; |
---|
| 115 | end |
---|
| 116 | |
---|
| 117 | case 'pwf' |
---|
| 118 | % Has to be placed here due to the case when |
---|
| 119 | % all functions are double, since in this case, |
---|
| 120 | % we cannot determine in pwf if we want the double or |
---|
| 121 | % create a pw constant function... |
---|
| 122 | n = length(extstruct.arg)/2; |
---|
| 123 | i = 1; |
---|
| 124 | val = nan; |
---|
| 125 | while i<=n |
---|
| 126 | if min(checkset(extstruct.arg{2*i}))>=0 |
---|
| 127 | val = extstruct.arg{2*i-1}; |
---|
| 128 | break |
---|
| 129 | end |
---|
| 130 | i = i + 1; |
---|
| 131 | end |
---|
| 132 | |
---|
| 133 | case 'mpower' |
---|
| 134 | val = extstruct.arg{1}; |
---|
| 135 | case {'max','min'} % Cannot take several inputs, put everything in a vector |
---|
| 136 | val = feval(extstruct.fcn,[extstruct.arg{:}]); |
---|
| 137 | case {'or','and'} |
---|
| 138 | try |
---|
| 139 | val = feval(extstruct.fcn,extstruct.arg{:}); |
---|
| 140 | catch |
---|
| 141 | val = nan; |
---|
| 142 | end |
---|
| 143 | |
---|
| 144 | otherwise |
---|
| 145 | try |
---|
| 146 | if ismembc(extvar,allevaluators) |
---|
| 147 | % Evaluator variables (used for exp, log, ...) |
---|
| 148 | % have an appended argument that we need to |
---|
| 149 | % remove. The appended variables is used |
---|
| 150 | % internally to convert from general format |
---|
| 151 | % f(a'x+c) to f(z), z==a'z+b |
---|
| 152 | val = feval(extstruct.fcn,extstruct.arg{1:end-1}); |
---|
| 153 | else |
---|
| 154 | val = feval(extstruct.fcn,extstruct.arg{:}); |
---|
| 155 | end |
---|
| 156 | catch |
---|
| 157 | val = nan; |
---|
| 158 | end |
---|
| 159 | end |
---|
| 160 | values(extvar) = full(val); |
---|
| 161 | end |
---|
| 162 | end |
---|
| 163 | end |
---|
| 164 | |
---|
| 165 | if ~isempty(nonlinears) |
---|
| 166 | mt_t = mt'; %Working columnwise is faster |
---|
| 167 | use_these = find(ismember(lmi_variables,nonlinears)); |
---|
| 168 | all_extended_variables = yalmip('extvariables'); |
---|
| 169 | all_evaluator_variables = yalmip('evalVariables'); |
---|
| 170 | all_extended_variables = union(all_extended_variables,all_evaluator_variables); |
---|
| 171 | |
---|
| 172 | for i = use_these |
---|
| 173 | monom_i = mt_t(:,lmi_variables(i)); |
---|
| 174 | used_in_monom = find(monom_i); |
---|
| 175 | |
---|
| 176 | if ~isempty(all_extended_variables) |
---|
| 177 | extended_variables = find(ismember(used_in_monom,all_extended_variables)); |
---|
| 178 | if ~isempty(extended_variables) |
---|
| 179 | for ii = 1:length(extended_variables) |
---|
| 180 | extvar = used_in_monom(extended_variables(ii)); |
---|
| 181 | extstruct = yalmip('extstruct',extvar); |
---|
| 182 | for k = 1:length(extstruct.arg) |
---|
| 183 | if isa(extstruct.arg{k},'sdpvar') |
---|
| 184 | extstruct.arg{k} = double(extstruct.arg{k}); |
---|
| 185 | end |
---|
| 186 | end |
---|
| 187 | |
---|
| 188 | switch extstruct.fcn |
---|
| 189 | |
---|
| 190 | case 'sort' |
---|
| 191 | w = sort(extstruct.arg{1}); |
---|
| 192 | val = w(extstruct.arg{2}); |
---|
| 193 | |
---|
| 194 | case 'semivar' |
---|
| 195 | val = values(getvariables(extstruct.var)); |
---|
| 196 | |
---|
| 197 | case 'mpower' % |
---|
| 198 | val = extstruct.arg{1}; |
---|
| 199 | case {'max','min'} % Cannot take several inputs, put everything in a vector |
---|
| 200 | val = feval(extstruct.fcn,[extstruct.arg{:}]); |
---|
| 201 | otherwise % VAL = OPERATOR(X1,X2,...) |
---|
| 202 | if ismembc(extvar,all_evaluator_variables) |
---|
| 203 | % Evaluator variables (used for exp, log, ...) |
---|
| 204 | % have an appended argument that we need to |
---|
| 205 | % remove. The appended variables is used |
---|
| 206 | % internally to convert from genreal format |
---|
| 207 | % f(a'x+c) to f(z), z==a'z+b |
---|
| 208 | val = feval(extstruct.fcn,extstruct.arg{1:end-1}); |
---|
| 209 | else |
---|
| 210 | val = feval(extstruct.fcn,extstruct.arg{:}); |
---|
| 211 | end |
---|
| 212 | end |
---|
| 213 | values(extvar) = val; |
---|
| 214 | end |
---|
| 215 | end |
---|
| 216 | end |
---|
| 217 | % This code is a bit shaky due to the 0^0 bug in linux 6.5 |
---|
| 218 | %the_product = prod(values(used_in_monom).^monom_i(used_in_monom)); |
---|
| 219 | the_product = 1; |
---|
| 220 | for j = 1:length(used_in_monom) |
---|
| 221 | the_product = the_product*values(used_in_monom(j))^monom_i(used_in_monom(j)); |
---|
| 222 | end |
---|
| 223 | values(lmi_variables(i)) = the_product; |
---|
| 224 | end |
---|
| 225 | end |
---|
| 226 | sys = X.basis*[1;values(lmi_variables(:))]; |
---|
| 227 | |
---|
| 228 | if X.typeflag==10 |
---|
| 229 | sys = eig(full(reshape(sys,X.dim(1),X.dim(2)))); |
---|
| 230 | else |
---|
| 231 | sys = full(reshape(sys,X.dim(1),X.dim(2))); |
---|
| 232 | end |
---|