source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/opt/yalmip/extras/@ncvar/mtimes.m @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 5.6 KB
Line 
1function Z = mtimes(X,Y)
2%MTIMES (overloaded)
3
4% Author Johan Löfberg
5% $Id: mtimes.m,v 1.3 2006/08/11 11:48:15 joloef Exp $
6
7% Brute-force implementation of multiplication of noncommuting variables
8% (with possible commuting variables involved)
9
10% Check classes
11X_is_spdvar = isa(X,'sdpvar');
12Y_is_spdvar = isa(Y,'sdpvar');
13
14X_is_ncvar = isa(X,'ncvar');
15Y_is_ncvar = isa(Y,'ncvar');
16
17% Get all the tables, and expand them so that they correspond to the same
18% number of variables globally (nonCommutingTable is not up to date after a
19% new commuting variables has been defined, to save flops)
20nonCommutingTable         = yalmip('nonCommutingTable');
21[monomtable,variabletype] = yalmip('monomtable');
22if size(monomtable,1)>size(nonCommutingTable,1)
23    nonCommutingTable((1+size(nonCommutingTable,1)):(size(monomtable,1)),1) = (1+size(nonCommutingTable,1)):(size(monomtable,1));
24end
25
26% Cast commutative variables as nc temporarily by adding them to the table
27commuting = find(~any(nonCommutingTable,2));
28nonCommutingTable(commuting,1) = commuting;
29
30x_variables = getvariables(X);Xbase = getbase(X);
31y_variables = getvariables(Y);Ybase = getbase(Y);
32temp_monom_table = [];
33temp_nc_table = [];
34temp_c_table = [];
35new_base = [];
36
37for i = 0:length(x_variables)
38    if i>0
39        x_monom = nonCommutingTable(x_variables(i),:);
40    else
41        x_monom = nan;
42    end
43    x_base = Xbase(:,i+1);
44    for j = 0:length(y_variables)
45        if j>0
46            y_monom = nonCommutingTable(y_variables(j),:);
47        else
48            y_monom = nan;
49        end
50        y_base = Ybase(:,j+1);
51        xy_base = reshape(x_base,size(X))*reshape(y_base,size(Y));
52
53        if (i == 0) & (j== 0)
54            new_base = xy_base(:);
55        elseif nnz(xy_base)>0
56            xy_monom = [x_monom(2:end) y_monom(2:end)];
57            xy_monom = xy_monom(find(xy_monom));
58            temp_nc_table(end+1,1:length(xy_monom)) = xy_monom;
59            temp_c_table(end+1,1:2) = [x_monom(1) y_monom(1)];
60            new_base = [new_base xy_base(:)];
61        end
62    end
63end
64
65% It could have happended that new commuting monomials where generated
66% during the multiplication. Check and create these
67for i = 1:size(temp_c_table,1)
68    aux = spalloc(1,size(monomtable,2),2);
69    if ~isnan(temp_c_table(i,1))
70        aux = monomtable(temp_c_table(i,1),:) + aux;
71    end
72    if ~isnan(temp_c_table(i,2))
73        aux = monomtable(temp_c_table(i,2),:)  + aux;
74    end
75    if nnz(aux)>0
76        candidates = findrows(monomtable,aux);
77        if ~isempty(candidates)
78            temp_c_table(i,1) = candidates;
79        else
80            monomtable = [monomtable;aux];
81            nonCommutingTable(end+1,1) = nan;
82            temp_c_table(i,1) = size(monomtable,1);
83            switch sum(aux)
84                case 1
85                    variabletype(end+1) = 0;
86                case 2
87                    if nnz(aux) == 1
88                        variabletype(end+1) = 2;
89                    else
90                        variabletype(end+1) = 1;
91                    end
92                otherwise
93                    variabletype(end+1) = 3;
94            end
95        end
96    end
97end
98
99temp_nc_table = [temp_c_table(:,1) temp_nc_table];
100% Okay, now we have the monomials. Now we have to match them to
101% possible earlier monomials
102if size(nonCommutingTable,2) < size(temp_nc_table,2)
103    nonCommutingTable(1,size(temp_nc_table,2)) = 0;
104elseif size(temp_nc_table,2) < size(nonCommutingTable,2)
105    temp_nc_table(1,size(nonCommutingTable,2)) = 0;
106end
107for i = 1:size(temp_nc_table,1)
108    candidates = findrows_nan(nonCommutingTable,temp_nc_table(i,:));
109    if isempty(candidates)
110        nonCommutingTable = [nonCommutingTable;temp_nc_table(i,:)];
111        monomtable(end+1,end+1) = 0;
112        involved =  temp_nc_table(i,1+find(temp_nc_table(i,2:end)));
113        switch length(involved)
114            case 1
115                if isnan(temp_nc_table(i,1))
116                    variabletype(end+1) = 0;
117                else
118                    if variabletype(temp_nc_table(i,1)) == 0
119                        variabletype(end+1) = 1;
120                    else
121                        variabletype(end+1) = 3;
122                    end
123                end
124            case 2
125                if isnan(temp_nc_table(i,1))
126                    if involved(1) == involved(2)
127                        variabletype(end+1) = 2;
128                    else
129                        variabletype(end+1) = 1;
130                    end
131                else
132                    variabletype(end+1) = 3;
133                end
134            otherwise
135                variabletype(end+1) = 3;
136        end
137        lmivariables(i) = size(nonCommutingTable,1);
138    else
139        lmivariables(i) = candidates;
140
141    end
142end
143
144% Create an output variable quickly
145if X_is_ncvar
146    Z = X;
147else
148    Z = Y;
149end
150Z.basis = new_base;
151Z.lmi_variables = lmivariables;
152
153% Fucked up order (lmi_variables should be sorted and unique)
154if any(diff(Z.lmi_variables)<0)
155    [i,j]=sort(Z.lmi_variables);
156    Z.basis = [Z.basis(:,1) Z.basis(:,j+1)];
157    Z.lmi_variables = Z.lmi_variables(j);
158end
159[un_Z_vars2] = uniquestripped(Z.lmi_variables);
160if length(un_Z_vars2) < length(Z.lmi_variables)
161    [un_Z_vars,hh,jj] = unique(Z.lmi_variables);
162    if length(Z.lmi_variables) ~=length(un_Z_vars)
163        Z.basis = Z.basis*sparse([1 1+jj],[1 1+(1:length(jj))],ones(1,1+length(jj)))';
164        Z.lmi_variables = un_Z_vars;
165    end
166end
167Z.dim = size(xy_base);
168Z = clean(Z);
169if size(monomtable,2) < size(monomtable,1)
170    monomtable(size(monomtable,1),size(monomtable,1)) = 0;
171end
172yalmip('nonCommutingTable',nonCommutingTable);
173yalmip('setmonomtable',monomtable,variabletype);
174
175function c = findrows_nan(a,b)
176a(isnan(a)) = 0;
177b(isnan(b)) = 0;
178c=findrows(a,b);
Note: See TracBrowser for help on using the repository browser.