Къде мога да намеря ефективността 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
О, разбирам.. но това не е приложимо за meshgrid и linspace все пак...   -  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