How to resolve the algorithm Faulhaber's triangle step by step in the C programming language

Published on 7 June 2024 03:52 AM
#C

How to resolve the algorithm Faulhaber's triangle step by step in the C programming language

Table of Contents

Problem Statement

Named after Johann Faulhaber, the rows of Faulhaber's triangle are the coefficients of polynomials that represent sums of integer powers, which are extracted from Faulhaber's formula:

where

B

n

{\displaystyle B_{n}}

is the nth-Bernoulli number.

The first 5 rows of Faulhaber's triangle, are:

Using the third row of the triangle, we have:

k

1

n

k

2

=

1 6

n +

1 2

n

2

1 3

n

3

{\displaystyle \sum _{k=1}^{n}k^{2}={1 \over 6}n+{1 \over 2}n^{2}+{1 \over 3}n^{3}}

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Faulhaber's triangle step by step in the C programming language

The provided C code calculates and prints the Faulhaber polynomials for different values of the parameter p. Faulhaber's formula expresses a polynomial as a sum of terms, each containing a Bernoulli number. Bernoulli numbers are rational numbers that arise in number theory and combinatorics.

Here is a detailed explanation of the code:

  • Header Includes:

    • The code includes several standard C libraries:
      • <stdbool.h> for boolean data types.
      • <stdio.h> for input and output operations.
      • <stdlib.h> for standard library functions like malloc and free.
      • <string.h> for string manipulation functions like snprintf.
  • Function Declarations:

    • The code declares several functions, including:
      • binomial(int n, int k): Calculates the binomial coefficient n choose k.
      • gcd(int a, int b): Computes the greatest common divisor (GCD) of two integers a and b using the Euclidean algorithm.
      • makeFrac(int n, int d): Creates a fraction structure with numerator n and denominator d.
      • negateFrac(Frac f): Negates a fraction by inverting its numerator.
      • subFrac(Frac lhs, Frac rhs): Subtracts two fractions by multiplying the first by the second's denominator and vice versa, then subtracting the products.
      • multFrac(Frac lhs, Frac rhs): Multiplies two fractions by multiplying their numerators and denominators.
      • equalFrac(Frac lhs, Frac rhs): Compares two fractions for equality by checking if their numerators and denominators match.
      • lessFrac(Frac lhs, Frac rhs): Compares two fractions to determine if the first is less than the second in value.
      • printFrac(Frac f): Nicely prints a fraction, padding it with spaces if needed.
      • bernoulli(int n): Calculates the nth Bernoulli number using a recursive process.
      • faulhaber(int p): Calculates the Faulhaber polynomial coefficients for the given value of p.
      • main(): The entry point of the program.
  • binomial Function:

    • This function calculates the binomial coefficient n choose k using a simple loop-based approach.
  • gcd Function:

    • This function computes the GCD of two integers using the Euclidean algorithm.
  • makeFrac, negateFrac, subFrac, multFrac, equalFrac, lessFrac, printFrac Functions:

    • These functions perform various operations on fractions represented as structures with num (numerator) and denom (denominator) members.
  • bernoulli Function:

    • This function calculates the nth Bernoulli number using a recursive process.
  • faulhaber Function:

    • This is the main function that calculates the coefficients of the Faulhaber polynomial for a given value of p.
    • It iterates from 0 to p, calculating each coefficient using a formula involving binomial coefficients and Bernoulli numbers.
    • The coefficients are then printed as fractions, separated by spaces.
  • main Function:

    • In main, the code calls faulhaber with values of p ranging from 0 to 9 to compute and print the coefficients for the corresponding Faulhaber polynomials.

Source code in the c programming language

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int binomial(int n, int k) {
    int num, denom, i;

    if (n < 0 || k < 0 || n < k) return -1;
    if (n == 0 || k == 0) return 1;

    num = 1;
    for (i = k + 1; i <= n; ++i) {
        num = num * i;
    }

    denom = 1;
    for (i = 2; i <= n - k; ++i) {
        denom *= i;
    }

    return num / denom;
}

int gcd(int a, int b) {
    int temp;
    while (b != 0) {
        temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

typedef struct tFrac {
    int num, denom;
} Frac;

Frac makeFrac(int n, int d) {
    Frac result;
    int g;

    if (d == 0) {
        result.num = 0;
        result.denom = 0;
        return result;
    }

    if (n == 0) {
        d = 1;
    } else if (d < 0) {
        n = -n;
        d = -d;
    }

    g = abs(gcd(n, d));
    if (g > 1) {
        n = n / g;
        d = d / g;
    }

    result.num = n;
    result.denom = d;
    return result;
}

Frac negateFrac(Frac f) {
    return makeFrac(-f.num, f.denom);
}

Frac subFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom);
}

Frac multFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.num, lhs.denom * rhs.denom);
}

bool equalFrac(Frac lhs, Frac rhs) {
    return (lhs.num == rhs.num) && (lhs.denom == rhs.denom);
}

bool lessFrac(Frac lhs, Frac rhs) {
    return (lhs.num * rhs.denom) < (rhs.num * lhs.denom);
}

void printFrac(Frac f) {
    char buffer[7];
    int len;

    if (f.denom != 1) {
        snprintf(buffer, 7, "%d/%d", f.num, f.denom);
    } else {
        snprintf(buffer, 7, "%d", f.num);
    }

    len = 7 - strlen(buffer);
    while (len-- > 0) {
        putc(' ', stdout);
    }

    printf(buffer);
}

Frac bernoulli(int n) {
    Frac a[16];
    int j, m;

    if (n < 0) {
        a[0].num = 0;
        a[0].denom = 0;
        return a[0];
    }

    for (m = 0; m <= n; ++m) {
        a[m] = makeFrac(1, m + 1);
        for (j = m; j >= 1; --j) {
            a[j - 1] = multFrac(subFrac(a[j - 1], a[j]), makeFrac(j, 1));
        }
    }

    if (n != 1) {
        return a[0];
    }

    return negateFrac(a[0]);
}

void faulhaber(int p) {
    Frac q, *coeffs;
    int j, sign;

    coeffs = malloc(sizeof(Frac)*(p + 1));

    q = makeFrac(1, p + 1);
    sign = -1;
    for (j = 0; j <= p; ++j) {
        sign = -1 * sign;
        coeffs[p - j] = multFrac(multFrac(multFrac(q, makeFrac(sign, 1)), makeFrac(binomial(p + 1, j), 1)), bernoulli(j));
    }

    for (j = 0; j <= p; ++j) {
        printFrac(coeffs[j]);
    }
    printf("\n");

    free(coeffs);
}

int main() {
    int i;

    for (i = 0; i < 10; ++i) {
        faulhaber(i);
    }

    return 0;
}


  

You may also check:How to resolve the algorithm User input/Text step by step in the AWK programming language
You may also check:How to resolve the algorithm Deepcopy step by step in the Raku programming language
You may also check:How to resolve the algorithm Enumerations step by step in the Scheme programming language
You may also check:How to resolve the algorithm Lah numbers step by step in the ALGOL W programming language
You may also check:How to resolve the algorithm 99 bottles of beer step by step in the ooRexx programming language