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.
- sdpa_python-0.2.2.dist-info/LICENSE +339 -0
- sdpa_python-0.2.2.dist-info/METADATA +69 -0
- sdpa_python-0.2.2.dist-info/RECORD +24 -0
- sdpa_python-0.2.2.dist-info/WHEEL +5 -0
- sdpa_python-0.2.2.dist-info/top_level.txt +1 -0
- sdpap/__init__.py +28 -0
- sdpap/convert.py +348 -0
- sdpap/fileio.py +836 -0
- sdpap/fvelim/__init__.py +24 -0
- sdpap/fvelim/fvelim.py +256 -0
- sdpap/fvelim/fvelimext.cp313-win_amd64.pyd +0 -0
- sdpap/matdata.py +80 -0
- sdpap/param.py +366 -0
- sdpap/sdpacall/__init__.py +24 -0
- sdpap/sdpacall/sdpa.cp313-win_amd64.pyd +0 -0
- sdpap/sdpacall/sdpacall.py +71 -0
- sdpap/sdpap.py +450 -0
- sdpap/sdpaputils.py +140 -0
- sdpap/spcolo/__init__.py +26 -0
- sdpap/spcolo/asputils.py +182 -0
- sdpap/spcolo/clique.py +68 -0
- sdpap/spcolo/spcolo.py +356 -0
- sdpap/spcolo/spcoloext.cp313-win_amd64.pyd +0 -0
- sdpap/symcone.py +157 -0
sdpap/convert.py
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Convert CLP format to SeDuMi format
|
|
4
|
+
|
|
5
|
+
These routines were originally implemented in SparseCoLO (MATLAB) [1] and are
|
|
6
|
+
Copyright (C) 2009 Masakazu Kojima Group
|
|
7
|
+
Department of Mathematical and Computing Sciences, Tokyo Institute of Technology
|
|
8
|
+
|
|
9
|
+
SparseCoLO [1] implements sparsity exploitation algorithms in [2]
|
|
10
|
+
|
|
11
|
+
Python translations of routines written for SDPAP and are
|
|
12
|
+
Copyright (C) 2010-2022 SDPA Project
|
|
13
|
+
|
|
14
|
+
[1] http://www.opt.c.titech.ac.jp/kojima/SparseCoLO/SparseCoLO.htm
|
|
15
|
+
[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
|
|
16
|
+
|
|
17
|
+
This program is free software; you can redistribute it and/or modify
|
|
18
|
+
it under the terms of the GNU General Public License as published by
|
|
19
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
20
|
+
(at your option) any later version.
|
|
21
|
+
|
|
22
|
+
This program is distributed in the hope that it will be useful,
|
|
23
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
24
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
25
|
+
GNU General Public License for more details.
|
|
26
|
+
|
|
27
|
+
You should have received a copy of the GNU General Public License along
|
|
28
|
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
29
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
30
|
+
|
|
31
|
+
September 2010: `clp_toLMI` and `result_fromLMI` written by Kenta Kato
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from .symcone import SymCone
|
|
35
|
+
from scipy.sparse import csc_matrix, bmat, eye
|
|
36
|
+
from scipy import sparse
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def clp_toLMI(A, b, c, K, J):
|
|
40
|
+
"""Convert from CLP format to LMI standard form (SeDuMi dual format).
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
A, b, c, K, J: CLP format
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
A tuple (A2, b2, c2, K2, J2, map_sdpIndex). Each members are:
|
|
47
|
+
LMI standard form in SeDuMi dual format, (A2, b2, c2, K2, J2)
|
|
48
|
+
J2 has only an attribute 'f'
|
|
49
|
+
Index mapping from converted matrix to original matrix map_sdpIndex
|
|
50
|
+
"""
|
|
51
|
+
# Type check
|
|
52
|
+
if not sparse.isspmatrix_csc(A):
|
|
53
|
+
A = A.tocsc()
|
|
54
|
+
if not sparse.isspmatrix_csc(b):
|
|
55
|
+
b = b.tocsc()
|
|
56
|
+
if not sparse.isspmatrix_csc(c):
|
|
57
|
+
c = c.tocsc()
|
|
58
|
+
if not K.check_validity() or not J.check_validity():
|
|
59
|
+
print('clp_toLMI(): K or J is invalid.')
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
# Get size
|
|
63
|
+
size_m, size_n = A.shape
|
|
64
|
+
|
|
65
|
+
K_f = K.f
|
|
66
|
+
K_l = K.l
|
|
67
|
+
K_q = sum(K.q)
|
|
68
|
+
K_s = sum([i ** 2 for i in K.s])
|
|
69
|
+
|
|
70
|
+
J_f = J.f
|
|
71
|
+
J_l = J.l
|
|
72
|
+
J_q = sum(J.q)
|
|
73
|
+
J_s = sum([i ** 2 for i in J.s])
|
|
74
|
+
|
|
75
|
+
# ----------------------------------------
|
|
76
|
+
# Make converted K.s part
|
|
77
|
+
# ----------------------------------------
|
|
78
|
+
if len(K.s) > 0:
|
|
79
|
+
# Make index mapping from converted index to original index
|
|
80
|
+
map_sdpIndex = [0] * sum([k * (k + 1) / 2 for k in K.s])
|
|
81
|
+
offset = 0
|
|
82
|
+
for k in K.s:
|
|
83
|
+
for i in range(k):
|
|
84
|
+
for j in range(i):
|
|
85
|
+
idx1 = i * k + j
|
|
86
|
+
idx2 = j * k + i
|
|
87
|
+
map_sdpIndex[i * (i + 1) / 2 + j + offset] = (idx1, idx2)
|
|
88
|
+
# i == j case
|
|
89
|
+
idx = i * k + i
|
|
90
|
+
map_sdpIndex[i * (i + 1) / 2 + i + offset] = (idx, idx)
|
|
91
|
+
offset += k * (k + 1) / 2
|
|
92
|
+
|
|
93
|
+
# Split matrix
|
|
94
|
+
c_flq = c[0:(K_f + K_l + K_q), :]
|
|
95
|
+
c_s = c[(K_f + K_l + K_q):, :]
|
|
96
|
+
A_flq = A[:, 0:(K_f + K_l + K_q)]
|
|
97
|
+
A_s = A[:, (K_f + K_l + K_q):]
|
|
98
|
+
|
|
99
|
+
# To make converted matrix
|
|
100
|
+
convcs_row = []
|
|
101
|
+
convcs_val = []
|
|
102
|
+
convAs_row = []
|
|
103
|
+
convAs_col = []
|
|
104
|
+
convAs_val = []
|
|
105
|
+
addAs_row = []
|
|
106
|
+
addAs_col = []
|
|
107
|
+
col_ptr = 0
|
|
108
|
+
offset_row = 0
|
|
109
|
+
offset_col = 0
|
|
110
|
+
else:
|
|
111
|
+
map_sdpIndex = None
|
|
112
|
+
|
|
113
|
+
for sDim in K.s:
|
|
114
|
+
A_block = A_s[:, col_ptr:(col_ptr + sDim ** 2)]
|
|
115
|
+
c_block = c_s[col_ptr:(col_ptr + sDim ** 2)]
|
|
116
|
+
|
|
117
|
+
# Make conv_cs
|
|
118
|
+
for (row, val) in zip(c_block.nonzero()[0], c_block.data):
|
|
119
|
+
i = row // sDim
|
|
120
|
+
j = row % sDim
|
|
121
|
+
if i >= j:
|
|
122
|
+
convcs_row.append(i * (i + 1) / 2 + j + offset_col)
|
|
123
|
+
convcs_val.append(val * 2 if i > j else val)
|
|
124
|
+
|
|
125
|
+
# Make conv_As
|
|
126
|
+
for (row, col, val) in zip(A_block.nonzero()[0], A_block.nonzero()[1],
|
|
127
|
+
A_block.data):
|
|
128
|
+
i = col // sDim
|
|
129
|
+
j = col % sDim
|
|
130
|
+
if i >= j:
|
|
131
|
+
convAs_row.append(row)
|
|
132
|
+
convAs_col.append(i * (i + 1) / 2 + j + offset_col)
|
|
133
|
+
convAs_val.append(val * 2 if i > j else val)
|
|
134
|
+
|
|
135
|
+
# Make add_As
|
|
136
|
+
for i in range(sDim):
|
|
137
|
+
for j in range(i):
|
|
138
|
+
addAs_row.extend([i * sDim + j + offset_row,
|
|
139
|
+
j * sDim + i + offset_row])
|
|
140
|
+
idx = i * (i + 1) / 2 + j + offset_col
|
|
141
|
+
addAs_col.extend([idx, idx])
|
|
142
|
+
# i == j case
|
|
143
|
+
addAs_row.append(i * sDim + i + offset_row)
|
|
144
|
+
addAs_col.append(i * (i + 1) / 2 + i + offset_col)
|
|
145
|
+
|
|
146
|
+
col_ptr += sDim ** 2
|
|
147
|
+
offset_row += sDim ** 2
|
|
148
|
+
offset_col += sDim * (sDim + 1) / 2
|
|
149
|
+
|
|
150
|
+
# ----------------------------------------
|
|
151
|
+
# Make converted matrix
|
|
152
|
+
# ----------------------------------------
|
|
153
|
+
# A2
|
|
154
|
+
if K_s > 0:
|
|
155
|
+
newJ_s = offset_row
|
|
156
|
+
newK_s = offset_col
|
|
157
|
+
sub_A = csc_matrix((convAs_val, (convAs_row, convAs_col)),
|
|
158
|
+
shape=(size_m, newK_s))
|
|
159
|
+
sub_As = csc_matrix(([1.0] * len(addAs_row), (addAs_row, addAs_col)),
|
|
160
|
+
shape=(newJ_s, newK_s))
|
|
161
|
+
new_A = bmat([[A_flq, sub_A]])
|
|
162
|
+
else:
|
|
163
|
+
newJ_s = 0
|
|
164
|
+
newK_s = 0
|
|
165
|
+
new_A = A
|
|
166
|
+
|
|
167
|
+
if not sparse.isspmatrix_csc(new_A):
|
|
168
|
+
new_A = new_A.tocsc()
|
|
169
|
+
|
|
170
|
+
list_A2 = []
|
|
171
|
+
list_c2 = []
|
|
172
|
+
if J_f > 0:
|
|
173
|
+
A_f = new_A[0:(J_f), :]
|
|
174
|
+
list_A2.append(-A_f.T)
|
|
175
|
+
b_f = b[0:(J_f), :]
|
|
176
|
+
list_c2.append([-b_f])
|
|
177
|
+
|
|
178
|
+
if J_l > 0:
|
|
179
|
+
A_l = new_A[(J_f):(J_f + J_l), :]
|
|
180
|
+
list_A2.append(-A_l.T)
|
|
181
|
+
b_l = b[(J_f):(J_f + J_l), :]
|
|
182
|
+
list_c2.append([-b_l])
|
|
183
|
+
|
|
184
|
+
if K_l > 0:
|
|
185
|
+
list_subAl = []
|
|
186
|
+
if K_f > 0:
|
|
187
|
+
list_subAl.append([csc_matrix((K_f, K_l))])
|
|
188
|
+
list_subAl.append([eye(K_l, K_l, format='csc')])
|
|
189
|
+
if K_q + newK_s > 0:
|
|
190
|
+
list_subAl.append([csc_matrix((K_q + newK_s, K_l))])
|
|
191
|
+
sub_Al = bmat(list_subAl)
|
|
192
|
+
list_A2.append(-sub_Al)
|
|
193
|
+
list_c2.append([csc_matrix((K_l, 1))])
|
|
194
|
+
|
|
195
|
+
if J_q > 0:
|
|
196
|
+
A_q = new_A[(J_f + J_l):(J_f + J_l + J_q), :]
|
|
197
|
+
list_A2.append(-A_q.T)
|
|
198
|
+
b_q = b[(J_f + J_l):(J_f + J_l + J_q), :]
|
|
199
|
+
list_c2.append([-b_q])
|
|
200
|
+
|
|
201
|
+
if K_q > 0:
|
|
202
|
+
list_subAq = []
|
|
203
|
+
if K_f + K_l > 0:
|
|
204
|
+
list_subAq.append([csc_matrix((K_f + K_l, K_q))])
|
|
205
|
+
list_subAq.append([eye(K_q, K_q, format='csc')])
|
|
206
|
+
if K_s > 0:
|
|
207
|
+
list_subAq.append([csc_matrix((newK_s, K_q))])
|
|
208
|
+
sub_Aq = bmat(list_subAq)
|
|
209
|
+
list_A2.append(-sub_Aq)
|
|
210
|
+
list_c2.append([csc_matrix((K_q, 1))])
|
|
211
|
+
|
|
212
|
+
if J_s > 0:
|
|
213
|
+
A_s = new_A[(J_f + J_l + J_q):, :]
|
|
214
|
+
list_A2.append(-A_s.T)
|
|
215
|
+
b_s = b[(J_f + J_l + J_q):, :]
|
|
216
|
+
list_c2.append([-b_s])
|
|
217
|
+
|
|
218
|
+
if K_s > 0:
|
|
219
|
+
list_subAs = []
|
|
220
|
+
if K_f + K_l + K_q > 0:
|
|
221
|
+
list_subAs.append([csc_matrix((K_f + K_l + K_q, K_s))])
|
|
222
|
+
list_subAs.append([sub_As.T])
|
|
223
|
+
sub_As = bmat(list_subAs)
|
|
224
|
+
list_A2.append(-sub_As)
|
|
225
|
+
list_c2.append([csc_matrix((K_s, 1))])
|
|
226
|
+
|
|
227
|
+
A2 = bmat([list_A2])
|
|
228
|
+
c2 = bmat(list_c2)
|
|
229
|
+
|
|
230
|
+
if newK_s > 0:
|
|
231
|
+
conv_cs = csc_matrix((convcs_val, (convcs_row, [0] * len(convcs_row))),
|
|
232
|
+
shape=(newK_s, 1))
|
|
233
|
+
b2 = -bmat([[c_flq],
|
|
234
|
+
[conv_cs]])
|
|
235
|
+
else:
|
|
236
|
+
b2 = -c
|
|
237
|
+
|
|
238
|
+
K2 = SymCone()
|
|
239
|
+
K2.f = J.f
|
|
240
|
+
K2.l = J.l + K.l
|
|
241
|
+
K2.q = J.q + K.q
|
|
242
|
+
K2.s = J.s + K.s
|
|
243
|
+
|
|
244
|
+
J2 = SymCone()
|
|
245
|
+
J2.f = A2.shape[0]
|
|
246
|
+
|
|
247
|
+
return A2, b2, c2, K2, J2, map_sdpIndex
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def clp_toEQ(A, b, c, K, J):
|
|
251
|
+
"""Convert from CLP format to Equality standard form (Sedumi primal format)
|
|
252
|
+
|
|
253
|
+
THIS FUNCTION HAS NOT IMPLEMENTED YET.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
A, b, c, K, J: CLP format
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Equality standard form in SeDuMi primal format, (A2, b2, c2, K2, J2)
|
|
260
|
+
"""
|
|
261
|
+
##################################################
|
|
262
|
+
# Under construction
|
|
263
|
+
##################################################
|
|
264
|
+
print('THIS FUNCTION HAS NOT IMPLEMENTED YET.')
|
|
265
|
+
return A2, b2, c2, K2, J2
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def result_fromLMI(x2, y2, K, J, map_sdpIndex):
|
|
269
|
+
"""Get result of CLP from result of converted problem by clp_toLMI().
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
x2, y2: Result of converted problem by clp_toLMI()
|
|
273
|
+
K, J : SymCone of CLP
|
|
274
|
+
map_sdpIndex: Index mapping from converted matrix to original matrix
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Result of CLP, (x, y)
|
|
278
|
+
"""
|
|
279
|
+
# Type check
|
|
280
|
+
if not sparse.isspmatrix_csc(x2):
|
|
281
|
+
x2 = x2.tocsc()
|
|
282
|
+
if not sparse.isspmatrix_csc(y2):
|
|
283
|
+
y2 = y2.tocsc()
|
|
284
|
+
|
|
285
|
+
if len(K.s) > 0:
|
|
286
|
+
K_f = K.f
|
|
287
|
+
K_l = K.l
|
|
288
|
+
K_q = sum(K.q)
|
|
289
|
+
K_s = sum([i ** 2 for i in K.s])
|
|
290
|
+
|
|
291
|
+
x_flq = y2[:(K.f + K.l + K_q)]
|
|
292
|
+
x_s = y2[(K.f + K.l + K_q):]
|
|
293
|
+
x_row = []
|
|
294
|
+
x_val = []
|
|
295
|
+
for (row, val) in zip(x_s.nonzero()[0], x_s.data):
|
|
296
|
+
(idx1, idx2) = map_sdpIndex[row]
|
|
297
|
+
if idx1 != idx2:
|
|
298
|
+
x_row.extend([idx1, idx2])
|
|
299
|
+
x_val.extend([val, val])
|
|
300
|
+
else:
|
|
301
|
+
x_row.append(idx1)
|
|
302
|
+
x_val.append(val)
|
|
303
|
+
|
|
304
|
+
x = bmat([[x_flq],
|
|
305
|
+
[csc_matrix((x_val, (x_row, [0] * len(x_row))),
|
|
306
|
+
shape=(K_s, 1))]])
|
|
307
|
+
else:
|
|
308
|
+
x = y2
|
|
309
|
+
|
|
310
|
+
size_Jq = sum(J.q)
|
|
311
|
+
size_Js = sum([z ** 2 for z in J.s])
|
|
312
|
+
size_Kq = sum(K.q)
|
|
313
|
+
|
|
314
|
+
y_list = []
|
|
315
|
+
if J.f + J.l > 0:
|
|
316
|
+
yfl = x2[:(J.f + J.l)]
|
|
317
|
+
y_list.append([yfl])
|
|
318
|
+
|
|
319
|
+
if size_Jq > 0:
|
|
320
|
+
yq = x2[(J.f + J.l + K.l):(J.f + J.l + K.l + size_Jq)]
|
|
321
|
+
y_list.append([yq])
|
|
322
|
+
|
|
323
|
+
if size_Js > 0:
|
|
324
|
+
ys = x2[(J.f + J.l + K.l + size_Jq + size_Kq):
|
|
325
|
+
(J.f + J.l + K.l + size_Jq + size_Kq + size_Js)]
|
|
326
|
+
y_list.append([ys])
|
|
327
|
+
|
|
328
|
+
y = bmat(y_list)
|
|
329
|
+
return x, y
|
|
330
|
+
|
|
331
|
+
def result_fromEQ(x2, y2, K, J):
|
|
332
|
+
"""Get result of CLP from result of converted problem by clp_toEQ().
|
|
333
|
+
|
|
334
|
+
THIS FUNCTION HAS NOT IMPLEMENTED YET.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
x2, y2: Result of converted problem by clp_toEQ()
|
|
338
|
+
K, J : SymCone of CLP
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
x, y : Result of CLP, (x, y)
|
|
342
|
+
"""
|
|
343
|
+
##################################################
|
|
344
|
+
# Under construction
|
|
345
|
+
##################################################
|
|
346
|
+
print('THIS FUNCTION HAS NOT IMPLEMENTED YET.')
|
|
347
|
+
return x, y
|
|
348
|
+
|