Dirichlet Konvolüsyonu


20

Dirichlet konvolüsyon özel bir tür olan kıvrım sayısı teorik olarak çok faydalı bir araç olarak görünür. Aritmetik fonksiyonlar kümesi üzerinde çalışır .

Meydan okuma

Verilen iki aritmetik fonksiyon (yani ), Dirichlet evrişimini aşağıda tanımlandığı gibi hesaplar .f,gf,g:NR ( f g ) : NR (fg):NR

ayrıntılar

  • kuralını kullanıyoruz .0N={1,2,3,}
  • İki aritmetik fonksiyonun Dirichlet evrişliği , yine aritmetik bir fonksiyondur ve. (Hem toplamları ifade eşdeğer aracı bölme , bu nedenle toplam doğal üzerinde bölenler arasında . Aynı şekilde biz subsitute olabilirfgf,g
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    d|ndNnni=nni=ndN,j=dN(n N f(n)ve ikinci eşdeğer formülasyonu elde ediyoruz. Bu gösterime alışkın değilseniz, aşağıdaki adım adım bir örnek vardır.) Sadece ayrıntılandırmak için (bu doğrudan bu meydan okuma ile ilgili değildir): Tanım, Dirichlet serisinin ürününün hesaplanmasından gelir :
    (nNf(n)ns)(nNg(n)ns)=nN(fg)(n)ns
  • Giriş iki kara kutu işlevi olarak verilir . Alternatif olarak, sınırsız sayıda değer üretebilecek sonsuz bir liste, bir jeneratör, bir akış veya benzeri bir şey de kullanabilirsiniz.
  • İki çıkış yöntemi vardır: ya işlevi döndürülür ya da alternatif olarak ek bir girişi alabilir ve doğrudan döndürebilirsiniz .fgnN(fg)(n)
  • Basit olması için, her öğesinin, örneğin pozitif bir 32 bit int ile temsil edilebileceğini varsayabilirsiniz .N
  • Basitlik açısından, her bir girişinin örneğin tek bir gerçek kayan nokta numarası ile temsil edilebileceğini varsayabilirsiniz .R

Örnekler

Önce birkaç işlevi tanımlayalım. Her tanımın altındaki sayı listesinin bu işlevin ilk birkaç değerini temsil ettiğini unutmayın.

  • çarpımsal kimlik ( 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, ...
  • sabit birim işlevi ( 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, ...
  • kimlik fonksiyonu ( A000027 )
    id(n)=nn
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
  • Möbius işlevi ( 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, ...
  • Euler totient işlevi ( 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, ...
  • Liouville işlevi ( A008836 ) ; burada , çokluk ile sayılan temel faktörlerinin sayısıdır
    λ(n)=(1)k
    kn1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, ...
  • bölen toplamı işlevi ( A000203 )
    σ(n)=d|nd
    1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, 24, 31, 18, 39, 20, ...
  • bölen sayma işlevi ( 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, ...
  • kare sayıların karakteristik işlevi ( 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, ...

Sonra aşağıdaki örneklere sahibiz:

  • ϵ=1μ
  • f=ϵff
  • ϵ=λ|μ|
  • σ=φτ
  • id=σμσ = i d 1 veσ=id1
  • sq=λ1 λ = μ s q veλ=μsq
  • τ=111 = τ μ ve1=τμ
  • id=φ1 veφ=idμ

Sonuncusu Möbius inversiyonunun bir sonucudur : Herhangi bir denklemi eşittir .f,gg=f1f=gμ

Adım Adım Örnek

Bu, tanımda kullanılan gösterime aşina olmayanlar için adım adım hesaplanan bir örnektir. ve işlevlerini göz önünde bulundurun . Biz şimdi onların büklüm değerlendirecek en . İlk birkaç terimi aşağıdaki tabloda listelenmiştir.f=μg=σμσn=12

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

Toplam , bölen tüm doğal sayılar üzerinde yinelenir , böylece , tüm doğal bölenlerini varsayar . Bunlar . Her bir toplam kısmı olarak, değerlendirme de ve çarpma onunla değerlendirildi . Şimdi sonuçlandırabilirizdNn=12dn=12=223d=1,2,3,4,6,12g=σdf=μnd

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

Yanıtlar:



4

Haskell , 46 bayt

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

Çevrimiçi deneyin!

-6 bayt için kusur sayesinde ve büyük bir meydan okuma! Ve bir tane daha H.PWiz'e teşekkürler -6!


Burada daha basit
H.PWiz

@ H.PWiz Bu oldukça akıllı - bu şekilde yapmayı bile düşünmedim!
Mego

3

Python 3 , 59 bayt

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

Çevrimiçi deneyin!


Is //gerçekten yerine gerekli /?
Bay Xcoder

/şamandıralar üretecek değil mi?
Leaky Nun

Çünkü dbir bölen bir ntanım olarak, ondalık kısmı n/dsıfırdır, yani kayan nokta aritmetik ilgili herhangi bir sorun olmamalıdır. Kesirli kısmı sıfır olan şamandıralar Pythonic amaçları için int'lere yeterince yakındır ve işlevin çıktısı gerçek bir sayıdır, bu yüzden n/dyerine yapmak n//diyi olmalıdır.
Mego


2

++ , 51 bayt ekle

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

Çevrimiçi deneyin!

n(fg)(n)

Nasıl çalışır

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 bayt

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

Çevrimiçi deneyin!

Alır n,, fve g. Neyse ki numberspaketin zaten uygulanmış fonksiyonlarından birkaçı var.

Her biri ile sarılarak mümkün olan vektörleştirilmiş sürümler mevcutsa, Vectorizeaşağıdaki 45 baytlık sürüm mümkündür:

R , 45 bayt

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

Çevrimiçi deneyin!


2

APL (Dyalog Klasik) , 20 bayt

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

ile ⎕IO←1

Çevrimiçi deneyin!

Çözülmesi kolay, test edilmesi zor - genellikle benim zorluk türüm değil. Yine de bundan çok keyif aldım!

{ }işlenenleri ⍺⍺ve ⍵⍵iki işlevi kıvrık olan bir ikili operatörü tanımlar ; sayısal argüman

∪⍵∨⍳⍵artan düzenin bölücüleridir , yani LCM'lerin ( ) kendine özgü ( ) değeri, ona kadar olan tüm doğal sayılarla ( )

⍵⍵¨ her birine doğru işleneni uygulayın

⍺⍺¨∘⌽ soldaki işleneni tersine uygula

+.× iç ürün - karşılık gelen öğeleri ve toplamı çarpın


Aynı ngn / apl'de Unicode tanımlayıcıları nedeniyle daha iyi görünür, ancak 1 dizinleme nedeniyle 2 ek bayt alır.


Ngn / apl 27 ek bayt alır emin ...
Erik the Outgolfer



1

JavaScript (ES6), 47 bayt

Girişi alır (f)(g)(n).

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

Çevrimiçi deneyin!

Örnekler

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 bayt

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

Leaky Nun'ün Python cevabından utanmadan çalınan basit uygulama .

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

Çevrimiçi deneyin!


1

F #, 72 bayt

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

İki işlevi fve gdoğal bir sayıyı alır n. dDoğal olarak bölünmeyen değerleri filtreler n. Daha sonra bunları değerlendirir f(n/d) ve g(d)birlikte çoğaltır ve sonuçları toplar.



0

APL (NARS), 47 karakter, 94 bayt

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

burada m ve n bir kullanmak zorunda işlevdir (çünkü ben APL bir işlevde bir işlev dizisi aramak için nasıl bilmiyorum). Yukarıdaki örneği Mobius fonksiyonunun çarpımı (burada 12π) ve bölücü fonksiyonunun toplamı (burada 11π), çarpma için 12 değeri için:

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

eğer başka bir değer hesaplamak zorundaysa:

  {(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 

Örneğin, işlev sonucunun ilk 2000 sayısının kimlik olup olmadığı görülebilir.

  (⍳2000)≡{(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}¨⍳2000
1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.