Skip to content

Commit

Permalink
root also is a nice AlgebraicIntOperator.
Browse files Browse the repository at this point in the history
  • Loading branch information
mihxil committed Oct 24, 2024
1 parent d169684 commit 1427734
Show file tree
Hide file tree
Showing 21 changed files with 152 additions and 31 deletions.
6 changes: 6 additions & 0 deletions README-source.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ The terminology which is adopted is this:
|equals | `=` | equals | equals | equality| object| `java.lang.Object`
|loosely equals | `≈` | eq | equals | equality| other element| link:{ghm}abstractalgebra/AlgebraicElement.java[`AlgebraicElement`]

7+^| integer operators
| root | '`√`' | root | root | root | root | link:{ghm}abstractalgebra/CompleteFieldElement.java[`CompleteFieldElement`]
| power | '^' | root | root | root | root | link:{ghm}abstractalgebra/CompleteFieldElement.java[`CompleteFieldElement`]
| tetration | '^' | root | root | root | root | | link:{ghm}abstractalgebra/CompleteFieldElement.java[`CompleteFieldElement`]



|===

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public S sqrt() {
);
}

@Override
public S root(int i) {
return pow(getStructure().one().dividedBy(i));
}

@Override
public S sin() {
return _of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.checkerframework.checker.nullness.qual.NonNull;
import org.meeuw.configuration.ConfigurationService;
import org.meeuw.math.BigDecimalUtils;
import org.meeuw.math.abstractalgebra.*;
import org.meeuw.math.abstractalgebra.rationalnumbers.RationalNumber;
import org.meeuw.math.exceptions.*;
Expand Down Expand Up @@ -86,6 +87,24 @@ public E pow(@Positive int n) {
}
}


public E tetration(int height) {
return with(_tetration(value, height));
}

static protected BigInteger _tetration(BigInteger v, int height) {
if (height < 0) {
throw new IllegalPowerException("Cannot tetrate with negative", BasicAlgebraicIntOperator.TETRATION.stringify(v.toString(), Integer.toString(height)));
}
if (height == 0) {
return BigInteger.ONE;
}
return BigDecimalUtils.pow(v,_tetration(v, height -1 ));
}




@Override
public long longValue() {
return value.longValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public IntegerElement dividedBy(IntegerElement divisor) {
}

/**
* The remainder of euclidean division of integers.
* The remainder of Euclidean division of integers.
* @param divisor integer divisor
* @return this % divisor
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public class Integers extends AbstractIntegers<IntegerElement, IntegerElement, I

static final NavigableSet<GenericFunction> FUNCTIONS = navigableSet(Ring.FUNCTIONS, MultiplicativeMonoid.FUNCTIONS, Group.FUNCTIONS, navigableSet(BasicFunction.ABS));

static final NavigableSet<AlgebraicIntOperator> INT_OPERATORS = navigableSet(BasicAlgebraicIntOperator.POWER, BasicAlgebraicIntOperator.TETRATION);


@Override
public NavigableSet<AlgebraicBinaryOperator> getSupportedOperators() {
return OPERATORS;
Expand All @@ -56,6 +59,11 @@ public NavigableSet<AlgebraicUnaryOperator> getSupportedUnaryOperators() {
return UNARY_OPERATORS;
}

@Override
public NavigableSet<AlgebraicIntOperator> getSupportedIntOperators() {
return INT_OPERATORS;
}

@Override
public NavigableSet<GenericFunction> getSupportedFunctions() {
return FUNCTIONS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ public BigDecimalElement sqrt() {
operations().sqrt(uncertainty).getValue().max(sqrt.getUncertainty())
);
}
@Override
public BigDecimalElement root(int i) {
UncertainNumber<BigDecimal> sqrt = operations().root(value, i);
return new BigDecimalElement(sqrt.getValue(),
operations().sqrt(uncertainty).getValue().max(sqrt.getUncertainty())
);
}

@Override
@NonAlgebraic(reason = NonAlgebraic.Reason.ELEMENTS, value = "Not possible for negative arguments")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ public RealNumber sqrt() {
return immutableInstanceOfPrimitives(Math.sqrt(value), max(uncertainty, DoubleUtils.uncertaintyForDouble(value)));
}

@Override
public RealNumber root(int root) {
return immutableInstanceOfPrimitives(Math.pow(value, 1d/root), max(uncertainty, DoubleUtils.uncertaintyForDouble(value)));
}

@Override
@NonAlgebraic(reason = NonAlgebraic.Reason.SOME)
public RealNumber pow(RealNumber exponent) throws IllegalPowerException, OverflowException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,25 @@ public void tetration() {

withLooseEquals(() -> {
BigComplexNumber i = BigComplexNumber.of( "i");
assertThat(i.tetrate(1)).isEqualTo(i);
assertThat(i.tetrate(2)).isEqualTo(
assertThat(i.tetration(1)).isEqualTo(i);
assertThat(i.tetration(2)).isEqualTo(
BigComplexNumber.of(".2078795763507619085469556198349787700338778416317696080751358830554198772854821397886002778654260353")
);
assertThat(i.tetrate(3)).isEqualTo(
assertThat(i.tetration(3)).isEqualTo(
BigComplexNumber.of("0.9471589980723783806534753520181933335039061339031493636713681179446929279300488084526262684626490224 + 0.3207644499793085346601168458748631401023670206812767998296571687407552221593630018130863397275275956i")
);
});


withLooseEquals(() -> {
BigComplexNumber mi = BigComplexNumber.of( "-i");
assertThat(mi.tetrate(2)).isEqualTo(
assertThat(mi.tetration(2)).isEqualTo(
BigComplexNumber.of(".2078795763507619085469556198349787700338778416317696080751358830554198772854821397886002778654260353")
);
assertThat(mi.tetrate(3)).isEqualTo(
assertThat(mi.tetration(3)).isEqualTo(
BigComplexNumber.of("0.9471589980723783806534753520181933335039061339031493636713681179446929279300488084526262684626490224 - 0.3207644499793085346601168458748631401023670206812767998296571687407552221593630018130863397275275956i")
);
assertThat(mi.tetrate(4)).isEqualTo(
assertThat(mi.tetration(4)).isEqualTo(
BigComplexNumber.of(".050092236109321075325057857667404946468201913766929482251191903794255108466570245223267516389354812588592387618207418313011412671583091915593513930380985112553213035843274365368782823138559170316757475 - 0.60211652703600378785675053054092402757580126795341617146912039064405965761446533166149876455748874894091972947073733788769473802085944138985142758564968985377506548603564612677376823835793273631198015i")
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,5 @@ public Arbitrary<IntegerElement> elements() {




}
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,19 @@ public void tetration() {

withLooseEquals(() -> {

assertThat(two.tetrate(2)).isEqualTo(of(4));
assertThat(two.tetrate(3)).isEqualTo(of(16));
assertThat(two.tetrate(4)).isEqualTo(of(65_536));
assertThat(two.tetrate(5)).isEqualTo(of("2.003529930406846464979072351560255750447825475569751419265016973710894059556311453089506130880933348E+19728"));
assertThat(two.tetration(2)).isEqualTo(of(4));
assertThat(two.tetration(3)).isEqualTo(of(16));
assertThat(two.tetration(4)).isEqualTo(of(65_536));
assertThat(two.tetration(5)).isEqualTo(of("2.003529930406846464979072351560255750447825475569751419265016973710894059556311453089506130880933348E+19728"));

});


BigDecimalElement three = of(3);

withLooseEquals(() -> {
assertThat(three.tetrate(2)).isEqualTo(of(27));
assertThat(three.tetrate(3)).isEqualTo(of("7625597484987"));
assertThat(three.tetration(2)).isEqualTo(of(27));
assertThat(three.tetration(3)).isEqualTo(of("7625597484987"));
});

}
Expand Down
25 changes: 23 additions & 2 deletions mihxil-math/src/main/java/org/meeuw/math/BigDecimalUtils.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.meeuw.math;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.*;

import org.meeuw.configuration.ConfigurationService;
import org.meeuw.math.exceptions.IllegalPowerException;
import org.meeuw.math.exceptions.OverflowException;
import org.meeuw.math.numbers.MathContextConfiguration;
import org.meeuw.math.text.TextUtils;

import static java.math.BigDecimal.*;
Expand Down Expand Up @@ -65,4 +67,23 @@ public static BigDecimal pow(BigDecimal base, long e, MathContext context) {
return result;
}

public static BigInteger pow(BigInteger base, BigInteger e) {
BigInteger result = BigInteger.ONE;
if (base.equals(BigInteger.ZERO)) {
if (e.signum() <= 0) {
throw new IllegalPowerException("Cannot raise to negative power", base + TextUtils.superscript(e.toString()));
}
return result;
}
// branching will make this slow
while (e.signum() > 0) {
result = result.multiply(base);
if (result.bitLength() > ConfigurationService.getConfigurationAspect(MathContextConfiguration.class).getMaxBits()) {
throw new OverflowException("Too big", base + TextUtils.superscript(e.toString()));
}
e = e.add(BigInteger.ONE.negate());
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import static org.meeuw.math.CollectionUtils.navigableSet;
import static org.meeuw.math.operators.BasicAlgebraicBinaryOperator.POWER;
import static org.meeuw.math.operators.BasicAlgebraicIntOperator.ROOT;
import static org.meeuw.math.operators.BasicAlgebraicIntOperator.TETRATION;
import static org.meeuw.math.operators.BasicAlgebraicUnaryOperator.*;

Expand All @@ -36,7 +37,7 @@ public interface CompleteField<E extends CompleteFieldElement<E>> extends Field<

NavigableSet<AlgebraicUnaryOperator> UNARY_OPERATORS = navigableSet(ScalarField.UNARY_OPERATORS, SQRT, SIN, COS, EXP, LN, SINH, COSH);

NavigableSet<AlgebraicIntOperator> INT_OPERATORS = navigableSet(MultiplicativeSemiGroup.INT_OPERATORS, TETRATION);
NavigableSet<AlgebraicIntOperator> INT_OPERATORS = navigableSet(MultiplicativeSemiGroup.INT_OPERATORS, ROOT, TETRATION);


E pi();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public interface CompleteFieldElement<E extends CompleteFieldElement<E>>

E sqrt();

E root(int i);

E sin();

E cos();
Expand All @@ -49,19 +51,15 @@ default E pow(E exponent) throws IllegalPowerException, OverflowException {
}
}

default E tetrate(int n) {
if (n < 0) {
throw new IllegalPowerException("Cannot tetrate with negative", BasicAlgebraicIntOperator.TETRATION.stringify(toString(), Integer.toString(n)));
default E tetration(int height) {
if (height < 0) {
throw new IllegalPowerException("Cannot tetrate with negative", BasicAlgebraicIntOperator.TETRATION.stringify(toString(), Integer.toString(height)));
}
if (n == 0) {
if (height == 0) {
return getStructure().one();
}
final E t = (E) this;
E e = t;
while (--n > 0) {
e = t.pow(e);
}
return e;
return t.pow(t.tetration(height -1 ));
}

E exp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ public UncertainNumber<BigDecimal> sqrt(BigDecimal radicand) {
}
}


@Override
public UncertainNumber<BigDecimal> root(BigDecimal radicand, int i) {
//return uncertain(radicand.sqrt(mathContext)); // java 9
try {
return uncertain(BigDecimalMath.root(radicand, BigDecimal.valueOf(i), context()));
} catch (ArithmeticException arithmeticException) {
throw new IllegalSqrtException(arithmeticException, radicand.toString());
}
}

@Override
public BigDecimal abs(BigDecimal v) {
return v.abs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,19 @@ public UncertainNumber<Double> sqrt(final Double radicand) {
}
double d = Math.sqrt(radicand);
if (Double.isNaN(d)) {
throw new IllegalSqrtException("Illegal sqrt result " + d, Double.toString(radicand));
throw new IllegalSqrtException("Illegal sqrt result " + d, Double.toString( radicand));
}
return uncertain(d);
}

@Override
public UncertainNumber<Double> root(final Double radicand, int i) {
if (Double.isNaN(radicand)) {
return uncertain(Double.NaN);
}
double d = Math.pow(radicand, 1d/i);
if (Double.isNaN(d)) {
throw new IllegalSqrtException("Illegal root result " + d, Double.toString(radicand));
}
return uncertain(d);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,21 @@ public static MathContextConfiguration get() {
@With
private final MathContext uncertaintyContext;


/**
*/
@Getter
@With
private final long maxBits;

public MathContextConfiguration() {
this( new MathContext(100), null);
this( new MathContext(100), null, 100_000);
}

public MathContextConfiguration(MathContext context, MathContext uncertaintyContext) {
public MathContextConfiguration(MathContext context, MathContext uncertaintyContext, long maxBits) {
this.context = context;
this.uncertaintyContext = uncertaintyContext == null ? DEFAULT_UNCERTAINTY_CONTEXT : uncertaintyContext;
this.maxBits = maxBits;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ static <N extends Number> NumberOperations<N> of(N n) {

UncertainNumber<N> sqrt(N radicand);

UncertainNumber<N> root(N radicand, int i);


N abs(N v);

UncertainNumber<N> reciprocal(N v);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ public enum BasicAlgebraicIntOperator implements AlgebraicIntOperator {
getDeclaredMethod(MultiplicativeSemiGroupElement.class, "pow", int.class),
(s, i) -> withBracketsIfNeeded(s) + TextUtils.superscript(i)
),
ROOT(
getDeclaredMethod(CompleteFieldElement.class, "root", int.class),
(s, i) -> TextUtils.superscript(i) + "√" + withBracketsIfNeeded(s)
),
TETRATION(
getDeclaredMethod(CompleteFieldElement.class, "tetrate", int.class),
getDeclaredMethod(CompleteFieldElement.class, "tetration", int.class),
(s, i) -> TextUtils.superscript(i) + withBracketsIfNeeded(s)
)

Expand Down Expand Up @@ -79,9 +83,11 @@ public <E extends AlgebraicElement<E>> E apply(E e, int i) {
try {
// It is possible that the operation is defined, but the class does not extend the correct class
// e.g. an odd integer implements negation, but it is not an additive group (negation is possible inside the algebra, but addition itself isn't).
return (E) e.getClass().getMethod(method.getName()).invoke(e);
return (E) e.getClass().getMethod(method.getName(), int.class).invoke(e, i);
} catch (NoSuchMethodException noSuchMethodError) {
throw new NoSuchOperatorException("No operation " + this + " found on " + e, noSuchMethodError);
} catch (InvocationTargetException ex) {
throw ex.getCause();
}
} catch (InvocationTargetException ex) {
throw ex.getCause();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
*/
public class UncertainDoubleFormatProvider extends AlgebraicElementFormatProvider<UncertainDoubleFormat> {

public UncertainDoubleFormatProvider() {

}

@Override
public UncertainDoubleFormat getInstance(Configuration configuration) {
UncertainDoubleFormat format = new UncertainDoubleFormat();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ public UncertainDoubleElement sqrt() {
return of(Math.sqrt(value), uncertainty);
}


@Override
public UncertainDoubleElement root(int i) {
return of(Math.pow(value, 1d/i), uncertainty);
}

@Override
public UncertainDoubleElement sin() {
UncertainNumber<Double> sin = operations().sin(value);
Expand Down
Loading

0 comments on commit 1427734

Please sign in to comment.