[37] | 1 | function y=min(varargin) |
---|
| 2 | %MIN (overloaded) |
---|
| 3 | % |
---|
| 4 | % t = MIN(X,Y,DIM) |
---|
| 5 | % |
---|
| 6 | % Creates an internal structure relating the variable t with concave |
---|
| 7 | % operator MIN(X). |
---|
| 8 | % |
---|
| 9 | % The variable t is primarily meant to be used in convexity preserving |
---|
| 10 | % operations such as t>0, maximize t etc. |
---|
| 11 | % |
---|
| 12 | % If the variable is used in a non-convexity preserving operation, such as |
---|
| 13 | % t<0, a mixed integer model will be derived. |
---|
| 14 | % |
---|
| 15 | % See built-in MIN for syntax. |
---|
| 16 | |
---|
| 17 | % Author Johan Löfberg |
---|
| 18 | % $Id: min.m,v 1.12 2006/07/26 00:06:02 joloef Exp $ |
---|
| 19 | |
---|
| 20 | % MIN is implemented as a nonlinear operator. |
---|
| 21 | % However, for performance issues, it is not |
---|
| 22 | % implemented in the default high-level way. |
---|
| 23 | % |
---|
| 24 | % The return of the double value and the |
---|
| 25 | % construction of the epigraph/milp is done |
---|
| 26 | % in the file model.m |
---|
| 27 | % |
---|
| 28 | % To study a better example of how to create |
---|
| 29 | % your own nonlinear operator, check the |
---|
| 30 | % function sdpvar/norm instead |
---|
| 31 | |
---|
| 32 | % To simplify code flow, code for different #inputs |
---|
| 33 | switch nargin |
---|
| 34 | case 1 |
---|
| 35 | % Three cases: |
---|
| 36 | % 1. One scalar input, return same as output |
---|
| 37 | % 2. A vector input should give scalar output |
---|
| 38 | % 3. Matrix input returns vector output |
---|
| 39 | X = varargin{1}; |
---|
| 40 | |
---|
| 41 | if max(size(X))==1 |
---|
| 42 | y = X; |
---|
| 43 | return |
---|
| 44 | elseif min(size(X))==1 |
---|
| 45 | y = yalmip('addextendedvariable','min',X); |
---|
| 46 | return |
---|
| 47 | else |
---|
| 48 | % This is just short hand for general command |
---|
| 49 | y = min(X,[],1); |
---|
| 50 | end |
---|
| 51 | |
---|
| 52 | case 2 |
---|
| 53 | |
---|
| 54 | X = varargin{1}; |
---|
| 55 | Y = varargin{2}; |
---|
| 56 | [nx,mx] = size(X); |
---|
| 57 | [ny,my] = size(Y); |
---|
| 58 | if ~((nx*mx==1) | (ny*my==1)) |
---|
| 59 | % No scalar, so they have to match |
---|
| 60 | if ~((nx==ny) & (mx==my)) |
---|
| 61 | error('Array dimensions must match.'); |
---|
| 62 | end |
---|
| 63 | end |
---|
| 64 | |
---|
| 65 | % Convert to compatible matrices |
---|
| 66 | if nx*mx==1 |
---|
| 67 | X = X*ones(ny,my); |
---|
| 68 | nx = ny; |
---|
| 69 | mx = my; |
---|
| 70 | elseif ny==my |
---|
| 71 | Y = Y*ones(nx,mx); |
---|
| 72 | ny = nx; |
---|
| 73 | my = mx; |
---|
| 74 | end |
---|
| 75 | |
---|
| 76 | % Ok, done with error checks etc. |
---|
| 77 | % Introduce one extended variable/element |
---|
| 78 | % Lame code since we cannot call overloaded |
---|
| 79 | % subsref from inside of SDPVAR object... |
---|
| 80 | % This is most likely not a often used syntax, |
---|
| 81 | % so performance is neglected here... |
---|
| 82 | y = []; |
---|
| 83 | for i = 1:nx |
---|
| 84 | temp = []; |
---|
| 85 | for j = 1:mx |
---|
| 86 | Xij = extsubsref(X,i,j); |
---|
| 87 | Yij = extsubsref(Y,i,j); |
---|
| 88 | yij = min([Xij Yij]); |
---|
| 89 | temp = [temp yij]; |
---|
| 90 | end |
---|
| 91 | y = [y;temp]; |
---|
| 92 | end |
---|
| 93 | |
---|
| 94 | case 3 |
---|
| 95 | |
---|
| 96 | X = varargin{1}; |
---|
| 97 | Y = varargin{2}; |
---|
| 98 | DIM = varargin{3}; |
---|
| 99 | |
---|
| 100 | if ~(isa(X,'sdpvar') & isempty(Y)) |
---|
| 101 | error('MIN with two matrices to compare and a working dimension is not supported.'); |
---|
| 102 | end |
---|
| 103 | |
---|
| 104 | if ~isa(DIM,'double') |
---|
| 105 | error('Dimension argument must be 1 or 2.'); |
---|
| 106 | end |
---|
| 107 | |
---|
| 108 | if ~(length(DIM)==1) |
---|
| 109 | error('Dimension argument must be 1 or 2.'); |
---|
| 110 | end |
---|
| 111 | |
---|
| 112 | if ~(DIM==1 | DIM==2) |
---|
| 113 | error('Dimension argument must be 1 or 2.'); |
---|
| 114 | end |
---|
| 115 | |
---|
| 116 | if DIM==1 |
---|
| 117 | % Create one extended variable per column |
---|
| 118 | y = []; |
---|
| 119 | for i = 1:size(X,2) |
---|
| 120 | inparg = extsubsref(X,1:size(X,1),i); |
---|
| 121 | if isa(inparg,'sdpvar') |
---|
| 122 | y = [y yalmip('addextendedvariable','min',inparg)]; |
---|
| 123 | else |
---|
| 124 | y = [y min(inparg)]; |
---|
| 125 | end |
---|
| 126 | end |
---|
| 127 | else |
---|
| 128 | % Re-use code recursively |
---|
| 129 | y = min(X',[],1)'; |
---|
| 130 | end |
---|
| 131 | |
---|
| 132 | otherwise |
---|
| 133 | error('Too many input arguments.') |
---|
| 134 | end |
---|