Dirichlet-Faltung

19

Die Dirichlet-Faltung ist eine spezielle Art der Faltung , die in der Zahlentheorie als sehr nützliches Werkzeug erscheint. Es arbeitet mit dem Satz von arithmetischen Funktionen .

Herausforderung

Wenn zwei arithmetische Funktionen f,g (dh Funktionen f,g:NR ) gegeben sind, berechnen Sie die Dirichlet-Faltung (fg):NR wie unten definiert.

Einzelheiten

  • Wir verwenden die Konvention 0N={1,2,3,} .
  • Die Dirichlet-Faltung fg zweier arithmetischer Funktionen f,g ist wiederum eine arithmetische Funktion und definiert als
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    (Beide Summen sind äquivalent. Der Ausdruckd|nbedeutetdNdividiertn, daher ist die Summation über den natürlichenTeilernvon n. Ebenso können wiri=ndN,j=dNund wir erhalten die zweite äquivalente Formulierung. Wenn Sie nicht an diese Notation gewöhnt sind, finden Sie im Folgenden ein schrittweises Beispiel.) Nur zur Erläuterung (dies ist für diese Herausforderung nicht direkt relevant): Die Definition stammt aus der Berechnung des Produkts derDirichlet-Reihe:
    (nNf(n)ns)(nNg(n)ns)=nN(fg)(n)ns
  • Die Eingabe erfolgt als zwei Blackbox-Funktionen . Alternativ können Sie auch eine unendliche Liste, einen Generator, einen Stream oder ähnliches verwenden, um eine unbegrenzte Anzahl von Werten zu erzeugen.
  • Es gibt zwei Ausgabemethoden: Entweder wird eine Funktion fg zurückgegeben, oder Sie können eine zusätzliche Eingabe nN und (fg)(n) direkt zurückgeben.
  • Der Einfachheit halber können Sie davon ausgehen, dass jedes Element von N zB mit einem positiven 32-Bit-Int dargestellt werden kann.
  • Der Einfachheit halber kann man auch davon ausgehen, dass jeder Eintrag R zB durch eine einzige reelle Gleitkommazahl dargestellt werden kann.

Beispiele

Definieren wir zunächst einige Funktionen. Beachten Sie, dass die Liste der Zahlen unter jeder Definition die ersten Werte dieser Funktion darstellt.

  • die multiplikative Identität ( A000007 )
    ϵ(n)={1n=10n>1
    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
  • die konstante Einheitsfunktion ( A000012 )
    1(n)=1n
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
  • die Identitätsfunktion ( A000027 )
    id(n)=nn
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
  • die Möbius-Funktion ( A008683 )
    μ(n)={(1)k if n is squarefree and k is the number of Primefactors of n0 otherwise 
    1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, ...
  • die Euler-Totientenfunktion ( A000010 )
    φ(n)=np|n(11p)
    1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, ...
  • die Liouville-Funktion ( A008836 )
    λ(n)=(1)k
    wobei k die Anzahl der Primfaktoren von n die mit der Multiplizität gezählt werden 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, ...
  • die Divisorsummenfunktion ( A000203 )
    σ(n)=d|nd
    1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, 24, 31, 18, 39, 20, ...
  • die Divisor-Zählfunktion ( A000005 )
    τ(n)=d|n1
    1, 2, 2, 3, 2, 4, 2, 4, 3, 4, 2, 6, 2, 4, 4, 5, 2, 6, 2, 6, 4, 4, 2, 8, ...
  • die charakteristische Funktion von Quadratzahlen ( A010052 )
    sq(n)={1 if n is a square number0otherwise
    1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ...

Dann haben wir folgende Beispiele:

  • ϵ=1μ
  • f=ϵff
  • ϵ=λ|μ|
  • σ=φτ
  • id=σμ undσ=id1
  • sq=λ1 and λ=μsq
  • τ=11 and 1=τμ
  • id=φ1 and φ=idμ

The last for are a consequence of the Möbius inversion: For any f,g the equation g=f1 is equivalent to f=gμ.

Step by Step Example

This is an example that is computed step by step for those not familiar with the notation used in the definition. Consider the functions f=μ and g=σ. We will now evaluate their convolution μσ at n=12. Their first few terms are listed in the table below.

ff(1)f(2)f(3)f(4)f(5)f(6)f(7)f(8)f(9)f(10)f(11)f(12)μ111011100110σ134761281513181228

The sum iterates over all natural numbers dN that divide n=12, thus d assumes all the natural divisors of n=12=223. These are d=1,2,3,4,6,12. In each summand, we evaluate g=σ at d and multiply it with f=μ evaluated at nd. Now we can conclude

(μσ)(12)=μ(12)σ(1)+μ(6)σ(2)+μ(4)σ(3)+μ(3)σ(4)+μ(2)σ(6)+μ(1)σ(12)=01+13+04+(1)7+(1)12+128=0+310712+28=12=id(12)

flawr
quelle

Antworten:

4

Lean, 108 100 95 78 75 bytes

def d(f g:_->int)(n):=(list.iota n).foldr(λd s,ite(n%d=0)(s+f d*g(n/d))s)0

Try it online!

More testcases with all of the functions.

Leaky Nun
quelle
is lambda really more expensive than four bytes for fun ?
Mario Carneiro
lambda is three bytes, I suppose
Leaky Nun
I think it's two in UTF8 (greek is pretty low unicode)
Mario Carneiro
You're right. I also golfed the import
Leaky Nun
I also used cond to save 5 bytes
Leaky Nun
4

Haskell, 46 bytes

(f!g)n=sum[f i*g(div n i)|i<-[1..n],mod n i<1]

Try it online!

Thanks to flawr for -6 bytes and a great challenge! And thanks to H.PWiz for another -6!

Mego
quelle
Simpler is shorter here
H.PWiz
@H.PWiz That's pretty clever - I didn't even think of doing it that way!
Mego
3

Python 3, 59 bytes

lambda f,g,n:sum(f(d)*g(n//d)for d in range(1,n+1)if 1>n%d)

Try it online!

Leaky Nun
quelle
Is // really needed instead of /?
Mr. Xcoder
/ would produce floats right?
Leaky Nun
Because d is a divisor of n by definition, the fractional part of n/d is zero, so there shouldn't be any issues with floating point arithmetic. Floats with fractional part zero are close enough to ints for Pythonic purposes, and the output of the function is a real number, so doing n/d instead of n//d should be fine.
Mego
3

Wolfram Language (Mathematica), 17 bytes

Of course Mathematica has a built-in. It also happens to know many of the example functions. I've included some working examples.

DirichletConvolve

Try it online!

Kelly Lowder
quelle
2

Add++, 51 bytes

D,g,@~,$z€¦~¦*
D,f,@@@,@b[VdF#B]dbRzGb]$dbL$@*z€g¦+

Try it online!

Takes two pre-defined functions as arguments, plus n, and outputs (fg)(n)

How it works

D,g,		; Define a helper function, $g
	@~,	; $g takes a single argument, an array, and splats that array to the stack
		; $g takes the argument e.g. [[τ(x) φ(x)] [3 4]]
		; STACK : 			[[τ(x) φ(x)] [3 4]]
	$z	; Swap and zip:			[[3 τ(x)] [4 φ(x)]]
	€¦~	; Reduce each by execution:	[[τ(3) φ(4)]]
	¦*	; Take the product and return:	τ(3)⋅φ(4) = 4

D,f,		; Define the main function, $f
	@@@,	; $f takes three arguments: φ(x), τ(x) and n (Let n = 12)
		; STACK:			[φ(x) τ(x) 12]
	@	; Reverse the stack:		[12 τ(x) φ(x)]
	b[V	; Pair and save:		[12]			Saved: [τ(x) φ(x)]
	dF#B]	; List of factors:		[[1 2 3 4 6 12]]
	dbR	; Copy and reverse:		[[1 2 3 4 6 12] [12 6 4 3 2 1]]
	z	; Zip together:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]]]
	Gb]	; Push Saved:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] [[τ(x) φ(x)]]]
	$dbL	; Number of dividors:		[[[τ(x) φ(x)]] [[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] 6]
	$@*	; Repeat:			[[[1 12] [2 6] [3 4] [4 3] [6 2] [12 1]] [[τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)] [τ(x) φ(x)]]]
	z	; Zip:				[[[τ(x) φ(x)] [1 12]] [[τ(x) φ(x)] [2 6]] [[τ(x) φ(x)] [3 4]] [[τ(x) φ(x)] [4 3]] [[τ(x) φ(x)] [6 2]] [[τ(x) φ(x)] [12 1]]]
	€g	; Run $g over each subarray:	[[4 4 4 6 4 6]]
	¦+	; Take the sum and return:	28
caird coinheringaahing
quelle
2

R, 58 bytes

function(n,f,g){for(i in (1:n)[!n%%1:n])F=F+f(i)*g(n/i)
F}

Try it online!

Takes n, f, and g. Luckily the numbers package has quite a few of the functions implemented already.

If vectorized versions were available, which is possible by wrapping each with Vectorize, then the following 45 byte version is possible:

R, 45 bytes

function(n,f,g,x=1:n,i=x[!n%%x])f(i)%*%g(n/i)

Try it online!

Giuseppe
quelle
1

Jelly, 9 bytes

ÆDṚÇ€ḋÑ€Ʋ

Try it online!

Line at the top is the main line of f, line at the bottom is the main line of g. n is passed as an argument to this function.

Erik the Outgolfer
quelle
1

Swift 4,  74 70  54 bytes

{n in(1...n).map{n%$0<1 ?f(n/$0)*g($0):0}.reduce(0,+)}

Try it online!

Mr. Xcoder
quelle
1

JavaScript (ES6), 47 bytes

Takes input as (f)(g)(n).

f=>g=>h=(n,d=n)=>d&&!(n%d)*f(n/d)*g(d)+h(n,d-1)

Try it online!

Examples

liouville =
n => (-1) ** (D = (n, k = 2) => k > n ? 0 : (n % k ? D(n, k + 1) : 1 + D(n / k, k)))(n)

mobius =
n => (M = (n, k = 1) => n % ++k ? k > n || M(n, k) : n / k % k && -M(n / k, k))(n)

sq =
n => +!((n ** 0.5) % 1)

identity =
n => 1

// sq = liouville * identity
console.log([...Array(25)].map((_, n) => F(liouville)(identity)(n + 1)))

// liouville = mobius * sq
console.log([...Array(20)].map((_, n) => F(mobius)(sq)(n + 1)))
Arnauld
quelle
1

APL (Dyalog Classic), 20 bytes

{(⍺⍺¨∘⌽+.×⍵⍵¨)∪⍵∨⍳⍵}

with ⎕IO←1

Try it online!

Easy to solve, hard to test - generally not my type of challenge. Yet, I enjoyed this one very much!

{ } defines a dyadic operator whose operands ⍺⍺ and ⍵⍵ are the two functions being convolved; is the numeric argument

∪⍵∨⍳⍵ are the divisors of in ascending order, i.e. unique () of the LCMs () of with all natural numbers up to it ()

⍵⍵¨ apply the right operand to each

⍺⍺¨∘⌽ apply the left operand to each in reverse

+.× inner product - multiply corresponding elements and sum


The same in ngn/apl looks better because of Unicode identifiers, but takes 2 additional bytes because of 1-indexing.

ngn
quelle
Pretty sure it takes 27 additional bytes in ngn/apl...
Erik the Outgolfer
1

C (gcc), 108 bytes

#define F float
F c(F(*f)(int),F(*g)(int),int n){F s=0;for(int d=0;d++<n;)if(n%d<1)s+=f(n/d)*g(d);return s;}

Straightforward implementation, shamelessly stolen from Leaky Nun's Python answer.

Ungolfed:

float c(float (*f)(int), float (*g)(int), int n) {
    float s = 0;
    for(int d = 1; d <= n;++d) {
        if(n % d == 0) {
            s += f(n / d) * g(d);
        }
    }
    return s;
}

Try it online!

joH1
quelle
1

F#, 72 bytes

let x f g n=Seq.filter(fun d->n%d=0){1..n}|>Seq.sumBy(fun d->f(n/d)*g d)

Takes the two functions f and g and a natural number n. Filters out the values of d that do not naturally divide into n. Then evaluates f(n/d) and g(d), multiples them together, and sums the results.

Ciaran_McCarthy
quelle
0

Pari/GP, 32 bytes

(f,g,n)->sumdiv(n,d,f(n/d)*g(d))

Try it online!

There is a built-in dirmul function, but it only supports finite sequences.

alephalpha
quelle