Skip to content

Commit a4cf37b

Browse files
committed
Merge branch 'master' of git://github.com/mciancia/java-algorithms-implementation into mciancia-master
2 parents 14aea2e + 867761c commit a4cf37b

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,12 @@ This is a collection of algorithms and data structures which I've implement over
6868
+ using recursion
6969
+ using only shifts
7070
+ using logarithms
71+
+ using FFT
7172
* Primes
7273
+ is prime
7374
+ prime factorization
7475
+ sieve of eratosthenes
76+
* FFT
7577

7678
## Numbers
7779
* Integers
@@ -93,6 +95,12 @@ This is a collection of algorithms and data structures which I've implement over
9395
- using divide and modulus
9496
- using right shift and modulus
9597
- using BigDecimal
98+
* Complex
99+
+ addition
100+
+ subtraction
101+
+ multiplication
102+
+ absolute value
103+
+ polar value
96104

97105
## Path
98106
* Find shortest path(s) in a Graph from a starting Vertex
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.jwetherell.algorithms.mathematics;
2+
3+
import com.jwetherell.algorithms.numbers.Complex;
4+
5+
import static com.jwetherell.algorithms.numbers.Complex.polar;
6+
7+
/**
8+
* Simple implementation of Cooley-Tukey FFT algorithm
9+
* Coefficients array size must be power of 2
10+
*
11+
* @author Mateusz Cianciara <e.cianciara@gmail.com>
12+
*/
13+
public class FFT {
14+
//coefficients size must be power of 2
15+
public static void FFT(Complex[] coefficients) {
16+
int size = coefficients.length;
17+
if (size <= 1) return;
18+
Complex[] even = new Complex[size / 2];
19+
Complex[] odd = new Complex[size / 2];
20+
for (int i = 0; i < size; i++) {
21+
if (i % 2 == 0) {
22+
even[i / 2] = coefficients[i];
23+
} else {
24+
odd[(i - 1) / 2] = coefficients[i];
25+
}
26+
}
27+
FFT(even);
28+
FFT(odd);
29+
for (int k = 0; k < size / 2; k++) {
30+
Complex t = polar(1.0, -2 * Math.PI * k / size).multiply(odd[k]);
31+
coefficients[k] = even[k].add(t);
32+
coefficients[k + size / 2] = even[k].sub(t);
33+
}
34+
}
35+
}

src/com/jwetherell/algorithms/mathematics/Multiplication.java

+79
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package com.jwetherell.algorithms.mathematics;
22

3+
import com.jwetherell.algorithms.numbers.Complex;
4+
5+
import java.util.ArrayList;
6+
import java.util.Collections;
7+
38
public class Multiplication {
49

510
public static final long multiplication(int a, int b) {
@@ -47,4 +52,78 @@ public static final long multiplyUsingLogs(int a, int b) {
4752
long result = Math.round(Math.pow(10, (Math.log10(absA) + Math.log10(absB))));
4853
return (a > 0 && b > 0 || a < 0 && b < 0) ? result : -result;
4954
}
55+
56+
public static String multiplyUsingFFT(String a, String b) {
57+
if (a.equals("0") || b.equals("0")) {
58+
return "0";
59+
}
60+
boolean negative = false;
61+
if ((a.charAt(0) == '-' && b.charAt(0) != '-') || (a.charAt(0) != '-' && b.charAt(0) == '-')) {
62+
negative = true;
63+
}
64+
if (a.charAt(0) == '-') {
65+
a = a.substring(1);
66+
}
67+
if (b.charAt(0) == '-') {
68+
b = b.substring(1);
69+
}
70+
int size = 1;
71+
while (size < (a.length() + b.length())) {
72+
size *= 2;
73+
}
74+
Complex[] aCoefficients = new Complex[size];
75+
Complex[] bCoefficients = new Complex[size];
76+
for (int i = 0; i < size; i++) {
77+
aCoefficients[i] = new Complex();
78+
bCoefficients[i] = new Complex();
79+
}
80+
for (int i = 0; i < a.length(); i++) {
81+
aCoefficients[i] = new Complex((double) (Character.getNumericValue(a.charAt(a.length() - i - 1))), 0.0);
82+
}
83+
for (int i = 0; i < b.length(); i++) {
84+
bCoefficients[i] = new Complex((double) (Character.getNumericValue(b.charAt(b.length() - i - 1))), 0.0);
85+
}
86+
87+
88+
FFT.FFT(aCoefficients);
89+
FFT.FFT(bCoefficients);
90+
91+
92+
for (int i = 0; i < size; i++) {
93+
aCoefficients[i] = aCoefficients[i].multiply(bCoefficients[i]);
94+
}
95+
for (int i = 0; i < size / 2; i++) {
96+
Complex temp = aCoefficients[i];
97+
aCoefficients[i] = aCoefficients[size - i - 1];
98+
aCoefficients[size - i - 1] = temp;
99+
}
100+
FFT.FFT(aCoefficients);
101+
102+
ArrayList<Integer> res = new ArrayList<Integer>();
103+
int pass = 0;
104+
for (int i = 0; i < size; i++) {
105+
res.add((int) (pass + Math.floor((aCoefficients[i].abs() + 1) / size)));
106+
if (res.get(i) >= 10) {
107+
pass = res.get(i) / 10;
108+
res.set(i, res.get(i) % 10);
109+
} else {
110+
pass = 0;
111+
}
112+
}
113+
Collections.reverse(res);
114+
StringBuilder result = new StringBuilder();
115+
if (negative) {
116+
result.append('-');
117+
}
118+
boolean startPrinting = false;
119+
for (Integer x : res) {
120+
if (x != 0) {
121+
startPrinting = true;
122+
}
123+
if (startPrinting) {
124+
result.append(x);
125+
}
126+
}
127+
return result.toString();
128+
}
50129
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.jwetherell.algorithms.numbers;
2+
3+
/**
4+
* @author Mateusz Cianciara <e.cianciara@gmail.com>
5+
*/
6+
public class Complex {
7+
public double real;
8+
public double imaginary;
9+
10+
public Complex() {
11+
this.real = 0.0;
12+
this.imaginary = 0.0;
13+
}
14+
15+
public Complex(double r, double i) {
16+
this.real = r;
17+
this.imaginary = i;
18+
}
19+
20+
public Complex multiply(final Complex x) {
21+
Complex copy = new Complex(this.real, this.imaginary);
22+
copy.real = this.real * x.real - this.imaginary * x.imaginary;
23+
copy.imaginary = this.imaginary * x.real + this.real * x.imaginary;
24+
return copy;
25+
}
26+
27+
public Complex add(final Complex x) {
28+
Complex copy = new Complex(this.real, this.imaginary);
29+
copy.real += x.real;
30+
copy.imaginary += x.imaginary;
31+
return copy;
32+
}
33+
34+
public Complex sub(final Complex x) {
35+
Complex copy = new Complex(this.real, this.imaginary);
36+
copy.real -= x.real;
37+
copy.imaginary -= x.imaginary;
38+
return copy;
39+
}
40+
41+
public double abs() {
42+
return Math.sqrt(this.real * this.real + this.imaginary * this.imaginary);
43+
}
44+
45+
public String toString() {
46+
return "(" + this.real + "," + this.imaginary + ")";
47+
}
48+
49+
public static Complex polar(final double rho, final double theta) {
50+
return new Complex(rho * Math.cos(theta), rho * Math.sin(theta));
51+
}
52+
}

test/com/jwetherell/algorithms/mathematics/test/Mathematics.java

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ private static int nextRandomInt(int min, int max) {
3131
public void multiplication() {
3232
int a = nextRandomInt(MIN, MAX);
3333
int b = nextRandomInt(MIN, MAX);
34+
String resultString;
3435
long result = Multiplication.multiplyUsingLoop(a, b);
3536
long check = Multiplication.multiplication(a, b);
3637
assertTrue("Multiplication using a loop. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
@@ -46,6 +47,11 @@ public void multiplication() {
4647
result = Multiplication.multiplyUsingLogs(a, b);
4748
check = Multiplication.multiplication(a, b);
4849
assertTrue("Multiplication using logs. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
50+
51+
result = Integer.parseInt(Multiplication.multiplyUsingFFT(Integer.toString(a), Integer.toString(b)));
52+
check = Multiplication.multiplication(a, b);
53+
assertTrue("Multiplication using FFT. a=" + a + " b=" + b + " result=" + result + " check=" + check, (result == check));
54+
4955
}
5056

5157
@Test

0 commit comments

Comments
 (0)