Как я могу умножить разреженный вектор на целочисленную матрицу быстро? - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть вектор v, который имеет много нулей и только пару ненулевых элементов (в основном 1 с). У меня есть матрица m, которая является квадратной, симметричной и имеет целочисленные значения.

Тестовый скрипт

Следующий скрипт генерирует аналогичные данные и время интересующей меня части:

#!/usr/bin/env python

import time
import numpy as np

np.random.seed(0)

n = 20000
m = 20
assert n >= m

# Create the vector
v = [1] * m + [0] * (n - m)
np.random.shuffle(v)
v = np.array(v, np.int8)

# Create the matrix
m = np.random.randint(0, 256, size=(n, n), dtype=np.uint8)
m = (m + m.T) / 2
m = m.astype(np.uint8)

# Multiplication
t0 = time.time()
result = np.dot(v, m)
t1 = time.time()

# Check the results
print("result shape: {}".format(result.shape))
print("result[0]: {}".format(result[0]))  # should be 1757
print('Time: {:0.2f}s'.format(t1 - t0))

Результаты испытаний

Я проверил пару вариантов вышеописанного скрипта:

| Variation                                         | Time   |
| ------------------------------------------------- | ------ |
| Original                                          | 21.65s |
| (1) m = m.astype(np.float32)                      | 0.09s  |
| (2) v = v.astype(np.uint8)                        | 4.87s  |
| (3) v = v.astype(np.int16);m = m.astype(np.int16) | 5.77s  |
| (4) = (3) + matmul instead of dot                 | 6.91s  |
| (5) = (1) + matmul instead of dot                 | 0.09s  |

Вопрос

Глядя на результаты моего теста, у меня есть два вопроса:

  1. Почему такая огромная разница? Это проверка типа / границы?
  2. Есть ли другой способ ускорить его; например разреженные матрицы? (Я пытался использовать v = scipy.sparse.csr_matrix(v), но я не получаю тот же результат)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...