-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathOLMS-SMbase.sage
134 lines (103 loc) · 3.86 KB
/
OLMS-SMbase.sage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
class OLMS1(object):
def sequence(self, len): # sequence
A = self.generator()
return [A.next() for _ in range(len)]
def convolve(self, seq, len): # seq sequence generator
L = [seq.next() for _ in range(len)]
R = self.sequence(len)
return convolution(L, R)[:len]
def number(self, n): # single value
return self.sequence(n+1)[n]
def __call__(self, n): # single value
return self.number(n)
class Triangle():
def __init__(self, number, generator) :
self.number = number
self.generator = generator
def get(self, len): # triangle as a list of rows
A = self.generator()
return [list(A.next()) for _ in range(len)]
def row(self, n) :
return [self.number(n, k) for k in (0..n)]
def center(self, len) :
return [self.number(2*k, k) for k in range(len)]
class Rectangle():
def __init__(self, number, generator) :
self.number = number
self.generator = generator
def get(self, numrow, numcol) :
return [self.row(m, numcol) for m in range(numrow)]
def row(self, m, len) :
return [self.number(m + k, k) for k in range(len)]
def column(self, m, len) :
return [self.number(k + m , m) for k in range(len)]
def rowdiag(self, m, len) :
return [self.number(m + 2*k, k) for k in range(len)]
def coldiag(self, m, len) :
return [self.number(m + 2*k, m + k) for k in range(len)]
def center(self, len) :
return [self.number(2*k, k) for k in range(len)]
class Matrix():
def __init__(self, number, generator) :
self.number = number
self.generator = generator
def get(self, dim) :
G = self.generator()
L = [G.next() + [0]*(dim-n-1) for n in range(dim)]
return matrix(ZZ, L)
def reverse(self, dim) :
G = self.generator()
L = [G.next()[::-1] + [0]*(dim-n-1) for n in range(dim)]
return matrix(ZZ, L)
def inverse(self, dim) :
M = self.get(dim)
if M.det() == 0 :
print "Not invertible."
return
return M.inverse()
class OLMS2(object):
def number(self, n, k): # single value
if k<0 or k>n: return 0
G = self.row_generator()
for _ in (0..n): L = G.next()
return L[k]
def __call__(self, n, k): # single value
return self.number(n,k)
def triangle(self, len = None):
if len == None:
return Triangle(self.number, self.row_generator)
return Triangle(self.number, self.row_generator).get(len)
def rectangle(self, numrow = None, numcol = None):
if numrow == None and numcol == None:
return Rectangle(self.number, self.row_generator)
if numcol == None:
return Rectangle(self.number, self.row_generator).get(numrow, numrow)
return Rectangle(self.number, self.row_generator).get(numrow, numcol)
def matrix(self, dim = None):
if dim == None:
return Matrix(self.number, self.row_generator)
return Matrix(self.number, self.row_generator).get(dim)
def polynomials(self, len): # list of polynomials
R = self.row_generator()
L = []
for n in range(len):
r = R.next()
L.append(sum(r[k]*x^k for k in (0..n)))
return L
def values(self, numrow, numcol): # polynomials at integers
P = self.polynomials(numrow)
L = []
for p in P:
L.append([p(x=k) for k in range(numcol)])
return L
def transform(self, seq, inv = false): # seq generator
R = self.row_generator()
S, n = [], 0
while True:
r = R.next()
S.append(seq.next())
if inv:
yield sum((-1)^(n-k)*r[k]*S[k] for k in (0..n))
else:
yield sum(r[k]*S[k] for k in (0..n))
n += 1