Recently learned about Cramers rule in precalculus, and decided to make an algorithm in Java to help me understand it better.
The following code works 100% correctly, however it does not use any sort of for loop to do what it does in a much simpler fashion.
Question: Is there a more elegant implementation of Cramers Rule in Java?
I'm thinking that making a basic determinant method, and then doing some column swapping for when I need to take the determinant of Dx, Dy, and Dz. (for Dx, swap column 4 with column 1 of the original matrix, then take determinant and divide by original determinant.)
This sound good?
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for(int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if(check(base, r, base[3])) {
info("System " + (i+1) + " checks!");
} else {
info("System " + (i+1) + " fails check!");
}
}
}
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[2];
int D = (m[0][0] * m[1][1]) - (m[1][0] * m[0][1]);
int Dx = (m[0][2] * m[1][1]) - (m[1][2] * m[0][1]);
int Dy = (m[0][0] * m[1][2]) - (m[1][0] * m[0][2]);
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
} else if (m.length == 3) {
result = new int[3];
int D = (((m[0][2] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][0]) + (m[2][2]
* m[1][0] * m[0][2])) - ((m[0][0] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[0][2]) + (m[0][2] * m[1][0] * m[2][1])));
int Dx = (((m[2][3] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][3] * m[0][1])) - ((m[0][3] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[2][3]) + (m[0][2] * m[1][3] * m[2][1])));
int Dy = (((m[2][0] * m[1][3] * m[0][2]) + (m[2][3] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][0] * m[0][3])) - ((m[0][0] * m[1][3] * m[2][2])
+ (m[0][3] * m[1][2] * m[2][0]) + (m[0][2] * m[1][0] * m[2][3])));
int Dz = (((m[2][0] * m[1][1] * m[0][3]) + (m[2][1] * m[1][3] * m[0][0]) + (m[2][3]
* m[1][0] * m[0][1])) - ((m[0][0] * m[1][1] * m[2][3])
+ (m[0][1] * m[1][3] * m[2][0]) + (m[0][3] * m[1][0] * m[2][1])));
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
result[2] = (int) (Dz / D);
} else {
return new int[] {};
}
return result;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length -1)];
for(int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
My question pertains to the specific algorithm that can be used to solve systems of equations using Cramers rule only, is there any algorithm that is more elegant? The function is only designed for square matrices.
This is not a homework assignment, after HS I will be studying CS and I've been working on developing algorithms as preliminary practice.
Thank you for checking this out
First of, there is one way in which Cramers rule is perfect: It gives the algebraic solution of a linear system as a rational function in its coefficients.
However, practically, it has its limits. While the most perfect formula for a 2x2 system, and still good for a 3x3 system, its performance, if implemented in the straightforward way, deteriorates with each additional dimension.
An almost literal implementation of Cramers rule can be achieved with the Leverrier-Faddeev algorithm a b. It only requires the computation of matrix products and matrix traces, and manipulations of the matrix diagonal. Not only does it compute the determinant of the matrix A (along with the other coefficients of the characteristic polynomial), it also has the adjugate or co-factor matrix A# in its iteration matrix. The interesting fact about this matrix is that it allows to write the solution of A*x=b as (A#*b)/det(A), that is, the entries of A#*b already are the other determinants required by Cramers rule.
Leverrier-Faddeev requires n4+O(n3) operations. The same results can be obtained by the more complicated Samuelson-Berkowitz algorith, which has one third of that complexity, that is n4/3+O(n3).
The computation of the determinants required in Cramers rule becomes downright trivial if the system (A|b) is first transformed into triangular form. That can be achieved by Gauß elimination, aka LU decomposition (with pivoting for numerical stability) or the QR decomposition (easiest to debug should be the variant with Givens rotations). The efficient application of Cramers rule is then backward substitution in the triangular system.
Your method sounds good to me at least; however, I just may not be aware of any more efficient methods. The not-fun part may be figuring out how to best implement the determinant-calculating method, as apparently it's not an inexpensive operation.
But once you know that that's working, the rest sounds pretty OK to me. Cache the determinant of the original matrix, substitute in columns, etc.
Figured out exactly how to do this effectively.
http://sandsduchon.org/duchon/math/determinantJava.html
Provides a method for seamless determinants, and mentions matrix decomposition. I have not learned this yet as it's not a HS level concept however I did some problems using it and it's a solid method.
Final Code:
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for (int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if (check(base, r, base[3])) {
info("System " + (i + 1) + " checks!");
} else {
info("System " + (i + 1) + " fails check!");
}
}
}
public static int getDet(int[][] a) {
int n = a.length - 1;
if (n < 0)
return 0;
int M[][][] = new int[n + 1][][];
M[n] = a; // init first, largest, M to a
// create working arrays
for (int i = 0; i < n; i++)
M[i] = new int[i + 1][i + 1];
return getDet(M, n);
} // end method getDecDet double [][] parameter
public static int getDet(int[][][] M, int m) {
if (m == 0)
return M[0][0][0];
int e = 1;
// init subarray to upper left mxm submatrix
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i][j];
int sum = M[m][m][m] * getDet(M, m - 1);
// walk through rest of rows of M
for (int i = m - 1; i >= 0; i--) {
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i + 1][j];
e = -e;
sum += e * M[m][i][m] * getDet(M, m - 1);
} // end for each row of matrix
return sum;
} // end getDecDet double [][][], int
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = getDet(slide(m, i, m.length)) / D;
}
} else if (m.length == 3) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = (getDet(slide(m, i, m.length)) / D);
}
} else {
return new int[] {};
}
return result;
}
public static int[][] slide(int[][] base, int col, int fin) {
int[][] copy = new int[base.length][];
for (int i = 0; i < base.length; i++) {
int[] aMatrix = base[i];
int aLength = aMatrix.length;
copy[i] = new int[aLength];
System.arraycopy(aMatrix, 0, copy[i], 0, aLength);
}
for (int i = 0; i < base.length; i++) {
copy[i][col] = base[i][fin];
}
return copy;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length - 1)];
for (int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
Related
i'm just created a java project to print string that is given in rows and column just like matrix. Here's the output that i just made:
h e l l o
_ w o r l
d _ i t s
_ b e a u
t i f u l
Is it possible to show the output like a spiral pattern like this?
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
For the clarification how this spiral matrix created:
Here's my current code:
String str = "hello world its beautiful";
double length = Math.sqrt(str.length());
int x = (int) length;
for (int i = 0, len = str.length(); i < len; i++) {
System.out.print(str.charAt(i) + " ");
if (i % x == x - 1) {
System.out.println();
}
}
I'm trying to make the same pattern like that, but it's never be. Let me know that you can help me with this. I appreciate for every answer that you gave, thank you.
Basically, you move through the string from start to end, but treat the stringbuffer as an array.
You#ll also need to to keep track of your direction (dx,dy) and where your bounds are.
The following code will produce:
hello
beau
l.tw
sufio
i dlr
given the input "hello world is beautiful"
public class Main {
public static void main(String[] args) {
String text ="hello world is beautiful";
int len = text.length();
double sideLength = Math.sqrt( len );
int width = 0;
int height = 0;
// check if it's a square
if ( sideLength > (int) sideLength) {
// nope... it#s a rectangle
width = (int) sideLength +1;
height = (int) Math.ceil((double)len / (double)width);
} else {
// square
width = (int) sideLength;
height = (int) sideLength;
}
// create a buffer for the spiral
StringBuffer buf = new StringBuffer( width * height );
buf.setLength( width * height );
// clear it.
for (int a=0; a < buf.length(); a++ ) {
buf.setCharAt(a, '.');
}
int dstX = 0;
int dstY = 0;
int curWidth = width;
int curHeight = height;
int startX = 0;
int startY = 0;
int dx = 1;
int dy = 0;
// go through the string, char by char
for (int srcPos =0; srcPos < len; srcPos++) {
buf.setCharAt( dstX + dstY * width, text.charAt( srcPos ));
// move cursor
dstX += dx;
dstY += dy;
// check for bounds
if ( dstX == curWidth-1 && dx > 0) {
// end of line while going right, need to go down
dx = 0;
dy = 1;
// also, reduce width
curWidth--;
startY++;
} else if (dstY == curHeight-1 && dy > 0) {
// end of column while going down, need to go left
dx = -1;
dy = 0;
// also, reduce height
curHeight--;
} else if (dstX == startX && dx < 0) {
// hit left border while going left, need to go up
dx = 0;
dy = -1;
// also, increase startX
startX++;
} else if (dstY == startY && dy < 0) {
// hit top border, while going up, need to go right
dx = 1;
dy = 0;
// also, increase startY
startY++;
}
}
// display string
for (int line = 0; line < height; line++) {
System.out.println( buf.substring( line* width, line*width +width) );
}
}
}
spiralMatrix(int s) returns s x s spiral matrix.
static int[][] spiralMatrix(int s) {
int[][] a = new int[s][s];
int n = 0;
for (int b = s - 1, c = 0, x = 0, y = 0, dx = 0, dy = 1; b > 0; b -= 2, x = y = ++c)
for (int j = 0, t = 0; j < 4; ++j, t = dx, dx = dy, dy = -t)
for (int i = 0; i < b; ++i, x += dx, y += dy, ++n)
a[x][y] = n;
if (s % 2 == 1)
a[s / 2][s / 2] = n;
return a;
}
test
for (int s = 0; s < 6; ++s) {
int[][] a = spiralMatrix(s);
System.out.println("s=" + s);
for (int[] row : a)
System.out.println(Arrays.toString(row));
System.out.println();
}
result
s=0
s=1
[0]
s=2
[0, 1]
[3, 2]
s=3
[0, 1, 2]
[7, 8, 3]
[6, 5, 4]
s=4
[0, 1, 2, 3]
[11, 12, 13, 4]
[10, 15, 14, 5]
[9, 8, 7, 6]
s=5
[0, 1, 2, 3, 4]
[15, 16, 17, 18, 5]
[14, 23, 24, 19, 6]
[13, 22, 21, 20, 7]
[12, 11, 10, 9, 8]
And you can do it with this method.
String str = "hello world its beautiful";
int[][] spiral = spiralMatrix(5);
int length = str.length();
for (int x = 0, h = spiral.length, w = spiral[0].length; x < h; ++x) {
for (int y = 0; y < w; ++y) {
int p = spiral[x][y];
System.out.print((p < length ? str.charAt(p) : " ") + " " );
}
System.out.println();
}
result
h e l l o
b e a
s u l u w
t f i t o
i d l r
you could try to make the spiral algorithm first and try to find the value of its each index in the matrix so that later you could map every index of your string into the specific index in the spiral array matrix.
for example:
Input: n = 5
Output: 1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Aligned Output: 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
the algorithm can be found here or here.
now you know all the index of each position to make the letters aligned in a spiral way, what you have to do is map each letter of your string to be print according to the number of the spiral matrix sequentially.
print string 1.
print string 2.
print string 3.
print string 4.
print string 5.
print string 16.
print string 17.
print string 18.
print string 19.
print string 6.
print string 15.
cont...
Probably I'll add my answer too, idea is to flatten a two dimensional array to 1d and use the 1D array and transform it to a 2D spiral array. Hope it helps.
Code:
class Test {
static String[][] spiralPrint(int m, int n, String[] a) {
String[][] output = new String[m][n];
int count = 0;
int i, k = 0, l = 0;
while (k < m && l < n) {
for (i = l; i < n; ++i) {
output[k][i] = a[count++];
}
k++;
for (i = k; i < m; ++i) {
output[i][n - 1] = a[count++];
}
n--;
if (k < m) {
for (i = n - 1; i >= l; --i) {
output[m - 1][i] = a[count++];
}
m--;
}
if (l < n) {
for (i = m - 1; i >= k; --i) {
output[i][l] = a[count++];
}
l++;
}
}
return output;
}
private static String[] flattenArray(String[][] input, int m, int n) {
String[] output = new String[m * n];
int k = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
output[k++] = input[i][j];
}
}
return output;
}
public static void main(String[] args) {
String[][] input = {
{"h", "e", "l", "l", "o"},
{"_", "w", "o", "r", "l"},
{"d", "_", "i", "t", "s"},
{"_", "b", "e", "a", "u"},
{"t", "i", "f", "u", "l"}};
int m = 5;
int n = 5;
String[] flattenArray = flattenArray(input, m, n);
String[][] spiralArray = spiralPrint(m, n, flattenArray);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(spiralArray[i][j] + " ");
}
System.out.println();
}
}
}
Output:
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
Note: Indeed that I followed this Spiral transform to 1D, but it is not straight forward, I have re-modified to fit to the problem.
I think that the best way to implement this is the following:
create an instruction object (Dictionary.java) which controls the fill-in process of the matrix
fill in the matrix with data (Spiral.java)
then show the matrix
With this approach, you can change the pattern easily, without changing the rest of the code because the pattern generator works detached from the rest of the code.
This is how the basic Dictionary class may look like:
public abstract class Dictionary {
protected int matrixSize;
protected String[] dictionary;
public Dictionary(int matrixSize) {
this.matrixSize = matrixSize;
dictionary = new String[matrixSize * matrixSize];
}
public abstract String[] createPattern();
public void showPattern() {
Arrays.stream(dictionary).forEach(System.out::println);
}
}
For each pattern, you need to implement the createPattern() method differently.
For example, a frame pattern implementation can be something like this:
public class FrameDictionary extends Dictionary {
protected int dictionaryIndex = 0;
protected int startX, endX;
protected int startY, endY;
public FrameDictionary(int matrixSize) {
super(matrixSize);
startX = -1;
endX = matrixSize - 1;
startY = 0;
endY = matrixSize - 1;
}
#Override
public String[] createPattern() {
while (dictionaryIndex < matrixSize) {
pattern1();
pattern2();
}
return dictionary;
}
/**
* pattern 1
* direction: left -> right then top -> bottom
*/
protected void pattern1() {
startX++;
for (int i = startX; i <= endX; i++) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
for (int i = startY; i <= endY; i++) {
dictionary[dictionaryIndex] = endX + ":" + i;
dictionaryIndex++;
}
}
/**
* pattern 2
* direction: right -> left then bottom -> top
*/
protected void pattern2() {
endX--;
for (int i = endX; i >= startX; i--) {
dictionary[dictionaryIndex] = i + ":" + endY;
dictionaryIndex++;
}
endY--;
for (int i = endY; i >= startY; i--) {
dictionary[dictionaryIndex] = startX + ":" + i;
dictionaryIndex++;
}
}
}
Output:
a b c d e f
t g
s h
r i
q j
p o n m l k
You can draw the pattern what you need with the following implementation of the createPattern() method:
public class ClockWiseDictionary extends FrameDictionary {
public ClockWiseDictionary(int matrixSize) {
super(matrixSize);
}
#Override
public String[] createPattern() {
int pixelsInMatrix = matrixSize * matrixSize;
while (dictionaryIndex < pixelsInMatrix) {
pattern1();
pattern2();
}
return dictionary;
}
}
Output:
a b c d e f
t u v w x g
s 6 7 8 y h
r 5 0 9 z i
q 4 3 2 1 j
p o n m l k
Or just for fun, a "snake" pattern implementation:
public class SnakeDictionary extends Dictionary {
private int dictionaryIndex = 0;
private int startY = 0;
public SnakeDictionary(int matrixSize) {
super(matrixSize);
}
#Override
public String[] createPattern() {
int pixelsInMatrix = matrixSize * matrixSize;
while (dictionaryIndex < pixelsInMatrix) {
pattern1();
if (dictionaryIndex < pixelsInMatrix) {
pattern2();
}
}
return dictionary;
}
public void pattern1() {
for (int i = 0; i < matrixSize; i++) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
}
public void pattern2() {
for (int i = matrixSize - 1; i >= 0; i--) {
dictionary[dictionaryIndex] = i + ":" + startY;
dictionaryIndex++;
}
startY++;
}
}
Output:
a b c d e f
l k j i h g
m n o p q r
x w v u t s
y z 1 2 3 4
0 9 8 7 6 5
This is how the main method looks like:
public static void main(String[] args) {
String sentence = "abcdefghijklmnopqrstuvwxyz1234567890";
String[][] spiral = new String[MATRIX_SIZE][MATRIX_SIZE];
// Dictionary dictionary = new FrameDictionary(MATRIX_SIZE);
Dictionary dictionary = new ClockWiseDictionary(MATRIX_SIZE);
// Dictionary dictionary = new SnakeDictionary(MATRIX_SIZE);
String[] pattern = dictionary.createPattern();
//dictionary.showPattern();
Spiral.fill(sentence, pattern, spiral);
Spiral.show(spiral);
}
You can check/download the complete source code from GitHub.
Hope that it helps you.
Here's a one with a recursive approach,
I am traversing the matrix in right -> down -> left -> up fashion on the boundaries
Then change the size and do the same for inner boundaries,
Matrix M would be a spiral matrix then of character indices
Create spiral matrix C for characters by traversing matrix M.
int m = 5;
int n = 5;
int limit = m * n;
int[][] M = new int[m][n];
public void spiral(int[][] M, int row, int col, int c, int start, int m, int n) {
if (c > limit | row >= m | col >= n)
return;
if (M[row][col] == 0)
M[row][col] = c;
if (row == start) // go right
spiral(M, row, col + 1, c + 1, start, m, n);
if (col == n - 1) // go down
spiral(M, row + 1, col, c + 1, start, m, n);
if (row == m - 1 && col > start) // go left
spiral(M, row, col - 1, c + 1, start, m, n);
if (col == start && row >= start) // go up
spiral(M, row - 1, col, c + 1, start, m, n);
};
spiral(M, 0, 0, 1, 0, m, n);
for (int i = m - 1, x = 1, j = n - 1; i >= m - 2 && j >= n - 2; i--, j--, x++)
spiral(M, x, x, M[x][x - 1] + 1, x, i, j);
This would give you spiral Matrix M
Output:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Then create a spiral matrix for characters using matrix M
String string = "hello_world_its_beautiful";
char[][] C = new char[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++)
C[i][j] = string.charAt(M[i][j] - 1);
}
Output:
h e l l o
_ b e a _
s u l u w
t f i t o
i _ d l r
When can't go straight turn left to walk, this is the theory used in this solution
int dr[] = {0, 1, 0, -1};
int dc[] = {1, 0, -1, 0};
this is used for always move pattern. And curr & curc represent current position and curm represent current move pattern.
public int[][] solve(int r, int c, String s) {
int m[][] = new int[5][5];
int curr = 0, curc = 0;
for (int pos = 0, curm = 0; pos < r*c; pos++) {
m[curr][curc] = (int) s.charAt(pos);
if (curr + dr[curm] < 0 || curr + dr[curm] >= r || curc + dc[curm] < 0 || curc + dc[curm] >= c
|| m[curr + dr[curm]][curc + dc[curm]] != 0)
curm = (curm + 1) % 4;
curr = curr + dr[curm];
curc = curc + dc[curm];
}
return m;
}
Then you can print this way
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
System.out.printf("%c ", m[i][j]);
}
System.out.println("");
}
Given an array, it contains N element, which are all positive integers; if we can find three elements, and they divide the array into four parts (Notice: the three elements are not contained in any part of the four), and the sum of each part are equal, then we call the array a "balanced" array. Design an algorithm to judge whether an array is balance, with limit: Time O(N), Space O(N).
Here is an example:
a = [1,7,4,2,6,5,4,2,2,9,8];
b = [1,8,10,5,3,1,2,3]
a is balanced, 'cause the element 4, 5, 9 divide the array into [1,7], [2,6], [4,2,2], [8], the sum of each is 8.
b is not balanced, because we can not find a solution.
Any idea is appreciated!
Hints
Consider the first element to be removed.
Once you know this position, you can compute the size of the first part.
Once you know the size of the first part, you can compute the location of the second element to be removed, and so on (because all elements are positive integers).
Now you need to find a way to perform this in O(N). Try thinking about what you can do to reuse computations that have already been done, e.g. by keeping a rolling sum of the size of each of your parts.
You can try with this solution:
class BalancedArray
{
public static void main( String[] args ) throws java.lang.Exception
{
int[] a = { 1, 7, 4, 2, 6, 5, 4, 2, 2, 9, 8 }; //BALANCED
//int[] a = {7,0,6,1,0,1,1,5,0,1,2,2,2}; //BALANCED
//int[] a = {1}; //NOT BALANCED
int l = a.length;
if ( l < 7 )
{
System.out.println( "Array NOT balanced" );
} else
{
int maxX = l - 5;
int maxY = l - 3;
int maxZ = l - 1;
int x = 1;
int y = 3;
int z = 5;
int sumX = 0; //From 0 to x
int sumY = 0; //From x to y
int sumJ = 0; //From y to z
int sumZ = 0; //From z to l
for(x = 1; x < maxX; x++)
{
sumX = calcSum(a,0,x);
for(y = x + 2; y < maxY; y++)
{
sumY = calcSum(a,x+1,y);
if(sumY != sumX){
continue;
}
for(z = y + 2; z < maxZ; z++)
{
sumJ = calcSum(a,y+1,z);
if(sumJ != sumY)
{
continue;
}
sumZ = calcSum(a,z+1,l);
if(sumZ != sumJ){
continue;
}
if(sumZ == sumX && sumX == sumY && sumY == sumJ)
{
System.out.println( "Array balanced!!! Elements -> X:" + x + " Y: " + y + " Z:" + z );
return;
}
}
}
}
System.out.println("Array NOT balanced!!");
}
}
private static int calcSum(int[] src, int start, int end)
{
int toReturn = 0;
for ( int i = start; i < end; i++ )
{
toReturn += src[i];
}
return toReturn;
}
}
I made these assumptions:
between each of the three elements, which should split the array in 4 parts, there must be at least a distance of 2;
to be divided in 4 sub-arrays the source array must be at least 7 elements long;
I am having trouble getting the correct results when performing multiplication of elliptic curve points. I have been able to get addition working but when trying to multiply a point I am confused on the proper way to add to the previous values. I also am doing this without Javas EC points.
Example:
Expected: 12(2,7)=(153,36)
Results: 12(2,7)=(55,121)
private static int a = 11;
private static int mod = 167;
public static void main(String[] args) {
int[] p1 = { 2, 7 };
int[] p2 = addPoints(new int[] { 1, 4 }, new int[] { 3, 1 });
System.out.println("ADDING: (" + p2[0] + "," + p2[1] + ")");
int[] p3 = multiplyPoint(12, p1);
System.out.println("MULTIPLYING: (" + p3[0] + "," + p3[1] + ")");
}
public static int[] multiplyPoint(int iterations, int[] point) {
int[] newPoint = new int[2];
for (int i = 1; i < iterations; i++) {
System.out.println("(" + newPoint[0] + "," + newPoint[1] + ")");
newPoint = addPoints(newPoint, point);
}
return newPoint;
}
public static int[] addPoints(int[] p1, int[] p2) {
int[] p3 = { 0, 0 };
int m;
if (p1[0] == p2[0] && p1[1] == p2[1])
m = mod(((3 * p1[0] * p1[0]) + a) / (2 * p1[1]), mod);
else
m = mod((int) p2[1] - p1[1], mod) / mod(p2[0] - p1[0], mod);
p3[0] = mod((int) (Math.pow(m, 2) - p1[0] - p2[0]), mod);
p3[1] = mod((m * (p1[0] - p3[0]) - p1[1]), mod);
return p3;
}
/**
* Used because Java's default modulus operator does not give the correct
* value for negative numbers
*
* #param value
* Number to perform the mod operation on
* #param divisor
* Mod by
* #return The modulus of number mod divisor... Should now work for any
* number
*/
public static int mod(int value, int divisor) {
return ((value % divisor + divisor) % divisor);
}
Thanks
EDIT:
Still unsuccessful
public static int[] multiplyPoint(int iterations, int[] point) {
int[] newPoint = new int[2];
String binary = Integer.toBinaryString(iterations);
System.out.println(binary);
for (int i = 0; i < binary.length(); i++) {
System.out.println("(" + newPoint[0] + "," + newPoint[1] + ")");
if (binary.charAt(i) == '1')
newPoint = addPoints(newPoint, point);
point = doublePoint(point);
}
return newPoint;
}
public static int[] doublePoint(int[] point) {
int[] newPoint = new int[2];
int m = mod(((3 * point[0] * point[0]) + a) / (2 * point[1]), mod);
newPoint[0] = mod((int) (Math.pow(m, 2) - point[0] - point[0]), mod);
newPoint[1] = mod((m * (point[0] - newPoint[0]) - point[1]), mod);
return newPoint;
}
public static int[] addPoints(int[] p1, int[] p2) {
int[] p3 = new int[2];
int m = mod((int) p2[1] - p1[1], mod) / mod(p2[0] - p1[0], mod);
p3[0] = mod((int) (Math.pow(m, 2) - p1[0] - p2[0]), mod);
p3[1] = mod((m * (p1[0] - p3[0]) - p1[1]), mod);
return p3;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
So I already have this whole entire class done in Int and now I had to convert it to BigInteger. Main objective is so I can store the coefficients as the BigIntegers for large coefficients. I am getting a null pointer error with the code but I knew that BigInteger was immutable and needed that format. Just maybe another eye or maybe I'm just not doing this correctly.
public class Polynomial {
private BigInteger[] coef; // coefficients
private int deg; // degree of polynomial (0 for the zero polynomial)
/** Creates the constant polynomial P(x) = 1.
*/
public Polynomial(){
coef = new BigInteger[1];
coef[0] = BigInteger.valueOf(1);
deg = 0;
}
/** Creates the linear polynomial of the form P(x) = x + a.
*/
public Polynomial(int a){
coef = new BigInteger[2];
coef[1] = BigInteger.valueOf(1);
coef[0] = BigInteger.valueOf(a);
deg = 1;
}
/** Creates the polynomial P(x) = a * x^b.
*/
public Polynomial(int a, int b) {
coef = new BigInteger[b+1];
coef[b] = BigInteger.valueOf(a);
deg = degree();
}
public Polynomial(BigInteger a, int b) {
coef = new BigInteger[b+1];
coef[b] = a;
deg = degree();
}
/** Return the degree of this polynomial (0 for the constant polynomial).
*/
public int degree() {
int d = 0;
for (int i = 0; i < coef.length; i++)
if (coef[i] != BigInteger.valueOf(0)) d = i;
return d;
}
/** Return the sum of this polynomial and b, i.e., return c = this + b.
*/
public Polynomial plus(Polynomial b) {
Polynomial a = this;
Polynomial c = new Polynomial(0, Math.max(a.deg, b.deg));
for (int i = 0; i <= a.deg; i++) c.coef[i] = c.coef[i].add(a.coef[i]);
for (int i = 0; i <= b.deg; i++) c.coef[i] = c.coef[i].add(b.coef[i]);
c.deg = c.degree();
return c;
}
/** Return the difference of this polynomial and b, i.e., return (this - b).
*/
public Polynomial minus(Polynomial b) {
Polynomial a = this;
Polynomial c = new Polynomial(0, Math.max(a.deg, b.deg));
for (int i = 0; i <= a.deg; i++) c.coef[i] = c.coef[i].add(a.coef[i]);
for (int i = 0; i <= b.deg; i++) c.coef[i] = c.coef[i].subtract(b.coef[i]);
c.deg = c.degree();
return c;
}
/** Return the product of this polynomial and b, i.e., return (this * b).
*/
public Polynomial times(Polynomial b) {
Polynomial a = this;
Polynomial c = new Polynomial(0, a.deg + b.deg);
for (int i = 0; i <= a.deg; i++)
for (int j = 0; j <= b.deg; j++)
c.coef[i+j] = c.coef[i+j].add(a.coef[i].multiply(b.coef[j]));
c.deg = c.degree();
return c;
}
/** Return the composite of this polynomial and b, i.e., return this(b(x)) - compute using Horner's method.
*/
public Polynomial compose(Polynomial b) {
Polynomial a = this;
Polynomial c = new Polynomial(0, 0);
for (int i = a.deg; i >= 0; i--) {
Polynomial term = new Polynomial(a.coef[i], 0);
c = term.plus(b.times(c));
}
return c;
}
/** Return true whenever this polynomial and b are identical to one another.
*/
public boolean equals(Polynomial b) {
Polynomial a = this;
if (a.deg != b.deg) return false;
for (int i = a.deg; i >= 0; i--)
if (a.coef[i] != b.coef[i]) return false;
return true;
}
/** Evaluate this polynomial at x, i.e., return this(x).
*/
public int evaluate(int x) {
int p = 0;
for (int i = deg; i >= 0; i--){
coef[i] = coef[i].add(BigInteger.valueOf(x * p));
p = coef[i].intValue();
}
return p;
}
/** Return the derivative of this polynomial.
*/
public Polynomial differentiate() {
if (deg == 0) return new Polynomial(0, 0);
Polynomial deriv = new Polynomial(0, deg - 1);
deriv.deg = deg - 1;
for (int i = 0; i < deg; i++)
deriv.coef[i] = coef[i + 1].multiply(BigInteger.valueOf(i+1));
return deriv;
}
/** Return a textual representationof this polynomial.
*/
public String toString() {
if (deg == 0) return "" + coef[0];
if (deg == 1) return String.valueOf(coef[1]) + "x + " + String.valueOf(coef[0]);
String s = String.valueOf(coef[deg]) + "x^" + deg;
for (int i = deg-1; i > 0; i--) {
if (coef[i].intValue() == 0) continue;
else if (coef[i].intValue() > 0) s = s + " + " + ( coef[i].intValue());
else if (coef[i].intValue() < 0) s = s + " - " + (-coef[i].intValue());
if (i == 1) s = s + "x";
else if (i > 1) s = s + "x^" + i;
}
return s;
}
public static void main(String[] args) {
Polynomial zero = new Polynomial(1, 0);
Polynomial p1 = new Polynomial(4, 3);
Polynomial p2 = new Polynomial(3, 2);
Polynomial p3 = new Polynomial(-1, 0);
Polynomial p4 = new Polynomial(-2, 1);
Polynomial p = p1.plus(p2).plus(p3).plus(p4); // 4x^3 + 3x^2 - 2x - 1
Polynomial q1 = new Polynomial(3, 2);
Polynomial q2 = new Polynomial(5, 0);
Polynomial q = q1.minus(q2); // 3x^2 - 5
Polynomial r = p.plus(q);
Polynomial s = p.times(q);
Polynomial t = p.compose(q);
System.out.println("zero(x) = " + zero);
System.out.println("p(x) = " + p);
System.out.println("q(x) = " + q);
System.out.println("p(x) + q(x) = " + r);
System.out.println("p(x) * q(x) = " + s);
System.out.println("p(q(x)) = " + t);
System.out.println("0 - p(x) = " + zero.minus(p));
System.out.println("p(3) = " + p.evaluate(3));
System.out.println("p'(x) = " + p.differentiate());
System.out.println("p''(x) = " + p.differentiate().differentiate());
Polynomial poly = new Polynomial();
for(int k=0; k<=4; k++){
poly = poly.times(new Polynomial(-k));
}
System.out.println(poly);
}
}
So when you initialize your array of BigInteger, the values are null because you have specified an array of objects (if it was int[] then initial values are 0).
As you can see from your constructor:
public Polynomial(int a, int b) {
coef = new BigInteger[b+1];
coef[b] = BigInteger.valueOf(a);
deg = degree();
}
You have only assigned coef[b], the other values remain null.
Hence in first iteration of loop in method plus(Polynomial b), c.coef[0] is null hence NullPointerException when your loop tries to call c.coef[0].add(a.coef[0]).
Suggestion: define a method to initialize all the BigInteger values in an array to 0 to be consistent with declaration of int[] and call in your constructors. Example:
private static void initializeBigIntegerArray(BigInteger[] bigIntegers) {
for (int i=0; i<bigIntegers.length; i++) {
// So you don't overwrite anything you assign explicitly
if (bigInteger[i] == null) {
bigIntegers[i] = BigInteger.ZERO;
}
}
}
Recall that in Java an array of objects is actually an array of references to objects. So you need to create a BigInteger object for every array element. The entries you don't assign are not 0, they are null.
So in the plus method, you create this polynomial c whose backing array contains one zero, and several nulls. Then you go ahead and try to operate on all the coefficients in that polynomial, including all those nulls. So you're calling methods on variables for which an object hasn't been created yet, and that's what makes your null pointer problem.
When you create each polynomial, make sure you have a BigInteger created for every entry in the backing array.
I have this Java code that with a set of Point in input return a set of graph's edge that represent a Delaunay triangulation.
I would like to know what strategy was used to do this, if exist, the name of algorithm used.
In this code GraphEdge contains two awt Point and represent an edge in the triangulation, GraphPoint extends Awt Point, and the edges of final triangulation are returned in a TreeSet object.
My purpose is to understand how this method works:
public TreeSet getEdges(int n, int[] x, int[] y, int[] z)
below the complete source code of this triangulation :
import java.awt.Point;
import java.util.Iterator;
import java.util.TreeSet;
public class DelaunayTriangulation
{
int[][] adjMatrix;
DelaunayTriangulation(int size)
{
this.adjMatrix = new int[size][size];
}
public int[][] getAdj() {
return this.adjMatrix;
}
public TreeSet getEdges(int n, int[] x, int[] y, int[] z)
{
TreeSet result = new TreeSet();
if (n == 2)
{
this.adjMatrix[0][1] = 1;
this.adjMatrix[1][0] = 1;
result.add(new GraphEdge(new GraphPoint(x[0], y[0]), new GraphPoint(x[1], y[1])));
return result;
}
for (int i = 0; i < n - 2; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = i + 1; k < n; k++)
{
if (j == k) {
continue;
}
int xn = (y[j] - y[i]) * (z[k] - z[i]) - (y[k] - y[i]) * (z[j] - z[i]);
int yn = (x[k] - x[i]) * (z[j] - z[i]) - (x[j] - x[i]) * (z[k] - z[i]);
int zn = (x[j] - x[i]) * (y[k] - y[i]) - (x[k] - x[i]) * (y[j] - y[i]);
boolean flag;
if (flag = (zn < 0 ? 1 : 0) != 0) {
for (int m = 0; m < n; m++) {
flag = (flag) && ((x[m] - x[i]) * xn + (y[m] - y[i]) * yn + (z[m] - z[i]) * zn <= 0);
}
}
if (!flag)
{
continue;
}
result.add(new GraphEdge(new GraphPoint(x[i], y[i]), new GraphPoint(x[j], y[j])));
//System.out.println("----------");
//System.out.println(x[i]+" "+ y[i] +"----"+x[j]+" "+y[j]);
result.add(new GraphEdge(new GraphPoint(x[j], y[j]), new GraphPoint(x[k], y[k])));
//System.out.println(x[j]+" "+ y[j] +"----"+x[k]+" "+y[k]);
result.add(new GraphEdge(new GraphPoint(x[k], y[k]), new GraphPoint(x[i], y[i])));
//System.out.println(x[k]+" "+ y[k] +"----"+x[i]+" "+y[i]);
this.adjMatrix[i][j] = 1;
this.adjMatrix[j][i] = 1;
this.adjMatrix[k][i] = 1;
this.adjMatrix[i][k] = 1;
this.adjMatrix[j][k] = 1;
this.adjMatrix[k][j] = 1;
}
}
}
return result;
}
public TreeSet getEdges(TreeSet pointsSet)
{
if ((pointsSet != null) && (pointsSet.size() > 0))
{
int n = pointsSet.size();
int[] x = new int[n];
int[] y = new int[n];
int[] z = new int[n];
int i = 0;
Iterator iterator = pointsSet.iterator();
while (iterator.hasNext())
{
Point point = (Point)iterator.next();
x[i] = (int)point.getX();
y[i] = (int)point.getY();
z[i] = (x[i] * x[i] + y[i] * y[i]);
i++;
}
return getEdges(n, x, y, z);
}
return null;
}
}
Looks like what is described here http://en.wikipedia.org/wiki/Delaunay_triangulation :
The problem of finding the Delaunay triangulation of a set of points in d-dimensional Euclidean space can be converted to the problem of finding the convex hull of a set of points in (d + 1)-dimensional space, by giving each point p an extra coordinate equal to |p|2, taking the bottom side of the convex hull, and mapping back to d-dimensional space by deleting the last coordinate.
In your example d is 2.
The vector (xn,yn,zn) is the cross product of the vectors (point i -> point j) and (point i -> point k) or in other words a vector perpendicular to the triangle (point i, point j, point k).
The calculation of flag checks whether the normal of this triangle points towards the negative z direction and whether all other points are on the side opposite to the normal of the triangle (opposite because the other points need to be above the triangle's plane because we're interested in the bottom side of the convex hull). If this is the case, the triangle (i,j,k) is part of the 3D convex hull and therefore the x and y components (the projection of the 3D triangle onto the x,y plane) is part of the (2D) Delaunay triangulation.