Dirichlet卷积


19

狄利克雷卷积是一种特殊的卷积出现在数论中一个非常有用的工具。它对一组算术函数进行运算

挑战

给定两个算术函数(即函数),计算Dirichlet卷积如下定义。f,gf,g:NRf g NR (fg):NR

细节

  • 我们使用约定。0N={1,2,3,}
  • 两个算术函数的Dirichlet卷积再次是算术函数,它的定义为(两个和都是等价的。表达式表示除以,因此求和在的自然除数上 。类似地,我们可以用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位int表示。N
  • 为简单起见,您还可以假定每个条目都可以由例如单个实数浮点数表示。R

例子

让我们首先定义一些功能。请注意,每个定义下方的数字列表代表该函数的前几个值。

  • 乘法身份(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, ...
  • 常数单位函数(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, ...
  • 莫比乌斯函数(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, ...
  • 欧拉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) 其中是的素数个数乘以复数
    λ(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
    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=σμσ=id1
  • sq=λ1λ=μsq
  • τ=111=τμ
  • id=φ1φ=idμ

最后一个是莫比乌斯反演的结果:对于任何,方程等效于。f,gg=f1f=gμ

分步示例

这是为不熟悉定义中使用的符号的人员逐步计算的示例。考虑函数和。现在我们将在处评估它们的卷积。下表列出了他们的前几个术语。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

该总和遍历除所有自然数,因此假设所有自然除数。这些是。在每个求和项中,我们在处计算并将其与在处计算的相乘。现在我们可以得出结论dNn=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)

Answers:




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)

在线尝试!


//真正需要的,而不是/
Xcoder先生18年

/会产生漂浮物吗?
Leaky Nun

因为根据定义d是的除数n,所以的小数部分n/d为零,因此浮点算术应该没有任何问题。与小数部分零花车足够接近整数的Python的目的,该函数的输出是实数,这样做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}

在线尝试!

注意到nfg。幸运的是,该numbers软件包已经实现了很多功能。

如果有矢量化版本,可以通过用来包装每个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

在线尝试!

易于解决,难以测试-通常不是我的挑战类型。但是,我非常喜欢这个!

{ }定义一个二元运算符,其操作数⍺⍺⍵⍵是被卷积的两个函数;是数字参数

∪⍵∨⍳⍵升序的除数,即LCM的唯一(),且所有自然数都等于(

⍵⍵¨ 将正确的操作数应用于每个

⍺⍺¨∘⌽ 反向应用左操作数

+.× 内积-乘以对应的元素并求和


ngn / apl中的相同项由于使用Unicode标识符而看起来更好,但由于进行了1索引编制,因此需要占用2个额外的字节。


可以肯定的是,
在ngn

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

简单易用的实现,从Leaky Nun的Python答案中毫不知情地偷了。

取消高尔夫:

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)

具有两个函数fg和一个自然数n。过滤掉d不会自然分为的值n。然后评估f(n/d)g(d),倍数在一起,总结的结果。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.