Skip to the content.

Aproximace ludolfova čísla

1. Úkol

Vytvořte celkem 2 funkce s jediným vstupním parametrem N, jejichž výstupem bude aproximace čísla π určená pomocí součtu prvních N prvků následujících posloupností:

Eulerova

$a_1 = 1, a_n = \frac{1}{n^2} \to \frac{n^2}{6} = \sum^{\infty}_{n=1}{a_n}$

double Euler(int n)
{
    double a1 = 1;
    double sum = a1;
    for (int i = 2; i < n; i++)
    {
        double ai = Math.Pow(i, -2);
        sum += ai;
    }

    // pi^2 / 6 = sum
    return Math.Sqrt(sum * 6);
}

Console.WriteLine("Euler for n = {1}: {0}", Euler(repetitions), repetitions);

Ludolfova

$a_1 = 1, a_n = \frac{(-1)^{n-1}}{2n-1} \to \frac{\pi}{4} = \sum^{\infty}_{n=1}{a_n}$

double Leibniz(int n)
{
    double a1 = 1;
    double sum = a1;

    for (int i = 2; i < n; i++)
    {
        double ai = Math.Pow(-1, i - 1) / (2 * i - 1);
        sum += ai;
    }

    // pi/4 = sum
    return sum * 4;
}

Console.WriteLine("Leibniz for n = {1}: {0}", Leibniz(repetitions), repetitions);

2. Úkol

Vytvořte funkci s jediným vstupním parametrem N, jejímž výstupem bude aproximace čísla π určená součinem prvních N členů následující rekurentní posloupností:

Viétova

$a_1 = \sqrt{\frac{1}{2}}, a_n = \sqrt{\frac{1}{2} + \frac{1}{2} \sqrt{a_{n-1}}} \to \frac{2}{\pi} = \prod_{n=1}^{\infty} a_n$

double Viete(int n)
{
    double a1 = Math.Sqrt(.5);

    double value = a1;
    
    // a_{n-1}
    double last = a1;
    for (int i = 2; i < n; i++)
    {
        double an = Math.Sqrt(.5 + .5 * Math.Sqrt(last));
        value *= an;
        last = an;
    }
    
    // 2 / pi = value => value * pi = 2 => pi = 2 / value
    return 2 / value;
}

Console.WriteLine("Viete for n = {1}: {0}", Viete(repetitions), repetitions);

3. Úkol

Vytvořte funkci, která seřadí tyto tři různé aproximace čísla π podle rychlosti jejich konvergence pro danou požadovanou přesnost. Jedná se o matematickou konvergenci, takže nejrychleji konverguje ta aproximace, která dosáhne požadované přesnosti pro nejmenší N.

// seřazení podle rychlosti konvergence
void RateOnConvergence(double accuracy)
{
    Console.WriteLine("Methods ordered by convergence speed for accuracy {0}:", accuracy);
    int maxRepetitions = repetitions;
    
    // ten list pak uchová i pořadí, můžeme ho vrátit
    // v této ukázce logujeme pořadí do konzole
    List<string> orderedMethods = [];
    
    for (int i = 1; i < maxRepetitions && orderedMethods.Count != 3; i++)
    {
        double distanceEuler = Math.Abs(Math.PI - Euler(i));
        double distanceLeibniz = Math.Abs(Math.PI - Leibniz(i));
        double distanceViete  = Math.Abs(Math.PI - Viete(i));
        
        if (distanceEuler < accuracy && !orderedMethods.Contains("Euler"))
        {
            orderedMethods.Add("Euler");
            Console.WriteLine("{0}. Euler", orderedMethods.Count);
        } else if (distanceLeibniz < accuracy && !orderedMethods.Contains("Leibniz"))
        {
            orderedMethods.Add("Leibniz");
            Console.WriteLine("{0}. Leibniz", orderedMethods.Count);
        } else if (distanceViete < accuracy && !orderedMethods.Contains("Viete"))
        {
            orderedMethods.Add("Viete");
            Console.WriteLine("{0}. Viete", orderedMethods.Count);
        }
    }
}

RateOnConvergence(0.2);