Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

170
Visualizações
Diagonal of a numpy matrix without compute the entire matrix

I have a simple algebric problem and I would like to solve it with numpy (of course that I could solve it easily with numba, but that is not the point).

Let us consider a first random matrix A with size (m x n), with n a big value, and a second random matrix B with size (n x n).

A = np.random.random((1E6, 1E2))
B = np.random.random((1E2, 1E2))

We want to compute the following expression:

np.diag(np.dot(np.dot(A,B),B.T))

The problem is that the entire matrix is loaded to the memory and only then is extracted the diagonal. Is it possible to do this operation in a more efficient way?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

This is how I would approach it from your starting expression

np.diag(np.dot(np.dot(A,B),B.T))

You can start by grouping terms:

np.diag(np.dot(A, np.dot(B,B.T)))

then only use the first relevant (square) part of A:

np.diag(np.dot(A[:B.shape[0], :], np.dot(B,B.T)))

and then avoid the extra multiplications (that will fall out of the diagonal), by doing the element-wise multiplications yourself:

np.sum( np.multiply(A[:B.shape[0], :].T, np.dot(B,B.T)), 0)
over 4 years ago · Santiago Trujillo Relatório

0

  1. Changed (A*B)*B.T to A*(B*B.T)
  2. Multiplied only this part of A (A[:B.shape[0]]) that would result in the diagonal part of the matrix
import numpy as np
import time

A = np.random.random((1000_000, 100))
B = np.random.random((100, 100))

start_time = time.time()
result = np.diag(np.dot(np.dot(A, B), B.T))
print('Baseline: ', time.time() - start_time)

start_time = time.time()
for i in range(100):
    result2 = np.diag(np.dot(A[:B.shape[0]], np.dot(B, B.T)))
print('Optimized: ', (time.time() - start_time) / 100)
stop = 1

assert np.allclose(result, result2)
Baseline:  1.7957241535186768
Optimized:  0.00016015291213989258
over 4 years ago · Santiago Trujillo Relatório

0

Yes.

N = 1E6

A = np.random.random((N, 1E2))
B = np.random.random((1E2, 1E2))

result = 0;
for i in range(N):
  result += np.dot(np.dot(A[i,:], B[i,:])[i, :], B.T[i, :])

  # Replacing B.T[i, :] with B[:, i].T might be a little more efficient

Explanation:

Say we have: K = np.dot(np.dot(A,B),B.T).

Then, K[0,0] = (A[0, :] * B[:,0])[0, :] * B.T[:])

  • Let X = (A[0, :] * B[:,0]), which is the [0, 0] element of np.dot(A,B)
  • Then X[0, :] * B.T[:, 0] is the [0, 0] element of np.dot(np.dot(A,B),B.T)
  • Then X[0, :] * B.T[:, 0] = (A[0, :] * B[:,0])[0, :] * B.T[:])

We can also generalize this result to: K[i,i] = (A[i, :] * B[:,i])[i, :] * B.T[:, i])

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda