2012-09-23 18 views
5

enter image description hereMatlab'da bir dizi bölümlenmiş satırın eğrisi nasıl oluşturulur?

Yukarıdaki gibi basit bir loglog eğrisi var. Matlab'da bu eğriye bölünmüş çizgilerle sığabilecek ve bu bölümlerin başlangıç ​​ve bitiş noktalarını gösterebilecek bir fonksiyon var mı? Matlab'da eğri montaj araç kutusunu kontrol ettim. Bir çizgi veya bazı fonksiyonlarla eğri uydurma yapıyor gibi görünüyorlar. Ben sadece bir hat ile uydurma eğmek istemiyorum.

Doğrudan bir işlev yoksa, aynı hedefe ulaşmak için herhangi bir alternatif benim için sorun değil. Amacım, eğri çizgilerle eğriye uydurmak ve bu segmentlerin bitiş noktalarının yerlerini almaktır.

cevap

7

Her şeyden önce, probleminize eğri uydurma denir. Eğri uydurma, verilere sahip olduğunuzda ve bir anlamda onu tanımlayan en iyi işlevi bulmanızdır. Diğer taraftan, işlevin parçalı doğrusal bir yaklaşımını oluşturmak istersiniz. bölüme elle

  1. Böl:

    aşağıdaki stratejiyi önerebilir. Bölüm boyutu, türevin büyük türevi -> küçük bölüm 0L

  2. 'a bağlı olmalıdır. Örnekler
  3. arasındaki düğümlerde örnekleme Yukarıda belirtilen noktalardan geçen doğrusal bir enterpolasyon bulun.

İşte bunu yapan bir kod örneği. Az sayıda bölüme rağmen kırmızı çizginin (enterpolasyon) orijinal fonksiyona çok yakın olduğunu görebilirsiniz. Bu uyarlanabilir bölüm boyutu nedeniyle olur.

enter image description here

function fitLogLog() 
    x = 2:1000; 
    y = log(log(x)); 

    %# Find section sizes, by using an inverse of the approximation of the derivative 
    numOfSections = 20; 
    indexes = round(linspace(1,numel(y),numOfSections)); 
    derivativeApprox = diff(y(indexes)); 
    inverseDerivative = 1./derivativeApprox; 
    weightOfSection = inverseDerivative/sum(inverseDerivative); 
    totalRange = max(x(:))-min(x(:)); 
    sectionSize = weightOfSection.* totalRange; 

    %# The relevant nodes 
    xNodes = x(1) + [ 0 cumsum(sectionSize)]; 
    yNodes = log(log(xNodes)); 

    figure;plot(x,y); 
    hold on; 
    plot (xNodes,yNodes,'r'); 
    scatter (xNodes,yNodes,'r'); 
    legend('log(log(x))','adaptive linear interpolation'); 
end 
+0

açıklamalar için çok teşekkür ederim;

(çok daha hızlı versiyonu kabul edilebilir Xdata sıralanır ben bu çözüm vektörize girişiminde bulunmadı unutmayın.). Doğrusal enterpolasyon ve Matlab için benim sığ arka plan için özür dilerim. Yaptığın şeyin harika olduğunu düşünüyorum. Bununla birlikte, kodlarımı buna göre değiştirmek için zor bir zamanım var. Orijinal verilerim y, cjh'nin çözümünde normal grafiğe benzeyen 1 * 73 satır vektörü. Son sonucu bir log-log eksen çiziminde göstermek için kodlarınızı nasıl değiştirebileceğinizi işaret edebilir misiniz (Log (log (x)) hesaplaması değil)? Tekrar çok teşekkür ederim, – Cassie

5

Andrey en adaptif çözüm daha doğru oturuş sağlar. İstediğiniz şey sabit uzunlukta bölümlerse, o zaman burada, takılan tüm değerlerin eksiksiz bir setini döndüren bir yöntem kullanarak çalışılması gereken bir şey vardır. Hız gerektiğinde vectorized olabilir.

Nsamp = 1000;  %number of data samples on x-axis 
x = [1:Nsamp]; %this is your x-axis 
Nlines = 5;  %number of lines to fit 

fx = exp(-10*x/Nsamp); %generate something like your current data, f(x) 
gx = NaN(size(fx));  %this will hold your fitted lines, g(x) 

joins = round(linspace(1, Nsamp, Nlines+1)); %define equally spaced breaks along the x-axis 

dx = diff(x(joins)); %x-change 
df = diff(fx(joins)); %f(x)-change 

m = df./dx; %gradient for each section 

for i = 1:Nlines 
    x1 = joins(i); %start point 
    x2 = joins(i+1); %end point 
    gx(x1:x2) = fx(x1) + m(i)*(0:dx(i)); %compute line segment 
end 

subplot(2,1,1) 
h(1,:) = plot(x, fx, 'b', x, gx, 'k', joins, gx(joins), 'ro'); 
title('Normal Plot') 

subplot(2,1,2) 
h(2,:) = loglog(x, fx, 'b', x, gx, 'k', joins, gx(joins), 'ro'); 
title('Log Log Plot') 

for ip = 1:2 
    subplot(2,1,ip) 
    set(h(ip,:), 'LineWidth', 2) 
    legend('Data', 'Piecewise Linear', 'Location', 'NorthEastOutside') 
    legend boxoff 
end 

MATLAB plotted output

+0

+1 - Genel olarak iyi cevap. Bu arada, her iki metodun da fonksiyonun örneklenmesi yerine tüm hataların toplamını en aza indirerek daha da geliştirilebileceğini düşündüm. Örneğin, ilk çiziminizde, ikinci düğümü toplam uyumu artırmak için işlev değerinin altına taşınabilir. –

+0

+1 - evet, sadece aynı şeyi düşünüyordum :) Özellikle konveks veya içbükey işlevler için, bu tarz bir yöntem her zaman doğrusal enterpolasyondan daha iyi performans gösterirdi. – cjh

+0

@cjh, yardımlarınız için teşekkür ederim. "Sabit uzunlukta bölüm" derken ne demek istiyorsun? Çözümünüzün x yayılmasını aynı uzunlukta yaptığı anlamına mı geliyor? – Cassie

0

Bu, bu soruya kesin bir cevap değil ama Aramaya göre buraya geldi beri, (sığmayan) nasıl oluşturulacağı ilgili soruya cevap vermek istediğiniz bir dağılım grafiğinde aralık verilerinin ortalamasını (veya ortanca veya başka bir başka işlevi) temsil etmeyi amaçlayan parçalı doğrusal işlev. İlk olarak, görünüşe göre some MATLAB code listed on the wikipedia page'a sahip olan regresyon kullanılarak ilgili ancak daha karmaşık bir alternatif olan Multivariate adaptive regression splines.

burada çözüm sadece ben 0 uzunluğunda aralıklarla kullanışlı olan bazı eşleştirilmiş X ve Y veri üzerinden ortalamayı hesaplamak için puan Örneğin

function [x, y] = intervalAggregate(Xdata, Ydata, aggFun, intStep, intOverlap) 
% intOverlap in [0, 1); 0 for no overlap of intervals, etc. 
% intStep this is the size of the interval being aggregated. 

minX = min(Xdata); 
maxX = max(Xdata); 

minY = min(Ydata); 
maxY = max(Ydata); 

intInc = intOverlap*intStep; %How far we advance each iteraction. 
if intOverlap <= 0 
    intInc = intStep; 
end 
nInt = ceil((maxX-minX)/intInc); %Number of aggregations 

parfor i = 1:nInt 
    xStart = minX + (i-1)*intInc; 
    xEnd = xStart + intStep; 
    intervalIndices = find((Xdata >= xStart) & (Xdata <= xEnd)); 
    x(i) = aggFun(Xdata(intervalIndices)); 
    y(i) = aggFun(Ydata(intervalIndices)); 
end 

almak için örtüşen aralıklarla üzerinde ortalamasını hesaplamak etmektir.

Scatter plot example for Xdat and Ydat

[x, y] = intervalAggregate (Xdat, Ydat, @mean, 0.1, 0.333)

: 1 birbirlerine (bakınız dağılım görüntüsü) ile aşağı yukarı 1/3 kesişmeyen

x =

Sütunlar 1 8

boyunca

Sütun 9 görüyoruz 1 9

0.9803 0.9750 0.9707 0.9653 0.9598 0.9560 0.9537 

15 arasındaki sütunlar
0.9992 0.9983 0.9971 0.9955 0.9927 0.9905 0.9876 0.9846 

8 ile 15

0.3182 0.3561 0.3875 0.4178 0.4494 0.4671 0.4822 

y =

kolonlarından, x arttıkça, y hafifliği azaltma eğilimindedir y. Oradan, çizgi parçaları çizmek ve/veya başka bir çeşit düzeltme yapmak için yeterince kolaydır.

İlgili konular