I have been trying to implement the given formula in JAVA but i was unsuccessful. Can someone help me find what I am doing wrong? Do i need to shift the summation index and if so how?
My code:
public final class LinearSystem {
private LinearSystem() {
}
public static int[] solve(int [][]A , int []y) {
int n = A.length;
int[] x = new int[n];
for (int i = 0 ; i < n; i ) {
x[i] = 0;
int sum = 0;
for(int k = i 1 ; k == n; k ) {
sum = A[i][k]*x[k]; // **java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3**
}
x[i] = 1/A[i][i] * (y[i] - sum);
}
return x;
}
public static void main(String[] args) {
int[][]A = new int[][]{{2,-1,-3},{0,4,-1},{0,0,3}};
int [] y = new int[] {4,-1,23};
System.out.println(Arrays.toString(solve(A,y))); **// awaited result [2, -3, 1]**
}
}
CodePudding user response:
Just trying to collect all my comments under the question into one coherent answer, since there are quite a few different mistakes in your program.
This method of solving linear equations relies on your calculating the components of the answer in reverse order - that is, from bottom to top. That's because each
x[i]
value depends on the values below it in the vector, but not on the values above it. So your outer loop, where you iterate over thex
values needs to start at the biggest index, and work down to the smallest. In other words, instead of beingfor (int i = 0; i < n; i )
, it needs to befor (int i = n - 1; i >= 0; i )
.The inner loop has the wrong stopping condition. With a
for
loop, the part between the two semicolons is the condition to continue iterating, not the condition to stop. So instead offor(int k = i 1; k == n; k )
, you needfor(int k = i 1; k < n; k )
.You're doing an integer division at the beginning of
1 / A[i][i] * (y[i] - sum);
, which means the value is rounded to an integer before carrying on. When you divide1
by another integer, you always get-1
,0
or1
because of the rounding, and that makes your answer incorrect. The fix from point 4 below will deal with this.The formula relies on the mathematical accuracy that comes with working with either floating point types or decimal types. Integers aren't going to be accurate. So you need to change the declarations of some of your variables, as follows.
public static double[] solve(double[][] A, double[] y)
double x[] = new double[n];
double sum = 0.0;
along with the corresponding changes in the main
method.
CodePudding user response:
First, you need the second loop to go until k < n, otherwise this throws the ArrayOutOfBounds Exceptions.
Second, you need to calculate your x
in reverse order as @Dawood ibn Kareem said.
Also, you probably want x[] to be a double-array to not only get 0-values as result.
CodePudding user response:
I am sorry I don't know much about math side so I couldn't fix it to the right solution but I noticed a few things wrong about your code.
1-You shouldn't initialize your arrays as integer arrays, because you will be doing integer division all over the place. For example 1/A[i][i] will result in 0 even if A[i][i] = 2
2-You shouldn't write k == n, if you do it like this then your for loop will only execute if k equals n, which is impossible for your case. I think you want to do k < n, which loops from i 1 to the point where k = n - 1
Here is my code:
import java.util.Arrays;
public final class LinearSystem {
private LinearSystem() {
}
public static double[] solve(double [][]A , double []y) {
int n = A.length;
double[] x = new double[n];
for (int i = 0 ; i < n; i ) {
x[i] = 0;
int sum = 0;
for(int k = i 1 ; k < n; k ) {
sum = A[i][k] * x[k]; // **java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3**
}
x[i] = 1/A[i][i] * (y[i] - sum);
}
return x;
}
public static void main(String[] args) {
double[][]A = new double[][]{{2,-1,-3},{0,4,-1},{0,0,3}};
double [] y = new double[] {4,-1,23};
System.out.println(Arrays.toString(solve(A,y))); // awaited result [2, -3, 1]**
}
}
CodePudding user response:
Remember that arrays are indexed from 0, so the last element is at index n - 1
, not n
.