sdpa-python 0.2.2__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env python
2
+
3
+ """
4
+ SparseCoLO [1] implements sparsity exploitation algorithms in [2]
5
+ These routines were originally implemented as subprograms of SparseCoLO (MATLAB) and are
6
+ Copyright (C) 2009 Masakazu Kojima Group
7
+ Department of Mathematical and Computing Sciences, Tokyo Institute of Technology
8
+
9
+ Python translations written for SDPAP and are
10
+ Copyright (C) 2010-2022 SDPA Project
11
+
12
+ [1] http://www.opt.c.titech.ac.jp/kojima/SparseCoLO/SparseCoLO.htm
13
+ [2] Sunyoung Kim, Masakazu Kojima, Martin Mevissen and Makoto Yamashita, "Exploiting sparsity in linear and nonlinear matrix inequalities via positive semidefinite matrix completion," Mathematical Programming, 129(1), 33–68. https://doi.org/10.1007/s10107-010-0402-6
14
+
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License as published by
17
+ the Free Software Foundation; either version 2 of the License, or
18
+ (at your option) any later version.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License along
26
+ with this program; if not, write to the Free Software Foundation, Inc.,
27
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28
+
29
+ September 2010: `getASP`, `symb_cholesky`, `cliques_fromASP` written by Kenta Kato
30
+ December 2010: Modified for SciPy
31
+ """
32
+
33
+ __all__ = ['getASP', 'cliques_fromASP']
34
+
35
+ from sdpap.matdata import MatData
36
+ from . import spcoloext
37
+ from .clique import CliqueSet
38
+ from scipy.sparse import csc_matrix, tril
39
+ from scipy import sparse
40
+ # from numpy import array
41
+
42
+ def getASP(A, c, K_s):
43
+ """Get Aggregate Sparsity Pattern
44
+
45
+ Args;
46
+ A, c: submatrix or subvector of CoLO
47
+ K_s: A tuple of block struct of A or c
48
+
49
+ Returns:
50
+ Aggregate Sparsity Pattern Matrix
51
+ """
52
+ if not isinstance(K_s, tuple):
53
+ raise TypeError('K_s must be tuple.')
54
+
55
+ if len(K_s) == 0:
56
+ print("getASP(): K_s is not assigned.")
57
+ return
58
+
59
+ size_asp = sum(K_s)
60
+ sDim = sum([x ** 2 for x in K_s])
61
+ size_m, size_n = A.shape
62
+
63
+ asp_I = set(c.nonzero()[0])
64
+ asp_I.update(set(A.nonzero()[1]))
65
+
66
+ list_I = sorted(list(asp_I))
67
+ mat_offset = 0
68
+ vec_offset = 0
69
+ asp_row = []
70
+ asp_col = []
71
+ for k in K_s:
72
+ block_I = list_I[vec_offset:(vec_offset + k ** 2)]
73
+ asp_row.extend([((i - vec_offset) // k) + mat_offset
74
+ for i in block_I])
75
+ asp_col.extend([((i - vec_offset) % k) + mat_offset
76
+ for i in block_I])
77
+ mat_offset += k
78
+ vec_offset += k ** 2
79
+
80
+ ret_mat = csc_matrix(([1] * len(asp_row), (asp_row, asp_col)),
81
+ shape=(size_asp, size_asp))
82
+
83
+ return ret_mat
84
+
85
+
86
+ def symb_cholesky(asp):
87
+ """Symbolic Cholesky Factorization
88
+
89
+ Args:
90
+ asp: Aggregated Sparsity Pattern Matrix
91
+
92
+ Returns:
93
+ Indices and indptr of Lower triangular matrix L (indL, ptrL)
94
+ """
95
+ A = tril(asp, k=-1, format='csc')
96
+ A.sort_indices()
97
+ parent = dict()
98
+ indA = A.indices
99
+ ptrA = A.indptr
100
+ setL = []
101
+ for i in range(A.shape[0]):
102
+ setL.append(set(indA[ptrA[i]:ptrA[i+1]]))
103
+ for j in parent.keys():
104
+ if parent[j] == i:
105
+ setL[i].update(setL[j])
106
+
107
+ setL[i] -= set(range(i+1))
108
+ if setL[i]:
109
+ parent[i] = min(setL[i])
110
+
111
+ indL = []
112
+ ptrL = [0] * (A.shape[0] + 1)
113
+ for i in range(A.shape[0]):
114
+ indL.append(i)
115
+ indL.extend(sorted(list(setL[i])))
116
+ ptrL[i+1] = len(indL)
117
+
118
+ #L = csc_matrix((array([1.0] * len(indL)),
119
+ # array(indL),
120
+ # array(ptrL)),
121
+ # shape=A.shape)
122
+ return indL, ptrL
123
+
124
+
125
+ def cliques_fromASP(asp):
126
+ """Get cliques from Aggregate Sparsity Pattern Matrix
127
+
128
+ Args:
129
+ asp: Aggregate Sparsity Pattern Matrix
130
+
131
+ Returns:
132
+ orig_cliques: A list of list. Each list has indexes of clique.
133
+ """
134
+ from scipy import ix_
135
+
136
+ size_n = asp.shape[0]
137
+ A = asp + sparse.eye(size_n, size_n, format='csc')
138
+ #A = asp + (2 * size_n + 1) * sparse.eye(size_n, size_n, format='csc')
139
+ data_A = MatData(mat=A.tocsc().sorted_indices())
140
+
141
+ # Minimum degree ordering
142
+ # using spooles
143
+ ordering = spcoloext.ordering_mmd(data_A)
144
+ if len(ordering) == 0:
145
+ return None
146
+
147
+ if A.shape != (1, 1):
148
+ #data_A = MatData(mat=A.tocsc()[ix_(ordering, ordering)])
149
+ A = A.tocsc()[ix_(ordering, ordering)]
150
+ else:
151
+ #data_A = MatData(mat=A.tocsc())
152
+ A = A.tocsc()
153
+
154
+ # Cholesky factorization
155
+ #L = symb_cholesky(A)
156
+ indL, ptrL = symb_cholesky(A)
157
+ #values, rowind, colptr = spcoloext.cholesky(data_A)
158
+ #data_R = MatData(values=values, rowind=rowind, colptr=colptr,
159
+ # size=(size_n,size_n))
160
+
161
+ #R = data_R.tomatrix()
162
+ #L = R.T
163
+
164
+ # Finding the maximal cliques
165
+ #clique_set = [set(L[:,col].nonzero()[0]) for col in range(size_n)]
166
+ clique_set = [set(indL[ptrL[col]:ptrL[col+1]]) for col in range(size_n)]
167
+ maxclique_idx = [0]
168
+ for i in range(1, size_n):
169
+ for j in range(i):
170
+ if clique_set[i] <= clique_set[j]:
171
+ break
172
+ else:
173
+ maxclique_idx.append(i)
174
+
175
+ cliqueSet = CliqueSet(size_n)
176
+ for i in maxclique_idx:
177
+ clq = sorted([ordering[j] for j in clique_set[i]])
178
+ cliqueSet.append_clique(clq)
179
+
180
+ # print cliqueSet.cliques
181
+
182
+ return cliqueSet
sdpap/spcolo/clique.py ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Class definition of `CliqueSet`
4
+ This file is a component of SDPAP
5
+ Copyright (C) 2010-2022 SDPA Project
6
+
7
+ This program is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Public License as published by
9
+ the Free Software Foundation; either version 2 of the License, or
10
+ (at your option) any later version.
11
+
12
+ This program is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU General Public License for more details.
16
+
17
+ You should have received a copy of the GNU General Public License along
18
+ with this program; if not, write to the Free Software Foundation, Inc.,
19
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
+
21
+ October 2010: Originally written by Kenta Kato
22
+ """
23
+
24
+ __all__ = ['CliqueSet']
25
+
26
+ class CliqueSet(object):
27
+ """Maximal clique set of Aggregate sparsity pattern
28
+
29
+ Attributes:
30
+ cliques: A list of clique. Each clique is described as list of integer.
31
+ map_convIndex: A dictionary of mapping list from index of ASP (i,j)
32
+ to converted index.
33
+ i.e. map_convIndex[(i,j)] = converted_index
34
+ map_origIndex: A dictionary of mapping list from converted index
35
+ to original index.
36
+ i.e. map_index[converted_index] = original_index
37
+ """
38
+ def __init__(self, size_n):
39
+ """Constructor"""
40
+ self.cliques = []
41
+ self.map_convIndex = {}
42
+ self.map_origIndex = {}
43
+ self.num_element = 0
44
+ self.size_n = size_n
45
+
46
+ def __len__(self):
47
+ """Return number of cliques"""
48
+ return len(self.cliques)
49
+
50
+ def append_clique(self, clq):
51
+ """Append one clique to cliques and make index mapping
52
+
53
+ Args:
54
+ clq: A list of integer.
55
+ """
56
+ self.cliques.append(clq)
57
+ for i in clq:
58
+ for j in clq:
59
+ if i >= j:
60
+ origIndex1 = i * self.size_n + j
61
+ origIndex2 = j * self.size_n + i
62
+ if origIndex1 not in self.map_convIndex:
63
+ self.map_origIndex[self.num_element] = \
64
+ (origIndex1, origIndex2)
65
+ self.map_convIndex[origIndex1] = self.num_element
66
+ self.map_convIndex[origIndex2] = self.num_element
67
+ self.num_element += 1
68
+ return
sdpap/spcolo/spcolo.py ADDED
@@ -0,0 +1,356 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ Exploit sparsity in SDPs using techniques from [1]
4
+
5
+ These routines were originally implemented in SparseCoLO (MATLAB) [2] and are
6
+ Copyright (C) 2009 Masakazu Kojima Group
7
+ Department of Mathematical and Computing Sciences, Tokyo Institute of Technology
8
+
9
+ Python translations written for SDPAP and are
10
+ Copyright (C) 2010-2022 SDPA Project
11
+
12
+ [1] Sunyoung Kim, Masakazu Kojima, Martin Mevissen and Makoto Yamashita, "Exploiting sparsity in linear and nonlinear matrix inequalities via positive semidefinite matrix completion," Mathematical Programming, 129(1), 33–68. https://doi.org/10.1007/s10107-010-0402-6
13
+ [2] http://www.opt.c.titech.ac.jp/kojima/SparseCoLO/SparseCoLO.htm
14
+
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License as published by
17
+ the Free Software Foundation; either version 2 of the License, or
18
+ (at your option) any later version.
19
+
20
+ This program is distributed in the hope that it will be useful,
21
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
+ GNU General Public License for more details.
24
+
25
+ You should have received a copy of the GNU General Public License along
26
+ with this program; if not, write to the Free Software Foundation, Inc.,
27
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28
+
29
+ August 2010: `dconv_basisrep`, `rconv_matdecomp`, `dconv_basisresult`, `rconv_decompresult` written by Kenta Kato
30
+ December 2010: Modified for SciPy
31
+ """
32
+
33
+ __all__ = ['dconv_basisrep', 'rconv_matdecomp',
34
+ 'dconv_basisresult', 'rconv_decompresult']
35
+
36
+ from . import asputils
37
+ from .clique import CliqueSet
38
+ from sdpap.symcone import SymCone
39
+ from scipy.sparse import csc_matrix, bmat, eye
40
+ from scipy import sparse
41
+
42
+ #from cvxopt import matrix, spmatrix, sparse
43
+ #import cvxopt
44
+
45
+
46
+ def dconv_basisrep(A, b, c, K, J):
47
+ """The d-space conversion method using basis representation
48
+
49
+ Args:
50
+ A, b, c, K, J: CLP format
51
+
52
+ Returns:
53
+ A converted problem in CLP format and list of CliqueSet,
54
+ (A2, b2, c2, K2, J2, list_cliqueSet)
55
+ """
56
+ if len(K.s) == 0:
57
+ print('No conversion becsuse K.s is empty.')
58
+ import copy
59
+ A2 = copy.deepcopy(A)
60
+ b2 = copy.deepcopy(b)
61
+ c2 = copy.deepcopy(c)
62
+ K2 = K.SymCone()
63
+ J2 = J.SymCone()
64
+ return A2, b2, c2, K2, J2, None
65
+
66
+ sDimTotal = sum([x ** 2 for x in K.s])
67
+ size_m, size_n = A.shape
68
+ numSDPcones = len(K.s)
69
+
70
+ list_cliqueSet = []
71
+
72
+ # When a block is not converted
73
+ list_addcs = []
74
+ list_addAs = []
75
+ list_addKs = []
76
+
77
+ # Additional J.s part
78
+ list_addAclq = []
79
+ list_addJs = []
80
+
81
+ # --------------------------------------------------
82
+ # Type check
83
+ # --------------------------------------------------
84
+ if not sparse.isspmatrix_csc(A):
85
+ A = A.tocsc()
86
+
87
+ if not sparse.isspmatrix_csc(b):
88
+ b = b.tocsc()
89
+
90
+ if not sparse.isspmatrix_csc(c):
91
+ c = c.tocsc()
92
+
93
+ # --------------------------------------------------
94
+ # Get maximal cliques and make additional submatrix
95
+ # --------------------------------------------------
96
+ col_ptr = K.f + K.l + sum(K.q)
97
+ offset_row = 0
98
+ offset_col = 0
99
+ # Additional c_f
100
+ addcf_row = []
101
+ addcf_val = []
102
+ # Additional A_f
103
+ addAf_row = []
104
+ addAf_col = []
105
+ addAf_val = []
106
+ # Additional J.s part of A_f
107
+ addAclq_row = []
108
+ addAclq_col = []
109
+
110
+ for sDim in K.s:
111
+ A_block = A[:, col_ptr:(col_ptr + sDim ** 2)]
112
+ c_block = c[col_ptr:(col_ptr + sDim ** 2)]
113
+
114
+ # Get Aggregate Sparsity Pattern
115
+ asp = asputils.getASP(A_block, c_block, (sDim,))
116
+ # print asp
117
+
118
+ # Get maximal clique and add to clique list
119
+ cliqueSet = asputils.cliques_fromASP(asp)
120
+ if cliqueSet == None:
121
+ # Doesn't need to convert this block
122
+ list_addcs.append([c_block])
123
+ list_addAs.append(A_block)
124
+ list_addKs.append(sDim)
125
+ list_cliqueSet.append(None)
126
+ continue
127
+
128
+ list_cliqueSet.append(cliqueSet)
129
+ # print cliqueSet.map_convIndex
130
+
131
+ # ----------------------------------------
132
+ # Make additional submatrix
133
+ # ----------------------------------------
134
+
135
+ # Make addAclq
136
+ add_Js = [len(clq) for clq in cliqueSet.cliques]
137
+ addJs_size = sum([x ** 2 for x in add_Js])
138
+ addAclq_row.extend([i + offset_row for i in range(addJs_size)])
139
+ for clq in cliqueSet.cliques:
140
+ addAclq_col.extend([cliqueSet.map_convIndex[i*sDim+j] + offset_col
141
+ for i in clq for j in clq])
142
+
143
+ # Make addcf
144
+ for (row, val) in zip(c_block.nonzero()[0], c_block.data):
145
+ i = row // sDim
146
+ j = row % sDim
147
+ if i >= j:
148
+ addcf_row.append(cliqueSet.map_convIndex[row] + offset_col)
149
+ addcf_val.append(val * 2 if i > j else val)
150
+
151
+ #print addcf_row
152
+
153
+ # Make addAf
154
+ for (row, col, val) in zip(A_block.nonzero()[0], A_block.nonzero()[1],
155
+ A_block.data):
156
+ i = col // sDim
157
+ j = col % sDim
158
+ if i >= j:
159
+ addAf_row.append(row)
160
+ addAf_col.append(cliqueSet.map_convIndex[col] + offset_col)
161
+ addAf_val.append(val * 2 if i > j else val)
162
+
163
+
164
+ list_addJs.extend(add_Js)
165
+
166
+ col_ptr += sDim ** 2
167
+ offset_row += addJs_size
168
+ offset_col += cliqueSet.num_element
169
+
170
+ # --------------------------------------------------
171
+ # Make converted matrix
172
+ # --------------------------------------------------
173
+ size_addJs = offset_row
174
+ size_addKf = offset_col
175
+ size_addKs = sum(list_addKs)
176
+
177
+ list_A = []
178
+ list_c = []
179
+
180
+ # J.f, J.l, J.q, J.s part
181
+ # K.f part
182
+ if K.f > 0:
183
+ A_f = A[:, 0:K.f]
184
+ list_A.append(A_f)
185
+ c_f = c[0:K.f]
186
+ list_c.append([c_f])
187
+
188
+ # Additional K.f part
189
+ if len(addAf_val) > 0:
190
+ add_Af = csc_matrix((addAf_val, (addAf_row, addAf_col)),
191
+ shape=(size_m, size_addKf))
192
+ add_cf = csc_matrix((addcf_val, (addcf_row, [0] * len(addcf_row))),
193
+ shape=(size_addKf, 1))
194
+ list_A.append(add_Af)
195
+ list_c.append([add_cf])
196
+
197
+ # K.l, K.q part
198
+ if K.l > 0 or len(K.q) > 0:
199
+ A_lq = A[:, K.f:(K.f + K.l + sum(K.q))]
200
+ list_A.append(A_lq)
201
+ c_lq = c[K.f:(K.f + K.l + sum(K.q))]
202
+ list_c.append([c_lq])
203
+
204
+ # Additional K.s part
205
+ if len(addAf_val) > 0:
206
+ list_A.extend(list_addAs)
207
+ list_c.extend(list_addcs)
208
+
209
+ # Concatenate matrix
210
+ A2 = bmat([list_A])
211
+ c2 = bmat(list_c)
212
+
213
+ # Additional J.s part
214
+ if len(addAf_val) > 0:
215
+ list_A = []
216
+ add_Aclq = csc_matrix(([1.0] * len(addAclq_row),
217
+ (addAclq_row, addAclq_col)),
218
+ shape=(size_addJs, size_addKf))
219
+ if K.f > 0:
220
+ list_A.append(csc_matrix((size_addJs, K.f)))
221
+
222
+ list_A.append(add_Aclq)
223
+
224
+ if K.l > 0 or len(K.q) > 0:
225
+ list_A.append(csc_matrix((size_addJs, K.l + sum(K.q))))
226
+
227
+ if len(list_addAs) > 0:
228
+ list_A.append(csc_matrix((size_addJs, size_addKs)))
229
+
230
+ add_A = bmat([list_A])
231
+ A2 = bmat([[A2], [add_A]])
232
+ b2 = bmat([[b], [csc_matrix((size_addJs, 1))]])
233
+ else:
234
+ b2 = b
235
+
236
+ # --------------------------------------------------
237
+ # Make converted SymCone
238
+ # --------------------------------------------------
239
+ K2 = SymCone(f=K.f+size_addKf, l=K.l, q=K.q, s=tuple(list_addKs))
240
+ J2 = SymCone(f=J.f, l=J.l, q=J.q, s=tuple(list(J.s)+list_addJs))
241
+
242
+ return A2, b2, c2, K2, J2, list_cliqueSet
243
+
244
+
245
+ def rconv_matdecomp(A, b, c, K, J):
246
+ """The r-space conversion method using matrix decomposition.
247
+
248
+ Args:
249
+ A, b, c, K, J: CoLO format
250
+
251
+ Returns:
252
+ A converted problem in CoLO format and list of CliqueSet,
253
+ (A2, b2, c2, K2, J2, list_cliqueSet)
254
+ """
255
+ dom_A, dom_b, dom_c, dom_K, dom_J, list_cliqueSet = \
256
+ dconv_basisrep(-A.T, -c, -b, J, K)
257
+ A2 = -dom_A.T
258
+ c2 = -dom_b
259
+ b2 = -dom_c
260
+ J2 = dom_K
261
+ K2 = dom_J
262
+
263
+ return A2, b2, c2, K2, J2, list_cliqueSet
264
+
265
+
266
+ def dconv_basisresult(x, y, K, J, dom_K, cliqueD):
267
+ """Retrieve an optimal solution which solved by dconv_basisrep()
268
+
269
+ Args:
270
+ x, y: Results of the converted problem
271
+ K, J: A SymCone of the original problem
272
+ dom_K: A SymCone of the converted problem
273
+ cliqueD: A list of CliqueSet
274
+
275
+ Returns:
276
+ x0, y0: Results of the original problem
277
+ """
278
+ # --------------------------------------------------
279
+ # Type check
280
+ # --------------------------------------------------
281
+ if not sparse.isspmatrix_csc(x):
282
+ x = x.tocsc()
283
+ if not sparse.isspmatrix_csc(y):
284
+ y = y.tocsc()
285
+
286
+ x0_row = []
287
+ x0_val = []
288
+ if K.f > 0:
289
+ x_f = x[:K.f]
290
+ x0_row.extend(list(x_f.nonzero()[0]))
291
+ x0_val.extend(list(x_f.data))
292
+
293
+ add_xf = x[K.f:dom_K.f]
294
+
295
+ if K.l > 0 or len(K.q) > 0:
296
+ x_lq = x[dom_K.f:(dom_K.f + dom_K.l + sum(dom_K.q))]
297
+ x0_row.extend(list(x_lq.nonzero()[0]))
298
+ x0_val.extend(list(x_lq.data))
299
+
300
+ if len(dom_K.s) > 0:
301
+ add_xs = x[(dom_K.f + dom_K.l + sum(dom_K.q)):]
302
+
303
+ offset_x0 = K.f + K.l + sum(K.q)
304
+ offset_addxf = 0
305
+ offset_addxs = 0
306
+ index_addKs = 0
307
+ for cliqueSet in cliqueD:
308
+ if cliqueSet != None:
309
+ size_clique = cliqueSet.num_element
310
+ addxf_block = add_xf[offset_addxf:(offset_addxf + size_clique)]
311
+ for (row, val) in zip(addxf_block.nonzero()[0], addxf_block.data):
312
+ orig_idx = cliqueSet.map_origIndex[row]
313
+ if orig_idx[0] != orig_idx[1]:
314
+ x0_row.extend([offset_x0 + orig_idx[0],
315
+ offset_x0 + orig_idx[1]])
316
+ x0_val.extend([val, val])
317
+ else:
318
+ x0_row.append(offset_x0 + orig_idx[0])
319
+ x0_val.append(val)
320
+
321
+ offset_addxf += size_clique
322
+ offset_x0 += size_clique
323
+ else:
324
+ size_Ks = dom_K.s[index_addKs] ** 2
325
+ addxs_block = add_xs[offset_addxs:(offset_addxs + size_Ks)]
326
+ addxs_row = list(addxs_block.I)
327
+ for row in addxs_row:
328
+ x0_row.append(offset_x0 + row)
329
+
330
+ x0_val.extend(list(addxs_block.V))
331
+ offset_addxs += size_Ks
332
+ offset_x0 += size_Ks
333
+
334
+ totalsize_x = K.f + K.l + sum(K.q) + sum([i ** 2 for i in K.s])
335
+ totalsize_y = J.f + J.l + sum(J.q) + sum([i ** 2 for i in J.s])
336
+ x0 = csc_matrix((x0_val, (x0_row, [0] * len(x0_row))),
337
+ shape=(totalsize_x, 1))
338
+ y0 = y[:totalsize_y]
339
+
340
+ return x0, y0
341
+
342
+
343
+ def rconv_decompresult(x, y, K, J, ran_J, cliqueR):
344
+ """Retrieve an optimal solution which solved by rconv_matdecomp()
345
+
346
+ Args:
347
+ x, y: Results of the converted problem
348
+ K, J: A SymCone of the original problem
349
+ ran_J: A SymCone of the converted problem
350
+ cliqueR: A list of CliqueSet
351
+
352
+ Returns:
353
+ x0, y0: Results of the original problem
354
+ """
355
+ y0, x0 = dconv_basisresult(y, x, J, K, ran_J, cliqueR)
356
+ return x0, y0