Different situations might occur in our daily lives, where we require quick answers to polynomial operations. A student might need to verify their math assignment, an engineer could be designing a mechanical system that involves polynomial modeling, or a researcher may need to involve polynomial expressions to gain a better understanding of their data.
This project relies on two main classes: Polynomial and Monomial. The Polynomial class represents a polynomial expression, consisting of one or more monomials. Each Monomial object contains a coefficient and an exponent. The Polynomial and Monomial classes work together to enable users to input, manipulate, and perform operations on polynomial expressions efficiently.
• gui package : this package houses the CalculatorGui class, which manages the graphical user interface for the application;
• model package : within this package, you'll find the Monomial and Polynomial classes, essential for representing and manipulating polynomial data;
• operations package : this package includes the OperationInterface, Operations and PolynomialConvertor classes, providing the necessary methods for executing polynomial operations and the conversion from a string to a polynomial using pattern matching;
• testing package : this package contains the OperationsTest and ParsingTest classes, designed to conduct JUnit tests to verify the calculator's functionality.
For an improved functionality, I used a TreeMap<Integer, Monomial> structure to store the monomials of the polynomial. These monomials, containing only a coefficient and a degree, are sorted in ascending order in the TreeMap, based on their exponents, facilitating printing from the greatest exponent to the smallest.
For validating the provided polynomial i used a regex, which helped me correctly separate the monomials:
public static Polynomial parsePolynomial(String polynomial) {
Polynomial pol = new Polynomial();
Pattern pattern = Pattern.compile("(\\+|\\-)?(\\s*)(\\d*)(x)?(\\^)?(\\d*)");
Matcher matcher = pattern.matcher(polynomial);
while (matcher.find()) {
String sign = matcher.group(1);
String coef = matcher.group(3);
String x = matcher.group(4);
String degree = matcher.group(6);
Double c1;
Integer p1;
if(x != null) {
c1= (coef == null || coef.isEmpty()) ? 1.0 : Double.parseDouble(coef);
p1= (degree == null || degree.isEmpty()) ? 1 : Integer.parseInt(degree);
}
else{
c1= (coef == null || coef.isEmpty()) ? 0.0 : Double.parseDouble(coef);
p1 = 0;
}
if (sign != null && sign.equals("-")){c1 = -c1;}
if(c1 != 0) {
if (pol.getMonomials().containsKey(p1)) {
Double value = (Double) pol.getMonomials().get(p1).getCoefficient();
pol.getMonomials().get(p1).setCoefficient(value + c1);
} else {
Monomial newMonomial= new Monomial(p1, c1);
pol.getMonomials().put(p1, newMonomial);
}
}
}
return pol;
}
The challenge I encountered during the implementation of this project was correctly creating the mathematical operations. The polynomial calculator is capable of performing various mathematical operations on one or two polynomials, including addition, subtraction, division, multiplication, differentiation and integration. Some examples of how i implemented the most complex functions in my code:
The method below (integration method) accepts a single polynomial as input and computes its integral:
public Polynomial integration(Polynomial p1) {
Polynomial pFinal = new Polynomial();
for (Map.Entry<Integer, Monomial> entry : p1.getMonomials().entrySet()) {
if(entry.getValue() != null) {
Integer degree = entry.getValue().getDegree();
degree= degree+1;
Monomial newMonomial = new Monomial(degree, (
Double)entry.getValue().getCoefficient()/ degree.doubleValue());
pFinal.getMonomials().put(degree,newMonomial);
}
}
return pFinal;
}
public Polynomial[] division(Polynomial p1, Polynomial p2) {
Polynomial divider = new Polynomial();
Polynomial quotient = new Polynomial();
Polynomial remainder = new Polynomial(); //the one that is divided
Integer p1degree= p1.getMonomials().firstEntry().getKey();
Integer p2degree= p2.getMonomials().firstEntry().getKey();
if(p1degree>= p2degree) { //swap so we divide the polynomial with bigger power
for (Map.Entry<Integer, Monomial> entry : p1.getMonomials().entrySet())
remainder.addMonomials(entry.getValue().copy());
for (Map.Entry<Integer, Monomial> entry : p2.getMonomials().entrySet())
divider.addMonomials(entry.getValue().copy());
}
else {
for (Map.Entry<Integer, Monomial> entry : p2.getMonomials().entrySet())
remainder.addMonomials(entry.getValue().copy());
for (Map.Entry<Integer, Monomial> entry : p1.getMonomials().entrySet())
divider.addMonomials(entry.getValue().copy());
}
while(remainder.getMonomials().firstEntry()!=null &&
remainder.getMonomials().firstEntry().getValue().getDegree() >= divider.getMonomials().firstEntry().getValue().getDegree()) {
Integer degree1 = remainder.getMonomials().firstEntry().getKey();
Number coef1 = remainder.getMonomials().firstEntry().getValue().getCoefficient();
Integer degree2 = divider.getMonomials().firstEntry().getKey();
Number coef2 = divider.getMonomials().firstEntry().getValue().getCoefficient();
Integer degreeFinal = degree1 - degree2;
Number coefFinal = (Double) coef1 / (Double) coef2;
Monomial m = new Monomial(degreeFinal, coefFinal);
Polynomial p = new Polynomial();
p.getMonomials().put(degreeFinal, m);
quotient.getMonomials().put(degreeFinal, m);
remainder = sub(remainder, multiplication(divider, p));
if(remainder.getMonomials().firstEntry()!=null)
if ((Double)remainder.getMonomials().firstEntry().getValue().getCoefficient()== 0.0) {
System.out.println(remainder.getMonomials().firstEntry().getValue().getCoefficient());
remainder.getMonomials().remove(remainder.getMonomials().firstEntry().getKey());
}
}
return new Polynomial[]{quotient, remainder};
}
Besides gaining proficiency in polynomial operations, working with the TreeMap structure helped me organize and manage data efficiently. Moreover, the project helped me understand better OOP concepts and application of design patterns, especially in the context of creating graphical user interfaces.
I have conducted a series of JUnit tests for each operation and for parsing the polynomial. All my tests have passed successfully, indicating that the functionality is working as expected.