У меня есть простой код, который делает следующее.
Итерирует по всей возможной длины n списков F
с + -1 элементами. Для каждого он выполняет итерацию по всей возможной длине 2n
списков S
с + -1 элементами, где первая половина $S $является просто копией второй половины. Код вычисляет скалярное произведение F
с каждым подсписком S
длины n
. Для каждого F, S он считает внутренние произведения равными нулю до первого ненулевого скалярного произведения.
Вот код.
#!/usr/bin/python
from __future__ import division
import itertools
import operator
import math
n=14
m=n+1
def innerproduct(A, B):
assert (len(A) == len(B))
s = 0
for k in xrange(0,n):
s+=A[k]*B[k]
return s
leadingzerocounts = [0]*m
for S in itertools.product([-1,1], repeat = n):
S1 = S + S
for F in itertools.product([-1,1], repeat = n):
i = 0
while (i<m):
ip = innerproduct(F, S1[i:i+n])
if (ip == 0):
leadingzerocounts[i] +=1
i+=1
else:
break
print leadingzerocounts
Правильный вывод для n=14
-
[56229888, 23557248, 9903104, 4160640, 1758240, 755392, 344800, 172320, 101312, 75776, 65696, 61216, 59200, 59200, 59200]
Используя pypy, это занимает 1 минуту 18 секунд для n = 14. К сожалению, мне бы очень хотелось запустить его за 16,18,20,22,24,26. Я не против использования numba или cython, но я хотел бы оставаться рядом с python, если это вообще возможно.
Любая помощь, ускоряющая это, очень ценится.
Я расскажу о самых быстрых решениях здесь. (Пожалуйста, дайте мне знать, если я пропущу обновленный ответ.)
- n = 22 при 9m35.081s по Eisenstat (C)
- n = 18 при 1m16.344s by Eisenstat (pypy)
- n = 18 при 2m54.998s Tupteq (pypy)
- n = 14 at 26s by Neil (numpy)
- n - 14 в 11m59.192s by kslote1 (pypy)