2010-07-21 8 views
8

커브를 형성하는 샘플 벡터가 있습니다. 1000 점이 있다고 상상해 봅시다. 1500 포인트를 채우기 위해 늘리면 가장 간단한 알고리즘은 무엇입니까? C/C++의 몇 줄에 불과한 것을 찾고 있습니다.배열 늘이기

저는 항상 벡터의 크기를 늘리고 싶습니다. 새로운 벡터는 현재 벡터의 크기의 1.1 배에서 50 배까지 될 수 있습니다.

감사합니다.

+0

안녕 ... 새 데이터를 입력하려면 어떻게 고른 데이터 당신은 프로그램해야 할 수 있습니다? spline (그리고 꽤 오래 걸릴 수 있습니다.) 그런데 꽤 좋은 질문입니다! – Barranka

+1

정말 새로운 데이터가 따라야 할 모델에 달렸습니다 ... [Wikipedia : Interpolation] (http : // ko .wikipedia.org/wiki/Interpolation) –

답변

6

다음은 선형 및 2 차 보간을위한 C++입니다.
interp1(5.3, a, n)은 [5] + .3 * (a [6] - a [5]), .3에서 [5]에서 [6]
interp1array(a, 1000, b, 1500)a에서 b까지 늘어납니다.
interp2(5.3, a, n)은 가장 가까운 3 개의 점 a [4] a [5] a [6]를 통해 포물선을 그립니다. interp1보다 부드럽지만 여전히 빠릅니다.
(자유 곡선이 부드럽게 아직 4 개 가까운 지점을 사용합니다. 당신은 파이썬을 읽으면, 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

나는 철저히 시험하지 않았다. 이 코드를 테스트 해 보았으므로 그 정확성을 보증 할 수는 없지만 이것이 정확히 내가 찾던 답변의 종류입니다. 감사! – twk

+0

당신을 진심으로 환영합니다. 작동한다면 상사에게 말하십시오. 그렇지 않다면 말해줘. – denis

2

괜찮은 결과를주는 가장 단순한 알고리즘은 무엇입니까?

Catmull-Rom splines. 각각의 새로운 항목이 기존 배열의 분수 위치를 계산 들어

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

(당신이 부드러운 곡선을 원하는 경우), 사용 분수 부분을 사용 (F - 층 (F)) 보간 요소로, 그리고 "정수 "(ie floor (f)) 부분을 사용하여 가장 가까운 요소를 찾습니다.

수학적으로 보간 (수레) 할 수있는 데이터를 사용한다고 가정합니다. 데이터를 보간 할 수없는 경우 (문자열), 유일한 해결책은 구 어레이의 가장 가까운 사용 가능한 요소를 사용하는 것입니다.

배열의 포인트가 고르게 분포되지 않은 경우 약간의 조정이 필요합니다.

X, Y, Z

X이되고, 평균 (X, Y : I 생각할 수

0

간단한 옵션이므로 평균 평균에 기초하여 상기 어레이를 확대 단지 FN 인), y, avg (y, z), z

데이터 포인트가 더 필요하면 벡터에서 여러 번 실행하면됩니다.

+0

.. 만약 새로운 배열이 이전 것보다 2 배 크지 않다면, 결과는 정확하지 않을 것입니다. 선형 보간보다 훨씬 좋지는 않습니다 - 이런 식으로 부드러운 커브를 얻지는 못할 것입니다 . – SigTerm