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);
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;
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);
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:
Sử dụng đầu tiên 150 điểm dữ liệu:
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
Ở đây tôi lấy đỉnh cho mỗi 25 điểm dữ liệu và sau đó lấy trung bình c
Ở đâ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
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. –