Калькулятор с решением степеней: Алгебраический калькулятор | Microsoft Math Solver

python — Калькулятор степени Херста

Несколько замечаний:


s_t = np.zeros(n) и r_t = np.zeros(n) больше, чем вам нужно. Поскольку вы на самом деле не используете значения массива, а только перезаписываете их, вы можете использовать здесь np.empty .


Вы выполняете довольно много избыточной работы в цикле для .

При вычислении s_t[i] numpy в основном должен повторить все вычисления, которые он уже сделал для с_т[i-1] . Если вы посмотрите на определение np.std , вы увидите, что здесь играет роль среднее значение. Поскольку вы уже придумали хорошее решение для среднего значения, вы можете использовать его здесь:

 s_t = np.empty(n)
для я в диапазоне (n):
    s_t[i] = np.mean((sig[:i+1] - mean_t[i])**2)
    ...
s_t = np.sqrt (s_t)
 

Я проверил это по исходному коду с помощью np.allclose .

r_t также имеет дополнительную работу, от которой можно избавиться.

На данный момент ваш код делает следующее:

 x_t = y - t * mean_t[i]
r_t[i] = np.ptp(x_t[:i + 1])
 

Все значения x_t в [i+1:n] вычисляются, но никогда не используются, поэтому вы можете сделать

 r_t[i] = np.ptp(y[:i+1] - t [:i+1] * среднее_t[i])
 
вместо

без изменения результата. Вы также можете написать это как два понимания списка:

 s_t = np.sqrt(
    np.array([np.mean((sig[:i+1] - mean_t[i])**2) для i в диапазоне (n)])
)
r_t = np.array([np.ptp(y[:i+1] - t[:i+1] * mean_t[i]) для i в диапазоне(n)])
 

Или даже один, если вы хотите проявить немного творчества:

 rs_t = np.array([
    [
        np.mean((sig[:i + 1] - mean_t[i])**2),
        np.ptp(y[:i + 1] - t[:i + 1] * mean_t[i])
    ] для i в диапазоне (n)
])
rs_t [:, 0] = np.sqrt (rs_t [:, 0])
 

Полностью векторизованное вычисление x_t Я придумал, начиная с

 x_t = y.reshape(1, -1) - mean_t.reshape(-1, 1) @ t. reshape(1, -1) )
 

значительно медленнее, чем зацикленная версия.


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


Я замерял время разных версий этого алгоритма. Полный код теста можно найти в этой сути. Это то, что я получил до сих пор (за n=15360 ):

 база: 3,748915 с
лучший_цикл: 2.605374 с
двойной_лк: 2.430255с
single_lc: 2,445943 с
-----------------------
base_numba: 0,866583 с
better_loop_numba: 0,813630 с
double_lc_numba: 0,776361 с
single_lc_numba*: Н/Д
 

Нижняя группа результатов использует numba, своевременный компилятор для кода Python, который иногда помогает ускорить выполнение циклов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *