Exercício¶
Crie uma classe em Java que recebe em seu construtor uma matriz que represente um sistema linear de $n\leq 4$ incógnitas e implemente pelo menos os seguintes métodos:
matriz: Imprime o sistema em forma de matriz;
resultado: Imprime a solução do sistema;
equacao: Imprime a equação do sistema.
A matriz de entrada possui $n$ linhas e $n+1$ colunas, esta contendo as constantes das equações.
In [1]:
public class SistemaLinear{
int n;
double[][] mat;
double[][] invertida;
double[][] resultado;
char []var = {'x', 'y', 'z', 'w'};
public SistemaLinear(double [][]mat){
this.n = mat.length;
this.mat = new double[n][n+1];
invertida = new double[n][n];
//Copie a matriz
for (int i = 0; i < n; i++)
for (int j = 0; j < n+1; j++)
this.mat[i][j] = mat[i][j];
invertida = inverta(mat);
this.resultado = new double[n][1];
for (int i = 0; i < n; i++)
for (int j = 0; j < 1; j++)
for (int k = 0; k < n; k++)
resultado[i][j] = resultado[i][j] + invertida[i][k] * mat[k][n];
}
public void matriz(){
for(int i=0; i<n; i++){
System.out.print("|");
for(int j=0; j<n; j++)
System.out.print(" "+mat[i][j]);
System.out.print(" | "+(i==n/2?"x":" ")+" |"+ var[i]+"|");
System.out.print(" "+(i==n/2?"=":" ")+" |"+ mat[i][n]+"|");
System.out.println();
}
}
public void equacao(){
int i=0;
System.out.print("("+round(resultado[i][0],5)+")"+var[i]);
for(i++; i<n; i++)
System.out.print(" + ("+round(resultado[i][0],5)+")"+var[i]);
System.out.println(" = 0");
}
public void inverso(){
for (int i=0; i<n; ++i){
for (int j=0; j<n; ++j)
System.out.print(invertida[i][j]+" ");
System.out.println();
}
}
public void resultado(){
for(int i=0; i<n; i++)
System.out.println(var[i]+" = "+round(resultado[i][0],5));
}
public static double[][] inverta(double[][] a_){
int n = a_.length;
double a[][] = new double[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
a[i][j] = a_[i][j];
double x[][] = new double[n][n];
double b[][] = new double[n][n];
int index[] = new int[n];
for (int i=0; i<n; ++i)
b[i][i] = 1;
//Transform the matrix into an upper triangle
gaussian(a, index);
//Update the matrix b[i][j] with the ratios stored
for (int i=0; i<n-1; ++i)
for (int j=i+1; j<n; ++j)
for (int k=0; k<n; ++k)
b[index[j]][k] -= a[index[j]][i]*b[index[i]][k];
//Perform backward substitutions
for(int i=0; i<n; ++i){
x[n-1][i] = b[index[n-1]][i]/a[index[n-1]][n-1];
for (int j=n-2; j>=0; --j){
x[j][i] = b[index[j]][i];
for (int k=j+1; k<n; ++k)
x[j][i] -= a[index[j]][k]*x[k][i];
x[j][i] /= a[index[j]][j];
}
}
return x;
}
//Method to carry out the partial-pivoting Gaussian
//elimination. Here index[] stores pivoting order.
public static void gaussian(double a[][], int index[]){
int n = index.length;
double c[] = new double[n];
//Initialize the index
for (int i=0; i<n; ++i)
index[i] = i;
//Find the rescaling factors, one from each row
for (int i=0; i<n; ++i){
double c1 = 0;
for (int j=0; j<n; ++j){
double c0 = Math.abs(a[i][j]);
if (c0 > c1) c1 = c0;
}
c[i] = c1;
}
//Search the pivoting element from each column
int k = 0;
for (int j=0; j<n-1; ++j){
double pi1 = 0;
for (int i=j; i<n; ++i){
double pi0 = Math.abs(a[index[i]][j]);
pi0 /= c[index[i]];
if (pi0 > pi1){
pi1 = pi0;
k = i;
}
}
//Interchange rows according to the pivoting order
int itmp = index[j];
index[j] = index[k];
index[k] = itmp;
for (int i=j+1; i<n; ++i){
double pj = a[index[i]][j]/a[index[j]][j];
//Record pivoting ratios below the diagonal
a[index[i]][j] = pj;
//Modify other elements accordingly
for (int l=j+1; l<n; ++l)
a[index[i]][l] -= pj*a[index[j]][l];
}
}
}
//Para deixar o resultado para apenas duas casas decimais:
public static double round(double valor, int casas) {
if (casas < 0) throw new IllegalArgumentException();
long fator = (long) Math.pow(10, casas);
valor *= fator;
return (double) Math.round(valor) / fator;
}
}
//Utilização
double[][] equacao = {{1, 2, 3, 5},
{5, 3, 1, 7},
{1, 2, 2, 4}};
SistemaLinear eq = new SistemaLinear(equacao);
eq.matriz();
eq.resultado();
eq.equacao();