Home > Software design >  Weighted sum of multiple matrices
Weighted sum of multiple matrices

Time:06-30

I have a list of m n x n matrices and a list of m real values (alphas). The values of n and m can be quite large. I am trying to calculate the weighted sum of the matrices with weights in alphas.

I was wondering if there is a numpy function (or any other library) that can do this faster than the manual for-loop method.

I have included my current function below.

def calculate_matrix_sums(mats, alphas):
    """
        Calculate the weighted sum of matrices in mats with weights alpha
    """
    k_mults = [np.multiply(mats[i], alphas[i]) for i in range(len(alphas))]
    k_sums1 = np.matrix(k_mults[0])   np.matrix(k_mults[1])
    for i in range(2, len(k_mults)):
        k_sums1 = k_sums1   np.asmatrix(k_mults[i])
    k_sums2 = np.asarray(k_sums1).astype(float)
    k_sums2 = k_sums2.reshape(len(mats[0]), len(mats[0]))
    return k_sums2

and a sample code:

matrices = np.asarray([np.array([[1., 0.77841638, 0.53239253, 0.9444068, 0.93024477],
                                 [0.77841638, 1., 0.7221497, 0.5805838, 0.68501944],
                                 [0.53239253, 0.7221497, 1., 0.36986265, 0.62792847],
                                 [0.9444068, 0.5805838, 0.36986265, 1., 0.88303226],
                                 [0.93024477, 0.68501944, 0.62792847, 0.88303226, 1.]]),
                       np.array([[1., 0.45650032, 0.13898701, 0.83605729, 0.79743304],
                                 [0.45650032, 1., 0.36094014, 0.18229867, 0.30596445],
                                 [0.13898701, 0.36094014, 1., 0.04443844, 0.23300302],
                                 [0.83605729, 0.18229867, 0.04443844, 1., 0.67745532],
                                 [0.79743304, 0.30596445, 0.23300302, 0.67745532, 1.]])])
alpha_vals = [0.47547796, 0.52452204]

print(calculate_matrix_sums(matrices, alpha_vals))

Any suggestions are appreciated.

CodePudding user response:

You can reshape alpha_vals so that it broadcasts across the first axis of matrices correctly:

(np.array(alpha_vals)[:, None, None] * matrices).sum(axis=0)

Alternatively, you can adjust the strides of matrices, so that the last dimension corresponds to alpha_vals:

(np.moveaxis(matrices, 0, -1) * alpha_vals).sum(axis=-1)

You can also use np.einsum for this sort of thing (probably the most elegant solution):

np.einsum('ijk,i->jk', matrices, alpha_vals)

CodePudding user response:

If you want a matrix result, it's simply:

def calculate_matrix_sums(mats, alphas):
    """
        Calculate the weighted sum of matrices in mats with weights alpha
    """
    return np.sum( m * a for m,a in zip(mats,alphas))
  • Related