symja_android_library icon indicating copy to clipboard operation
symja_android_library copied to clipboard

[BUG] ContinuedFraction[30000000000000/53*Pi] returns wrong result

Open tranleduy2000 opened this issue 3 years ago • 5 comments

Input:

ContinuedFraction[30000000000000/53*Pi]

Latest version of Symja returns {𝟤𝟣𝟦𝟩𝟦𝟪𝟥𝟨𝟦𝟩,𝟢} which is wrong.

image

The correct answer should be:

image

tranleduy2000 avatar Jun 16 '22 18:06 tranleduy2000

Can you try this algorithm instead of ContinuedFraction#realToContinuedFraction() in NumberTheory.java

    private static IAST realToContinuedFraction(INum value, int iterationLimit, EvalEngine engine) {
      final double doubleValue = value.getRealPart();
      if (value.isNumIntValue()) {
        return F.list(F.ZZ((int) Math.rint(doubleValue)));
      }
      BigFraction bigFraction = new BigFraction(doubleValue);
      IRational rat = F.QQ(bigFraction);
      IASTAppendable continuedFractionList;
      if (rat.denominator().isOne()) {
        continuedFractionList = F.ListAlloc(1);
        continuedFractionList.append(rat.numerator());
      } else if (rat.numerator().isOne()) {
        continuedFractionList = F.ListAlloc(2);
        continuedFractionList.append(F.C0);
        continuedFractionList.append(rat.denominator());
      } else {
        IFraction temp = F.fraction(rat.numerator(), rat.denominator());
        IInteger quotient;
        IInteger remainder;
        continuedFractionList = F.ListAlloc(10);
        while (temp.denominator().compareInt(1) > 0 && (0 < iterationLimit--)) {
          quotient = temp.numerator().div(temp.denominator());
          remainder = temp.numerator().mod(temp.denominator());
          continuedFractionList.append(quotient);
          temp = F.fraction(temp.denominator(), remainder);
          if (temp.denominator().isOne()) {
            continuedFractionList.append(temp.numerator());
          }
          System.out.println(1 / temp.doubleValue());
          if (F.isZero(1 / temp.doubleValue(), Config.SPECIAL_FUNCTIONS_TOLERANCE)) {
            break;
          }
        }
      }
      return continuedFractionList;
    }

axkr avatar Jun 16 '22 20:06 axkr

I checked the function. There are some results:

ContinuedFraction[9.0/22]
={0,2,2,3,1}

=> It should be in simplified form {0,2,2,4}

ContinuedFraction[-Sin(7/17)]
= {0,1,1,2,175,1,2,4,5,3,1,1151,1,1,1,1,1,1,1,1,2,7,2,1,1,5,1,3,1,1,1,3,4,3}

=> It should be -[0; 2, 2, 175, 1, 2, 4, 5, 3, 1, 1153, 2, 1, 1, 4, 2, 1, 3, 2, 1, 1, 2, 1, 1, 6, 1, 1, 1, 1, ...]

ContinuedFraction[((219679)/(22))]
={9985,2,2,4,2498890062,1,9}

=> The correct result is [9985; 2, 2, 4]

tranleduy2000 avatar Jun 17 '22 14:06 tranleduy2000

Another case:

ContinuedFraction[ -19/10 ]
={-1,9,1}
=-1+1/(9 + 1/1)
=9/10

The correct result is

- [1; 1, 9]
=-1+1/(-1+1/-9)

tranleduy2000 avatar Jun 17 '22 14:06 tranleduy2000

I checked the function. There are some results:

ContinuedFraction[9.0/22]
={0,2,2,3,1}

Because of numeric calculations (in Java double format), you have to distinguish the numeric evaluation ContinuedFraction[9.0/22] from symbolic evaluation ContinuedFraction[9/22]

axkr avatar Jun 17 '22 16:06 axkr

I refactored realToContinuedFraction (sorry for bad commit) https://github.com/axkr/symja_android_library/blob/a8e38ff08767067b031ac1a4880da34e52109703/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/NumberTheory.java#L1097

axkr avatar Jun 19 '22 14:06 axkr