Я новичок ie в Python, и я писал код для вычисления, а затем подгонки данных намагничивания.
Во-первых, я пишу функцию для минимизации энергии относительно к параметру "тета".
def E_uniaxial(H, phi, theta, Keff, Ms):
e = Keff*(np.cos(theta))**2 - ((4*np.pi)**2*mu0)*Ms*H*np.cos(theta - phi)
return e
Затем, поскольку намагниченность сильно зависит от предыдущего положения равновесия системы, я пишу функцию для "следующего положения равновесия", параметр Н является одним должен измениться между предыдущим и новым положением равновесия.
def next_theta(Ms, phi, Keff, H, lasttheta, fctE):
E = lambda x : fctE(H, phi, x, Keff, Ms)[0]
result = scipy.optimize.minimize(E, lasttheta)
return result.x
После этого я пишу функцию, которая вычисляет весь цикл гистерезиса. Учитывая известную начальную точку, функция увеличивает H и вычисляет все положения равновесия, которые зависят от предыдущего (затем H уменьшается, и выполняется тот же процесс).
def cycle_theta(Ms, desfield, Keff, Hmax, theta_init_1, theta_init_2, fctE):
#aller
H1 = np.linspace(-Hmax, Hmax, 2000)
sol1 = np.zeros(np.shape(H1))
sol1[0] = theta_init_1
for i in range(len(H1)-1):
sol1[i+1] = next_theta(Ms, desfield, Keff, H1[i+1], sol1[i], fctE)
#retour
H2 = np.linspace(Hmax, -Hmax, 2000)
sol2 = np.zeros(np.shape(H2))
sol2[0] = theta_init_2
for i in range(len(H2) -1):
sol2[i+1] = next_theta(Ms, desfield, Keff, H2[i+1], sol2[i], fctE)
return H1, sol1, np.flip(sol2)
Тогда у меня есть чтобы соответствовать данным, чтобы найти параметры Ms и Keff. Я определил эту функцию:
def test_fit(H, Ms, Keff):
a = cycle_theta(Ms, 1., Keff, 20, np.pi, 0., E_uniaxial)[1]
idx = 0
if isinstance(H, float):
idx = find_nearest(a, H)
print('float')
return np.sin(a[idx])
if isinstance(H, np.ndarray):
c = np.zeros(np.shape(H))
for i in range(len(H)):
idx = find_nearest(a, H[i])
c[i] = a[idx]
print('array')
return np.sin(c)
Похоже, что условие для типа требуется для работы функции с curve_fit. Наконец, я называю popt = curve_fit(test_fit, b, sig)
, где «b» и «sig» - мои экспериментальные данные.
Но я несколько раз получал эту ошибку, исходя из scipy.optimize.minimize
, а не кривой_fit:
ValueError: setting an array element with a sequence.
Я прочитал, что это сообщение может исходить из того факта, что моя энергетическая функция E_unixial возвращает массив, а не скаляр, но на самом деле это довольно регулярная функция: если вы вводите скаляр, вы получаете скаляр и если вы вводите массив, вы получить массив. Так что я действительно не понимаю, не должен ли я использовать scipy.optimize.minimize и scipy.minimize.curve_fit один в другой?
Спасибо большое за вашу помощь! !