crowlogic / arb4j

arb4j is a Java API for the arbitrary precision ball arithmetic library found at http://arblib.org
Other
1 stars 0 forks source link

quasipolynomial hypergeometric function support in expression compiler #409

Closed crowlogic closed 2 weeks ago

crowlogic commented 2 months ago

decompiled...

   try ( var hypergeometricPolynomial = new HypergeometricPolynomial(vℝ1.set(alpha),
                                                                      vℝ2.set(beta),
                                                                      RealPolynomialNullaryFunction.parse("0-(z^2)")))
    {
      return v.ascendingFactorial(in, bits, ℝ1)
              .mul(result.identity().div(cℤ1, bits, Xℝ1).pow(cℤ2.sub(in, bits, ℤ1), bits, Xℝ2), bits, Xℝ3)
              .mul(hypergeometricPolynomial.evaluate(null, 1, bits, result), bits, result);
    }

should be moved into a constant static field so as to remove the unnecessary parsing of the expression on each invocation of evaluate which is obviously not very efficient. it would be better to inline the hypergeometric expression code instead of relying on the use of HypergeometricPolynomial anyway

  public HypergeometricPolynomial(Real α,
                                  Real β,
                                  Expression<Object, RealPolynomial, RealPolynomialNullaryFunction> arg)
  {
    this.α  = α;
    this.β  = β;
    context = new Context(p = new Integer(α.dim,
                                          "p"),
                          q = new Integer(β.dim,
                                          "q"),
                          α.setName("α"),
                          β.setName("β"));

    context.registerVariable("N", N = new Integer());

    F = RealPolynomialNullaryFunction.parse("F", "Σn➔zⁿ*∏k➔α[k]₍ₙ₎{k=1…p}/(n!*∏k➔β[k]₍ₙ₎{k=1…q}){n=0…N}", context);

    F.substitute("z", arg);
  }
import arb.Initializable;
import arb.Integer;
import arb.Real;
import arb.RealPolynomial;
import arb.Typesettable;
import arb.functions.polynomials.HypergeometricPolynomial;
import arb.functions.sequences.RealPolynomialSequence;

public class testing implements
                     RealPolynomialSequence,
                     Typesettable,
                     AutoCloseable,
                     Initializable
{
  private boolean       isInitialized;
  Integer               cℤ2 = new Integer("0");
  Integer               cℤ1 = new Integer("2");
  Integer               cℤ3 = new Integer("1");
  Real                  cℝ4 = new Real("0.0",
                                       128);
  public Real           v;
  public RealPolynomial Xℝ2 = new RealPolynomial();
  public RealPolynomial Xℝ1 = new RealPolynomial();
  public Integer        ℤ1  = new Integer();
  public RealPolynomial Xℝ3 = new RealPolynomial();
  public Real           vℝ2 = new Real();
  public Real           vℝ1 = new Real();
  public Real           ℝ1  = new Real();
  public Real           ℝ2  = new Real();
  public Real           ℝ3  = new Real();
  public Real           ℝ4  = new Real();
  public Real           ℝ9  = new Real();
  public Real           ℝ5  = new Real();
  public Real           ℝ6  = new Real();
  public Real           ℝ7  = new Real();
  public Real           ℝ8  = new Real();

  public Class<RealPolynomial> rangeType()
  {
    return RealPolynomial.class;
  }

  public RealPolynomial evaluate(Integer in, int order, int bits, RealPolynomial result)
  {
    if (!isInitialized)
    {
      initialize();
    }

    Real[] alpha = new Real[]
    { cℤ3.div(cℤ1, bits, ℝ2).sub(in.div(cℤ1, bits, ℝ3), bits, ℝ4), cℤ2.sub(in.div(cℤ1, bits, ℝ5), bits, ℝ6) };

    Real[] beta  = new Real[]
    { v, cℤ2.sub(in, bits, ℝ7), cℤ3.sub(v, bits, ℝ8).sub(in, bits, ℝ9) };

    try ( var hypergeometricPolynomial = new HypergeometricPolynomial(vℝ1.set(alpha),
                                                                      vℝ2.set(beta),
                                                                      RealPolynomialNullaryFunction.parse("0-(z^2)")))
    {
      return v.ascendingFactorial(in, bits, ℝ1)
              .mul(result.identity().div(cℤ1, bits, Xℝ1).pow(cℤ2.sub(in, bits, ℤ1), bits, Xℝ2), bits, Xℝ3)
              .mul(hypergeometricPolynomial.evaluate(null, 1, bits, result), bits, result);
    }
  }

  public void initialize()
  {
    if (isInitialized)
    {
      throw new AssertionError("Already initialized");
    }
    else if (v == null)
    {
      throw new AssertionError("v is null");
    }
    else
    {
      isInitialized = true;
    }
  }

  @Override
  public void close()
  {
    cℤ2.close();
    cℤ1.close();
    cℤ3.close();
    cℝ4.close();
    Xℝ2.close();
    Xℝ1.close();
    ℤ1.close();
    Xℝ3.close();
    vℝ2.close();
    vℝ1.close();
    ℝ1.close();
    ℝ2.close();
    ℝ3.close();
    ℝ4.close();
    ℝ9.close();
    ℝ5.close();
    ℝ6.close();
    ℝ7.close();
    ℝ8.close();
  }

  @Override
  public String toString()
  {
    return "n➔v₍ₙ₎*(z/2)^(-n)*pFq([1/2-n/2,-n/2],[v,-n,1-v-n],-z^2)";
  }

  public String typeset()
  {
    return "{{(v)_{n}} \\cdot {{\\frac{z}{2}}^{0-n}}} \\cdot {pFq(0-{z}^{2})}";
  }
}
crowlogic commented 2 weeks ago

I just realized that the notion of quasi polynomial can be dropped altogether if the operations on the polynomial types are extended to taken to account the value of the remainder and the divisor that led to the remainder being attached to that particular polynomial value. Things carry and factor naturally therefore you don't have to deal with the proliferation of function compositions that you do if you're just generally ignoring the remainder and dealing with it in some other fashion

crowlogic commented 2 weeks ago

Proposal: Unified Polynomial Representation Including Remainders and Divisors for Rational Functions

Objective: Refine the expression parser to include a unified representation that integrates remainders and divisors into the polynomial structure, with a specific emphasis on handling rational functions, particularly Lommel polynomials.

Details:

Example: Considering this:

$${\text{polynomial: } 0, \text{remainder: } x^2, \text{divisor: } x^2}$$

Which reduces to

$${\text{polynomial: } 0, \text{remainder: } 1, \text{divisor: } x}$$

Now multiply by x

$${\text{polynomial: } 0, \text{remainder: } x, \text{divisor: } x}$$

Which reduces to

$${\text{polynomial: } 1, \text{remainder: } 0, \text{divisor: } 1}$$