Engee documentation
Notebook

The arithmetic derivative

This example demonstrates the implementation and use of the arithmetic derivative algorithm in the Julia programming language.

Introduction

The arithmetic derivative is an analogue of the usual derivative function from mathematical analysis, but applied to integers. It was proposed to study the properties of numbers in terms of differentiation, similar to how derivatives are applied to functions. Formally, for a natural number , is denoted by , and is defined as follows:

  • If – a prime number, then
  • If Then )

It allows you to apply intuition from differential calculus to numerical sequences and is used in solving some problems in number theory.

This code implements a recursive version of this definition using prime factorization.

Implementation of the arithmetic derivative function D(n)

To use the function of checking for simplicity and factoring, you need the package 'Primes'

In [ ]:
import Pkg; Pkg.add("Primes")

using Primes
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
function D(n)
    # Если число отрицательное, вызываем D(-n) и меняем знак результата
    n < 0 && return -D(-n)
    
    # Для 0 и 1 значение D всегда равно 0
    n < 2 && return zero(n)
    
    # Если число простое, то его производная равна 1
    isprime(n) && return one(n)

    # Если число составное, используем формулу:
    # D(n) = Σ (e_i * n / p_i), где p_i -- простые множители, e_i -- их степени в разложении
    return typeof(n)(sum(e * n ÷ p for (p, e) in eachfactor(n)))
end
Out[0]:
D (generic function with 1 method)

Function D(n) calculates the arithmetic derivative of a number n. Below is a detailed analysis of its implementation.:

  • Processing of negative numbers is implemented through recursion with a sign change.
  • The numbers 0 and 1 return 0, according to the definition.
  • For prime numbers, 1 is returned.
  • Decomposition is used for composite numbers eachfactor(n) — we get pairs (prime, exponent).
  • For each prime divisor with a degree indicator let's summarize ; the result is converted to the type of the input argument.

Thus, the function completely satisfies the formal definition of an arithmetic derivative.

Calculating the arithmetic derivative

Output of values for the range from -99 to 100 in formatted format

In [ ]:
foreach(p -> print(lpad(p[2], 5), p[1] % 10 == 0 ? "\n" : ""),
        pairs(map(D, -99:100)))
  -75  -77   -1 -272  -24  -49  -34  -96  -20 -123
   -1 -140  -32  -45  -22 -124   -1  -43 -108 -176
   -1  -71  -18  -80  -55  -39   -1 -156   -1  -59
  -26  -72   -1  -61  -18 -192  -51  -33   -1  -92
   -1  -31  -22  -92  -16  -81   -1  -56  -20  -45
  -14 -112   -1  -25  -39  -48   -1  -41   -1  -68
  -16  -21   -1  -60  -12  -19  -14  -80   -1  -31
   -1  -32  -27  -15  -10  -44   -1  -13  -10  -24
   -1  -21   -1  -32   -8   -9   -1  -16   -1   -7
   -6  -12   -1   -5   -1   -4   -1   -1    0    0
    0    1    1    4    1    5    1   12    6    7
    1   16    1    9    8   32    1   21    1   24
   10   13    1   44   10   15   27   32    1   31
    1   80   14   19   12   60    1   21   16   68
    1   41    1   48   39   25    1  112   14   45
   20   56    1   81   16   92   22   31    1   92
    1   33   51  192   18   61    1   72   26   59
    1  156    1   39   55   80   18   71    1  176
  108   43    1  124   22   45   32  140    1  123
   20   96   34   49   24  272    1   77   75  140

Here we calculate the arithmetic derivatives of all integers in the range from -99 to 100, displaying them in a human-readable form.

Team map(D, -99:100) builds an array of values for each number in the interval.

Function pairs(...) creates index => value pairs so that the row number can be tracked.

foreach(...) passes through these pairs and outputs each value p[2], formatted via lpad in a 5-character field. If the pair number is divisible by 10 (p[1] % 10 == 0), there is a transition to a new line \n.

This gives us a table showing the behavior in a short interval.

Derivation of derived powers of ten

The next block calculates and prints the values for from 1 to 20:

In [ ]:
for m in 1:20
    result = D(Int128(10)^m) ÷ 7  # Вычисление D(10^m), затем деление на 7
    println("D for 10^$(rpad(m, 3)) divided by 7 is $result")
end
D for 10^1   divided by 7 is 1
D for 10^2   divided by 7 is 20
D for 10^3   divided by 7 is 300
D for 10^4   divided by 7 is 4000
D for 10^5   divided by 7 is 50000
D for 10^6   divided by 7 is 600000
D for 10^7   divided by 7 is 7000000
D for 10^8   divided by 7 is 80000000
D for 10^9   divided by 7 is 900000000
D for 10^10  divided by 7 is 10000000000
D for 10^11  divided by 7 is 110000000000
D for 10^12  divided by 7 is 1200000000000
D for 10^13  divided by 7 is 13000000000000
D for 10^14  divided by 7 is 140000000000000
D for 10^15  divided by 7 is 1500000000000000
D for 10^16  divided by 7 is 16000000000000000
D for 10^17  divided by 7 is 170000000000000000
D for 10^18  divided by 7 is 1800000000000000000
D for 10^19  divided by 7 is 19000000000000000000
D for 10^20  divided by 7 is 200000000000000000000

Pay attention to:

  • Conversion to Int128: it is necessary because for large degrees of tens 10^m it is possible to go beyond the standard type Int.
  • Expression D(Int128(10)^m) calculates the arithmetic derivative of a number 10^m.
  • Integer division operation ÷ it is needed to get an integer for a beautiful output.

This part of the code shows how the behavior of the derivative changes for powers of ten.

Conclusion

We have reviewed the implementation and operation of the arithmetic derivative algorithm in the Julia language.

The implementation includes the function D(n) corresponding to the formal definition for integers. A table of derivative values was created for a small range of numbers, and the behavior of the derivative for powers of ten was analyzed. This approach can help in studying the properties of arithmetic derivatives, and also shows Julia's power in quickly working with numerical problems from number theory. The example demonstrates a combination of precision in mathematical definitions and efficient work with large numbers through the use of specialized packages (in this case — Primes). The practice of readable presentation of results and handling of extreme cases was also shown.

The example was developed using materials from Rosetta Code