Skip to content

Commit

Permalink
Add some more polynomial methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
noeppi-noeppi committed Feb 4, 2024
1 parent 86d88f2 commit cffb5b1
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 1 deletion.
82 changes: 82 additions & 0 deletions src/main/java/org/moddingx/libx/util/math/DoublePolynomial.java
Expand Up @@ -21,6 +21,11 @@ public final class DoublePolynomial extends Polynomial<Double> implements Double
* The polynomial that is always zero.
*/
public static final DoublePolynomial ZERO = new DoublePolynomial(0);

/**
* The polynomial that is always one.
*/
public static final DoublePolynomial ONE = new DoublePolynomial(1);

/**
* The identity polynomial.
Expand Down Expand Up @@ -93,6 +98,83 @@ public Double apply(Double x) {
return this.applyAsDouble(x);
}

@Override
public DoublePolynomial derivative() {
if (this.coefficients.length == 0) return this;
double[] coefficients = new double[this.coefficients.length - 1];
for (int i = 0; i < coefficients.length; i++) {
coefficients[i] = this.coefficients[i] * (this.coefficients.length - i - 1);
}
// Direct constructor, there will never be leading zeros.
return new DoublePolynomial(coefficients, true);
}

/**
* Integrates this polynomial with constant part {@literal 0}.
*/
public DoublePolynomial integrate() {
return this.integrate(0);
}

/**
* Integrates this polynomial with the given constant part.
*/
public DoublePolynomial integrate(double constant) {
double[] coefficients = new double[this.coefficients.length + 1];
for (int i = 0; i < coefficients.length - 1; i++) {
coefficients[i] = this.coefficients[i] / (this.coefficients.length - i);
}
coefficients[coefficients.length - 1] = constant;
return new DoublePolynomial(coefficients, false);
}

@Override
public DoublePolynomial negate() {
if (this.coefficients.length == 0) return this;
double[] coefficients = new double[this.coefficients.length];
for (int i = 0; i < coefficients.length; i++) {
coefficients[i] = -this.coefficients[i];
}
// Direct constructor, there will never be leading zeros.
return new DoublePolynomial(coefficients, true);
}

@Override
public DoublePolynomial add(Polynomial<Double> other) {
double[] otherCoefficients = trustedCoefficients(other);
double[] coefficients = new double[Math.max(this.coefficients.length, otherCoefficients.length)];
int thisOffset = coefficients.length - this.coefficients.length;
int otherOffset = coefficients.length - otherCoefficients.length;
for (int i = 0; i < coefficients.length; i++) {
double thisPart = (i - thisOffset) >= 0 ? this.coefficients[i - thisOffset] : 0;
double otherPart = (i - otherOffset) >= 0 ? otherCoefficients[i - otherOffset] : 0;
coefficients[i] = thisPart + otherPart;
}
return new DoublePolynomial(coefficients, false);
}

@Override
public DoublePolynomial multiply(Polynomial<Double> other) {
double[] otherCoefficients = trustedCoefficients(other);
double[] coefficients = new double[this.coefficients.length + otherCoefficients.length];
for (int i = 0; i < this.coefficients.length; i++) {
for (int j = 0; j < otherCoefficients.length; j++) {
int idx = coefficients.length - ((this.coefficients.length - i - 1) + (otherCoefficients.length - j - 1)) - 1;
coefficients[idx] += (this.coefficients[i] * otherCoefficients[j]);
}
}
return new DoublePolynomial(coefficients, false);
}

// Returns trusted arrays. Don't modify.
private static double[] trustedCoefficients(Polynomial<Double> other) {
if (other instanceof DoublePolynomial polynomial) {
return polynomial.coefficients;
} else {
return other.coefficients().stream().mapToDouble(Double::valueOf).toArray();
}
}

@Override
public int hashCode() {
return Arrays.hashCode(this.coefficients);
Expand Down
76 changes: 75 additions & 1 deletion src/main/java/org/moddingx/libx/util/math/IntPolynomial.java
Expand Up @@ -22,7 +22,12 @@ public final class IntPolynomial extends Polynomial<Integer> implements IntUnary
* The polynomial that is always zero.
*/
public static final IntPolynomial ZERO = new IntPolynomial(0);


/**
* The polynomial that is always one.
*/
public static final IntPolynomial ONE = new IntPolynomial(1);

/**
* The identity polynomial.
*/
Expand Down Expand Up @@ -94,6 +99,75 @@ public Integer apply(Integer x) {
return this.applyAsInt(x);
}

@Override
public IntPolynomial derivative() {
if (this.coefficients.length == 0) return this;
int[] coefficients = new int[this.coefficients.length - 1];
for (int i = 0; i < coefficients.length; i++) {
coefficients[i] = this.coefficients[i] * (this.coefficients.length - i - 1);
}
// Direct constructor, there will never be leading zeros.
return new IntPolynomial(coefficients, true);
}

@Override
public IntPolynomial negate() {
if (this.coefficients.length == 0) return this;
int[] coefficients = new int[this.coefficients.length];
for (int i = 0; i < coefficients.length; i++) {
coefficients[i] = -this.coefficients[i];
}
// Direct constructor, there will never be leading zeros.
return new IntPolynomial(coefficients, true);
}

@Override
public IntPolynomial add(Polynomial<Integer> other) {
int[] otherCoefficients = trustedCoefficients(other);
int[] coefficients = new int[Math.max(this.coefficients.length, otherCoefficients.length)];
int thisOffset = coefficients.length - this.coefficients.length;
int otherOffset = coefficients.length - otherCoefficients.length;
for (int i = 0; i < coefficients.length; i++) {
int thisPart = (i - thisOffset) >= 0 ? this.coefficients[i - thisOffset] : 0;
int otherPart = (i - otherOffset) >= 0 ? otherCoefficients[i - otherOffset] : 0;
coefficients[i] = thisPart + otherPart;
}
return new IntPolynomial(coefficients, false);
}

@Override
public IntPolynomial multiply(Polynomial<Integer> other) {
int[] otherCoefficients = trustedCoefficients(other);
int[] coefficients = new int[this.coefficients.length + otherCoefficients.length];
for (int i = 0; i < this.coefficients.length; i++) {
for (int j = 0; j < otherCoefficients.length; j++) {
int idx = coefficients.length - ((this.coefficients.length - i - 1) + (otherCoefficients.length - j - 1)) - 1;
coefficients[idx] += (this.coefficients[i] * otherCoefficients[j]);
}
}
return new IntPolynomial(coefficients, false);
}

/**
* Converts this polynomial to a {@link DoublePolynomial}.
*/
public DoublePolynomial toDouble() {
double[] coefficients = new double[this.coefficients.length];
for (int i = 0; i < coefficients.length; i++) {
coefficients[i] = this.coefficients[i];
}
return new DoublePolynomial(coefficients);
}

// Returns trusted arrays. Don't modify.
private static int[] trustedCoefficients(Polynomial<Integer> other) {
if (other instanceof IntPolynomial polynomial) {
return polynomial.coefficients;
} else {
return other.coefficients().stream().mapToInt(Integer::valueOf).toArray();
}
}

@Override
public int hashCode() {
return Arrays.hashCode(this.coefficients);
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/org/moddingx/libx/util/math/Polynomial.java
Expand Up @@ -19,6 +19,33 @@ protected Polynomial() {
* polynomial {@code 2x²+1}.
*/
public abstract List<T> coefficients();

/**
* Computes the derivative of this polynomial.
*/
public abstract Polynomial<T> derivative();

/**
* Negates this polynomial.
*/
public abstract Polynomial<T> negate();

/**
* Adds two polynomials together.
*/
public abstract Polynomial<T> add(Polynomial<T> other);

/**
* Subtracts two polynomials from each other.
*/
public Polynomial<T> subtract(Polynomial<T> other) {
return this.add(other.negate());
}

/**
* Multiplies two polynomials.
*/
public abstract Polynomial<T> multiply(Polynomial<T> other);

@Override
public String toString() {
Expand Down

0 comments on commit cffb5b1

Please sign in to comment.