Параметры cosine squared scipy optimize curvefit неверны в python

Я пытаюсь подогнать квадрат Косинуса к массиву данных из измерения интенсивности интерферометрии оптики. К сожалению, fit возвращает амплитуды и периоды, которые находятся далеко. Только один раз я получил более разумное соответствие, выбрав первые 200 точек данных из массива (и некоторые другие выборки). Эти параметры fit были использованы в качестве начальных догадок, чтобы расширить fit на весь массив, который дал назад участок, похожий на изображение .

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 ответ

  1. Я решил проблему с помощью Matlab. Оказывается, что параметры были плохо определены для curve_fit в python, чтобы найти наименьшие квадраты в его заданных границах (ограничение на количество итераций?).

    Matlab, по-видимому, принял большую погрешность в начальных параметрах и поэтому нашел пригодный для всех выборок данных. Использование параметров fit из matlab в качестве начальных параметров в Python возвращает правильный fit. Проблема в python может быть предотвращена путем вычисления догадок для параметров, чтобы получить лучшее начало.