Где я могу найти эффективность O (n) некоторых методов Numpy?

Я делаю школьный проект, и они спросили об эффективности O (n) некоторых методов Numpy, и я не могу их найти. Кто-нибудь может сказать мне, где я могу их найти?

Примеры таких методов, как:

numpy.linspace(x,y,z) numpy.meshgrid(x,y) numpy.zeroes(x,y)


person Mahmoud Ayman    schedule 24.05.2015    source источник
comment
Не думаю, что есть место, где их можно найти. Вам нужно будет подумать, что на самом деле делает алгоритм, чтобы сделать вывод о его сложности. Например, np.ones(n) должен выделить память для n чисел с плавающей запятой, а затем записать 1 в каждую из ячеек памяти. Всего он должен написать n единиц, так что вы находитесь в O(n).   -  person cel    schedule 24.05.2015
comment
О, понятно ... но это не применимо к сетке и линспейсу ...   -  person Mahmoud Ayman    schedule 24.05.2015


Ответы (1)


Вы можете просто измерить время выполнения для разных размеров задач, чтобы оценить временную сложность,

Например, ниже приведен код для измерения временной сложности для numpy.meshgrid(x,y), который также может использоваться для других функций numpy,

In [1]: import numpy as np
   ...: from time import time
   ...: import matplotlib.pyplot as plt
   ...: from scipy.optimize import curve_fit
   ...: %matplotlib inline
   ...: 
   ...: def complexity_model(x, n, A, C):
   ...:     return A*x**n + C
   ...: 
   ...: problem_size = np.logspace(2, 4, 10)
   ...: 
   ...: res = []
   ...: for N in problem_size:
   ...:     x = np.linspace(0, 1, N)
   ...:     y = x.copy()
   ...:     
   ...:     t0 = time()
   ...:     np.meshgrid(x,y)
   ...:     dt = time() - t0
   ...:     res.append(dt)
   ...: 
   ...: nn = np.logspace(np.log10(problem_size.min()), np.log10(problem_size.max()), 100)  
   ...: 
   ...: time_to_solution = np.asarray(res)
   ...: fig, ax = plt.subplots(1,1)
   ...: ax.loglog(problem_size, time_to_solution, 'o-b')
   ...: 
   ...: mask = problem_size > 100 # ignore initial points
   ...: 
   ...: popt, _ = curve_fit(complexity_model, problem_size[mask],
   ...:                               time_to_solution[mask],
   ...:                               p0=(1.0, 1.0,  0.0) )
   ...: print(popt)
   ...: ax.loglog(nn, complexity_model(nn, *popt), '--k')
   ...: 
   ...: 
   ...: ax.set_xlabel('Problem size: N')
   ...: ax.set_ylabel('Time to solution 
  [  1.94816942e+00   1.40955397e-08  -7.33862899e-04]

что дает следующую кривую,

введите описание изображения здесь

Таким образом, для достаточно больших размеров массива numpy.meshgrid(x,y) имеет временную сложность O(n**α) с α = 1.95 ≈ 2.

person rth    schedule 25.05.2015
comment
Большое спасибо за это всестороннее решение. Выбрал как правильный ответ :) - person Mahmoud Ayman; 25.05.2015
comment
numpy.zeros(n): O(1) кажется подозрительным. Это означало бы, что вы каким-то образом можете добиться большего успеха, чем заполнять каждую ячейку памяти символом 0. Вы уверены, что это возможно? - person cel; 25.05.2015
comment
@cel Да, я тоже так думал. Грубо говоря, это должна быть временная сложность соответствующего распределения памяти. Однако кажется, что время выполнения maloc не детерминировано (см. ответ). Например, %timeit -n 1 np.zeros(100000) дает что-то между 30 и 160 µs на моем ноутбуке. Я обновил ответ, чтобы отразить это. - person rth; 25.05.2015
comment
@rth, да, я думаю, это ограничение временного подхода. В этом случае, вероятно, происходят странные оптимизации ресурсов, которые не имеют ничего общего с временной сложностью самого алгоритма. - person cel; 25.05.2015