Introduction to Mobius inversion (original) (raw)

Last Updated : 24 Mar, 2023

The Mobius inversion formula is a technique used in number theory to find the inverse of an arithmetic function. It is based on the Mobius function, which is a function that assigns a value of -1, 0, or 1 to each positive integer based on its prime factorization.

mobius inversion function

The basic idea behind Mobius Inversion is to express a given function f(n) as a linear combination of the Mobius function μ(n), which is defined as follows:

μ(n) = 1 if n is a square-free positive integer with an even number of prime factors
= -1 if n is a square-free positive integer with an odd number of prime factors
= 0 if n is not square-free

Formula Derivation:

The Möbius inversion formula states that for any arithmetic functions f(n) and g(n) such that

g(n) = Σ_{d|n} f(d)

where the sum is taken over all positive divisors d of n, the function f(n) can be recovered from g(n) via the following formula:

f(n) = Σ_{d|n} μ(d)g(n/d)

where μ(n) is the Möbius function, which is defined as:

μ(n) = 1 if n is a square-free number with an even number of prime factors -1 if n is a square-free number with an odd number of prime factors 0 if n is not square-free

To derive this formula, we start by multiplying both sides of the original equation by μ(n), and then summing over all positive integers n:

Σ_{n=1}∞ μ(n) g(n) = Σ_{n=1}∞ μ(n) Σ_{d | n} f(d)

Since both sides are equal, we can say:

Σ_{n=1}∞ μ(n) g(n) = Σ_{d=1}∞ f(d)
or
g(n) = Σ_{d|n} f(d)
f(n) = Σ_{d|n} μ(d)g(n/d)

which is the Möbius inversion formula.

Example:

Let's take an example to understand this better:

Example: Let's say we have a function f(n) = n. We want to find the inverse function h(n) of this function.

Step 1: We define g(n) = ∑f(d)μ(n/d) = ∑d*μ(n/d)
Step 2: We define h(n) = ∑g(d)μ(n/d) = ∑(∑d*μ(n/d))μ(n/d) = ∑dμ(d)

We can see that h(n) = 1 if n = 1, and h(n) = 0 for all other positive integers.

In programming, the most common way to implement Mobius Inversion is by precomputing the values of the Mobius function for all integers up to a certain limit and then using these precomputed values to quickly compute the inverse function of a given function.

Here is a step-by-step algorithm for Mobius Inversion in C++:

It's important to note that this is a basic example and the algorithm can be adjusted and optimized as needed depending on the specific problem you are trying to solve.

Here is an example of how to implement Mobius Inversion in C++

C++ `

// C++ code to implement the Mobius inversion

#include <bits/stdc++.h> using namespace std;

// Set the limit for precomputing the Mobius function const int N = 20; int mobius[N + 1];

// Function to precompute the Mobius function void precompute_mobius() { for (int i = 1; i <= N; i++) { mobius[i] = 1; } for (int i = 2; i <= N; i++) { if (mobius[i] == 1) { for (int j = i; j <= N; j += i) { if (j % (i * i) == 0) { mobius[j] = 0; } else { mobius[j] *= -1; } } } } }

// Function to compute the inverse // of a given function using Mobius Inversion int inverse_function(int n, int f[]) { int result = 0; for (int d = 1; d <= n; d++) { int g = 0; for (int i = 1; i <= n / d; i++) { g += f[i] * mobius[i]; } result += g * mobius[n / d]; } return result; }

// Driver Code int main() {

// Precompute the Mobius function
precompute_mobius();

// Example function
int f[N + 1] = {
    0, 1, 3, 0, 2, 10, 7, 0, 5, 0,
    0, 4, 0, 0, 0, 0, 8, 0, 0, 6
};

// Example value to compute inverse function
int n = 10;
int h = inverse_function(n, f);
cout << "The inverse of f(n) for n = " << n
     << " is: " << h << endl;
return 0;

}

Python3

Python code to implement the Mobius inversion

N = 20 mobius = [1] * (N + 1)

Function to precompute the Mobius function

def precompute_mobius(): for i in range(2, N + 1): if mobius[i] == 1: for j in range(i, N + 1, i): if j % (i * i) == 0: mobius[j] = 0 else: mobius[j] *= -1

Function to compute the inverse

of a given function using Mobius Inversion

def inverse_function(n, f): result = 0 for d in range(1, n + 1): g = 0 for i in range(1, n // d + 1): g += f[i] * mobius[i] result += g * mobius[n // d] return result

Precompute the Mobius function

if name == 'main':

precompute_mobius()

# Example function
f = [0, 1, 3, 0, 2, 10, 7, 0, 5, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 6]

# Example value to compute inverse function\
n = 10
h = inverse_function(n, f)
print("The inverse of f(n) for n = ", n, " is: ", h)

Java

import java.util.*;

public class MobiusInversion { // Set the limit for precomputing the Mobius function static final int N = 20; static int[] mobius = new int[N + 1];

// Function to precompute the Mobius function
public static void precomputeMobius()
{
    Arrays.fill(mobius, 1);
    for (int i = 2; i <= N; i++) {
        if (mobius[i] == 1) {
            for (int j = i; j <= N; j += i) {
                if (j % (i * i) == 0) {
                    mobius[j] = 0;
                }
                else {
                    mobius[j] *= -1;
                }
            }
        }
    }
}

// Function to compute the inverse
// of a given function using Mobius Inversion
public static int inverseFunction(int n, int[] f)
{
    int result = 0;
    for (int d = 1; d <= n; d++) {
        int g = 0;
        for (int i = 1; i <= n / d; i++) {
            g += f[i] * mobius[i];
        }
        result += g * mobius[n / d];
    }
    return result;
}

// Driver Code
public static void main(String[] args)
{
    // Precompute the Mobius function
    precomputeMobius();

    // Example function
    int[] f = {
        0, 1, 3, 0, 2, 10, 7, 0, 5, 0,
        0, 4, 0, 0, 0, 0, 8, 0, 0, 6
    };

    // Example value to compute inverse function
    int n = 10;
    int h = inverseFunction(n, f);
    System.out.println("The inverse of f(n) for n = " + n + " is: " + h);
}

}

C#

using System;

public class MobiusInversion { // Set the limit for precomputing the Mobius function static int N = 20; static int[] mobius = new int[N + 1];

// Function to precompute the Mobius function
public static void precomputeMobius()
{
    Array.Fill(mobius, 1);
    for (int i = 2; i <= N; i++) {
        if (mobius[i] == 1) {
            for (int j = i; j <= N; j += i) {
                if (j % (i * i) == 0) {
                    mobius[j] = 0;
                }
                else {
                    mobius[j] *= -1;
                }
            }
        }
    }
}

// Function to compute the inverse
// of a given function using Mobius Inversion
public static int inverseFunction(int n, int[] f)
{
    int result = 0;
    for (int d = 1; d <= n; d++) {
        int g = 0;
        for (int i = 1; i <= n / d; i++) {
            g += f[i] * mobius[i];
        }
        result += g * mobius[n / d];
    }
    return result;
}

// Driver Code
public static void Main(string[] args)
{
    // Precompute the Mobius function
    precomputeMobius();

    // Example function
    int[] f = { 0, 1, 3, 0, 2, 10, 7, 0, 5, 0,
                0, 4, 0, 0, 0, 0, 8, 0, 0, 6 };

    // Example value to compute inverse function
    int n = 10;
    int h = inverseFunction(n, f);
    Console.WriteLine("The inverse of f(n) for n = " + n
                      + " is: " + h);
}

}

` JavaScript ``

// JavaScript code to implement the Mobius inversion // Set the limit for precomputing the Mobius function const N = 20; const mobius = new Array(N + 1).fill(1);

// Function to precompute the Mobius function function precomputeMobius() { for (let i = 2; i <= N; i++) { if (mobius[i] == 1) { for (let j = i; j <= N; j += i) { if (j % (i * i) == 0) { mobius[j] = 0; } else { mobius[j] *= -1; } } } } }

// Function to compute the inverse // of a given function using Mobius Inversion function inverseFunction(n, f) { let result = 0; for (let d = 1; d <= n; d++) { let g = 0; let x = Math.floor(n/d); for (let i = 1; i <= x; i++) { g += f[i] * mobius[i]; } result += g * mobius[x]; } return result; }

// Precompute the Mobius function precomputeMobius();

// Example function const f = [ 0, 1, 3, 0, 2, 10, 7, 0, 5, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 6 ];

// Example value to compute inverse function const n = 10; const h = inverseFunction(n, f); console.log(The inverse of f(n) for n = <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>i</mi><mi>s</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">{n} is: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6595em;"></span><span class="mord"><span class="mord mathnormal">n</span></span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>{h});

``

Output

The inverse of f(n) for n = 10 is: 42

Code Breakdown:

In this example,

The output of the Mobius Inversion implementation in C++ will depend on the specific function that is provided as input. Without a specific definition for the function f(n) and an input value for n, it is impossible to determine the exact output of the function.

It's important to note that the output value of the inverse function is only guaranteed to be correct if the input function satisfies the condition that the sum of the function over all positive integers is equal to zero.

Complexity analysis:

The time and space complexity of the Mobius Inversion algorithm in C++ will depend on the specific implementation and the size of the input values.

In the example,