2010-07-21 6 views
8

Tôi đã có một vectơ các mẫu tạo thành một đường cong. Hãy tưởng tượng có 1000 điểm trong đó. Nếu tôi muốn kéo dài nó để lấp đầy 1500 điểm, thuật toán đơn giản nhất mang lại kết quả phong nha là gì? Tôi đang tìm một cái gì đó mà chỉ là một vài dòng C/C++.Trải ra một mảng

Tôi luôn muốn tăng kích thước của vec-tơ và vectơ mới có thể ở bất kỳ vị trí nào từ 1,1x đến 50x kích thước của vectơ hiện tại.

Cảm ơn!

+0

Hi ... làm thế nào để bạn muốn điền vào các dữ liệu mới dữ liệu Smoothed Bạn có thể cần một chương trình? spline (và nó có thể là một nỗ lực khá dài) Khá một câu hỏi hay, bằng cách này! – Barranka

+1

Nó thực sự phụ thuộc vào mô hình dữ liệu mới được mong muốn theo sau ... [Wikipedia: Interpolation] (http: // vi .wikipedia.org/wiki/Interpolation) –

Trả lời

6

Đây là C++ cho phép nội suy tuyến tính và phương trình bậc hai.
interp1(5.3, a, n) là [5] + .3 * (a [6] - a [5]), .3 của đường từ [5] đến [6];
interp1array(a, 1000, b, 1500) sẽ kéo dài a đến b.
interp2(5.3, a, n) vẽ hình parabol qua 3 điểm gần nhất [4] a [5] a [6]: mượt mà hơn interp1 nhưng vẫn nhanh.
(Splines sử dụng 4 điểm gần nhất, mượt mà chưa;. Nếu bạn đọc trăn, xem basic-spline-interpolation-in-a-few-lines-of-numpy

// 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

Tôi chưa từng làm ted mã này, vì vậy tôi không thể xác minh cho tính chính xác của nó, nhưng điều này là chính xác các loại câu trả lời tôi đang tìm kiếm. Cảm ơn! – twk

+0

Bạn được chào đón. Nếu nó hoạt động, hãy nói với sếp; nếu không, hãy nói cho tôi biết – denis

2

thuật toán đơn giản nhất mang lại kết quả tốt như thế nào?

Vuốt Catmull-Rom. (Nếu bạn muốn có một đường cong mịn)

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

Đối với mỗi mục mới tính toán vị trí phân đoạn trong mảng cũ, sử dụng sử dụng một phần phân đoạn (f - sàn (f)) như yếu tố nội suy, và "số nguyên "(ví dụ: tầng (f)) một phần để tìm các phần tử gần nhất.

Giả sử bạn đang hoạt động trên dữ liệu có thể được nội suy về mặt toán học (phao). Nếu dữ liệu không thể được nội suy (chuỗi), thì giải pháp duy nhất là sử dụng phần tử có sẵn gần nhất của mảng cũ.

Bạn sẽ cần một số chỉnh sửa nếu các điểm trong mảng không được phân phối đồng đều.

0

đơn giản lựa chọn tôi có thể nghĩ đến chỉ là một fn mà mở rộng mảng dựa trên trung bình trung bình, vì vậy:

x, y, z

trở thành

x, trung bình (x, y), y, avg (y, z), z

Nếu bạn cần thêm điểm dữ liệu, chỉ cần chạy nhiều lần trên vectơ.

+0

..Và nếu mảng mới không lớn gấp 2 lần so với phiên bản cũ, kết quả sẽ không chính xác.Không tốt hơn nhiều so với nội suy tuyến tính - bạn sẽ không nhận được đường cong trơn tru theo cách này – SigTerm