Использование вложенного цикла for для добавления в несколько списков - PullRequest
1 голос
/ 19 мая 2019

Я пытаюсь зациклить уравнение диода Шокли для трех разных температур (с тремя разными токами насыщения) для диапазона значений напряжения, а затем вставить эти три партии данных в списки.

kb = 1.38E-23
q = 1.602E-19

voltage = np.arange(0.5, 1.02, 0.02)

T = np.array([269, 289.1, 294.5])
Is = np.array([1.707E-14, 6.877E-14, 1.4510E-13])

i269 = []
i284 = []
i294 = []

for i in range(1, len(voltage)):
    for j in range(1, 3):
        I = Is[j] * np.exp((voltage[i] * q) / (kb * T[j]))
        i269.append(I[j[0]])
        i284.append(I[j[1]])
        i294.append(I[j[2]])

Я знаю, что метод, который я использовал здесь, не является синтаксически правильным, но я написал его таким образом, чтобы попытаться помочь моим усилиям передать то, чего я пытаюсь достичь.

Я хочу сначала пройти через напряжение при j = 0, добавить I в i269, затем снова через напряжение при j = 1, добавить в i284 и т. Д.

Любая помощь будет высоко ценится. Спасибо

1 Ответ

0 голосов
/ 19 мая 2019

Обратите внимание, что при вашем текущем подходе I не может быть проиндексирован, так как вы просто присваиваете ему значение. Сначала нужно определить его как список, а затем проиндексировать, чтобы присвоить его значениям i269, i284 или i294:

kb = 1.38E-23
q = 1.602E-19

voltage = np.arange(0.5, 1.02, 0.02)

T = np.array([269, 289.1, 294.5])
Is = np.array([1.707E-14, 6.877E-14, 1.4510E-13])

I = [0 for _ in range(len(T))]
i269 = []
i284 = []
i294 = []

for i in range(len(voltage)):
    for j in range(3):
        I[j] = Is[j] * np.exp((voltage[i] * q) / (kb * T[j]))
    i269.append(I[0])
    i284.append(I[1])
    i294.append(I[2])

Однако можно добиться улучшения производительности, используя широковещательную рассылку и векторизовав вышеизложенное как:

i269, i284, i294 = Is[:,None] * np.exp((voltage * q) / (kb * T)[:,None])

Давайте проверим результаты и посмотрим на время обоих подходов:

kb = 1.38E-23
q = 1.602E-19

voltage = np.arange(0.5, 1.02, 0.02)

T = np.array([269, 289.1, 294.5])
Is = np.array([1.707E-14, 6.877E-14, 1.4510E-13])

def current_approach(kb, q, voltage, T, Is):
    I = [0 for _ in range(len(T))]
    i269 = []
    i284 = []
    i294 = []

    for i in range(len(voltage)):
        for j in range(3):
            I[j] = Is[j] * np.exp((voltage[i] * q) / (kb * T[j]))
        i269.append(I[0])
        i284.append(I[1])
        i294.append(I[2])
    return i269, i284, i294

def vect_approach(kb, q, voltage, T, Is):
    i269, i284, i294 = Is[:,None] * np.exp((voltage * q) / (kb * T)[:,None])
    return i269, i284, i294

np.allclose(current_approach(kb, q, voltage, T, Is), 
            vect_approach(kb, q, voltage, T, Is))
# True

%timeit current_approach(kb, q, voltage, T, Is)
# 201 µs ± 3.46 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit vect_approach(kb, q, voltage, T, Is)
# 30.9 ns ± 0.647 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

До огромного 6,500x ускорения с векторизованным подходом!

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