Hi Marco
I have been investigating about the most optimal inverse algorithm and I have found two good ones.
The first one is Shiplay’s method:
float[][] resul = a.clone();
if (a.length == a[0].length) {
int n = resul.length;
int k, j, i;
for (k = 0; k < n; k++) {
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
if ((i != k) && (j != k))
resul**[j] -= (resul**[k] * resul[k][j]) / resul[k][k];
}
for (j = 0; j < n; j++) {
if (j != k)
resul[k][j] = -resul[k][j] / resul[k][k];
}
for (i = 0; i < n; i++) {
if (i != k)
resul**[k] = resul**[k] / resul[k][k];
}
resul[k][k] = 1 / resul[k][k];
}
return resul;
} else
System.out.println("no se pudo");
return null;
}```
And the second one is:
import java.util.*;
public class Matriz{
public static double[][] matrizInversa(double[][] matriz) {
double det=1/determinante(matriz);
double[][] nmatriz=matrizAdjunta(matriz);
multiplicarMatriz(det,nmatriz);
return nmatriz;
}
public static void multiplicarMatriz(double n, double[][] matriz) {
for(int i=0;i<matriz.length;i++)
for(int j=0;j<matriz.length;j++)
matriz**[j]*=n;
}
public static double[][] matrizAdjunta(double [][] matriz){
return matrizTranspuesta(matrizCofactores(matri…
}
public static double[][] matrizCofactores(double[][] matriz){
double[][] nm=new double[matriz.length][matriz.length];
for(int i=0;i<matriz.length;i++) {
for(int j=0;j<matriz.length;j++) {
double[][] det=new double[matriz.length-1][matriz.length-1]…
double detValor;
for(int k=0;k<matriz.length;k++) {
if(k!=i) {
for(int l=0;l<matriz.length;l++) {
if(l!=j) {
int indice1=k<i ? k : k-1 ;
int indice2=l<j ? l : l-1 ;
det[indice1][indice2]=matriz[k][l];
}
}
}
}
detValor=determinante(det);
nm**[j]=detValor * (double)Math.pow(-1, i+j+2);
}
}
return nm;
}
public static double[][] matrizTranspuesta(double [][] matriz){
double[][]nuevam=new double[matriz[0].length][matriz.length];
for(int i=0; i<matriz.length; i++){
for(int j=0; j<matriz.length; j++)
nuevam**[j]=matriz[j]**;
}
return nuevam;
}
public static double determinante(double[][] matriz){
double det;
if(matriz.length==2){
det=(matriz[0][0]*matriz[1][1])-(matri…
return det;
}
double suma=0;
for(int i=0; i<matriz.length; i++){
double[][] nm=new double[matriz.length-1][matriz.length-1]…
for(int j=0; j<matriz.length; j++){
if(j!=i){
for(int k=1; k<matriz.length; k++){
int indice=-1;
if(j<i)
indice=j;
else if(j>i)
indice=j-1;
nm[indice][k-1]=matriz[j][k];
}
}
}
if(i%2==0)
suma+=matriz**[0] * determinante(nm);
else
suma-=matriz**[0] * determinante(nm);
}
return suma;
}
public static void imprimirMatriz(double[][] mat) {
for(int i=0;i<mat.length;i++) {
System.out.println(Arrays.toString(mat…
}
}
public static void main(String[]args){
double[][] deltaS= { {1,1,1,1,1 }, {0,0,1,0,1 }, {0,-1,0,1,0 }, {1,-2,0,0,0 }, {0,1,1,0,0 } };
double[][] deltaA= { {30,1,1,1,1 }, {14,0,1,0,1 }, {1,-1,0,1,0 }, {-1,-2,0,0,0 }, {10,1,1,0,0 } };
double[][] deltaB= { {1,30,1,1,1 }, {0,14,1,0,1 }, {0,1,0,1,0 }, {1,-1,0,0,0 }, {0,10,1,0,0 } };
double[][] deltaC= { {1,1,30,1,1 }, {0,0,14,0,1 }, {0,-1,1,1,0 }, {1,-2,-1,0,0 }, {0,1,10,0,0 } };
double[][] deltaD= { {1,1,1,30,1 }, {0,0,1,14,1 }, {0,-1,0,1,0 }, {1,-2,0,-1,0 }, {0,1,1,10,0 } };
double[][] deltaE= { {1,1,1,1,30 }, {0,0,1,0,14 }, {0,-1,0,1,1 }, {1,-2,0,0,-1 }, {0,1,1,0,10 } };
System.out.println( determinante(deltaA)/determinante( deltaS));
System.out.println( determinante(deltaB)/determinante( deltaS));
System.out.println( determinante(deltaC)/determinante( deltaS));
System.out.println( determinante(deltaD)/determinante( deltaS));
System.out.println( determinante(deltaE)/determinante( deltaS));
}
}```
I thing the first one is very clear.
However the second one is more modular and maybe there would be some methods implemented in jcubla libraries.
What do you thing is the best to try to implements in jcuda???
Thanks
Fran