Конверт Діріхле


20

Згортка Дирихле є особливим видом згортка , який виглядає як дуже корисним інструмент в теорії чисел. Він діє на безлічі арифметичних функцій .

Виклик

Враховуючи дві арифметичні функції (тобто функції ), обчислимо згортку Діріхле як визначено нижче.f,gf,g:NR (fg):NR

Деталі

  • Ми використовуємо конвенцію .0N={1,2,3,}
  • Згортання Діріхле двох арифметичних функцій знову є арифметичною функцією, і вона визначається як(Обидві суми еквівалентні експресії. означає ділить , отже , підсумовування ведеться по природним подільників з Аналогічно можна subsitute.fgf,g
    (fg)(n)=d|nf(nd)g(d)=ij=nf(i)g(j).
    d|ndNnni=ndN,j=dNі ми отримуємо другий еквівалентний препарат. Якщо ви не звикли до цієї позначення, є покроковий приклад нижче.) Просто для детальної розробки (це не має прямого значення для цього завдання): Визначення походить від обчислення продукту серії Діріхле :
    (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, ...
  • функція туйєнта Ейлера ( 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, ...
  • функція Ліувілля ( 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 = τ та1=τμ
  • 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)

Відповіді:


5

Lean , 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

Спробуйте в Інтернеті!

Більше тестів з усіма функціями.


чи справді лямбда дорожча чотирьох байтів fun ?
Маріо Карнейро

лямбда - три байти, я гадаю
Leaky Nun

Я думаю, що це два в UTF8 (грецький досить низький унікод)
Маріо Карнейро

Ти маєш рацію. Я також гольф імпорту
Leaky Nun

Я також condзаощаджував 5 байт
Leaky Nun


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

/випускає поплавці правильно?
Leaky Nun

Оскільки dподіл nза визначенням є дробовою частиною n/dнуля, тому з арифметикою з плаваючою комою не повинно виникати жодних питань. Поплавці з дробовою частиною нуль досить близькі до входів для пітонічних цілей, і вихід функції є реальним числом, тому робити n/dзамість цього n//dслід добре.
Мего


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пакет має досить багато функцій, які вже реалізовані.

Якщо були доступні векторні версії, що можливо, обернувши кожну Vectorize, можлива наступна 45-байтна версія:

R , 45 байт

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

Спробуйте в Інтернеті!


2

APL (Dyalog Classic) , 20 байт

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

з ⎕IO←1

Спробуйте в Інтернеті!

Легко вирішити, важко перевірити - як правило, це не мій виклик. Та все ж мені дуже сподобалось це!

{ }визначає діадичний оператор, операнди якого ⍺⍺і ⍵⍵дві функції, що з'єднуються; є числовим аргументом

∪⍵∨⍳⍵є дільниками у порядку зростання, тобто унікальні ( ) LCMs ( ) з усіма натуральними числами до нього ( )

⍵⍵¨ застосувати правильний операнд до кожного

⍺⍺¨∘⌽ застосувати лівий операнд до кожного зворотно

+.× внутрішній добуток - множте відповідні елементи та суму


Те саме в ngn / apl виглядає краще через ідентифікатори Unicode, але займає 2 додаткові байти через 1-індексацію.


Досить впевнений, що він займає 27 додаткових байтів у ngn / apl ...
Ерік the Outgolfer



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

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

Бере дві функції fі gі натуральне число n. Фільтрує значення d, які природним чином не поділяються n. Потім оцінює f(n/d) і g(d), множивши їх разом, підсумовує результати.



0

APL (NARS), 47 символів, 94 байти

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

де m і n - функція, яку потрібно використовувати (це тому, що я не знаю, як викликати один масив функції в одній функції в APL). На наведеному вище прикладі множення функції Мобіуса (тут це 12π) та суми дільницької функції (тут це 11π) для значення 12 таке множення було б:

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

якщо треба обчислити якесь інше значення:

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

Можна побачити, якщо, наприклад, перший номер 2000, результатом функції є ідентичність

  (⍳2000)≡{(12π⍵[1])×11π⍵[2]}{+/⍺⍺¨{k←⍳⍵⋄(⍵÷b),¨b←k/⍨0=k∣⍵}⍵}¨⍳2000
1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.