5

Tôi đang cố gắng để phù hợp với một đường cong theo hàm mũ cho các tập dữ liệu chứa dao động điều hòa giảm chấn. Các dữ liệu là một chút phức tạp theo nghĩa là các dao động hình sin chứa nhiều tần số như bên dưới:Làm thế nào để phù hợp với đường cong theo hàm mũ với dữ liệu dao động điều hòa dao động trong MATLAB?

enter image description here

tôi cần phải tìm ra tỷ lệ phân rã trong dữ liệu. Phương pháp tôi đang sử dụng có thể được tìm thấy here. Cách hoạt động, có phải nhật ký của các giá trị y trên giá trị trạng thái ổn định và sau đó sử dụng:

lsqlin(A,y1(:),-A,-y1(:),[],[],[],[],[],optimset('algorithm','active-set','display','off')) 

Để vừa với nó.

Tuy nhiên, kết quả này trong các dữ liệu sau đây phù hợp: enter image description here

tôi đã cố gắng sử dụng một sự phù hợp hồi quy tuyến tính mà rõ ràng là đã không làm việc vì phải mất trung bình. Tôi cũng đã thử RANSAC nghĩ rằng có nhiều dữ liệu hơn gần các đỉnh núi. Nó hoạt động tốt hơn một chút so với hồi quy tuyến tính nhưng phương pháp này là thiếu sót khi có nhiều thời điểm khi tồn tại nhiều điểm hơn ở các vùng sai.

Có ai biết phương pháp tốt để vừa với các đỉnh cho dữ liệu này không?

Hiện tại, tôi đang nghĩ đến việc chia 500 điểm dữ liệu thành 10 vùng khác nhau và trong từng khu vực sẽ tìm giá trị lớn nhất. Cuối cùng, tôi nên có 50 điểm mà tôi có thể phù hợp bằng cách sử dụng bất kỳ phương pháp phù hợp theo cấp số nhân đã đề cập ở trên. Bạn nghĩ gì về phương pháp này?

Trả lời

1

Nghĩ rằng tôi sẽ cung cấp cho mọi người bản cập nhật các giải pháp tiềm năng có thể hoạt động. Như đã đề cập trước đó, dữ liệu phức tạp bởi các tần số hình sin khác nhau, vì vậy một số phương pháp có thể không hoạt động vì điều này. Các phương pháp được liệt kê dưới đây có thể tốt tùy thuộc vào dữ liệu và tần số liên quan.

Trước hết, tôi cho rằng các dữ liệu có dạng:

y = average + b*e^-(c*x) 

Trong trường hợp của tôi, với mức trung bình là 290 nên ta có:

y = 290 + b*e^-(c*x) 

Với điều đó đang được nói, chúng ta hãy đi sâu vào các phương pháp khác nhau mà tôi đã thử:

findpeaks() Phương pháp

Đây là phương pháp mà Alexander Büse gợi ý.Đó là một phương pháp khá tốt cho hầu hết dữ liệu, nhưng đối với dữ liệu của tôi, vì có nhiều tần số hình sin, nó nhận được các đỉnh sai. Màu đỏ x hiển thị các đỉnh.

% Find Peaks Method 
[max_num,max_ind] = findpeaks(y(ind)); 
plot(max_ind,max_num,'x','Color','r'); hold on; 
x1 = max_ind; 
y1 = log(max_num-290); 
coeffs = polyfit(x1,y1,1) 
b = exp(coeffs(2)); 
c = coeffs(1); 

enter image description here

RANSAC

RANSAC là tốt nếu bạn có hầu hết các dữ liệu của bạn ở các đỉnh núi. Bạn thấy rằng trong tôi, vì có nhiều tần số, nhiều đỉnh hơn tồn tại gần đỉnh. Tuy nhiên, vấn đề với dữ liệu của tôi là không phải tất cả các tập dữ liệu đều như thế này. Do đó, nó đôi khi làm việc.

% RANSAC Method 
ind = (y > avg); 
x1 = x(ind); 
y1 = log(y(ind) - avg); 
iterNum = 300; 
thDist = 0.5; 
thInlrRatio = .1; 
[t,r] = ransac([x1;y1'],iterNum,thDist,thInlrRatio); 
k1 = -tan(t); 
b1 = r/cos(t); 
% plot(x1,k1*x1+b1,'r'); hold on; 
b = exp(b1); 
c = k1; 

enter image description here

Lsqlin Phương pháp

Phương pháp này là một trong những sử dụng here. Nó sử dụng Lsqlin để hạn chế hệ thống. Tuy nhiên, có vẻ như bỏ qua dữ liệu ở giữa. Tùy thuộc vào tập dữ liệu của bạn, điều này có thể hoạt động thực sự tốt như đối với người trong bài đăng gốc.

% Lsqlin Method 
avg = 290; 
ind = (y > avg); 
x1 = x(ind); 
y1 = log(y(ind) - avg); 
A = [ones(numel(x1),1),x1(:)]*1.00; 
coeffs = lsqlin(A,y1(:),-A,-y1(:),[],[],[],[],[],optimset('algorithm','active-set','display','off')); 
b = exp(coeffs(2)); 
c = coeffs(1); 

enter image description here

Tìm Peaks trong giai đoạn

Đây là phương pháp tôi đã đề cập trong bài viết của tôi, nơi tôi có được đỉnh cao trong từng khu vực,. Phương pháp này hoạt động khá tốt và từ đó tôi nhận ra rằng dữ liệu của tôi có thể không thực sự có sự phù hợp với hàm mũ hoàn hảo. Chúng tôi thấy rằng nó không thể phù hợp với các đỉnh núi lớn ngay từ đầu. Tôi đã có thể làm điều này tốt hơn một chút bằng cách chỉ sử dụng 150 điểm dữ liệu đầu tiên và bỏ qua các điểm dữ liệu trạng thái ổn định. Ở đây tôi tìm thấy đỉnh mỗi 25 điểm dữ liệu.

% Incremental Method 2 Unknowns 
x1 = []; 
y1 = []; 
max_num=[]; 
max_ind=[]; 
incr = 25; 
for i=1:floor(size(y,1)/incr) 
    [max_num(end+1),max_ind(end+1)] = max(y(1+incr*(i-1):incr*i)); 
    max_ind(end) = max_ind(end) + incr*(i-1); 
    if max_num(end) > avg 
     x1(end+1) = max_ind(end); 
     y1(end+1) = log(max_num(end)-290); 
    end 
end 
plot(max_ind,max_num,'x','Color','r'); hold on; 
coeffs = polyfit(x1,y1,1) 
b = exp(coeffs(2)); 
c = coeffs(1); 

Sử dụng tất cả 500 điểm dữ liệu: Using all 500 data points

Sử dụng đầu tiên 150 điểm dữ liệu: enter image description here

Tìm Peaks trong Thời gian Với b Constrained

Vì tôi muốn nó bắt đầu ở đỉnh đầu tiên, tôi đã hạn chế giá trị b. Tôi biết hệ thống là y=290+b*e^-c*x và tôi hạn chế hệ thống đó là b=y(1)-290. Bằng cách đó, tôi chỉ cần giải quyết cho c nơi c=(log(y-290)-logb)/x. Sau đó tôi có thể lấy trung bình hoặc trung bình của c. Phương pháp này là khá tốt là tốt, nó không phù hợp với giá trị gần cuối cũng nhưng đó không phải là lớn của một thỏa thuận kể từ khi thay đổi có tối thiểu.

% Incremental Method 1 Unknown (b is constrained y(1)-290 = b) 
b = y(1) - 290; 
c = []; 
max_num=[]; 
max_ind=[]; 
incr = 25; 
for i=1:floor(size(y,1)/incr) 
    [max_num(end+1),max_ind(end+1)] = max(y(1+incr*(i-1):incr*i)); 
    max_ind(end) = max_ind(end) + incr*(i-1); 
    if max_num(end) > avg 
     c(end+1) = (log(max_num(end)-290)-log(b))/max_ind(end); 
    end 
end 
c = mean(c); % Or median(c) works just as good 

Ở đây tôi lấy đỉnh cho mỗi 25 điểm dữ liệu và sau đó lấy giá trị trung bình của c enter image description here

Ở đây tôi lấy đỉnh cho mỗi 25 điểm dữ liệu và sau đó lấy trung bình c enter image description here

Ở đây tôi lấy điểm cao nhất cho mỗi 10 điểm dữ liệu và sau đó lấy giá trị trung bình của c enter image description here

0

Nếu mục tiêu chính là trích xuất thông số giảm xóc từ vừa vặn, có thể bạn muốn cân nhắc việc lắp thẳng trực tiếp đường cong sine vào dữ liệu của bạn. Nội dung như thế này (được tạo bằng công cụ lắp đường cong):

[xData, yData] = prepareCurveData(x, y); 
ft = fittype('a + sin(b*x - c).*exp(d*x)', 'independent', 'x', 'dependent', 'y'); 
opts = fitoptions('Method', 'NonlinearLeastSquares'); 
opts.Display = 'Off'; 
opts.StartPoint = [1 0.285116122712545 0.805911873245316 0.63235924622541]; 
[fitresult, gof] = fit(xData, yData, ft, opts); 
plot(fitresult, xData, yData); 

Đặc biệt vì một số dữ liệu ví dụ của bạn thực sự không có nhiều điểm dữ liệu trong khu vực thú vị (trên tiếng ồn).

Nếu tuy nhiên, bạn thực sự cần phải khớp trực tiếp với cực đại của dữ liệu thử nghiệm, bạn có thể sử dụng hàm findpeaks để chỉ chọn tối đa và sau đó phù hợp với chúng. Bạn có thể muốn chơi một chút với thông số MinPeakProminence để điều chỉnh nó theo nhu cầu của bạn.

+0

Cảm ơn Alexander. Vì vậy, điều khó khăn với dữ liệu này là nó không chỉ là một tần số hình sin, do đó, việc sử dụng findpeaks kết thúc lên nhận được đỉnh của sóng mà không thực sự là tối đa trong khu vực. Tôi đã cập nhật bài đăng gốc của mình bằng tín hiệu thực tế với các điểm được kết nối. Tôi chưa thử lắp nó với hộp công cụ phù hợp với đường cong (không có nó trên máy tính của tôi) nhưng tôi sẽ thử nó khi tôi ở trường. –

Các vấn đề liên quan