Hi there,
I got a little problem with finding the inverse of a matrix when using the BigDecimal type. I mean, I have got a method that finds the inverse of a matrix perfectly with the primitive type double. Here is the method as shown below:
import java.lang.*;
public class Inverse {
public static void main(String arg[]) {
double a[][]= {{0.0038053780181931084, 0.003729663276441426, 0.0064344762767650256, 0.0010346528952388523, -0.026667616352678624, -0.029400456101594908},
{0.003729663276441426, 0.0038541077016533546, 0.00647664820019812, 0.001041434069152789, -0.026842397426785514, -0.029593148362827063},
{0.0064344762767650256, 0.00647664820019812, 0.011273619736763435, 0.0017966991428170357, -0.046308944441478844, -0.05105458508765971},
{0.0010346528952388523, 0.001041434069152789, 0.0017966991428170357, 3.889061813315775E-4, -0.007446399890360643, -0.008209490874480767},
{-0.026667616352678624, -0.026842397426785514, -0.046308944441478844, -0.007446399890360643, 0.19202691229934035, 0.21159516790500957},
{-0.029400456101594908, -0.029593148362827063, -0.05105458508765971, -0.008209490874480767, 0.21159516790500957, 0.23337898388173603},
};
int n = a.length;
double d[][] = invert(a);
for (int i=0; i<a.length; ++i)
for (int j=0; j<a[i].length; ++j)
{
System.out.print(d[i][j]+ " ");
if(j == a[i].length - 1)
{
System.out.println();
System.out.println();
}
}
}
public static double[][] invert(double a[][]) {
int n = a.length;
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];
}
}
}
}
But when I changed the types to be that of BigDecimal and i called the invert method, as shown below:
public static BigDecimal[][] invert(BigDecimal a[][]) {
int n = a.length;
BigDecimal x[][] =new BigDecimal[n][n];
BigDecimal b[][] = new BigDecimal[n][n];
int index[] = new int[n];
for (int i=0; i<n; ++i) b[i][i] = new BigDecimal("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]
=b[index[j]][k].subtract( a[index[j]][i].multiply (b[index[i]][k]));
// Perform backward substitutions
for (int i=0; i<n; ++i) {
x[n-1][i] = b[index[n-1]][i].divide(a[index[n-1]][n-1],20,RoundingMode.HALF_UP);
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] =x[j][i].subtract( a[index[j]][k].multiply(x[k][i]));
}
x[j][i] = x[j][i].divide(a[index[j]][j],20,RoundingMode.HALF_UP);
}
}
return x;
}
// Method to carry out the partial-pivoting Gaussian
// elimination. Here index[] stores pivoting order.
public static void gaussian(BigDecimal a[][],
int index[]) {
int n = index.length;
BigDecimal c[] = new BigDecimal[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) {
BigDecimal c1 = new BigDecimal("0");
for (int j=0; j<n; ++j) {
BigDecimal c0 = (a[i][j]).abs();
if (c0.compareTo(c1)>0) c1 = c0;
}
c[i] = c1;
}
// Search the pivoting element from each column
int k = 0;
for (int j=0; j<n-1; ++j) {
BigDecimal pi1 = new BigDecimal("0");
for (int i=j; i<n; ++i) {
BigDecimal pi0 =a[index[i]][j].abs();
pi0 =pi0.divide(c[index[i]],20,RoundingMode.HALF_UP);
if (pi0.compareTo (pi1) >0) {
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) {
BigDecimal pj = a[index[i]][j].divide(a[index[j]][j],20,RoundingMode.HALF_UP);
// 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] =a[index[i]][l].subtract( pj.multiply(a[index[j]][l]));
}
}
}
public void inverse()
{
int i, j, k;
System.out.println();
System.out.println("The weightMatrix after inversion is:");
System.out.println();
weightMatrix1 = invert(weightMatrix);
for (i=0; i<weightMatrix1.length; ++i)
for (j=0; j<weightMatrix1[i].length; ++j)
{
System.out.print(weightMatrix1[i][j]+ " ");
if(j == weightMatrix1[i].length - 1)
{
System.out.println();
System.out.println();
}
}
}
it gives me an error saying:
Exception in thread "main" java.lang.NullPointerException
at newtonsMethod1.invert(newtonsMethod1.java:282)
at newtonsMethod1.inverse(newtonsMethod1.java:359)
the line 282 at newtonsMethod1.invert is this bit:
b[index[j]][k]
in the following part of the code:
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]
=b[index[j]][k].subtract( a[index[j]][i].multiply (b[index[i]][k]));
Can you figure out what is going on here, cos i have only this problem when I changed the types from double to BigDecimal, and it worked well with type double.
Thanks