1 | function varargout = pwf(varargin) |
---|
2 | %PWF Defines a piecewise function |
---|
3 | % |
---|
4 | % t = PWF(h1,F1,h2,F2,...,hn,Fn) |
---|
5 | % |
---|
6 | % The variable t can only be used in convexity/concavity preserving |
---|
7 | % operations, depending on the convexity of hi |
---|
8 | |
---|
9 | % Author Johan Löfberg |
---|
10 | % $Id: pwf.m,v 1.9 2006/07/11 13:48:05 joloef Exp $ |
---|
11 | |
---|
12 | switch class(varargin{1}) |
---|
13 | |
---|
14 | case {'cell','struct'} |
---|
15 | % This should be an internal call to |
---|
16 | % setup a pwa function defined fromk MPT |
---|
17 | |
---|
18 | if nargin<3 |
---|
19 | pwaclass = 'general' |
---|
20 | end |
---|
21 | |
---|
22 | if isa(varargin{1},'struct') |
---|
23 | varargin{1} = {varargin{1}}; |
---|
24 | end |
---|
25 | |
---|
26 | % Put in standard format |
---|
27 | if ~isfield(varargin{1}{1},'Bi') |
---|
28 | if ~isfield(varargin{1}{1},'Fi') |
---|
29 | error('Wrong format on input to PWA (requires Bi or Fi)'); |
---|
30 | else |
---|
31 | for i = 1:length(varargin{1}) |
---|
32 | varargin{1}{1}.Ai = cell(1, varargin{1}{i}.Fi); |
---|
33 | varargin{1}{i}.Bi = varargin{1}{i}.Fi |
---|
34 | varargin{1}{i}.Ci = varargin{1}{i}.Gi |
---|
35 | end |
---|
36 | end |
---|
37 | end |
---|
38 | |
---|
39 | if isempty(varargin{1}{1}.Ai{1}) |
---|
40 | varargout{1} = pwa_yalmip(varargin{:}); |
---|
41 | else |
---|
42 | if nnz([varargin{1}{1}.Ai{:}]) == 0 |
---|
43 | varargout{1} = pwa_yalmip(varargin{:}); |
---|
44 | else |
---|
45 | varargout{1} = pwq_yalmip(varargin{:}); |
---|
46 | end |
---|
47 | end |
---|
48 | |
---|
49 | case {'sdpvar','double'} % Overloaded operator for SDPVAR objects. Pass on args and save them. |
---|
50 | if length(varargin{1}) == 1 |
---|
51 | varargout{1} = yalmip('addextendedvariable',mfilename,varargin{:}); |
---|
52 | else |
---|
53 | y = []; |
---|
54 | VV = varargin; |
---|
55 | for i = 1:length(varargin{1}) |
---|
56 | VV = varargin; |
---|
57 | for j = 1:(length(varargin)/2) |
---|
58 | VV{2*j-1} = VV{2*j-1}(i); |
---|
59 | end |
---|
60 | y = [y;yalmip('addextendedvariable',mfilename,VV{:})]; |
---|
61 | end |
---|
62 | varargout{1} = y; |
---|
63 | end |
---|
64 | |
---|
65 | case 'char' % YALMIP sends 'model' when it wants the epigraph or hypograph |
---|
66 | if isequal(varargin{1},'graph') |
---|
67 | varargout{1} = []; |
---|
68 | varargout{2} = struct('convexity','failure','monotoncity','failure','definiteness','failure');; |
---|
69 | varargout{3} = []; |
---|
70 | elseif isequal(varargin{1},'milp') |
---|
71 | % pwf represented by t |
---|
72 | t = varargin{2}; |
---|
73 | % Get functions and guards |
---|
74 | for i = 3:2:nargin |
---|
75 | f{(i-1)/2} = varargin{i}; |
---|
76 | Guard{(i+1)/2-1} = varargin{i+1}; |
---|
77 | end |
---|
78 | |
---|
79 | % Indicator for where we are |
---|
80 | indicators = binvar(length(f),1); |
---|
81 | % We are in some of the regions |
---|
82 | F = set(sum(indicators) == 1); |
---|
83 | |
---|
84 | % Control where we are using the indicators and big-M |
---|
85 | X = []; |
---|
86 | for i = 1:length(Guard) |
---|
87 | Xi = sdpvar(Guard{i}); |
---|
88 | if is(Xi,'linear') |
---|
89 | [M,m] = derivebounds(Xi); |
---|
90 | else |
---|
91 | m = -1e4; |
---|
92 | end |
---|
93 | F = F + set(Xi >= m*(1-indicators(i))); |
---|
94 | X = [X;recover(depends(Guard{i}))]; |
---|
95 | end |
---|
96 | % cost = sum(delta_i*cost_i(x)) = sum(cost_i(delta_i*x)) |
---|
97 | X = recover(getvariables(X)); |
---|
98 | |
---|
99 | if 0 |
---|
100 | cost = 0; |
---|
101 | for i = 1:length(f) |
---|
102 | [Q{i},c{i},g{i},xi,info] = quaddecomp(f{i},X); |
---|
103 | if info |
---|
104 | error('Only convex quadratic functions allowed in PWF'); |
---|
105 | end |
---|
106 | [M,m] = derivebounds(xi); |
---|
107 | z{i} = sdpvar(length(xi),1); |
---|
108 | cost = cost + z{i}'*Q{i}*z{i}+c{i}'*z{i} + g{i}*indicators(i); |
---|
109 | F = F + set(xi+(1-indicators(i))*m<z{i}<xi+(1-indicators(i)).*M); |
---|
110 | F = F + set(m*indicators(i) < z{i} < M*indicators(i)); |
---|
111 | end |
---|
112 | F = F + set(cost < t); |
---|
113 | else |
---|
114 | fmax_max = -inf; |
---|
115 | fmin_min = inf; |
---|
116 | for i = 1:length(f) |
---|
117 | [Q{i},c{i},g{i},xi,info] = quaddecomp(f{i},X); |
---|
118 | if info |
---|
119 | error('Only convex quadratic functions allowed in PWF'); |
---|
120 | end |
---|
121 | [fmax,fmin] = derivebounds(c{i}'*xi+g{i}); |
---|
122 | fmax_max = max(fmax,fmax_max); |
---|
123 | fmin_min = min(fmin,fmin_min); |
---|
124 | F = F + set(c{i}'*xi +g{i} < t + fmax*(1-indicators(i))); |
---|
125 | end |
---|
126 | end |
---|
127 | % To help variable strenghtening, constraint removal etc in |
---|
128 | % other functions, let us update the internal bound info |
---|
129 | bounds(t,fmin_min,fmax_max); |
---|
130 | |
---|
131 | % This function is convex when we relax the binary variables |
---|
132 | varargout{1} = F; |
---|
133 | varargout{2} = struct('convexity','milp','monotoncity','milp','definiteness','none'); |
---|
134 | varargout{3} = X; |
---|
135 | else |
---|
136 | error('SDPVAR/NORM called with CHAR argument?'); |
---|
137 | end |
---|
138 | otherwise |
---|
139 | error('Strange type on first argument in SDPVAR/NORM'); |
---|
140 | end |
---|