How to resolve the algorithm Bernoulli numbers step by step in the Elixir programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Bernoulli numbers step by step in the Elixir programming language

Table of Contents

Problem Statement

Bernoulli numbers are used in some series expansions of several functions   (trigonometric, hyperbolic, gamma, etc.),   and are extremely important in number theory and analysis. Note that there are two definitions of Bernoulli numbers;   this task will be using the modern usage   (as per   The National Institute of Standards and Technology convention). The   nth   Bernoulli number is expressed as   Bn.

The Akiyama–Tanigawa algorithm for the "second Bernoulli numbers" as taken from wikipedia is as follows:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Bernoulli numbers step by step in the Elixir programming language

Source code in the elixir programming language

defmodule Bernoulli do
  defmodule Rational do
    import Kernel, except: [div: 2]
    
    defstruct numerator: 0, denominator: 1
    
    def new(numerator, denominator\\1) do
      sign = if numerator * denominator < 0, do: -1, else: 1
      {numerator, denominator} = {abs(numerator), abs(denominator)}
      gcd = gcd(numerator, denominator)
      %Rational{numerator: sign * Kernel.div(numerator, gcd),
                denominator: Kernel.div(denominator, gcd)}
    end
    
    def sub(a, b) do
      new(a.numerator * b.denominator - b.numerator * a.denominator,
          a.denominator * b.denominator)
    end
    
    def mul(a, b) when is_integer(a) do
      new(a * b.numerator, b.denominator)
    end
    
    defp gcd(a,0), do: a
    defp gcd(a,b), do: gcd(b, rem(a,b))
  end
  
  def numbers(n) do
    Stream.transform(0..n, {}, fn m,acc ->
      acc = Tuple.append(acc, Rational.new(1,m+1))
      if m>0 do
        new = 
          Enum.reduce(m..1, acc, fn j,ar ->
            put_elem(ar, j-1, Rational.mul(j, Rational.sub(elem(ar,j-1), elem(ar,j))))
          end)
        {[elem(new,0)], new}
      else
        {[elem(acc,0)], acc}
      end
    end) |> Enum.to_list
  end
  
  def task(n \\ 61) do
    b_nums = numbers(n)
    width  = Enum.map(b_nums, fn b -> b.numerator |> to_string |> String.length end)
             |> Enum.max
    format = 'B(~2w) = ~#{width}w / ~w~n'
    Enum.with_index(b_nums)
    |> Enum.each(fn {b,i} ->
         if b.numerator != 0, do: :io.fwrite format, [i, b.numerator, b.denominator]
       end)
  end
end

Bernoulli.task


  

You may also check:How to resolve the algorithm Problem of Apollonius step by step in the Nim programming language
You may also check:How to resolve the algorithm Partition function P step by step in the PicoLisp programming language
You may also check:How to resolve the algorithm Barnsley fern step by step in the Frink programming language
You may also check:How to resolve the algorithm Exponentiation operator step by step in the Action! programming language
You may also check:How to resolve the algorithm Keyboard input/Flush the keyboard buffer step by step in the Phix programming language