Advertisement
luizaspan

[PROVA FSC_COMP] Métodos de interpolação

Nov 4th, 2015
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.23 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. // FALTA: 'SPLINE (PRECISA SPLINE?)
  5.  
  6. /*
  7. Funções básicas de interpolação, do tipo linear,
  8. bilinear, polinomial e spline.
  9. Para as interpolações lineares, polinomiais e spline,
  10. o funcionamento é:
  11.  
  12.     y0 = interpol_xxx(n, x, y, x0)
  13.  
  14. onde x e y são vetores de double de tamanho n, que
  15. descrevem em apenas alguns pontos uma função y = f(x).
  16. O x0 é um double que é o ponto que queremos obter a
  17. interpolação em questão.
  18.  
  19. A interpolação bilinear possui o seguinte funcionamento:
  20.  
  21.     z0 = interpol_bilinear(n, m, x, y, z, x0, y0)
  22.  
  23. onde x é um vetor de tamanho n e y é um vetor de tamanho m,
  24. z é uma matriz n por m que descreve uma função z = f(x,y)
  25. em alguns pontos. Importante notar que o algoritmo realiza
  26. a interpolação primeiro no eixo y e depois no x.
  27.  
  28. Exemplo:
  29.  
  30.     Função y(x) = x^2 + x - 1.
  31.     Definimos x = {1,2,3,4,5} e n = 5.
  32.     Logo obtemos y = {1,5,11,19,29}, aplicando y(x) em um
  33.     loop.
  34.     -- A partir de agora, só temos conhecimento de x e y,
  35.     -- a expressão de y(x) não é mais conhecida.
  36.     Queremos y0 = y(x0) em x0 = 3.5. Claramente não temos
  37.     o valor exato nos vetores, logo necessitamos realizar
  38.     uma interpolação:
  39.     x0 = 3.5
  40.     y0 = interpol_xxx(n, x, y, x0)
  41.     No final temos que y0 = 15, muito próximo do resultado
  42.     real, y(3.5) = 14.75
  43.  
  44. Observações:
  45.  
  46. Um polinômio de grau N-1 pode ser descrito perfeitamente por N pontos, e vice-versa.
  47.  
  48. Para muitos pontos (n > 5), a interpolação polinomial se
  49. torna instável, então não é recomendada.
  50. */
  51.  
  52. double interpol_linear(int n, double x[n], double y[n], double x0)
  53. {
  54.     int k, i;
  55.     for(i = 1; i < n; i++) // Encontrar índices vizinhos
  56.     {
  57.         if(x0 <= x[i])
  58.         {
  59.             k = i - 1;
  60.             break;
  61.         }
  62.     }
  63.     if(i == n) k = i - 2;
  64.  
  65.     return (y[k+1] - y[k])/(x[k+1] - x[k])*(x0 - x[k]) + y[k];
  66. }
  67.  
  68. double interpol_polinomial(int n, double x[n], double y[n], double x0)
  69. {
  70.     double soma = 0;
  71.     int i, j;
  72.  
  73.     for(i = 0; i < n; i++)
  74.     {
  75.         double produto = 1;
  76.         for(j = 0; j < n; j++)
  77.         {
  78.             if(j != i)
  79.             {
  80.                 produto *= (x0 - x[j])/(x[i] - x[j]);
  81.             }
  82.         }
  83.         soma += produto * y[i];
  84.     }
  85.  
  86.     return soma;
  87. }
  88.  
  89. double interpol_bilinear(int n, int m, double x[n], double y[m], double z[n][m], double x0, double y0)
  90. {
  91.     double zn1, zn2;
  92.  
  93.     int i,kx;
  94.     for(i = 1; i < n; i++) // Encontrar índices vizinhos
  95.     {
  96.         if(x0 <= x[i])
  97.         {
  98.             kx = i - 1;
  99.             break;
  100.         }
  101.     }
  102.  
  103.     zn1 = interpol_linear(m, y, z[kx], y0);
  104.     zn2 = interpol_linear(m, y, z[kx+1], y0);
  105.  
  106.     double xpos[2] = {x[kx],x[kx+1]};
  107.     double zpos[2] = {zn1,zn2};
  108.     return interpol_linear(2, xpos, zpos,x0);
  109. }
  110.  
  111. /* ----------- COMEÇO DO EXEMPLO ----------- */
  112.  
  113. double f(double x)
  114. {
  115.     return 0.1*x*x*x + x*x + x - 1;
  116. }
  117.  
  118. int main(void)
  119. {
  120.     double x[4] = {1,2,3,4}, y[4], x0 = 0.9;
  121.  
  122.     int i;
  123.     for(i = 0; i < 4; i++) y[i] = f(x[i]);
  124.  
  125.     printf("x\t=\t%f\nf(x)\t=\t%f\nl(x)\t=\t%f\np(x)\t=\t%f\n", x0, f(x0), interpol_linear(4,x,y,x0), interpol_polinomial(4,x,y,x0));
  126.  
  127.     double zn[2][2] ={{0,1},{2,3}};
  128.     double xn[2] = {0,1};
  129.     double yn[2] = {0,1};
  130.     printf("%f",interpol_bilinear(2,2,xn,yn,zn,0.5,0.5));
  131.  
  132.     // Interpolação polinomial retorna ponto exato pois a
  133.     // função é de 3° grau, e são 4 pontos.
  134. }
  135.  
  136.  
  137. /* ------------ FIM DO EXEMPLO ------------ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement