Рад предложить (возможно, очевидную) реализацию этого, которая могла бы быть сделана на чистом Python или C / Cython, если у вас есть время и место для новых зависимостей и вам нужно, чтобы это было быстрее.
Разреженная матрица в N измерениях может предполагать, что большинство элементов пусты, поэтому мы используем словарь с ключом для кортежей:
class NDSparseMatrix:
def __init__(self):
self.elements = {}
def addValue(self, tuple, value):
self.elements[tuple] = value
def readValue(self, tuple):
try:
value = self.elements[tuple]
except KeyError:
# could also be 0.0 if using floats...
value = 0
return value
и вы бы использовали его так:
sparse = NDSparseMatrix()
sparse.addValue((1,2,3), 15.7)
should_be_zero = sparse.readValue((1,5,13))
Вы можете сделать эту реализацию более надежной, проверив, что ввод фактически является кортежем и содержит только целые числа, но это просто замедлит работу, поэтому я не буду беспокоиться, если вы не опубликуете свой код позже.
РЕДАКТИРОВАТЬ - реализация Cython задачи умножения матриц, предполагающая, что другой тензор является N-мерным массивом NumPy (numpy.ndarray
), может выглядеть следующим образом:
#cython: boundscheck=False
#cython: wraparound=False
cimport numpy as np
def sparse_mult(object sparse, np.ndarray[double, ndim=3] u):
cdef unsigned int i, j, k
out = np.ndarray(shape=(u.shape[0],u.shape[1],u.shape[2]), dtype=double)
for i in xrange(1,u.shape[0]-1):
for j in xrange(1, u.shape[1]-1):
for k in xrange(1, u.shape[2]-1):
# note, here you must define your own rank-3 multiplication rule, which
# is, in general, nontrivial, especially if LxMxN tensor...
# loop over a dummy variable (or two) and perform some summation:
out[i,j,k] = u[i,j,k] * sparse((i,j,k))
return out
Хотя вам всегда нужно будет делать это вручную, потому что (как указано в комментарии к коду) вам нужно будет определить, какие индексы вы суммируете, и будьте осторожны с длинами массивов, иначе ничего не сработает. !
РЕДАКТИРОВАТЬ 2 - если другая матрица также разреженная, вам не нужно выполнять трехсторонний цикл:
def sparse_mult(sparse, other_sparse):
out = NDSparseMatrix()
for key, value in sparse.elements.items():
i, j, k = key
# note, here you must define your own rank-3 multiplication rule, which
# is, in general, nontrivial, especially if LxMxN tensor...
# loop over a dummy variable (or two) and perform some summation
# (example indices shown):
out.addValue(key) = out.readValue(key) +
other_sparse.readValue((i,j,k+1)) * sparse((i-3,j,k))
return out
Мое предложение для реализации C заключалось бы в использовании простой структуры для хранения индексов и значений:
typedef struct {
int index[3];
float value;
} entry_t;
затем вам понадобятся некоторые функции для выделения и поддержки динамического массива таких структур и поиска в них так быстро, как вам нужно; но вы должны протестировать реализацию Python на месте на предмет производительности, прежде чем беспокоиться об этом.
person
tehwalrus
schedule
11.10.2011