Skip to content

Commit

Permalink
derivatives in operator, choice of variable
Browse files Browse the repository at this point in the history
  • Loading branch information
Tran-Antoine committed Mar 21, 2019
1 parent 6e63527 commit 3f1c62b
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 61 deletions.
2 changes: 1 addition & 1 deletion src/main/java/net/akami/mask/operation/Divider.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected String operate(String a, String b) {
}
}
String divisionResult = String.join("", numMonomials);
LOGGER.info("++++ Result of division between {} and {} : {}", a, b, divisionResult);
LOGGER.info("Result of division between {} and {} : {}", a, b, divisionResult);
return divisionResult;
}

Expand Down
46 changes: 4 additions & 42 deletions src/main/java/net/akami/mask/operation/MaskOperator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.akami.mask.exception.MaskException;
import net.akami.mask.math.MaskExpression;
import net.akami.mask.tree.DerivativeTree;
import net.akami.mask.utils.ExpressionUtils;
import net.akami.mask.utils.MathUtils;
import net.akami.mask.utils.ReducerFactory;
Expand Down Expand Up @@ -143,56 +144,17 @@ public MaskOperator differentiate(MaskExpression out, char var, boolean setToOut

public MaskOperator differentiate(MaskExpression in, MaskExpression out, char var, boolean setToOut) {

String reducedExp = ReducerFactory.reduce(in.getExpression());

List<String> monomials = ExpressionUtils.toMonomials(reducedExp);

int index = 0;

for(String monomial : monomials) {
monomials.set(index, differentiateMonomial(monomial, var, index == 0));
index++;
}
String result = String.join("", monomials);
out.reload(result);
DerivativeTree tree = new DerivativeTree(in.getExpression(), var);
out.reload(tree.merge());

if(setToOut) {
this.mask = out;
}
return this;
}

private String differentiateMonomial(String monomial, char var, boolean firstMonomial) {

String foundVar = ExpressionUtils.toVariables(monomial);
String regex = "(?!"+var+")[a-zA-Z]*";

foundVar = foundVar.replaceAll(regex, "");

if(!foundVar.contains(String.valueOf(var))) {
return "";
}

if(foundVar.length() == 1) {
return monomial.replace(String.valueOf(var), "");
}

String exponent = foundVar.substring(2);

String powResult = MathUtils.subtract(exponent, "1");
String numericValue = monomial.replace(foundVar, "");
System.out.println("---> "+exponent+" / "+numericValue);
numericValue = MathUtils.mult(exponent, numericValue);

if(!(numericValue.startsWith("+") && numericValue.startsWith("-")) && !firstMonomial) {
numericValue = "+" + numericValue;
}

return numericValue + foundVar.charAt(0) + (powResult.equals("1") ? "" : "^" + powResult);
}

/**
* Call {@link MaskOperator#reduce(MaskExpression, MaskExpression)} with the mask specified in the last begin call as the out
* Calls {@link MaskOperator#reduce(MaskExpression, MaskExpression)} with the mask specified in the last begin call as the out
* parameter. See the method itself for further information.
* @return the operator itself for chaining
*/
Expand Down
13 changes: 6 additions & 7 deletions src/main/java/net/akami/mask/tree/DerivativeTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

import net.akami.mask.operation.sign.BinaryOperationSign;
import net.akami.mask.operation.sign.QuaternaryOperationSign;
import net.akami.mask.utils.ExpressionUtils;
import net.akami.mask.utils.FormatterFactory;
import net.akami.mask.utils.MathUtils;

import java.util.Optional;

public class DerivativeTree extends CalculationTree<DerivativeBranch> {

public DerivativeTree(String initial) {
private char var;

public DerivativeTree(String initial, char var) {
super(FormatterFactory.formatForCalculations(initial));
this.var = var;
}

@Override
Expand All @@ -37,13 +38,11 @@ protected void evalBranch(DerivativeBranch self) {
}

public String differentiateElement(String element) {
if(ExpressionUtils.isANumber(element))
return "0";

if(element.length() == 1)
if(element.equals(String.valueOf(var)))
return "1";

return MathUtils.diffPow(String.valueOf(element.charAt(0)), null, element.substring(2), null);
return "0";
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/net/akami/mask/core/MainTester.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.akami.mask.core;

import net.akami.mask.math.MaskExpression;
import net.akami.mask.operation.MaskOperator;
import net.akami.mask.utils.ReducerFactory;

import java.util.Scanner;
Expand All @@ -10,6 +12,8 @@ public static void main(String... args) {

Scanner sc = new Scanner(System.in);
String expression;
MaskExpression.TEMP.reload(sc.nextLine());
System.out.println(MaskOperator.begin(MaskExpression.TEMP).differentiate('x').asExpression());

System.out.println("Next expression to reduce : ");
while(!(expression = sc.nextLine()).isEmpty()) {
Expand Down
28 changes: 17 additions & 11 deletions src/test/java/net/akami/mask/tree/DerivativeTreeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,38 @@ public class DerivativeTreeTest {

@Test
public void simpleDerivatives() {
assertDerivative("2x", "2");
assertDerivative("x", "1");
assertDerivative("2x", "2", 'x');
assertDerivative("x", "1", 'x');
}

@Test
public void polynomialDerivatives() {
assertDerivative("1+2", "0");
assertDerivative("1+x", "1");
assertDerivative("x^2+2x+1", "2x+2");
assertDerivative("3x^3 + 6x^2 + 3x", "9x^2+12x+3");
assertDerivative("1+2", "0", 'x');
assertDerivative("1+x", "1", 'x');
assertDerivative("x^2+2x+1", "2x+2", 'x');
assertDerivative("3x^3 + 6x^2 + 3x", "9x^2+12x+3", 'x');
}

// TODO : fix the problem that 2*3 does not become 6 because they are not branches
@Test
public void powDerivatives() {
assertDerivative("(3x+3)^2", "2*(3x+3)*3");
assertDerivative("(x+3)^2", "2*(x+3)");
assertDerivative("(3x+3)^2", "2*(3x+3)*3", 'x');
assertDerivative("(x+3)^2", "2*(x+3)", 'x');
}

@Test
public void divisionDerivatives() {
assertDerivative("(5x^2+3x)/(4x+1)", "(20x^2+10x+3)/(4x+1)^2");
assertDerivative("(5x^2+3x)/(4x+1)", "(20x^2+10x+3)/(4x+1)^2", 'x');
}

public void assertDerivative(String a, String b) {
DerivativeTree tree = new DerivativeTree(a);
@Test
public void multiVariablesDerivatives() {
assertDerivative("5x", "0", 'y');
assertDerivative("5x+y", "1", 'y');
assertDerivative("5xy", "5x", 'y');
}
public void assertDerivative(String a, String b, char var) {
DerivativeTree tree = new DerivativeTree(a, var);
Assertions.assertThat(tree.merge()).isEqualTo(b);
}
}

0 comments on commit 3f1c62b

Please sign in to comment.