1 | function sdpvarExpr = parseLMI(X) |
---|
2 | %PARSELMI Internal function for dirty parsing of lmi string |
---|
3 | |
---|
4 | % Author Johan Löfberg |
---|
5 | % $Id: parseLMI.m,v 1.3 2004/07/27 14:11:57 johanl Exp $ |
---|
6 | |
---|
7 | |
---|
8 | % Assume Error |
---|
9 | |
---|
10 | % TypeofConstraint = 1; |
---|
11 | |
---|
12 | % Check for obsolete notation .<, .>, = |
---|
13 | single_equality = findstr(X,'='); |
---|
14 | if isempty(findstr(X,'>=')) & isempty(findstr(X,'<=')) & (rem(length(single_equality),2) == 1) % There is a single = |
---|
15 | error('Obsolete constraint =, use == in equalities.'); |
---|
16 | %X = strrep(X,'=','=='); |
---|
17 | %X = strrep(X,'====','=='); % Whoops, == replaced with =====! |
---|
18 | end |
---|
19 | |
---|
20 | if ~isempty(findstr(X,'.<')) |
---|
21 | disp(' '); |
---|
22 | disp('Warning: Obsolete constraint .<, use < in equalities.'); |
---|
23 | disp('If you have a Hermitian matrix which you want to') |
---|
24 | disp('constrain to have negative values, use ,e.g., P(:)<0') |
---|
25 | disp('The constraint has been changed to <') |
---|
26 | disp(' '); |
---|
27 | X = strrep(X,'.<','<'); |
---|
28 | end |
---|
29 | |
---|
30 | if ~isempty(findstr(X,'.>')) |
---|
31 | disp(' '); |
---|
32 | disp('Warning: Obsolete constraint .>, use > in equalities.'); |
---|
33 | disp('If you have a Hermitian matrix which you want to') |
---|
34 | disp('constrain to have negative values, use e.g. P(:)>0') |
---|
35 | disp('The constraint has been changed to >') |
---|
36 | disp(' '); |
---|
37 | X = strrep(X,'.>','>'); |
---|
38 | end |
---|
39 | |
---|
40 | % Any norm? If not, we're done! |
---|
41 | if isempty(findstr(X,'||')) |
---|
42 | sdpvarExpr = X; |
---|
43 | return |
---|
44 | end |
---|
45 | |
---|
46 | |
---|
47 | % The only actual parsing needed is for the ||Axplusb||<cx+d notation |
---|
48 | delimiters = {'.<','.>','<.','>.','<','>','==',''}; |
---|
49 | delindex = 0;indtodel = []; |
---|
50 | while isempty(indtodel) & (delindex<=7) |
---|
51 | delindex = delindex+1; |
---|
52 | indtodel = findstr(X,delimiters{delindex}); |
---|
53 | end |
---|
54 | |
---|
55 | switch delindex |
---|
56 | case 5 %< |
---|
57 | TypeofConstraint = 1; |
---|
58 | ind_start = indtodel-1; |
---|
59 | ind_end = indtodel+1; |
---|
60 | REVERSE = 1; |
---|
61 | case 6 %> |
---|
62 | TypeofConstraint = 1; |
---|
63 | ind_start = indtodel-1; |
---|
64 | ind_end = indtodel+1; |
---|
65 | REVERSE = 0; |
---|
66 | case 7%= |
---|
67 | TypeofConstraint = 3; |
---|
68 | ind_start = indtodel-1; |
---|
69 | ind_end = indtodel+2; |
---|
70 | REVERSE = 0; |
---|
71 | case {3,4} |
---|
72 | error('Incorrect argument. Perhaps you mean .> or .<'); |
---|
73 | otherwise |
---|
74 | error('Incorrect argument. Could not find <=>.>.<') |
---|
75 | end |
---|
76 | |
---|
77 | LeftHand = X(1:ind_start); |
---|
78 | RightHand = X(ind_end:end); |
---|
79 | |
---|
80 | if REVERSE |
---|
81 | temp = LeftHand; |
---|
82 | LeftHand = RightHand; |
---|
83 | RightHand = temp; |
---|
84 | end |
---|
85 | |
---|
86 | % Search for a norm expression |
---|
87 | ind_norm_Right = findstr(RightHand,'||'); |
---|
88 | ind_norm_Left = findstr(LeftHand,'||'); |
---|
89 | |
---|
90 | % Any norm at all, if not, we're done! |
---|
91 | if isempty(ind_norm_Right) & isempty(ind_norm_Left) |
---|
92 | sdpvarExpr = [LeftHand '-(' RightHand ')']; |
---|
93 | return |
---|
94 | end |
---|
95 | |
---|
96 | % Equality constrained norm? |
---|
97 | if (TypeofConstraint == 3) & (ind_norm_Right | ind_norm_Left) |
---|
98 | error('Equality constraints cannot be used with ||..|| operator'); |
---|
99 | end |
---|
100 | |
---|
101 | % Convex normconstraint? |
---|
102 | if ~isempty(ind_norm_Left) |
---|
103 | error('Norm ||..|| must look like || column vector ||< scalar, or scalar>|| vector ||') |
---|
104 | end |
---|
105 | |
---|
106 | % Everthing seem ok in norm |
---|
107 | TypeofConstraint = 4; |
---|
108 | Axplusb = RightHand(2+ind_norm_Right(1):ind_norm_Right(2)-1); |
---|
109 | WithoutNorm = strrep(RightHand,RightHand(ind_norm_Right(1):ind_norm_Right(2)+1),'0'); |
---|
110 | if length(WithoutNorm)==1 |
---|
111 | cxplusd = LeftHand; |
---|
112 | else |
---|
113 | cxplusd = [LeftHand '-(' WithoutNorm ')']; |
---|
114 | end |
---|
115 | |
---|
116 | sdpvarExpr = ['cone( ' Axplusb ',' cxplusd ')']; |
---|
117 | |
---|
118 | |
---|