Переиндексирование списка f (x) для извлечения матрицы f (xy) - PullRequest
0 голосов
/ 09 октября 2018

Я не уверен, как сформулировать / назвать эту проблему, поэтому я прошу прощения заранее, если это уже было задано / получено ответ.Или, если у кого-то есть лучшее предложение для заголовка, дайте мне знать ...

Я хочу оценить функцию f(x), но я хочу сделать это по разнице значений, то есть f(x-y), 2Dвывод матрицы значений.Теперь самый простой способ сделать это:

dat_array = [[f(x-y) for x in xvalues] for y in xvalues]

, где xvalues - список чисел.Рассматриваемая функция f довольно вычислительно дорогая для вычисления, и мне нужно вычислить ее для многих точек.

Однако, кажется, что вычисление массива таким способом довольно неэффективно, поскольку существует высокая степеньсимметрии в задаче.Например, я могу получить все возможные значения для различий, используя (неуклюжий) код:

diff_vals = np.unique(np.sort(np.append(xlist , 2*xlist)))

Тогда у меня вопрос: можно ли просто оценить f по списку diff_vals, а затемизвлечь dat_array путем переиндексации?

Ответы [ 3 ]

0 голосов
/ 09 октября 2018

Не уверен, как ваш diff_vals должен работать ... но да, компьютер все возможные различия, сделать список уникальным, используя set, вычислить значение дорогой операции для набора, а затем поместить их в 2D-массив:

diffs = set(x - y for x in xvalues for y in yvalues)
values = { diff: f(diff) for diff in diffs }
[[values[x - y] for x in xvalues] for y in yvalues]
0 голосов
/ 09 октября 2018

np.unique имеет ключевое слово return_inverse, которое можно использовать здесь:

>>> a = np.r_[0:3, 6:9]
>>> D = np.subtract.outer(a, a)
>>> D                                                                                                               
array([[ 0, -1, -2, -6, -7, -8],                                                                                    
       [ 1,  0, -1, -5, -6, -7],                                                                                    
       [ 2,  1,  0, -4, -5, -6],                                                                                    
       [ 6,  5,  4,  0, -1, -2],                                                                                    
       [ 7,  6,  5,  1,  0, -1],                                                                                    
       [ 8,  7,  6,  2,  1,  0]])                                                                                   
>>> unq, bck = np.unique(D, return_inverse=True)
>>> unq                                                                                                             
array([-8, -7, -6, -5, -4, -2, -1,  0,  1,  2,  4,  5,  6,  7,  8])                                                 
>>> bck                                                                                                             
array([ 7,  6,  5,  2,  1,  0,  8,  7,  6,  3,  2,  1,  9,  8,  7,  4,  3,                                          
        2, 12, 11, 10,  7,  6,  5, 13, 12, 11,  8,  7,  6, 14, 13, 12,  9,                                          
        8,  7])                                                                                                     
>>> f_unq = 10 * unq
>>> f_D = f_unq[bck].reshape(6, 6)
>>> f_D                                                                                                             
array([[  0, -10, -20, -60, -70, -80],                                                                              
       [ 10,   0, -10, -50, -60, -70],                                                                              
       [ 20,  10,   0, -40, -50, -60],                                                                              
       [ 60,  50,  40,   0, -10, -20],                                                                              
       [ 70,  60,  50,  10,   0, -10],                                                                              
       [ 80,  70,  60,  20,  10,   0]])
0 голосов
/ 09 октября 2018

В модуле functools есть вещи для кэширования результатов вызовов функций.Таким образом, вы можете использовать это с вашей дорогой функцией и не беспокоиться о создании diff_vals.Посмотрите на декоратор lru_cache:

from functools import lru_cache

@lru_cache(maxsize=None)
def computationally_expensive_function(x):
    # do something computationally expensive

Кэш запомнит параметры, использованные при вызове этой функции, и вернет результат без необходимости повторного вычисления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...