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;
}
}
Related
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);
}
Suppose you have an array of Points on a 2D plane. Point being defined as such:
class Point {
public int x;
public int y;
Point(int _x, int _y) { x = _x; y = _y; }
}
How could I find the maximum number of points lying on the same straight line in java?
For each point in the array, calculate the angle between this point and other points. Counting the number of those with the same angle using a hashMap. Expected time O(n^2)
Pseudo code
int result = 0;
for(int i = 0; i < data.length; i++){
HashMap<Double, Integer> map = new HashMap();
for(int j = 0; j < data.length; j++){
if(i == j)
continue;
double angle = calculateAngle(data[i], data[j]);
if(map.containsKey(slope)){
map.put(angle, map.get(slope) + 1);
}else{
map.put(angle, 1);
}
result = max(result, map.get(slope));
}
}
Note: As mention in NiklasB 's comment, using double will cause some problems with precision, especially when we need to compare those floating values. We can avoid that by using the Rational class suggested by NiklasB. (Or less precise, using this)
Here is a solution in Java using precise arithmetic:
import java.util.List;
import java.util.Map;
import java.util.HashMap;
public class Solver {
public int maxPointsOnLine(List<Point> points) {
int ans = 0;
Map<Line, Integer> lines = new HashMap<Line, Integer>();
for (Point a : points) {
int max = 0;
int same = 0;
lines.clear();
for (Point b : points) {
if (a.x == b.x && a.y == b.y) {
++same;
} else {
Line line = new Line(b.x - a.x, b.y - a.y);
Integer count = lines.get(line);
if (count == null) {
count = 0;
}
++count;
lines.put(line, count);
max = Math.max(max, count);
}
}
ans = Math.max(ans, same + max);
}
return ans;
}
static class Line {
final int dx;
final int dy;
Line(int dx, int dy) {
if (dy == 0) {
dx = Math.abs(dx);
}
else if (dy < 0) {
dx = -dx;
dy = -dy;
}
int gcd = gcd(Math.abs(dx), dy);
dx /= gcd;
dy /= gcd;
this.dx = dx;
this.dy = dy;
}
#Override
public boolean equals(Object other) {
if (!(other instanceof Line)) {
return false;
}
Line another = (Line)other;
return dx == another.dy && dy == another.dy;
}
#Override
public int hashCode() {
return 31 * dx + dy;
}
}
static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector<Point> &points) {
int n = points.size(); //number of the points
if (n<=2){return n;}
vector<double> k; //vector to store the slops for one point with all the other points
int res = 0;
for (int i=0;i<n;i++){ // for each point in the 2d plane
k.clear();
int dup = 1; // number of the duplicates with currrent point
for (int j=0;j<n;j++){
if (i!=j){ // for every other point
if (points[i].x-points[j].x==0){ // if the slope is a vertical line
if (points[i].y-points[j].y==0){ // if the point j is the same as point i
dup++;
}else{
k.push_back(99999); //store the vertical line to a specific slope
}
}else{ // if it is the regular slop between point i and j
k.push_back(10000*(points[i].y-points[j].y)/(points[i].x-points[j].x)); // store the slope
}
}
}
sort(k.begin(),k.end()); //sort the slopes for counting
int pp = 1; //number of points in the same line of the point i
if (k.size()==0){pp=0;}
for (int jj=1;jj<k.size();jj++){ //count pp
if (k[jj]==k[jj-1]){
pp++;
}else{
if (pp+dup>res){res=pp+dup;} // res = pp + the number of duplicates
pp = 1;
}
}
if (pp+dup>res){res = pp+dup;}
}
return res;
}
};
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 designing a polynomial class for one of my com sci courses , I have a problem of getting the integration method right
can some one help me with that
/** The polynomial class includes the methods: evaluate , add, multiply,
* Differentiate , integrate and square root.
*/
public class polynomial {
private int degree;
private double[] coefficients;
// a constructor that creates a polynomial of degree degMax with all the coefficients are zeroes
public polynomial(int degMax) {
degree= degMax;
coefficients = new double[degree + 1];
}
// a setter method that let the users set the coefficients for the polynomial they constructed
public void setCoefficient(int d , double v ){
if (d > degree)
{
System.out.println("Erorr Message: the degree you specified is larger than the polynomial's degree that you have created ");
}
else {
coefficients[d]=v;
}
}
// a getter method to return the coefficient for the specified degree
public double getCoefficient(int i){
return coefficients[i];
}
// private method that counts the degree of the polynomial by searching for the last element in the coefficient array that
// does not contain zero
private int getDegree() {
int deg = 0;
for (int i = 0; i < coefficients.length; i++)
if (coefficients[i] != 0) deg = i;
return deg;
}
// a method that print out the polynomial as a string
public String print(){
if (degree == 0) return "" + coefficients[0];
if (degree == 1) return coefficients[1] + "x + " + coefficients[0];
String s = coefficients[degree] + "x^" + degree;
for (int i = degree-1; i >= 0; i--) {
if (coefficients[i] == 0) continue;
else if (coefficients[i] > 0) s = s + " + " + ( coefficients[i]);
else if (coefficients[i] < 0) s = s + " - " + (-coefficients[i]);
if (i == 1) s = s + "x";
else if (i > 1) s = s + "x^" + i;
}
return s;
}
// a method that evaluate the polynomial at specified value x
public double evaluate(double x) {
double result = 0;
for (int i = degree; i >= 0; i--)
result = coefficients[i] + (x * result);
return result;
}
// a method that perform symbolic addition of two polynomial
public polynomial addition(polynomial p2) {
polynomial p1 = this;
polynomial p3 = new polynomial(Math.max(p1.degree, p2.degree));
for (int i = 0; i <= p1.degree; i++) p3.coefficients[i] += p1.coefficients[i];
for (int i = 0; i <= p2.degree; i++) p3.coefficients[i] += p2.coefficients[i];
p3.degree = p3.getDegree();
return p3;
}
// a method that performs a symbolic multiplication
public polynomial multiply(polynomial p2) {
polynomial p1 = this;
polynomial p3 = new polynomial(p1.degree + p2.degree);
for (int i = 0; i <= p1.degree; i++)
for (int j = 0; j <= p2.degree; j++)
p3.coefficients[i+j] += (p1.coefficients[i] * p2.coefficients[j]);
p3.degree = p3.getDegree();
return p3;
}
// a method that apply differentiation to polynomial
public polynomial differentiate() {
if (degree == 0) return new polynomial(0);
polynomial derivative = new polynomial(degree - 1);
derivative.degree = degree - 1;
for (int i = 0; i < degree; i++){
derivative.coefficients[i] = (i + 1) * coefficients[i + 1];
}
return derivative;
}
// a method that find a polynomial integral over the interval a to b
public double integration(double a , double b) {
polynomial integral= new polynomial (degree+1);
integral.degree= degree+1;
for (int i=0 ; i<= degree+1 ; i++){
if (i==0) {
integral.coefficients[i]= 0;
}
else {
integral.coefficients[i]= (coefficients[i-1]/i);
}
}
return (evaluate(b)- evaluate(a));
}
public static void main(String[] args) {
polynomial p1 = new polynomial(3);
p1.setCoefficient(0, 3.0);
p1.setCoefficient(3, 5.0);
String r = p1.print(); //3.0 + 5.0 x^3
polynomial p2 = new polynomial(2);
p2.setCoefficient(1, 4.0);
p2.setCoefficient(2, 2.0);
polynomial n = p1.addition(p2);
String po = n.print();
polynomial t = p1.multiply(p2);
String tr = t.print();
polynomial di = p2.differentiate();
String dir = di.print();
double ev = p2.evaluate(5.0);
double inte = p1.integration(3.0, 7.0);
System.out.println("p1(x) = " + r );
System.out.println("p1(x) + p2(x) = " + po);
System.out.println("p1(x) * p2(x) = " + tr);
System.out.println("p2'(x) = " + dir);
System.out.println("p1(x) integration over [3.0, 7.0] = " + inte);
System.out.println("p2(5.0) = " + ev);
}
}
If I were you, I would split the methods :
public Polynomial integrate()
{
Polynomial integral = new Polynomial(this.degree + 1);
for (int i = 1; i <= this.degree+1; i++)
{
integral.coefficients[i] = (this.coefficients[i - 1] / i);
}
return integral;
}
// a method that find a Polynomial integral over the interval a to b
public double integration(double a, double b)
{
Polynomial integral = integrate();
return (integral.evaluate(b) - integral.evaluate(a));
}
Ok now why it didn't work as you expected :
public double integration(double a , double b) {
polynomial integral= new polynomial (degree+1);
integral.degree= degree+1;
for (int i=0 ; i<= degree+1 ; i++){
if (i==0) {
integral.coefficients[i]= 0;
}
else {
integral.coefficients[i]= (coefficients[i-1]/i);
}
}
return (evaluate(b)- evaluate(a));
}
you messed up your "integral" object with the current instance "this", clean your code first :
public double integration(double a , double b) {
polynomial integral= new polynomial (this.degree+1);
integral.degree= this.degree+1;
for (int i=0 ; i<= this.degree+1 ; i++){
if (i==0) {
integral.coefficients[i]= 0;
}
else {
integral.coefficients[i]= (this.coefficients[i-1]/i);
}
}
return (this.evaluate(b)- this.evaluate(a));
}
Here you can see that you evaluate on your instance object instead of "integral" object. That's why it messed up the result.
You almost got it correct. The only problem is that you should call:
return (integral.evaluate(b) - integral.evaluate(a));
instead of:
return (evaluate(b)- evaluate(a));
Otherwise the code seems ok.
Adding to Boris' answer, you could simplify the integrate method like this:
public double integration(double a, double b) {
polynomial integral = new polynomial(degree + 1);
for (int i = 1; i <= degree + 1; i++) {
integral.coefficients[i] = coefficients[i - 1] / i;
}
return integral.evaluate(b) - integral.evaluate(a);
}
I have two methods: power and factorial:
public static long pow(int x, int n) {
long p = x;
for (int i = 1; i < n; i++) {
p *= x;
}
return p;
}
public static long fact(int n) {
long s = n;
for (int i = 1; i < n; i++ ) {
s *= i;
}
return s;
}
that are returning longs. When I want to use them in new method evaluating Exponential function i get wrong results comparing to Math.exp(x). My code:
public static void exp(int x, double eps) {
int i = 1;
double pow = 1.0;
double fact = 1.0;
double sum = 0.0;
double temp;
do {
temp = pow/fact;
sum += temp;
pow = pow(x, i);
fact = fact(i);
i++;
}
while (temp > eps);
System.out.println("Check: " + Math.exp(x));
System.out.println("My: " + sum);
}
public static void main() {
int x = 10;
double eps = 0.0000000000001;
exp(x, eps);
}
and the output for x=10 is:
Check: 22026.465794806718
My: 21798.734894914145
the larger x, the bigger "loss of precision" (not exactly, because you can't really call it precise...).
The twist is, when methods power and factorial return double then the output is correct. Can anyone explain me how to make it work?
Methods pow and fact must return long and I must use them in exp (college assignment).
If you try this pow method:
public static long pow(int x, int n) {
long p = x;
System.out.println("Pow: "+x+","+n);
for (int i = 1; i < n; i++) {
p *= x;
System.out.println(p);
}
return p;
}
You get this output:
...
Pow: 10,20
100
1000
10000
...
...
1000000000000000
10000000000000000
100000000000000000
1000000000000000000
-8446744073709551616
7766279631452241920
The long value overflows: 10^20 is just too big to fit in a long.
Methods pow and fact must return long and I must use them in exp (college assignment).
Then there is not much you can do to fix it. You could throw an exception if eps is too small.
How large is x typically? It could be integer overflow. Try changing all the int arguments in pow and fact to be long instead.
Long data types can't handle decimal precision that's why you're values are wrong with long. Why don't you just have the functions return the double values?
Edit: Heres what I came up with:
public static long pow(int x, int n)
{
double p = x;
for (int i = 1; i < n; i++) {
p *= x;
}
return (long)p;
}
public static long fact(int n)
{
double s = n;
for (int i = 1; i < n; i++ ) {
s *= i;
}
return (long)s;
}
public static void exp(int x, double eps)
{
double pow = 1.0;
double fact = 1.0;
double sum = 0.0;
double temp;
for(int ii=1; ii < 100; ii++)
{
pow = pow(x, ii);
fact = fact(ii);
temp = (double)pow/(double)fact;
temp = temp == 1 ? 0 : temp;
sum += temp;
}
System.out.println("Check: " + Math.exp(x));
System.out.println("My: " + sum);
}
public static void main(final String[] args)
{
int x = 10;
double eps = 0.0000000000001;
exp(x, eps);
}
That's about the closest you're going to get without using the decimals.
Check: 22026.465794806718
My: 21946.785573087538