Dual Numbers
Sehr interessantes Youtube über “Duale Zahlen”.
Musste ich als kleine Fingerübung natürlich auch probieren:
package ch.luschmar.math.dualnumber;
import java.math.BigDecimal;
import java.util.function.UnaryOperator;
/**
* @see <a href="https://www.youtube.com/watch?v=QwFLA5TrviI">Dual Number</a>
*/
public class DualNumber {
BigDecimal real;
BigDecimal dual;
public DualNumber(int real) {
this.real = new BigDecimal(real);
this.dual = BigDecimal.ZERO;
}
public DualNumber(BigDecimal real) {
this.real = real;
this.dual = BigDecimal.ZERO;
}
public DualNumber(BigDecimal real, BigDecimal dual) {
this.real = real;
this.dual = dual;
}
public DualNumber add(DualNumber other) {
return new DualNumber(
this.real.add(other.real),
this.dual.add(other.dual));
}
public DualNumber multiply(DualNumber other) {
return new DualNumber(
this.real.multiply(other.real),
this.dual.multiply(other.real).add(this.real.multiply(other.dual)));
}
public static DualNumber diff(UnaryOperator<DualNumber> diff, int value) {
return new DualNumber(
diff.apply(
new DualNumber(BigDecimal.valueOf(value),
BigDecimal.ONE)).dual
);
}
}
Natürlich darf dann auch nicht der Test dazu fehlen:
package ch.luschmar.math.dualnumber;
import org.junit.jupiter.api.Test;
import java.util.function.UnaryOperator;
import static ch.luschmar.math.dualnumber.DualNumber.diff;
import static org.junit.jupiter.api.Assertions.assertEquals;
class DualNumberTest {
@Test
void test_dual_number() {
// x^4 + x*3 + 5
UnaryOperator<DualNumber> myFunction = x -> {
var a = x.multiply(x.multiply(x.multiply(x)));
var b = x.multiply(new DualNumber(3));
var c = new DualNumber(5);
return a.add(b).add(c);
};
// try to solve x = 12; diff(x^4 + x*3 + 5)
var res = diff(myFunction, 12 );
// diff -> 4*x^3+3
// x = 12
assertEquals(6915, res.real.intValue());
}
}
Interessant finde ich die Anmerkung, dass genau solche Funktionen für ML gebraucht werden.