Home

Awesome

arb4j Overview

What is arb4j?

arb4j is a robust Java API designed to efficiently represent mathematical structures in their most general forms, prioritizing high performance. It seamlessly integrates with the arblib library via an interface generated by SWIG, enabling arbitrary precision real and complex ball arithmetic operations.

Features and Usage Patterns

Fluent Interface Pattern

Example:

Real x = new Real("25", 128); // 128 bits of precision

// Both lines achieve the same result:
Real five = x.sqrt(128);
Real five = x.sqrt(128, x); // Using 'this' as the result variable explicitly
Real five = x.sqrt(128, new Real());
Real y = new Real("25", 128)
            .add(RealConstants.one, 128)
            .log(128)
            .tanh(128);

Resource Management with AutoCloseable

Example:

try (Real x = new Real("25", 128)) {
    doSomething(x);
} // x is automatically closed, ensuring proper resource management

Advanced Tools

Expression Compiler

Expressor

The Expressor program provides a tree-list view that shows the abstract-syntex-tree that constitutes a given expression and the intermediate values that combine to produce a given result.

Screenshot from 2024-08-25 21-42-44

Error Messages Produced By Expression Parser
Example: unmatched paranthesis
arb.exceptions.CompilerException: unexpected ')'(0x29) character at position=11 in expression '(1/2)-(z/2))^n' of length 14, remaining=)^n

	at arb4j/arb.expressions.Expression.throwNewUnexpectedCharacterException(Expression.java:1933)
	at arb4j/arb.expressions.Expression.parseRoot(Expression.java:1586)
	at arb4j/arb.functions.Function.parse(Function.java:381)
	at arb4j/arb.expressions.Compiler.compile(Compiler.java:161)
	at arb4j/arb.expressions.Compiler.express(Compiler.java:246)
	at arb4j/arb.expressions.Compiler.express(Compiler.java:222)
	at arb4j/arb.expressions.Compiler.compile(Compiler.java:127)
	at arb4j/arb.functions.Function.instantiate(Function.java:413)
	at arb4j/arb.functions.Function.express(Function.java:159)
	at arb4j/arb.functions.sequences.RationalFunctionSequence.express(RationalFunctionSequence.java:35)
	at arb4j/arb.functions.sequences.RationalFunctionSequence.express(RationalFunctionSequence.java:25)
	at arb4j/arb.RationalFunctionTest.testPowers(RationalFunctionTest.java:49)

which was generated because of the buggy test

  public void testPowers()
  {
    try ( Integer n = Integer.named("n").set(0))
    {
      Context          context            = new Context(n);
      var              rationalFunctional = RationalFunctionSequence.express("(1/2)-(z/2))^n", context);
      RationalFunction expressed          = rationalFunctional.evaluate(n, 128, new RationalFunction());
      assertEquals("x", expressed.toString());
    }
  }
Easily Decompilable Code
Example: Chebyshev Polynomials of the First Kind

The unmodified decompiled code generated by the RealChebyshevPolynomialsOfTheFirstKind class

import arb.Initializable;
import arb.Integer;
import arb.RealPolynomial;
import arb.Typesettable;
import arb.functions.integer.RealPolynomialSequence;

public class T implements RealPolynomialSequence, Typesettable, AutoCloseable, Initializable {
   public boolean isInitialized;
   public final Integer cℤ2 = new Integer("1");
   public final Integer cℤ1 = new Integer("0");
   public final Integer cℤ3 = new Integer("2");
   public T T;
   public RealPolynomial Xℝ6 = new RealPolynomial();
   public RealPolynomial Xℝ5 = new RealPolynomial();
   public RealPolynomial Xℝ2 = new RealPolynomial();
   public RealPolynomial Xℝ1 = new RealPolynomial();
   public Integer ℤ1 = new Integer();
   public RealPolynomial Xℝ4 = new RealPolynomial();
   public Integer ℤ2 = new Integer();
   public RealPolynomial Xℝ3 = new RealPolynomial();

   @Override
   public Class<RealPolynomial> coDomainType() {
      return RealPolynomial.class;
   }

   @Override
   public RealPolynomial evaluate(Integer n, int order, int bits, RealPolynomial result) {
      if (!this.isInitialized) {
         this.initialize();
      }
      return switch(n.getSignedValue()) {
         case 0 -> result.set(this.Xℝ1.set(this.cℤ2));
         case 1 -> result.set(result.identity());
         default -> this.cℤ3
         .mul(this.Xℝ2.identity(), bits, this.Xℝ3)
         .mul((RealPolynomial)this.T.evaluate(n.sub(this.cℤ2, bits, this.ℤ1), order, bits, this.Xℝ4), bits, this.Xℝ5)
         .sub((RealPolynomial)this.T.evaluate(n.sub(this.cℤ3, bits, this.ℤ2), order, bits, this.Xℝ6), bits, result);
      };
   }

   @Override
   public void initialize() {
      if (this.isInitialized) {
         throw new AssertionError("Already initialized");
      } else {
         this.T = new T();
         this.isInitialized = true;
      }
   }

   @Override
   public void close() {
      this.cℤ2.close();
      this.cℤ1.close();
      this.cℤ3.close();
      this.Xℝ6.close();
      this.Xℝ5.close();
      this.Xℝ2.close();
      this.Xℝ1.close();
      this.ℤ1.close();
      this.Xℝ4.close();
      this.ℤ2.close();
      this.Xℝ3.close();
      this.T.close();
   }

   @Override
   public String toString() {
      return "T:n➔when(n=0,1,n=1,x,else,2*x*T(n-1)-T(n-2))";
   }

   @Override
   public String typeset() {
      return "1, x \text{otherwise} \\left(2 \\cdot x \\cdot \\T(\\left(n-1\\right))-\\T(\\left(n-2\\right))\\right)";
   }
}

(Symbolic, Compiled, Automatic) Differentiation and Integration

Forked modularized version of jlatexmath

See this for a version of jlatexmath without the unnamed module warnings

Licensing

arb4j is made available under the terms of the Business Source License™ v1.1 which can be found in the root directory of this project in a file named License.pdf, License.txt, or License.tm which are the pdf, text, and TeXmacs format of the same document respectively.