2010-07-21 23 views
8

Bir eğri oluşturan örnekler vektörünü aldım. Bunun içinde 1000 puan olduğunu hayal edelim. 1500 puan doldurmak için uzatmak istersem, iyi sonuç veren en basit algoritma hangisidir? Sadece birkaç satır C/C++ olan bir şey arıyorum.Bir dizinin dışarı yayılması

hep vektör boyutunu artırmak isteyeceksiniz ve yeni vektör yerde 1.1x den 50x akım vektörü boyutu nedeniyle olabilir.

Teşekkürler!

+0

Merhaba ... yeni verileri doldurmak istiyor nasıl Düzgünleştirilmiş veri Bir programlamak gerekebilir? spline (ve uzun bir çaba olabilir) Bu arada, güzel bir soru! – Barranka

+1

Gerçekten de yeni verilere ulaşmak istediği modele bağlı ... [Wikipedia: Interpolation] (http: // en .wikipedia.org/wiki/Interpolation) –

cevap

6

Doğrusal ve karesel enterpolasyon için C++ işte burada.
interp1(5.3, a, n) bir [5] + .3 * (a [6] - a [5]), bir [5] 'den [6]' ya;
interp1array(a, 1000, b, 1500)b için a germek olacaktır.
interp2(5.3, a, n), en yakın 3 noktadan bir [4] a [5] a [6] 'dan bir parabol çizer: daha hızlıdır ancak 1'den daha yumuşaktır.
(Splaynlar pürüzsüz henüz 4 yakın noktaları, kullanma;. Eğer piton okursanız, basic-spline-interpolation-in-a-few-lines-of-numpy bkz

// linear, quadratic interpolation in arrays 
// from interpol.py denis 2010-07-23 July 

#include <stdio.h> 
#include <stdlib.h> 

    // linear interpolate x in an array 
// inline 
float interp1(float x, float a[], int n) 
{ 
    if(x <= 0) return a[0]; 
    if(x >= n - 1) return a[n-1]; 
    int j = int(x); 
    return a[j] + (x - j) * (a[j+1] - a[j]); 
} 

    // linear interpolate array a[] -> array b[] 
void inter1parray(float a[], int n, float b[], int m) 
{ 
    float step = float(n - 1)/(m - 1); 
    for(int j = 0; j < m; j ++){ 
     b[j] = interp1(j*step, a, n); 
    } 
} 

//.............................................................................. 
    // parabola through 3 points, -1 < x < 1 
float parabola(float x, float f_1, float f0, float f1) 
{ 
    if(x <= -1) return f_1; 
    if(x >= 1) return f1; 
    float l = f0 - x * (f_1 - f0); 
    float r = f0 + x * (f1 - f0); 
    return (l + r + x * (r - l))/2; 
} 

    // quadratic interpolate x in an array 
float interp2(float x, float a[], int n) 
{ 
    if(x <= .5 || x >= n - 1.5) 
     return interp1(x, a, n); 
    int j = int(x + .5); 
    float t = 2 * (x - j); // -1 .. 1 
    return parabola(t, (a[j-1] + a[j])/2, a[j], (a[j] + a[j+1])/2); 
} 

    // quadratic interpolate array a[] -> array b[] 
void interp2array(float a[], int n, float b[], int m) 
{ 
    float step = float(n - 1)/(m - 1); 
    for(int j = 0; j < m; j ++){ 
     b[j] = interp2(j*step, a, n); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
     // a.out [n m] -- 
    int n = 10, m = 100; 
    int *ns[] = { &n, &m, 0 }, 
     **np = ns; 
    char* arg; 
    for(argv ++; (arg = *argv) && *np; argv ++, np ++) 
     **np = atoi(arg); 
    printf("n: %d m: %d\n", n, m); 

    float a[n], b[m]; 
    for(int j = 0; j < n; j ++){ 
     a[j] = j * j; 
    } 
    interp2array(a, n, b, m); // a[] -> b[] 

    for(int j = 0; j < m; j ++){ 
     printf("%.1f ", b[j]); 
    } 
    printf("\n"); 
} 
+0

İyice tesekkur etmedim Bu koddan dolayı, doğruluk için kefil olamaz, ama bu tam olarak aradığım cevaptır. Teşekkürler! – twk

+0

Rica ederim. Çalışırsa, patrona söyle; değilse, söyle bana – denis

2

iyi sonuçlar verir basit algoritma nedir?

Catmull-Rom spline'lar. Her yeni öğe eski dizide fraksiyonel konumunu hesaplamak için

http://www.mvps.org/directx/articles/catmull/
http://en.wikipedia.org/wiki/Cubic_Hermite_spline

(sorunsuz bir eğri istiyorsanız), kullanım kesirli kısmı kullanmak (f - kat (f)) interpolasyon faktörü olarak ve "tamsayı "(örn. kat (f)) parçası en yakın elemanları bulmak için.

Eğer matematiksel olarak (yüzer) interpolated edilebilir veriler üzerinde çalışan olduğunuzu varsayarak olup olmadığını. Eğer veri enterpolasyon yapamıyorsa (dizeler), o zaman tek çözüm, eski dizinin en yakın mevcut elemanını kullanmaktır.

Dizideki noktalar eşit dağılmamışsa, biraz düzeltme yapmanız gerekir.

x, y, z

x olur, ort (x, y: ı düşünebiliriz

0

basit bir seçenek böylece ortalama ortalamalara göre dizi genişletir bir fn, olduğu), daha fazla veri noktaları ihtiyaç y ort (y, z), z

, sadece vektör ile birden çok kez çalıştırın.

+0

.. Ve eğer yeni dizi eskisinden 2 kat daha büyük değilse, sonuçlar yanlış olur. Doğrusal enterpolasyondan çok daha iyi değildir - bu şekilde düzgün bir eğri elde edemezsiniz – SigTerm