Konwolucja Dirichleta


20

Splot dirichleta to specjalny rodzaj splotu , który pojawia się jako bardzo użyteczne narzędzie w teorii liczb. Działa na zbiorze funkcji arytmetycznych .

Wyzwanie

Biorąc pod uwagę dwie funkcje arytmetyczne f,g (tj. Funkcje f,g:NR ), oblicz splot Dirichleta (fg):NR jak zdefiniowano poniżej.

Detale

  • Używamy konwencji 0N={1,2,3,} .
  • Splot Dirichleta fg dwóch funkcji arytmetycznych f,g jest ponownie funkcją arytmetyczną i jest zdefiniowany jako
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    (Obie sumy są równoważne. Wyrażenied|noznaczadNdzielin zatem sumowanie na naturalnychdzielnikówz n Podobnie można subsitute.i=ndN,j=dNi otrzymujemy drugi równoważny preparat. Jeśli nie jesteś przyzwyczajony do tej notacji, poniżej znajdziesz krok po kroku.) Tylko w celu rozwinięcia (nie ma to bezpośredniego związku z tym wyzwaniem): Definicja pochodzi z obliczenia iloczynuserii Dirichleta:
    (nNf(n)ns)(nNg(n)ns)=nN(fg)(n)ns
  • Dane wejściowe podano jako dwie funkcje czarnej skrzynki . Alternatywnie możesz również użyć nieskończonej listy, generatora, strumienia lub czegoś podobnego, co może wygenerować nieograniczoną liczbę wartości.
  • Istnieją dwie metody wyjściowe: albo funkcja fg jest zwracana, albo alternatywnie możesz wziąć dodatkowe wejście nN i zwrócić bezpośrednio (fg)(n) bezpośrednio.
  • Dla uproszczenia można założyć, że każdy element N może być reprezentowany np. Dodatnim 32-bitowym int.
  • Dla uproszczenia można również założyć, że każdy wpis R może być reprezentowany np. Przez jedną rzeczywistą liczbę zmiennoprzecinkową.

Przykłady

Najpierw zdefiniujmy kilka funkcji. Zauważ, że lista liczb pod każdą definicją reprezentuje kilka pierwszych wartości tej funkcji.

  • tożsamość multiplikatywna ( 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, ...
  • funkcja stałej jednostki ( 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, ...
  • funkcja tożsamości ( A000027 )
    id(n)=nn
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
  • funkcja Möbiusa ( 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, ...
  • funkcja sumy Eulera ( 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, ...
  • funkcja Liouville'a ( A008836 )
    λ(n)=(1)k
    gdziek jest liczbą czynników pierwszychn zliczonych 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, ...
  • funkcja sumy dzielników ( A000203 )
    σ(n)=d|nd
    1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, 24, 31, 18, 39, 20, ...
  • funkcja zliczania dzielników ( 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, ...
  • funkcja charakterystyczna liczb kwadratowych ( 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, ...

Następnie mamy następujące przykłady:

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

Ostatnie są konsekwencją inwersji Möbiusa : dla każdegof,g równanieg=f1 jest równoważnef=gμ .

Przykład krok po kroku

Jest to przykład obliczany krok po kroku dla tych, którzy nie znają notacji stosowanej w definicji. Rozważ funkcje f=μ i g=σ . Ocenimy teraz ich splot μσ przy n=12 . Ich kilka pierwszych terminów wymieniono w poniższej tabeli.

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

Suma iteruje się po wszystkich liczbach naturalnych dN które dzielą n=12 , a zatem d przyjmuje wszystkie naturalne dzielniki n=12=223 . Są to d=1,2,3,4,6,12 . W każdym podsumowaniu oceniamy g=σ punkcie d i mnożymy przez f=μ obliczone w punkciend . Teraz możemy podsumować

(μσ)(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)

Odpowiedzi:


5

Lean , 108 100 95 78 75 bajtów

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

Wypróbuj online!

Więcej przypadków testowych ze wszystkimi funkcjami.


czy lambda jest naprawdę droższa niż cztery bajty fun ?
Mario Carneiro,

lambda to trzy bajty, jak sądzę
Leaky Nun

Myślę, że jest dwa w UTF8 (grecki jest dość niskim unicode)
Mario Carneiro

Masz rację. Grałem również w golfa import
Leaky Nun

Zapisałem też cond5 bajtów
Leaky Nun

4

Haskell , 46 bajtów

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

Wypróbuj online!

Dzięki flawr dla -6 bajtów i wielkim wyzwaniem! I dzięki H.PWiz za kolejne -6!


Prostsze jest tutaj krótsze
H.PWiz

@ H.PWiz To całkiem sprytne - nawet nie pomyślałem o zrobieniu tego w ten sposób!
Mego

3

Python 3 , 59 bajtów

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

Wypróbuj online!


Czy //naprawdę jest potrzebny zamiast /?
Pan Xcoder,

/czy produkuje pływaki, prawda?
Leaky Nun

Ponieważ dz ndefinicji jest dzielnikiem , część ułamkowa n/dwynosi zero, więc nie powinno być żadnych problemów z arytmetyką zmiennoprzecinkową. Liczba zmiennoprzecinkowa z ułamkową częścią zerową jest wystarczająco zbliżona do liczb całkowitych dla celów Pythona, a wynikiem działania funkcji jest liczba rzeczywista, więc działanie n/dzamiast n//dpowinno być w porządku.
Mego


2

Dodaj ++ , 51 bajtów

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

Wypróbuj online!

Bierze dwie predefiniowane funkcje jako argumenty plus ni wyniki (fasol)(n)

Jak to działa

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

2

R , 58 bajtów

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

Wypróbuj online!

Trwa n, fi g. Na szczęście numberspakiet ma już zaimplementowanych kilka funkcji.

Jeśli dostępne były wersje wektoryzowane, co jest możliwe poprzez zawinięcie każdej z nich Vectorize, możliwa jest następująca 45-bajtowa wersja:

R , 45 bajtów

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

Wypróbuj online!


2

APL (Dyalog Classic) , 20 bajtów

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

z ⎕IO←1

Wypróbuj online!

Łatwy do rozwiązania, trudny do przetestowania - generalnie nie jest to mój typ wyzwania. Jednak bardzo mi się podobało!

{ }definiuje dynamiczny operator, którego argumenty ⍺⍺i ⍵⍵dwie funkcje są ze sobą powiązane; jest argumentem liczbowym

∪⍵∨⍳⍵są dzielnikami w porządku rosnącym, tj. niepowtarzalnym ( ) LCM ( ) dla wszystkich liczb naturalnych do niego ( )

⍵⍵¨ zastosować odpowiedni operand do każdego

⍺⍺¨∘⌽ zastosuj lewy operand do każdego w odwrotnej kolejności

+.× produkt wewnętrzny - pomnóż odpowiednie elementy i sumę


To samo w ngn / apl wygląda lepiej dzięki identyfikatorom Unicode, ale zajmuje 2 dodatkowe bajty z powodu 1-indeksowania.


Całkiem pewne, że zajmuje 27 dodatkowych bajtów w ngn / apl ...
Erik the Outgolfer



1

JavaScript (ES6), 47 bajtów

Pobiera dane wejściowe jako (f)(g)(n).

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

Wypróbuj online!

Przykłady

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)))

1

C (gcc) , 108 bajtów

#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;}

Prosta implementacja, bezwstydnie skradziona z odpowiedzi Pythona Leaky Nun .

Nie golfowany:

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;
}

Wypróbuj online!


1

F #, 72 bajty

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

Pobiera dwie funkcje fi gliczbę naturalną n. Odfiltrowuje wartości d, które nie dzielą się w naturalny sposób n. Następnie ocenia f(n/d) i g(d)mnoży je razem i sumuje wyniki.



0

APL (NARS), 47 znaków, 94 bajty

{(m⍵[1])×n⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}

gdzie m i n to funkcja, której należy użyć (ponieważ nie wiem, jak wywołać jedną tablicę funkcji w jednej funkcji w APL). Korzystając z powyższego przykładu, mnożenie funkcji Mobiusa (tutaj jest to 12π) i suma funkcji dzielników (tutaj jest 11π) dla wartości 12, to mnożenie byłoby:

  {(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}12
12

jeśli trzeba obliczyć inną wartość:

  {(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}1002
1002
  {(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}1001
1001
  {(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}20000x
20000 

Można zobaczyć, czy na przykład pierwszym numerem 2000 wynikiem funkcji jest tożsamość

  (⍳2000)≡{(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}¨⍳2000
1
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.