blob: 96ab37a0441abeb22f676a6c85acdf18f2c28cb6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.numbers.fraction;
import java.util.Locale;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* Tests for {@link ContinuedFraction}.
*/
class ContinuedFractionTest {
@Test
void testGoldenRatio() throws Exception {
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return 1;
}
@Override
public double getB(int n, double x) {
return 1;
}
};
final double eps = 1e-8;
double gr = cf.evaluate(0, eps);
Assertions.assertEquals(1.61803399, gr, eps);
}
@Test
void test415Over93() throws Exception {
// https://en.wikipedia.org/wiki/Continued_fraction
// 415 1
// --- = 4 + ---------
// 93 2 + 1
// -----
// 6 + 1
// -
// 7
// = [4; 2, 6, 7]
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return n <= 3 ? 1 : 0;
}
@Override
public double getB(int n, double x) {
switch (n) {
case 0: return 4;
case 1: return 2;
case 2: return 6;
case 3: return 7;
default: return 1;
}
}
};
final double eps = 1e-8;
double gr = cf.evaluate(0, eps, 5);
Assertions.assertEquals(415.0 / 93.0, gr, eps);
}
@Test
void testMaxIterationsThrows() throws Exception {
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return 1;
}
@Override
public double getB(int n, double x) {
return 1;
}
};
final double eps = 1e-8;
final int maxIterations = 3;
final Throwable t = Assertions.assertThrows(FractionException.class,
() -> cf.evaluate(0, eps, maxIterations));
assertExceptionMessageContains(t, "max");
}
@Test
void testNaNThrows() throws Exception {
// Create a NaN during the iteration
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return 1;
}
@Override
public double getB(int n, double x) {
return n == 0 ? 1 : Double.NaN;
}
};
final double eps = 1e-8;
final Throwable t = Assertions.assertThrows(FractionException.class,
() -> cf.evaluate(0, eps, 5));
assertExceptionMessageContains(t, "nan");
}
@Test
void testInfThrows() throws Exception {
// Create an infinity during the iteration:
// a / cPrev => a_1 / b_0 => Double.MAX_VALUE / 0.5
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return n == 0 ? 1 : Double.MAX_VALUE;
}
@Override
public double getB(int n, double x) {
return 0.5;
}
};
final double eps = 1e-8;
final Throwable t = Assertions.assertThrows(FractionException.class,
() -> cf.evaluate(0, eps, 5));
assertExceptionMessageContains(t, "infinity");
}
private static void assertExceptionMessageContains(Throwable t, String text) {
Assertions.assertTrue(t.getMessage().toLowerCase(Locale.ROOT).contains(text),
() -> "Missing '" + text + "' from exception message: " + t.getMessage());
}
// NUMBERS-46
@Test
void testOneIteration() {
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return 1;
}
@Override
public double getB(int n, double x) {
return 1;
}
};
final double eps = 10;
double gr = cf.evaluate(0, eps, 1);
Assertions.assertEquals(1.61, gr, eps);
}
// NUMBERS-46
@Test
void testTwoIterations() {
ContinuedFraction cf = new ContinuedFraction() {
@Override
public double getA(int n, double x) {
return 1;
}
@Override
public double getB(int n, double x) {
return 1;
}
};
final double eps = 0.5;
double gr = cf.evaluate(0, eps, 2);
Assertions.assertEquals(1.5, gr, 0d);
}
}