Skip to content

Commit db2c2c3

Browse files
committed
restore merge
1 parent cdeff88 commit db2c2c3

1 file changed

Lines changed: 26 additions & 19 deletions

File tree

pypfopt/cla.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,16 @@ def _compute_w(self, covarF_inv, covarFB, meanF, wB):
228228
g1 = np.dot(np.dot(onesF.T, covarF_inv), meanF)
229229
g2 = np.dot(np.dot(onesF.T, covarF_inv), onesF)
230230
if wB is None:
231-
g_result = -self.ls[-1] * g1 / g2 + 1 / g2
232-
g, w1 = float(g_result.item() if hasattr(g_result, 'item') else g_result), 0
231+
g = -self.ls[-1] * g1 / g2 + 1 / g2
232+
w1 = 0
233233
else:
234234
onesB = np.ones(wB.shape)
235235
g3 = np.dot(onesB.T, wB)
236236
g4 = np.dot(covarF_inv, covarFB)
237237
w1 = np.dot(g4, wB)
238238
g4 = np.dot(onesF.T, w1)
239-
g_result = -self.ls[-1] * g1 / g2 + (1 - g3 + g4) / g2
240-
g = float(g_result.item() if hasattr(g_result, 'item') else g_result)
239+
g = -self.ls[-1] * g1 / g2 + (1 - g3 + g4) / g2
240+
g = float(g[0, 0])
241241
# 2) compute weights
242242
w2 = np.dot(covarF_inv, onesF)
243243
w3 = np.dot(covarF_inv, meanF)
@@ -259,16 +259,16 @@ def _compute_lambda(self, covarF_inv, covarFB, meanF, wB, i, bi):
259259
# 3) Lambda
260260
if wB is None:
261261
# All free assets
262-
result = (c4[i] - c1 * bi) / c
263-
return float(result.item() if hasattr(result, 'item') else result), bi
262+
res = (c4[i] - c1 * bi) / c
264263
else:
265264
onesB = np.ones(wB.shape)
266265
l1 = np.dot(onesB.T, wB)
267266
l2 = np.dot(covarF_inv, covarFB)
268267
l3 = np.dot(l2, wB)
269268
l2 = np.dot(onesF.T, l3)
270-
result = ((1 - l1 + l2) * c4[i] - c1 * (bi + l3[i])) / c
271-
return float(result.item() if hasattr(result, 'item') else result), bi
269+
res = ((1 - l1 + l2) * c4[i] - c1 * (bi + l3[i])) / c
270+
res = float(res[0, 0])
271+
return res, bi
272272

273273
def _get_matrices(self, f):
274274
# Slice covarF,covarFB,covarB,meanF,meanB,wF,wB
@@ -288,18 +288,25 @@ def _diff_lists(list1, list2):
288288

289289
@staticmethod
290290
def _reduce_matrix(matrix, listX, listY):
291-
# Reduce a matrix to the provided list of rows and columns
291+
"""
292+
Extract a submatrix from the given matrix using specified row and column indices.
293+
294+
Uses numpy advanced indexing with np.ix_ for vectorized selection,
295+
which is significantly faster than the previous nested loop implementation
296+
for large matrices.
297+
298+
:param matrix: input matrix to extract submatrix from
299+
:type matrix: np.ndarray
300+
:param listX: row indices to select
301+
:type listX: list
302+
:param listY: column indices to select
303+
:type listY: list
304+
:return: submatrix with selected rows and columns, or None if indices are empty
305+
:rtype: np.ndarray or None
306+
"""
292307
if len(listX) == 0 or len(listY) == 0:
293-
return
294-
matrix_ = matrix[:, listY[0] : listY[0] + 1]
295-
for i in listY[1:]:
296-
a = matrix[:, i : i + 1]
297-
matrix_ = np.append(matrix_, a, 1)
298-
matrix__ = matrix_[listX[0] : listX[0] + 1, :]
299-
for i in listX[1:]:
300-
a = matrix_[i : i + 1, :]
301-
matrix__ = np.append(matrix__, a, 0)
302-
return matrix__
308+
return None
309+
return matrix[np.ix_(listX, listY)]
303310

304311
def _purge_num_err(self, tol):
305312
# Purge violations of inequality constraints (associated with ill-conditioned cov matrix)

0 commit comments

Comments
 (0)