Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions src/main/java/pl/jagiellonian/implementation/Expander.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package pl.jagiellonian.implementation;

import pl.jagiellonian.interfaces.ITreeExpression;
import pl.jagiellonian.interfaces.IVariable;
import pl.jagiellonian.utils.Operation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class Expander {

/**
* @param iTreeExpression - {@link ITreeExpression} expression to expand
* @return {@link ITreeExpression} expanded polynomial
*/
public ITreeExpression expand(ITreeExpression iTreeExpression) {
return divideIntoMonomials(iTreeExpression);
}

private ITreeExpression divideIntoMonomials(ITreeExpression iTreeExpression) {
ITreeExpression child0 = (ITreeExpression) iTreeExpression.getChildren().get(0);
ITreeExpression child1 = (ITreeExpression) iTreeExpression.getChildren().get(1);

List<Double> firstList;
List<Double> secondList = convertToDoubleArray(new ArrayList<>(), 0, child1);

if(isMultiplication(child0)) {
firstList = convertToDoubleArray(new ArrayList<>(), 0, divideIntoMonomials(child0));
}
else {
firstList = convertToDoubleArray(new ArrayList<>(), 0, child0);
}

return convertToTreePolynomial(multiplyCoefficients(firstList, secondList));
}

private boolean isMultiplication(ITreeExpression iTreeExpression) {
return iTreeExpression.getOperation() == Operation.MULT;
}


private List<Double> convertToDoubleArray(List<Double> list, int depth, ITreeExpression iTreeExpression) {
List<IVariable> listChildren = iTreeExpression.getChildren();

if(depth == 0) { //wyraz wolny
Operation sign = iTreeExpression.getOperation();
IVariable iVariable = listChildren.get(1);
double doubleVar = Double.parseDouble(iVariable.toString());
if(sign == Operation.SUB) {
doubleVar = - doubleVar;
}
list.add(doubleVar);
ITreeExpression next = (ITreeExpression) listChildren.get(0);
convertToDoubleArray(list, ++depth, next);
}
else if (depth == 1) { // x
ITreeExpression ite = (ITreeExpression) iTreeExpression.getChildren().get(0);
if(isNumber(ite)) {
list.add(Double.parseDouble(ite.getAllNodes().get(0).toString()));
}
else {
ITreeExpression var = (ITreeExpression) listChildren.get(1);
list.add(Double.parseDouble(var.getAllNodes().get(0).toString()));
ITreeExpression next = (ITreeExpression) listChildren.get(0);
convertToDoubleArray(list, ++depth, next);
}
}
else {
if(listChildren.size() == 1) {
ITreeExpression ite = (ITreeExpression) iTreeExpression.getChildren().get(0);
ITreeExpression var1 = (ITreeExpression) ite.getChildren().get(0);
list.add(Double.parseDouble(var1.getAllNodes().get(0).toString()));
return list;
}
else {
ITreeExpression ite = (ITreeExpression) iTreeExpression.getChildren().get(0);
if (!isNumber(ite)) {
ITreeExpression var = (ITreeExpression) listChildren.get(1);
ITreeExpression var1 = (ITreeExpression) var.getChildren().get(0);
list.add(Double.parseDouble(var1.getAllNodes().get(0).toString()));
ITreeExpression next = (ITreeExpression) listChildren.get(0);
convertToDoubleArray(list, ++depth, next);
} else {
ITreeExpression var = (ITreeExpression) listChildren.get(0);
list.add(Double.parseDouble(var.getAllNodes().get(0).toString()));
return list;
}
}
}
return list;
}

private ITreeExpression convertToTreePolynomial(List<Double> list) {
Collections.reverse(list);
int degree = list.size() - 1;

Iterator it = list.iterator();
ITreeExpression iTreeExpression = null;

while(it.hasNext()) {
ITreeExpression variable;

if(degree == 0) {
variable = new TreeExpression(Operation.ADD, new Variable(it.next().toString()));
}
else if (degree == 1) {
ITreeExpression value = new TreeExpression(Operation.ADD, new Variable(it.next().toString()));
variable = value.mult("x");
}
else {
ITreeExpression value = new TreeExpression(Operation.ADD, new Variable(it.next().toString()));
variable = new TreeExpression(Operation.POW, new Variable("x"));
variable = variable.pow(degree + "");
variable = value.mult(variable);
}

degree--;

if(iTreeExpression == null) {
iTreeExpression = new TreeExpression(Operation.ADD, variable);
}
else {
iTreeExpression = iTreeExpression.add(variable);
}
}

return iTreeExpression;
}

private boolean isNumber(ITreeExpression iTreeExpression) {
return iTreeExpression.getAllNodes().size() == 1;
}

private List<Double> multiplyCoefficients(List<Double> first, List<Double> second){
int totalLength = first.size() + second.size() - 1;
List<Double> resultAsArray = new ArrayList<>(totalLength);
double[] result = new double[totalLength];
for (int i = 0; i < first.size(); i++)
for (int j = 0; j < second.size(); j++) {
result[i + j] += first.get(i) * second.get(j);
}
for(double d: result){
resultAsArray.add(d);
}
return resultAsArray;
}
}
7 changes: 7 additions & 0 deletions src/main/java/pl/jagiellonian/interfaces/ITreeExpression.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package pl.jagiellonian.interfaces;

import pl.jagiellonian.utils.Operation;

import java.util.List;

/**
Expand All @@ -19,6 +21,11 @@ public interface ITreeExpression extends IVariable {
ITreeExpression setParenthesis();

Boolean getParenthesis();

Operation getOperation();

List<IVariable> getChildren();

int degree(IVariable variable);
int degree(List<IVariable> variables);
}
115 changes: 115 additions & 0 deletions src/test/java/pl/jagiellonian/TreeExpressionExpanderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package pl.jagiellonian;

import org.junit.Test;
import pl.jagiellonian.implementation.Expander;
import pl.jagiellonian.implementation.TreeExpression;
import pl.jagiellonian.implementation.Variable;
import pl.jagiellonian.interfaces.ITreeExpression;
import pl.jagiellonian.utils.Operation;

import static org.junit.Assert.assertEquals;

public class TreeExpressionExpanderTest {

@Test
public void twoComponentsTest() {
ITreeExpression tree = new TreeExpression(Operation.ADD, new Variable("1"));
tree = tree.mult("x");
tree = tree.sub("2");
ITreeExpression tree2 = new TreeExpression(Operation.ADD, new Variable("1"));
tree2 = tree2.mult("x");
tree2 = tree2.add("6");
tree = tree.mult(tree2);
Expander expander = new Expander();
String expected = "(1.0)*(x)^2+(4.0)*x+-12.0";

assertEquals(expected, expander.expand(tree).toString());
}

@Test
public void threeComponentsTest() {
ITreeExpression tree = new TreeExpression(Operation.ADD, new Variable("1"));
tree = tree.mult("x");
tree = tree.sub("2");
ITreeExpression tree2 = new TreeExpression(Operation.ADD, new Variable("1"));
tree2 = tree2.mult("x");
tree2 = tree2.add("6");
ITreeExpression tree3 = new TreeExpression(Operation.SUB, new Variable("6"));
tree3 = tree3.mult("x");
tree3 = tree3.sub("5");
tree = tree.mult(tree2);
tree = tree.mult(tree3);
Expander expander = new Expander();
String expected = "(6.0)*(x)^3+(19.0)*(x)^2+(-92.0)*x+60.0";

assertEquals(expected, expander.expand(tree).toString());
}

@Test
public void fourComponentsTest() {
ITreeExpression tree = new TreeExpression(Operation.ADD, new Variable("-6"));
tree = tree.mult("x");
tree = tree.sub("24");
ITreeExpression tree2 = new TreeExpression(Operation.ADD, new Variable("1"));
tree2 = tree2.mult("x");
tree2 = tree2.sub("10");
ITreeExpression tree3 = new TreeExpression(Operation.ADD, new Variable("6"));
tree3 = tree3.mult("x");
tree3 = tree3.sub("3");
ITreeExpression tree4 = new TreeExpression(Operation.ADD, new Variable("-2"));
tree4 = tree4.mult("x");
tree4 = tree4.sub("5");
tree = tree.mult(tree2);
tree = tree.mult(tree3);
tree = tree.mult(tree4);
Expander expander = new Expander();
String expected = "(72.0)*(x)^4+(-288.0)*(x)^3+(-3834.0)*(x)^2+(-5220.0)*x+3600.0";

assertEquals(expected, expander.expand(tree).toString());
}

@Test
public void multipleComponentsTest() {
ITreeExpression tree = new TreeExpression(Operation.ADD, new Variable("-1"));
tree = tree.mult("x");
tree = tree.add("6");
ITreeExpression tree2 = new TreeExpression(Operation.ADD, new Variable("-2"));
tree2 = tree2.mult("x");
tree2 = tree2.add("4");
ITreeExpression tree3 = new TreeExpression(Operation.ADD, new Variable("6"));
tree3 = tree3.mult("x");
tree3 = tree3.sub("13");
ITreeExpression tree4 = new TreeExpression(Operation.ADD, new Variable("-4"));
tree4 = tree4.mult("x");
tree4 = tree4.add("5");
ITreeExpression tree5 = new TreeExpression(Operation.ADD, new Variable("-3"));
tree5 = tree5.mult("x");
tree5 = tree5.sub("2");
ITreeExpression tree6 = new TreeExpression(Operation.ADD, new Variable("2"));
tree6 = tree6.mult("x");
tree6 = tree6.add("10");
ITreeExpression tree7 = new TreeExpression(Operation.ADD, new Variable("1"));
tree7 = tree7.mult("x");
tree7 = tree7.add("2");
ITreeExpression tree8 = new TreeExpression(Operation.ADD, new Variable("-5"));
tree8 = tree8.mult("x");
tree8 = tree8.sub("3");
ITreeExpression tree9 = new TreeExpression(Operation.ADD, new Variable("1"));
tree9 = tree9.mult("x");
tree9 = tree9.add("11");
tree = tree.mult(tree2);
tree = tree.mult(tree3);
tree = tree.mult(tree4);
tree = tree.mult(tree5);
tree = tree.mult(tree6);
tree = tree.mult(tree7);
tree = tree.mult(tree8);
tree = tree.mult(tree9);
Expander expander = new Expander();
String expected = "(-1440.0)*(x)^9+(-11304.0)*(x)^8+(97516.0)*(x)^7+(408068.0)*(x)^6" +
"+(-1491980.0)*(x)^5+(-1924636.0)*(x)^4+(5544544.0)*(x)^3+(2407712.0)*(x)^2+(-4178880.0)*x+-2059200.0";

assertEquals(expected, expander.expand(tree).toString());
}

}