Use o botão abaixo para reportar erros ou dar sugestões.

Computação Científica - Um Livro Colaborativo

4.1 Vetores


Vetor (ou array) é uma lista de elementos do mesmo tipo que podem ser acessados individualmente com o mesmo nome de variável. Definimos um vetor dizendo o tipo, o nome da variável e o número de elementos: tipo nome[n⁰ elementos];.

Exemplo 4.1.1. Alguns testes de inicialização de vetores.

#include <stdio.h>  
#include <math.h>  
 
main (void)  
{  
  int i;  
  double x[3]={1.5,2,3};  
  int y[]={1,2,5};  
  int z[8]={1,2,5};  
 
  for (i=0;i<3;i++)     printf("x[%d] = %f\n",i,x[i]);  
  printf("\n");  
  for (i=0;i<3;i++)     printf("y[%d] = %d\n",i,y[i]);  
  printf("\n");  
  for (i=0;i<8;i++)     printf("z[%d] = %d\n",i,z[i]);  
}

Exemplo 4.1.2. Implemente um programa que armazena em um vetor os 10 primeiros números da sequência de Fibonacci e imprime a soma do sétimo com o décimo.

 #include <stdio.h>  
 
main (void)  
{  
  int i,x[10];  
  x[0]=1;  
  x[1]=1;  
  for (i=0;i<8;i++)  
  {  
    x[i+2]=x[i+1]+x[i];  
  }  
  printf("soma do sétimo com o décimo = %d\n",x[6]+x[9]);  
}

No exemplo 4.1.2, definimos um vetor com 10 posições fazendo int x[10];. Depois, acessamos a posição i do vetor fazendo x[i]. Observe que as posições do vetor começamos em 0 e, portanto, a sétima posição é acessada por x[6] e a décima por x[9].

Exemplo 4.1.3. O método iterativo de Jacobi para calcular a solução do sistema linear a11x1 + a12x2 + ⋯ + a1nxn = y1 a21x1 + a22x2 + ⋯ + a2nxn = y2 ⋮ an1x1 + an2x2 + ⋯ + annxn = yn (4.1)

é dado pela recursão x1(k+1) = y1 − a12x2(k) + ⋯ + a 1nxn(k) a11 x2(k+1) = y2 − a21x1(k) + a 23x3(k) + ⋯ + a 2nxn(k) a22 ⋮ xn(k+1) = y2 − an1x1(k) + ⋯ + a n,n−2xn−2(k) + a n,n−1xn−1(k) ann

onde x10, x20, ⋯, xn0 é um chute inicial. A iteração converge para a solução quando a matriz do sistema é estritamente diagonal dominante.

Implemente um código para resolver o sistema 3x + y + z = 1 −x − 4y + 2z = 2 −2x + 2y + 5z = 3

com o método de Jacobi.

Primeiro, montamos a iteração: xk+1 = 1 − yk − zk 3 yk+1 = − 2 − xk + 2zk 4 zk+1 = 3 + 2xk − 2yk 5

Vamos usar o chute inicial x0 = 0, y0 = 0 e z0 = 0.

#include <stdio.h>  
#include <math.h>  
 
main (void)  
{  
  double norma2,tolerancia=1e-3,x_antigo[3],x_atual[3];  
  int i,controle=3;  
  //chute inicial  
  for (i=0;i<3;i++)x_antigo[i]=0;  
 
  //iteração  
  while (controle)  
  {  
    x_atual[0]=(1-x_antigo[1]-x_antigo[2])/3;  
    x_atual[1]=(-2-x_antigo[0]+2*x_antigo[2])/4;  
    x_atual[2]=(3+2*x_antigo[0]-2*x_antigo[1])/5;  
    norma2=0;  
    for (i=0;i<3;i++) norma2+=(x_atual[i]-x_antigo[i])*(x_atual[i]-x_antigo[i]);  
    if (norma2<tolerancia) controle--;  
    else controle=3;  
    for (i=0;i<3;i++) x_antigo[i]=x_atual[i];  
    printf("x=%f, y=%f, z=%f\n",x_atual[0],x_atual[1],x_atual[2]);  
  }  
}

Nessa versão de código usamos o critério de parada norma em l2 da diferença menor que uma tolerância, isto é, ||(xk+1−xk,yk+1−yk,zk+1−zk)|| 2 = (xk+1 − xk )2 + (yk+1 − yk )2 + (zk+1 − zk )2 < TOL.

Também usamos o dispositivo de controle, isto é, depois que atingimos a tolerança caminhamos mais três passos.

Agora vamos fazer um vesão um pouco mais elaborada. Vamos criar uma função que calcula norma l2 de vetores e outra que faz uma iteração. Para isso, temos que passar um vetor como parâmetro para a função. Observe o código:

#include <stdio.h>  
#include <math.h>  
 
double norma_dif_2(double x[3],double y[3])  
{  
  int i;  
  double norma2=0;  
  for (i=0;i<3;i++) norma2+=(x[i]-y[i])*(x[i]-y[i]);  
  return sqrt(norma2);  
}  
void Iteracao(double x_antigo[3],double x_atual[3])  
{  
    x_atual[0]=(1-x_antigo[1]-x_antigo[2])/3.;  
    x_atual[1]=(-2-x_antigo[0]+2*x_antigo[2])/4.;  
    x_atual[2]=(3+2*x_antigo[0]-2*x_antigo[1])/5.;  
}  
void Jacobi(double tolerancia,double x_atual[3])  
{  
  double x_antigo[3];  
  int i,controle=3;  
  //chute inicial  
  for (i=0;i<3;i++)x_antigo[i]=0;  
 
  //iteração  
  while (controle)  
  {  
    Iteracao(x_antigo,x_atual);  
    if (norma_dif_2(x_antigo,x_atual)<tolerancia) controle--;  
    else controle=3;  
    for (i=0;i<3;i++) x_antigo[i]=x_atual[i];  
    //printf("x=%f, y=%f, z=%f\n",x_atual[0],x_atual[1],x_atual[2]);  
  }  
  return;  
}  
 
main (void)  
{  
  int i;  
  double tolerancia=1e-3,solucao[3];  
  Jacobi(tolerancia,solucao);  
  for (i=0;i<3;i++)     printf("x[%d] = %f\n",i,solucao[i]);  
}

Esse último código passa vetores como parâmetros para funções. A função norma_dif_2 passa dois vetores e retorna double. A Iteracao passa dois vetores e retorna void, onde usamos um vetor para levar a informação para dentro da função e o outro vetor para retirar o resultado: x_antigo leva a informação e x_atual entra com qualquer coisa e é calculado dentro da função. Já a função Jacobi entra o valor da tolerância e passa um vetor para colocar a solução.

Os códigos que implementamos resolve apenas um único sistema 3x3. É interessante pensar em rotinas mais gerais, que resolvem um sistema Ax = b de dimensão nxn.

Creative Commons License Este texto é disponibilizado nos termos da licença Creative Commons Atribuição-CompartilhaIgual 3.0 Não Adaptada (CC-BY-SA 3.0). Página gerada em 19/8/2020 às 17:33:16.

Informe erros ou edite você mesmo!