Do for every natural number $n$ exist (possibly negative) integers $a_p$, finitely many of them nonzero, such that $$\log(n) = \sum_{p \text{ prime}} a_p \log(p-1)\,?$$ Equivalently: $$n = \prod_{p \text{ prime}} (p-1)^{a_p}.$$
Comment: This would follow from the hypothesis underlying this answer by GH from MO to Given a prime $p$ and by Dirichlet a prime $q = k\cdot p+1$ — minimal of this form — does the number $k = (q-1)/p$ have only prime divisors $<p$? by induction on $n$.
This representation would be unique, if we allow only linearly independent primes in the summation: Linear independent prime numbers?
Examples:
############################################################
# SageMath script:
# Recursive representation of log(n) as
#
# log(n) = sum_{q} a_q * log(q-1)
#
# where the primes q arise recursively as the smallest
# primes of the form q = k*p + 1 (Dirichlet-style),
# and are linearly independent in the sense of your construction.
#
# Author : me & ChatGPT (recursive version)
############################################################
from sage.all import (
ZZ, factor, is_prime
)
############################################################
# Global storage:
# rep[n] : dict {q : a_q} representing
# log n = sum_q a_q * log(q-1)
# LI_primes: set of "basis primes" q that appear as q = k*p+1
############################################################
rep = {} # n -> {q : a_q}
LI_primes = set() # primes q introduced as "basis" symbols
def _add_coeffs_inplace(target, source, factor=1):
"""
In-place: target[q] += factor * source[q].
Remove entries that become zero.
"""
for q, a in source.items():
new_val = target.get(q, 0) + factor * a
if new_val == 0:
if q in target:
del target[q]
else:
target[q] = new_val
return target
############################################################
# Recursive representation of log(n)
############################################################
def repr_log(n):
"""
Return a dictionary {q : a_q} such that
log(n) = sum_q a_q * log(q-1),
where the summation is over primes q produced
recursively by the procedure below.
The representation is unique (given this recursive
construction) once it exists.
"""
n = ZZ(n)
if n <= 0:
raise ValueError("n must be a positive integer.")
# already computed?
if n in rep:
return rep[n]
# base case: n = 1
if n == 1:
rep[n] = {}
return rep[n]
# if n is prime: use the special recursion with q = k*p+1
if is_prime(n):
return _repr_log_prime(n)
# otherwise: factor n and use log(n) = sum e_i * log(p_i)
coeffs = {}
for p, e in factor(n):
p = ZZ(p)
cp = repr_log(p) # representation for the prime p
for _ in range(e):
_add_coeffs_inplace(coeffs, cp, factor=1)
rep[n] = coeffs
return coeffs
def _repr_log_prime(p):
"""
Internal: representation of log(p) for p prime using the rule:
choose minimal k >= 1 such that q = k*p + 1 is prime,
then log(p) = log(q-1) - log(k),
and log(k) is expressed recursively (k < p).
"""
p = ZZ(p)
if p in rep:
return rep[p]
# Find minimal k such that q = k*p + 1 is prime
found = False
for k in range(1, int(p) + 1):
q = k * p + 1
if is_prime(q):
found = True
k = ZZ(k)
q = ZZ(q)
break
if not found:
raise ValueError(f"No prime of the form q = k*p + 1 found for p = {p} with k <= p.")
# q is a new (or reused) "basis prime"
LI_primes.add(q)
# log(p) = log(q-1) - log(k)
# => coefficients: {q: 1} - repr_log(k)
coeffs = {q: 1}
if k > 1:
coeffs_k = repr_log(k) # representation of log(k)
_add_coeffs_inplace(coeffs, coeffs_k, factor=-1)
rep[p] = coeffs
return coeffs
############################################################
# Pretty-printing
############################################################
def print_log_identity(n):
"""
Pretty-print the identity:
log(n) = sum_{q} a_q * log(q-1),
with primes q produced by the recursive construction.
"""
coeffs = repr_log(n)
# Build RHS as a string
terms = []
for q in sorted(coeffs.keys()):
a_q = coeffs[q]
if a_q == 1:
terms.append(f"log({q}-1)")
elif a_q == -1:
terms.append(f"-log({q}-1)")
else:
terms.append(f"{a_q}*log({q}-1)")
if not terms:
rhs = "0"
else:
rhs = terms[0]
for t in terms[1:]:
# if it starts with "-", write " - ..." otherwise " + ..."
if t.startswith("-"):
rhs += " " + t
else:
rhs += " + " + t
print(f"log({n}) = {rhs}")
def show_LI_primes():
"""
Print the list of recursively generated 'LI primes' q
(i.e. those that appear as q = k*p+1).
"""
print("Recursively generated LI primes q (basis primes):")
print(sorted(LI_primes))
############################################################
# Example usage in Sage:
#
# for p in primes(2, 50):
# print_log_identity(p)
#
# print_log_identity(60)
# show_LI_primes()
############################################################
for n in range(1,34):
print_log_identity(n)
log(1) = log(2-1)
log(2) = log(3-1)
log(3) = -log(3-1) + log(7-1)
log(4) = 2*log(3-1)
log(5) = -log(3-1) + log(11-1)
log(6) = log(7-1)
log(7) = -2*log(3-1) + log(29-1)
log(8) = 3*log(3-1)
log(9) = -2*log(3-1) + 2*log(7-1)
log(10) = log(11-1)
log(11) = -log(3-1) + log(23-1)
log(12) = log(3-1) + log(7-1)
log(13) = -2*log(3-1) + log(53-1)
log(14) = -log(3-1) + log(29-1)
log(15) = -2*log(3-1) + log(7-1) + log(11-1)
log(16) = 4*log(3-1)
log(17) = -log(7-1) + log(103-1)
log(18) = -log(3-1) + 2*log(7-1)
log(19) = -log(11-1) + log(191-1)
log(20) = log(3-1) + log(11-1)
log(21) = -3*log(3-1) + log(7-1) + log(29-1)
log(22) = log(23-1)
log(23) = -log(3-1) + log(47-1)
log(24) = 2*log(3-1) + log(7-1)
log(25) = -2*log(3-1) + 2*log(11-1)
log(26) = -log(3-1) + log(53-1)
log(27) = -3*log(3-1) + 3*log(7-1)
log(28) = log(29-1)
log(29) = -log(3-1) + log(59-1)
log(30) = -log(3-1) + log(7-1) + log(11-1)
log(31) = -log(11-1) + log(311-1)
log(32) = 5*log(3-1)
log(33) = -2*log(3-1) + log(7-1) + log(23-1)