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

expr compiler: fix Fuction from Integer to RealPolynomial when it appears as a NaryOperations factor subexpression #367

Closed crowlogic closed 5 months ago

crowlogic commented 5 months ago
java.lang.AssertionError: cannot set indeterminant to z since expression input node is already set to n for expression=Expression[expression=n➔z^n*∏k➔α[k]₍ₙ₎{k=1…p}/(n!*∏k➔β[k]₍ₙ₎{k=1…q}),
                      className=factorP1,
                      functionName=factorP1, recursive=false, functionClass=interface arb.functions.Function] + from 
    at arb4j/arb.expressions.nodes.Variable.resolveReference(Variable.java:351)
    at arb4j/arb.expressions.nodes.Variable.<init>(Variable.java:133)
    at arb4j/arb.expressions.Expression.newVariable(Expression.java:1380)
    at arb4j/arb.expressions.Expression.resolveFunctionOrVariableReference(Expression.java:1633)
    at arb4j/arb.expressions.Expression.evaluate(Expression.java:741)
    at arb4j/arb.expressions.Expression.exponentiate(Expression.java:845)
    at arb4j/arb.expressions.Expression.exponentiateMultiplyAndDivide(Expression.java:884)
    at arb4j/arb.expressions.Expression.resolveArithmetic(Expression.java:1540)
    at arb4j/arb.expressions.Expression.parseRoot(Expression.java:1449)
    at arb4j/arb.expressions.Compiler.express(Compiler.java:143)
    at arb4j/arb.expressions.nodes.nary.NAryOperation.generateFactorClass(NAryOperation.java:356)
    at arb4j/arb.expressions.nodes.nary.NAryOperation.generate(NAryOperation.java:306)
    at arb4j/arb.expressions.Expression.generateEvaluationMethod(Expression.java:1030)
    at arb4j/arb.expressions.Expression.compile(Expression.java:532)
    at arb4j/arb.expressions.Compiler.express(Compiler.java:143)
    at arb4j/arb.expressions.Compiler.express(Compiler.java:157)
    at arb4j/arb.expressions.Compiler.express(Compiler.java:109)
    at arb4j/arb.expressions.Expression.compile(Expression.java:218)
    at arb4j/arb.expressions.Expression.instantiate(Expression.java:165)
    at arb4j/arb.functions.real.RealPolynomialNullaryFunction.express(RealPolynomialNullaryFunction.java:20)
    at arb4j/arb.functions.polynomials.HypergeometricPolynomial.<init>(HypergeometricPolynomial.java:53)
    at arb4j/arb.functions.polynomials.HypergeometricPolynomialTest.testSum(HypergeometricPolynomialTest.java:73)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at junit@4.13.2/junit.framework.TestCase.runTest(TestCase.java:177)
    at junit@4.13.2/junit.framework.TestCase.runBare(TestCase.java:142)
    at junit@4.13.2/junit.framework.TestResult$1.protect(TestResult.java:122)
    at junit@4.13.2/junit.framework.TestResult.runProtected(TestResult.java:142)
    at junit@4.13.2/junit.framework.TestResult.run(TestResult.java:125)
    at junit@4.13.2/junit.framework.TestCase.run(TestCase.java:130)
    at junit@4.13.2/junit.framework.TestSuite.runTest(TestSuite.java:241)
    at junit@4.13.2/junit.framework.TestSuite.run(TestSuite.java:236)
    at junit@4.13.2/org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:90)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:93)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
crowlogic commented 5 months ago

that rule was too strict

[crow@c17 20240324-05:44:14PM]~/a$ decompile factorℝ2.class
INFO:  JVM info: Oracle Corporation - 21.0.2 - 21.0.2+13-LTS-58
INFO:  Scanning classes from file factorℝ2.class
INFO:  Loading Class: factorℝ2 from file factorℝ2.class
INFO:  Preprocessing class factorℝ2
INFO:  ... done
INFO:  Decompiling class factorℝ2
INFO:  ... done
import arb.Integer;
import arb.Real;
import arb.RealPolynomial;
import arb.functions.Function;

public class factorℝ2 implements Function<Integer, Real> {
   private boolean isInitialized;
   public Integer n;
   public Integer p;
   public Integer q;
   public Real α;
   public Real β;
   public Integer N;

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

      return β.get(in).ascendingFactorial((result).identity(), bits, result);
   }

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

   public String toString() {
      return "factorℝ2:k➔β[k]₍ₙ₎";
   }
}
[crow@c17 20240324-05:45:29PM]~/a$ 

this should be using n as the second argumen to the ascending factorial instead of n is the independent variable of a polynomial.. most likely cause it ssees that its parent exxpression has a polynomial output but it forgot that it needs to output the scalar downcast type of the real polynomial which is real

crowlogic commented 5 months ago

cause of this

Summation.loadResultvariable( resultVariable= sumP1, generatedType=class arb.Real )
crowlogic commented 5 months ago

cool

java.lang.ClassCastException: class arb.Real cannot be cast to class arb.RealPolynomial (arb.Real and arb.RealPolynomial are in module arb4j@0.89 of loader 'app')
    at factorℝ1.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at factorP1.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at F.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomial.evaluate(HypergeometricPolynomial.java:73)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomial.evaluate(HypergeometricPolynomial.java:14)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomialTest.testSum(HypergeometricPolynomialTest.java:78)
    at 
crowlogic commented 5 months ago

N should not be propagated to factorR1 because it does not appear in that subexpression


package arb.functions.real;

import arb.Integer;
import arb.Real;
import arb.RealPolynomial;
import arb.functions.Function;

public class factorP1 implements
                      Function<Integer, RealPolynomial>
{
  private boolean       isInitialized;
  Integer               c1;
  public Integer        p;
  public Integer        q;
  public Real           α;
  public Real           β;
  public Integer        N;
  public RealPolynomial P1;
  public Real           valueℝ1;
  public Integer        k;
  public Real           prodℝ1;
  public Integer        endIndexℤ1;
  public RealPolynomial P2;
  public Integer        ℤ1;
  public Real           valueℝ2;
  public Real           prodℝ2;
  public Integer        endIndexℤ2;
  public Real           ℝ1;
  public final factorℝ2 factorℝ2 = new factorℝ2();
  public final factorℝ1 factorℝ1 = new factorℝ1();

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

    RealPolynomial var10000 = result.identity().pow(in, bits, P1);
    factorℝ1.n = in;
    prodℝ1.multiplicativeIdentity();
    k.set(c1);
    endIndexℤ1.set(p);

    do
    {
      prodℝ1.mul(factorℝ1.evaluate(k, bits, valueℝ1), bits);
    }
    while (k.increment().compareTo(endIndexℤ1) <= 0);

    var10000 = var10000.mul(prodℝ1, bits, P2);
    Integer var10001 = in.factorial(bits, ℤ1);
    factorℝ2.n = in;
    prodℝ2.multiplicativeIdentity();
    k.set(c1);
    endIndexℤ2.set(q);

    do
    {
      prodℝ2.mul(factorℝ2.evaluate(k, bits, valueℝ2), bits);
    }
    while (k.increment().compareTo(endIndexℤ2) <= 0);

    return var10000.div(var10001.mul(prodℝ2, bits, ℝ1), bits, result);
  }

  public factorP1()
  {
    c1         = new Integer("1");
    P1         = new RealPolynomial();
    valueℝ1    = new Real();
    k          = new Integer();
    prodℝ1     = new Real();
    endIndexℤ1 = new Integer();
    P2         = new RealPolynomial();
    ℤ1         = new Integer();
    valueℝ2    = new Real();
    prodℝ2     = new Real();
    endIndexℤ2 = new Integer();
    ℝ1         = new Real();
  }

  public void initialize()
  {
    if (isInitialized)
    {
      throw new AssertionError("Already initialized");
    }
    else if (p == null)
    {
      throw new AssertionError("p is null");
    }
    else if (q == null)
    {
      throw new AssertionError("q is null");
    }
    else
    {
      factorℝ2.p    = p;
      factorℝ2.q    = q;
      factorℝ2.α    = α;
      factorℝ2.β    = β;
     // factorℝ2.N    = N;
      factorℝ1.p    = p;
      factorℝ1.q    = q;
      factorℝ1.α    = α;
      factorℝ1.β    = β;
     // factorℝ1.N    = N;
      isInitialized = true;
    }
  }

  public void close()
  {
    c1.close();
    P1.close();
    valueℝ1.close();
    k.close();
    prodℝ1.close();
    endIndexℤ1.close();
    P2.close();
    ℤ1.close();
    valueℝ2.close();
    prodℝ2.close();
    endIndexℤ2.close();
    ℝ1.close();
  }

  public String toString()
  {
    return "factorP1:n➔z^n*∏k➔α[k]₍ₙ₎{k=1…p}/(n!*∏k➔β[k]₍ₙ₎{k=1…q})";
  }
}```
crowlogic commented 5 months ago
java.lang.ClassCastException: class arb.Real cannot be cast to class arb.RealPolynomial (arb.Real and arb.RealPolynomial are in module arb4j@0.89 of loader 'app')
    at factorℝ1.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at factorP1.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at F.evaluate(Unknown Source)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomial.evaluate(HypergeometricPolynomial.java:73)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomial.evaluate(HypergeometricPolynomial.java:14)
    at arb4j@0.89/arb.functions.Function.evaluate(Function.java:201)
    at arb4j@0.89/arb.functions.polynomials.HypergeometricPolynomialTest.testSum(HypergeometricPolynomialTest.java:78)
crowlogic commented 5 months ago

its due to this part  33: checkcast #26 // class arb/Real in factorℝ1

dentity:()Larb/RealPolynomial;
        30: iload_3
        31: aload         4
        33: checkcast     #26                 // class arb/Real
        36: invokevirtual #40                 // Method arb/Real.ascendingFactorial:(Larb/RealPolynomial;ILarb/Real;)Larb/Real;
        39: areturn
      StackMapTable: number_of_entries = 1
        frame_type = 11 /* same */
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
crowlogic commented 5 months ago

no it was the other one.. most likely in the indexed acccess generation code in the Variable class

        12: getfield      #22                 // Field α:Larb/Real;
        15: aload_1
        16: checkcast     #24                 // class arb/Integer
        19: invokevirtual #30                 // Method arb/Real.get:(Larb/Integer;)Larb/Real;
        22: aload         4
        24: checkcast     #32                 // class arb/RealPolynomial
        27: invokevirtual #36                 // Method arb/RealPolynomial.identity:()Larb/RealPolynomial;
        30: iload_3
        31: aload         4
        33: checkcast     #26                 // class arb/Real
        36: invokevirtual #40                 // Method arb/Real.ascendingFactorial:(Larb/RealPolynomial;ILarb/Real;)Larb/Real;
        39: areturn
crowlogic commented 5 months ago

there shouldnt be any RealPolynomial access in the factor expression of the product