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("");
}
I have a very challenging problem here today. I cannot think of a way to solve it.
Given 6 numbers as input: a1, a2, a3, b1, b2, b3, find 2 numbers X and Y such that a1 * x^2 + a2 ^ x + a3 = b1 * y^2 + b2 * y + b3. X and Y must be between 10 and 15000 inclusive.
What I have tried:
I have tried all X values from 10-15000 and all Y values from 10-15000, and checked if they satisfied the equation. However, this method is extremely slow. Does anyone have a faster solution? Thanks.
My Bad Code:
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
for (int i = 10; i <= 15000; i++) {
for (int j = 10; j <= 15000; j++) {
if (conv(a, i) == conv(b, j)) {
cout << i << " " << j << endl;
j = 20000;
i = 20000;
}
}
}
}
long long conv(int x, int b) {
long long ans = 0;
int count = 0;
while (x) {
int y = x % 10;
ans += y * poww(b, count);
count++;
x /= 10;
}
return ans;
}
long long poww(int x, int y) {
long long ans = 1;
while (y != 0) {
ans *= x;
y--;
}
return ans;
}
I thought this might be a good occassion to exercise writing some Java code and came up with the following solution. On my system it gives the solution to the two numbers 419 and 792 (as you wrote in an earlier edit of your question the result should be Base X: 47 Base Y: 35) in 1 ms.
The code just uses some smart brute force :).
See it running online.
public class TwoBases {
public static void main(String[] args) {
long beg = System.nanoTime();
solve(419, 792);
System.out.println("Time needed to calculate: "+(System.nanoTime()-beg)/1000000.0 + "ms");
}
public static void solve(int a, int b) {
int[] aDigits = new int[3];
int[] bDigits = new int[3];
for (int i = 0; i < 3; i++) {
aDigits[2 - i] = (a / (int) Math.pow(10, i)) % 10;
bDigits[2 - i] = (b / (int) Math.pow(10, i)) % 10;
}
for (int x = 10; x <= 15000; x++) {
int numBaseX = digitsToBase10(aDigits, x);
int y = 10;
while (y <= 15000) {
int numBaseY = digitsToBase10(bDigits, y);
if (numBaseX == numBaseY) {
System.out.println("Base X: " + x + " Base Y: " + y);
return;
} else if (numBaseY > numBaseX) {
break;
} else {
y++;
}
}
}
System.out.println("Nothing found");
}
public static int digitsToBase10(int[] digits, int b) {
int res = 0;
for (int i = 0; i < digits.length; i++) {
res += digits[i] * (int) Math.pow(b, digits.length - 1 - i);
}
return res;
}
}
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);
}
Good evening!i´m trying to use the code of the FFT that works in Java in Android but don´t know why it doesn´t work fine.
This is my modified code in Android. Thanks in advance!!
package dani;
public class FFT {
// compute the FFT of x[], assuming its length is a power of 2
public static Complex[] fft(Complex[] x) {
int N = x.length;
// base case
if (N == 1) return new Complex[] { x[0] };
// radix 2 Cooley-Tukey FFT
if (N % 2 != 0) { throw new RuntimeException("N is not a power of 2"); }
// fft of even terms
Complex[] even = new Complex[N/2];
for (int k = 0; k < N/2; k++) {
even[k] = x[2*k];
}
Complex[] q = fft(even);
// fft of odd terms
Complex[] odd = even; // reuse the array
for (int k = 0; k < N/2; k++) {
odd[k] = x[2*k + 1];
}
Complex[] r = fft(odd);
// combine
Complex[] y = new Complex[N];
for (int k = 0; k < N/2; k++) {
double kth = -2 * k * Math.PI / N;
Complex wk = new Complex(Math.cos(kth), Math.sin(kth));
y[k] = q[k].plus(wk.times(r[k]));
y[k + N/2] = q[k].minus(wk.times(r[k]));
}
return y;
}
// compute the inverse FFT of x[], assuming its length is a power of 2
public static Complex[] ifft(Complex[] x) {
int N = x.length;
Complex[] y = new Complex[N];
// take conjugate
for (int i = 0; i < N; i++) {
y[i] = x[i].conjugate();
}
// compute forward FFT
y = fft(y);
// take conjugate again
for (int i = 0; i < N; i++) {
y[i] = y[i].conjugate();
}
// divide by N
for (int i = 0; i < N; i++) {
y[i] = y[i].times(1.0 / N);
}
return y;
}
// compute the circular convolution of x and y
public static Complex[] cconvolve(Complex[] x, Complex[] y) {
// should probably pad x and y with 0s so that they have same length
// and are powers of 2
if (x.length != y.length) { throw new RuntimeException("Dimensions don't
agree"); }
int N = x.length;
// compute FFT of each sequence
Complex[] a = fft(x);
Complex[] b = fft(y);
// point-wise multiply
Complex[] c = new Complex[N];
for (int i = 0; i < N; i++) {
c[i] = a[i].times(b[i]);
}
// compute inverse FFT
return ifft(c);
}
// compute the linear convolution of x and y
public static Complex[] convolve(Complex[] x, Complex[] y) {
Complex ZERO = new Complex(0, 0);
Complex[] a = new Complex[2*x.length];
for (int i = 0; i < x.length; i++) a[i] = x[i];
for (int i = x.length; i < 2*x.length; i++) a[i] = ZERO;
Complex[] b = new Complex[2*y.length];
for (int i = 0; i < y.length; i++) b[i] = y[i];
for (int i = y.length; i < 2*y.length; i++) b[i] = ZERO;
return cconvolve(a, b);
}
}
public static void main(String[] args) {
int N = 64;
Complex[] x = new Complex[N];
// original data
for (int i = 0; i < N; i++) {
x[i] = new Complex(i, 0);
x[i] = new Complex(-2*Math.cos(i)/N, 0);//AQUI se mete la funcion
}
// FFT of original data
Complex[] y = fft(x);
// take inverse FFT
Complex[] z = ifft(y);
// circular convolution of x with itself
Complex[] c = cconvolve(x, x);
// linear convolution of x with itself
Complex[] d = convolve(x, x);
}
}
i have define another class for the complex number
this is the code:
package dani;
public class Complex {
private final double re; // the real part
private final double im; // the imaginary part
// create a new object with the given real and imaginary parts
public Complex(double real, double imag) {
re = real;
im = imag;
}
// return a string representation of the invoking Complex object
public String toString() {
if (im == 0) return re + "";
if (re == 0) return im + "i";
if (im < 0) return re + " - " + (-im) + "i";
return re + " + " + im + "i";
}
// return abs/modulus/magnitude and angle/phase/argument
public double abs() { return Math.hypot(re, im); } // Math.sqrt(re*re + im*im)
public double phase() { return Math.atan2(im, re); } // between -pi and pi
// return a new Complex object whose value is (this + b)
public Complex plus(Complex b) {
Complex a = this; // invoking object
double real = a.re + b.re;
double imag = a.im + b.im;
return new Complex(real, imag);
}
// return a new Complex object whose value is (this - b)
public Complex minus(Complex b) {
Complex a = this;
double real = a.re - b.re;
double imag = a.im - b.im;
return new Complex(real, imag);
}
// return a new Complex object whose value is (this * b)
public Complex times(Complex b) {
Complex a = this;
double real = a.re * b.re - a.im * b.im;
double imag = a.re * b.im + a.im * b.re;
return new Complex(real, imag);
}
// scalar multiplication
// return a new object whose value is (this * alpha)
public Complex times(double alpha) {
return new Complex(alpha * re, alpha * im);
}
// return a new Complex object whose value is the conjugate of this
public Complex conjugate() { return new Complex(re, -im); }
// return a new Complex object whose value is the reciprocal of this
public Complex reciprocal() {
double scale = re*re + im*im;
return new Complex(re / scale, -im / scale);
}
// return the real or imaginary part
public double re() { return re; }
public double im() { return im; }
// return a / b
public Complex divides(Complex b) {
Complex a = this;
return a.times(b.reciprocal());
}
// return a new Complex object whose value is the complex exponential of this
public Complex exp() {
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im));
}
// return a new Complex object whose value is the complex sine of this
public Complex sin() {
return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im));
}
// return a new Complex object whose value is the complex cosine of this
public Complex cos() {
return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im));
}
// return a new Complex object whose value is the complex tangent of this
public Complex tan() {
return sin().divides(cos());
}
// a static version of plus
public static Complex plus(Complex a, Complex b) {
double real = a.re + b.re;
double imag = a.im + b.im;
Complex sum = new Complex(real, imag);
return sum;
}
}