Dirichlet Convolution


19

Dirichlet บิดเป็นชนิดพิเศษของบิดที่ปรากฏเป็นเครื่องมือที่มีประโยชน์มากในทฤษฎีจำนวน จะดำเนินการในชุดของฟังก์ชั่นทางคณิตศาสตร์

ท้าทาย

รับฟังก์ชั่นเลขคณิตสองฟังก์ชัน (เช่นฟังก์ชัน ) คำนวณDirichlet convolutionตามที่กำหนดไว้ด้านล่างf,gf,g:NR (fg):NR

รายละเอียด

  • เราใช้การประชุม\}0N={1,2,3,}
  • Dirichlet convolution ของฟังก์ชันทางคณิตศาสตร์สองฟังก์ชันเป็นฟังก์ชันทางคณิตศาสตร์อีกครั้งและถูกกำหนดเป็น(ผลรวมทั้งสองมีค่าเท่ากันนิพจน์หมายถึงหารดังนั้นผลรวมอยู่เหนือตัวหารธรรมชาติของ ในทำนองเดียวกันเราสามารถรองรับfgf,g
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    d|ndNnni=ndN,j=dNและเราได้สูตรที่สองเท่ากัน หากคุณไม่คุ้นเคยกับสัญกรณ์นี้มีตัวอย่างทีละขั้นตอนด้านล่าง) เพื่ออธิบายอย่างละเอียด (ไม่เกี่ยวข้องโดยตรงกับความท้าทายนี้): คำจำกัดความมาจากการคำนวณผลิตภัณฑ์ของชุด Dirichlet :
    (nNf(n)ns)(nNg(n)ns)=nN(fg)(n)ns
  • การป้อนข้อมูลที่จะได้รับเป็นสองฟังก์ชั่นกล่องดำ อีกวิธีหนึ่งคุณสามารถใช้รายการที่ไม่มีที่สิ้นสุดตัวกำเนิดกระแสข้อมูลหรืออะไรทำนองนั้นที่สามารถสร้างค่าได้ไม่ จำกัด จำนวน
  • มีสองวิธีเอาต์พุต: ฟังก์ชันถูกส่งคืนหรือคุณสามารถรับอินพุตเพิ่มเติมและส่งกลับโดยตรงfgnN(fg)(n)
  • เพื่อความง่ายคุณสามารถสรุปได้ว่าทุกองค์ประกอบของสามารถแสดงได้ด้วยเช่นค่าบวก 32- บิตN
  • เพื่อความง่ายคุณสามารถสันนิษฐานได้ว่าทุกรายการสามารถแสดงได้เช่นหมายเลขจุดลอยตัวเดียวR

ตัวอย่าง

ก่อนอื่นให้เรานิยามฟังก์ชั่นบางอย่างก่อน โปรดทราบว่ารายการหมายเลขใต้คำจำกัดความแต่ละรายการหมายถึงค่าสองสามค่าแรกของฟังก์ชันนั้น

  • ตัวคูณแบบหลายตัว ( A000007 ) start
    ϵ(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, ...
  • ฟังก์ชันหน่วยคงที่ ( 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, ...
  • ฟังก์ชันเอกลักษณ์ ( A000027 )
    id(n)=nn
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
  • ฟังก์ชั่นMöbius ( A008683 ) start
    μ(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 ( 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 ( A008836 ) โดยที่คือจำนวนของตัวประกอบตัวประกอบจำนวนของนับด้วย multiplicity
    λ(n)=(1)k
    kn1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, ...
  • ฟังก์ชันผลรวมของตัวหาร ( A000203 )
    σ(n)=d|nd
    1, 3, 4, 7, 6, 12, 8, 15, 13, 18, 12, 28, 14, 24, 24, 31, 18, 39, 20, ...
  • ฟังก์ชันการนับตัวหาร ( 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, ...
  • ฟังก์ชั่นลักษณะของตัวเลขสแควร์ ( A010052 ) start
    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, ...

จากนั้นเรามีตัวอย่างต่อไปนี้:

  • ϵ=1μ
  • f=ϵff
  • ϵ=λ|μ|
  • σ=φτ
  • id=σμσ = ฉันd * 1และσ=id1
  • sq=λ1 λและλ=μsq
  • τ=111และ1=τμ
  • id=φ1และφ=idμ

สุดท้ายสำหรับเป็นผลมาจากการผกผันMöbius : สำหรับการใด ๆสมเทียบเท่ากับ\f,gg=f1f=gμ

ตัวอย่างทีละขั้นตอน

นี่คือตัวอย่างที่ถูกคำนวณทีละขั้นตอนสำหรับผู้ที่ไม่คุ้นเคยกับสัญกรณ์ที่ใช้ในการกำหนด พิจารณาฟังก์ชันและ\ ตอนนี้เราจะประเมินบิดของพวกเขาที่nคำศัพท์สองสามคำแรกของพวกเขาอยู่ในตารางด้านล่าง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

iterates รวมมากกว่าตัวเลขจากธรรมชาติทั้งหมดdNที่แบ่งn=12จึงdถือว่าทั้งหมดหารตามธรรมชาติของn=12=223 3 เหล่านี้เป็นd=1,2,3,4,6,12 12 ในแต่ละสรุปเราประเมินg=σที่dและคูณด้วยf=μประเมินที่ndd ตอนนี้เราสามารถสรุปได้

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

คำตอบ:


4

ลีน , 108 100 95 78 75 ไบต์

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

ลองออนไลน์!

Testcase เพิ่มเติมด้วยฟังก์ชั่นทั้งหมด


แลมบ์ดามีราคาแพงกว่าสี่ไบต์จริงfun หรือ
Mario Carneiro

แลมบ์ดาเป็นสามไบต์ฉันคิดว่า
Leaky Nun

ฉันคิดว่ามันเป็นสองใน UTF8 (กรีกเป็นยูนิโค้ดค่อนข้างต่ำ)
Mario Carneiro

คุณถูก. ฉันเล่นกอล์ฟด้วยการนำเข้า
Leaky Nun

ฉันเคยcondบันทึก 5 ไบต์
Leun Nun

4

Haskell , 46 ไบต์

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

ลองออนไลน์!

ขอบคุณข้อบกพร่องสำหรับ -6 ไบต์และความท้าทายที่ยิ่งใหญ่! และขอบคุณ H.PWiz สำหรับอีก -6!


ความเรียบง่ายจะสั้นกว่าที่นี่
H.PWiz

@ H.PWiz มันค่อนข้างฉลาด - ฉันไม่เคยคิดที่จะทำแบบนั้น!
Mego

3

Python 3 , 59 ไบต์

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

ลองออนไลน์!


เป็น//ความจำเป็นจริงๆแทน/?
Mr. Xcoder

/จะผลิตลอยใช่ไหม
Leun Nun

เนื่องจากdเป็นตัวหารของnคำจำกัดความส่วนที่เป็นเศษส่วนของn/dเป็นศูนย์ดังนั้นจึงไม่ควรมีปัญหาใด ๆ กับการคำนวณเลขทศนิยม ทุ่นกับเศษส่วนส่วนศูนย์อยู่ใกล้พอที่จะ ints สำหรับวัตถุประสงค์ Pythonic และเอาท์พุทของฟังก์ชั่นเป็นจำนวนจริงดังนั้นการทำn/dแทนn//dควรจะดี
Mego


2

เพิ่ม ++ , 51 ไบต์

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

ลองออนไลน์!

n(fg)(n)

มันทำงานอย่างไร

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 ไบต์

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

ลองออนไลน์!

ใช้เวลาn, และf gโชคดีที่numbersแพ็คเกจมีฟังก์ชั่นการใช้งานบางส่วนอยู่แล้ว

หากเวอร์ชัน vectorized พร้อมใช้งานซึ่งสามารถทำได้โดยการห่อแต่ละรายการด้วยVectorizeดังนั้นเวอร์ชัน 45 ไบต์ต่อไปนี้จะเป็นไปได้:

R , 45 ไบต์

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

ลองออนไลน์!




1

JavaScript (ES6), 47 ไบต์

(f)(g)(n)จะเข้าเป็น

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

ลองออนไลน์!

ตัวอย่าง

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

APL (Dyalog Classic)ขนาด 20 ไบต์

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

กับ ⎕IO←1

ลองออนไลน์!

แก้ง่ายยากที่จะทดสอบ - โดยทั่วไปไม่ใช่ความท้าทายของฉัน แต่ฉันก็สนุกกับมันมาก!

{ }กำหนดโอเปอเรเตอร์ dyadic ที่มีตัวถูกดำเนินการ⍺⍺และ⍵⍵เป็นสองฟังก์ชันที่ถูก convolved; เป็นอาร์กิวเมนต์ตัวเลข

∪⍵∨⍳⍵คือตัวหารของเรียงลำดับจากมากไปหาน้อยนั่นคือเอกลักษณ์ ( ) ของ LCMs ( ) ของที่มีจำนวนธรรมชาติทั้งหมดขึ้นอยู่กับมัน ( )

⍵⍵¨ ใช้ตัวถูกดำเนินการที่เหมาะสมกับแต่ละ

⍺⍺¨∘⌽ ใช้ตัวถูกดำเนินการซ้ายกับแต่ละรายการในสิ่งที่ตรงกันข้าม

+.× ผลิตภัณฑ์ภายใน - องค์ประกอบและผลรวมที่สอดคล้องกันคูณ


เหมือนกันใน ngn / aplดูดีขึ้นเนื่องจากตัวระบุ Unicode แต่ใช้เวลา 2 ไบต์เพิ่มเติมเนื่องจากการสร้างดัชนี 1


ค่อนข้างแน่ใจว่าจะใช้เวลา 27 ไบต์เพิ่มเติมใน ngn / apl ...
Erik the Outgolfer

1

C (gcc) , 108 ไบต์

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

การดำเนินการตรงไปตรงมาขโมยลงคอจากรั่วนูนเป็นคำตอบหลาม

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

ลองออนไลน์!


1

F #, 72 ไบต์

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

ใช้เวลาทั้งสองฟังก์ชั่นfและและจำนวนธรรมชาติg nกรองออกค่าของที่ไม่เป็นธรรมชาติแบ่งออกเป็นd nจากนั้นประเมินf(n/d) และg(d)ทวีคูณพวกเขาเข้าด้วยกันและสรุปผล


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.