Параметры косинуса в квадрате scipy, оптимизирующие кривую, неверны в питоне
Я пытаюсь приспособить квадрат косинуса к массиву данных из измерения интенсивности оптической интерферометрии. К сожалению, подгонка возвращает амплитуды и периоды, которые далеко. Только однажды я получил более разумное соответствие, выбрав первые 200 точек данных из массива (и некоторые другие варианты). Эти параметры подгонки были использованы в качестве начальных догадок для расширения подгонки на весь массив, что дало график, похожий на изображение.
import csv
import numpy as np
import matplotlib.pyplot as plt
import scipy as sy
from numpy import genfromtxt
from scipy.optimize import curve_fit
# reads the data from the csv file
csvfile ="</home/pi/Desktop/molecularpolOutput_No2.csv>"
csv = genfromtxt ('molecularpolOutput_No2.csv', delimiter=",")
# defines the data as variables
pressure = csv[100:200,2]
intensity = csv[100:200,3]
temperature = csv[:,1]
pi = 3.14
P = pressure
# defines the function and initial fit parameters
def func(P, T, a, b, c):
return a*np.cos((2*pi*P)/T+b)**2+c
p0 = sy.array([2200, 45, 4000, 85])
# fits the function
coeffs, pcov = curve_fit(func, pressure, intensity, p0)
I = func(P, coeffs[0], coeffs[1], coeffs[2], coeffs[3])
print 'period =',(coeffs[0]), 'Pa'
# plots the data and the function
fig = plt.figure(figsize=(10, 3), dpi=100)
plt.plot(pressure, intensity, linestyle="none", marker=".")
plt.plot(pressure, I)
plt.xlabel('Pressure (Pa)')
plt.ylabel('Relative intensity')
plt.title('interference intensity plot of Newtons rings ')
plt.show()
Я ожидаю, что подгонка будет правильной как для больших, так и для маленьких массивов данных. Однако, как показывают рисунки, расширение массива мешает как амплитуде, так и периоду. Подгонка, которая выглядит нормально, также дает значения за период, сопоставимые с другими экспериментами. Данные, генерируемые фоторезистором, не являются точно линейными, но я предполагаю, что это не должно быть проблемой для curve_fit. Могу ли я изменить их в коде, чтобы они работали? Я уже пробовал этот код: как мне подобрать синусоидальную кривую к моим данным с помощью pylab и numpy?
обновление Подгонка кривой наименьших квадратов в Matlab дает ту же проблему. Должен ли я попробовать другой метод, чтобы соответствовать кривой или это данные, которые вызывают проблему? Код Matlab:
%% Opens excel file
filename = 'vpnat_1.xlsx';
Pr = xlsread(filename,'D1:D500');
I = xlsread(filename, 'E1:E500');
P = Pr;
% defines figure size relative to screen
scrsz = get(groot,'ScreenSize');
figure('Position',[1 scrsz(4)/2 scrsz(3)/2 scrsz(4)/4])
%% fit & plots
hold on
scatter(P,I,'.'); % scatter plot
%% defines parameter guesses
Im = mean(I);
Iu = max(I);
Il = min(I);
Ia = Iu-Il;
Ip = 2000;
Id = -4000;
a_0 = [Ia; Ip; Id; Im]; % initial guesses
fun = @(a,P) a(1).*(cos((2*pi*P)./a(2)+a(3)).^2)+a(4); % defines function
fcn = @(a) sum((fun(a,P)-I).^2); % finds best fit
s = fminsearch(fcn, a_0);
plot(P,fun(s,P)) % plots fitted function
hold off
1 ответ
Я решил проблему с помощью Matlab. Похоже, что параметры были плохо определены для curve_fit в python, чтобы найти наименьшие квадраты в пределах его заданных границ (Ограничить количество итераций?).
Похоже, что Matlab принял больший предел погрешности в исходных параметрах и поэтому нашел соответствие для всех выборок данных. Использование параметров соответствия из matlab в качестве начальных параметров в Python возвращает правильное соответствие. Проблема в python может быть предотвращена путем вычисления догадок для параметров, чтобы лучше начать.