Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
1236 views
1
# Work in progress
2
# Authors: Esther Banaian and Emily Gunawan
3
4
from sage.all import *
5
6
def frieze_dict_diag(diag = [1,1,1],width = 6):
7
"""
8
def frieze_dict_diag(diag = [1,1,1],width = 6)
9
diag - give one diagonal of the nontrivial part of a frieze pattern. This will be the leftmost diagonal of the output.
10
WARNING - we assume you did not include the border rows of 0's and 1's in this diagonal.
11
WARNING - we assume this is the diagonal of a valid frieze pattern. We test to verify that this diagonal should generate a positive integer frieze.
12
width - desired width of each row of the frieze when passing to the print feature. Each row will have equal width
13
14
Return a dictionary of frieze patterns indexed by (i,j)
15
following the convention of Gunawan-Musiker-Volgel: Cluster Algebraic Interpretations of Inifinite Friezes
16
17
To view as matrix, as in Bessenrodt-Holm-Jorgensen, use matrix(frieze_dict_diag())
18
19
"""
20
21
n=len(diag)
22
m=dict()
23
friezerow = n + 3
24
matrixwidth = friezerow + width - 1
25
leftstart = 0
26
27
if (diag[1] + 1)% diag[0] != 0:
28
print(' This is not the diagonal of a positive integer frieze pattern. Recheck position 0')
29
for i in range(n-2):
30
if (diag[i+2] + diag[i]) % diag[i+1] != 0:
31
print(' This is not the diagonal of a positive integer frieze pattern. Recheck position {}'.format(i))
32
if (diag[n-1] + 1)% diag[n-2] != 0:
33
print(' This is not the diagonal of a positive integer frieze pattern. Recheck position {}'.format(n))
34
35
36
# Fill in 0s at position (1,1), (2,2), (3,3), until (inputrow,inputrow)
37
# i.e. we fill in the quiddity row (repeated), the "frieze row" after the row of 1s.
38
#print '\n'
39
40
for col in range(matrixwidth+1):
41
if m.has_key((col,col)):
42
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col,col)))
43
m[(col,col)]=0
44
m[(0,n+3)] = 0
45
m[(n+3,0)] = 0
46
47
# Fill in the 1s at position (i,j) where |i - j| = 1 until (inputrow,inputrow +/- 1)
48
for col in range(1,matrixwidth+1):
49
if m.has_key((col,col-1)):
50
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col,col-1)))
51
m[(col,col-1)]=1
52
#print m[(col,col-1)]
53
#print (col,col-1)
54
for col in range(1,matrixwidth+1):
55
if m.has_key((col-1,col)):
56
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col-1,col)))
57
m[(col-1,col)]=1
58
#print m[(col-1,col)]
59
#print (col-1, col)
60
61
#Fill in diagonal of frieze in first row and column of matrix
62
for col in range(0,n):
63
if m.has_key((col+2,0)):
64
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col+2,0)))
65
m[(col+2,0)]=diag[col]
66
#print m[(col+2,col)]
67
if m.has_key((0,col+2)):
68
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((0,col+2)))
69
m[(0,col+2)]=diag[col]
70
#print m[(col+2,col)]
71
m[(n+2,0)] = 1
72
m[(0,n+2)] = 1
73
74
75
# Fill in the rest of the "frieze rows"
76
#print '\n'
77
for row in range(1,matrixwidth-friezerow+1):
78
m[(friezerow+row, row)] = 0
79
m[(row, friezerow+row)] = 0
80
for row in range(1, matrixwidth+1):
81
for col in range(2,min(friezerow, matrixwidth-row+1)):
82
i,j=row,col+row
83
if m.has_key((i,j)):
84
raise ValueError('There is a bug. This key {} should not exist'.format((i,j)))
85
#if m[(i+1,j-1)]<1:
86
#break
87
print i,j
88
#print (i+1,j%n+1)
89
#print m.keys()
90
m[(i,j)] = (m[(i,(j-1))]*m[(i-1,j)]+1)/m[(i-1,(j-1))]
91
if type(m[(i,j)]) == type(sqrt(2)):
92
m[(i,j)] = m[(i,j)].full_simplify()
93
#print m[(i,j)]
94
for col in range(2,min(friezerow, matrixwidth - row + 1)):
95
i,j=col+row,row
96
if m.has_key((i,j)):
97
raise ValueError('There is a bug. This key {} should not exist'.format((i,j)))
98
#if m[(i-1,j+1)]<1:
99
#break
100
#print (i,(j-1)%n+1)
101
#print (i+1,j%n+1)
102
#print m.keys()
103
m[(i,j)] = (m[((i-1),j)]*m[(i,(j-1))]+1)/m[((i-1),(j-1))]
104
if type(m[(i,j)]) == type(sqrt(2)):
105
m[(i,j)] = m[(i,j)].full_simplify()
106
#print m[(i,j)]
107
#print '\n'
108
return m
109
110
111
def frieze_dict_quid(quiddity_row=(2,1,4,2,3),leftstart = 0,width = 5,friezerow = 4, flag_rectangle=True):
112
"""
113
def frieze_mat3(quiddity_row=(2,1,4,2,3),leftstart = 0,width = 5,friezerow = 4, flag_rectangle=True)
114
quiddity_row - give at least one complete period of the quiddity row of your frieze. The program assumes this periodicity. Give this as a list or a tuple.
115
leftstart - Assuming the first entry of the inputted quiddity row exists at index (0,2), give i such that the leftmost quiddity row entry is (i,i+2).
116
width - desired width of each row of the frieze when passing to the print feature
117
friezerow - The index of the last row we want in the frieze.
118
119
We begin indexing the rows of our frieze pattern at the row of all 0's, so
120
the row of 0s is at "frieze row" = 0,
121
the row of 1s is at "frieze row" = 1
122
and the quiddity row is at "frieze row"=2
123
124
Return a dictionary of frieze patterns indexed by (i,j)
125
following the convention of Gunawan-Musiker-Volgel: Cluster Algebraic Interpretations of Inifinite Friezes
126
127
To view as matrix, as in Bessenrodt-Holm-Jorgensen, use matrix(frieze_dict_quid())
128
129
130
"""
131
n=len(quiddity_row)
132
if leftstart < 0:
133
leftstart = Integer(mod(leftstart,n))
134
m=dict()
135
matrixwidth = friezerow + width
136
#inputcol = Integer(mod((leftstart + 1),n))
137
#print inputcol
138
139
140
#use XXXXX
141
checkdict1 = dict()
142
checkdict2 = dict()
143
checkdict3 = dict()
144
for i in range(n-1):
145
checkdict1[(i,i)] = quiddity_row[i]
146
checkdict2[(i,i)] = quiddity_row[i+1]
147
for i in range(n-2):
148
checkdict1[(i,i+1)] = 1
149
checkdict1[(i+1,i)] = 1
150
checkdict2[(i,i+1)] = 1
151
checkdict2[(i+1,i)] = 1
152
checkdict3[(i,i)] = quiddity_row[i+1]
153
for i in range(n-3):
154
checkdict3[(i,i+1)] = 1
155
checkdict3[(i+1,i)] = 1
156
check1 = matrix(checkdict1)
157
check2 = matrix(checkdict2)
158
check3 = matrix(checkdict3)
159
if det(check1) != 0 or det(check2)!= 0 or det(check3)!= 1:
160
print('This is not the quiddity row of a finite frieze pattern, although it could be subsequence of a periodic quiddity row which does produce a finite frieze pattern')
161
162
163
if flag_rectangle: # not working yet (I want to have a rectangle shape and not triangle)
164
matrixwidth = friezerow + width
165
166
# Fill in 0s at position (1,1), (2,2), (3,3), until (inputrow,inputrow)
167
# i.e. we fill in the quiddity row (repeated), the "frieze row" after the row of 1s.
168
#print '\n'
169
170
for col in range(matrixwidth-1):
171
if m.has_key((col,col)):
172
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col,col)))
173
m[(col,col)]=0
174
#print m[(col,col)]
175
#print (col, col)
176
177
# Fill in the 1s at position (i,j) where |i - j| = 1 until (inputrow,inputrow +/- 1)
178
# i.e. we fill in the "frieze row" =2
179
for col in range(1,matrixwidth):
180
if m.has_key((col,col-1)):
181
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col,col-1)))
182
m[(col,col-1)]=1
183
# print m[(col,col-1)]
184
#print (col,col-1)
185
for col in range(1,matrixwidth):
186
if m.has_key((col-1,col)):
187
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col-1,col)))
188
m[(col-1,col)]=1
189
# print m[(col-1,col)]
190
#print (col-1, col)
191
192
#Fill in quiddity row for (i,j) where |i - j| = 2
193
for col in range(0,matrixwidth-2):
194
if m.has_key((col+2,col)):
195
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col+2,col)))
196
m[(col+2,col)]=quiddity_row[((col+leftstart) % n)]
197
#print m[(col+2,col)]
198
for col in range(0,matrixwidth-2):
199
if m.has_key((col,col+2)):
200
raise ValueError('There is a bug. This key {} should not have been assigned.'.format((col,col+2)))
201
m[(col,col+2)]=quiddity_row[(col+leftstart)%n]
202
203
# Fill in the rest of the "frieze rows" below the quiddity row
204
#print '\n'
205
for row in range(3, matrixwidth-(leftstart+1)):
206
for col in range(0,matrixwidth-row):
207
i,j=col,col+row
208
if m.has_key((i,j)):
209
raise ValueError('There is a bug. This key {} should not exist'.format((i,j)))
210
if m[(i+1,j-1)]<1:
211
break
212
#print (i,(j-1)%n+1)
213
#print (i+1,j%n+1)
214
#print m.keys()
215
m[(i,j)] = (m[(i,(j-1))]*m[(i+1,j)]-1)/m[(i+1,(j-1))]
216
if type(m[(i,j)]) == type(sqrt(2)):
217
m[(i,j)] = m[(i,j)].full_simplify()
218
#print m[(i,j)]
219
for col in range(0,matrixwidth-row):
220
i,j=col+row,col
221
if m.has_key((i,j)):
222
raise ValueError('There is a bug. This key {} should not exist'.format((i,j)))
223
if m[(i-1,j+1)]<1:
224
break
225
#print (i,(j-1)%n+1)
226
#print (i+1,j%n+1)
227
#print m.keys()
228
m[(i,j)] = (m[((i-1),j)]*m[(i,(j+1))]-1)/m[((i-1),(j+1))]
229
if type(m[(i,j)]) == type(sqrt(2)):
230
print 'hey'
231
m[(i,j)] = m[(i,j)].full_simplify()
232
#print m[(i,j)]
233
if m[(leftstart+row,leftstart)]<1:
234
break
235
#print '\n'
236
return m
237
238
def print_frieze(inputtype = 'quid', input_row=(2,1,4,2,3),leftstart = 0,width = 5, friezerow = 4,flag_rectangle=True):
239
"""
240
def print_frieze(inputtype = quid, input_row=(2,1,4,2,3),leftstart = 0,width = 5,friezerow = 4,flag_rectangle=True)
241
inputtype - for now write 'quid' or 'quiddity' if the input is a quiddity row, and 'diag' or 'diaganol' is the input is a diagonal
242
quiddity_row - give at least one complete period of the quiddity row of your frieze. The program assumes this periodicity. Give this as a list or a tuple.
243
leftstart - Assuming the first entry of the inputted quiddity row exists at index (0,2), give i such that the leftmost quiddity row entry is (i,i+2).
244
width - desired width of each row of the frieze
245
friezerow - The index of the last row we want in the frieze.
246
Note - if frieze row is greater than the total number of rows of the frieze pattern, the program will simply print the entire frieze pattern and nothing additional.
247
248
We begin indexing the rows of our frieze pattern at the row of all 0's, so
249
the row of 0s is at "frieze row" = 0,
250
the row of 1s is at "frieze row" = 1
251
and the quiddity row is at "frieze row"=2
252
253
The purpose of this function is to output code that will display the frieze pattern. Use view(print_frieze()) to see the frieze. It should also work on Latex??
254
"""
255
if inputtype == 'quid' or inputtype == 'quiddity':
256
m = frieze_dict_quid(input_row,leftstart,width,friezerow,flag_rectangle)
257
elif inputtype == 'diag' or inputtype == 'diaganol':
258
m = frieze_dict_diag(input_row, width)
259
friezerow = len(input_row) + 4
260
else:
261
m = dict()
262
width = 0
263
friezerow = 0
264
265
# Create a list with all the entries we will put into the frieze pattern.
266
L = []
267
# ones = []
268
# for k in range(0,width): # fill in 1s
269
# ones.append(1)
270
# L.append(ones)
271
for row in range(0,friezerow):
272
li = []
273
for col in range(0, width):
274
i,j = col, col+row
275
if m.has_key((i,j)):
276
li.append(m[(i,j)])
277
#print m[(i,j)]
278
else:
279
break
280
L.append(li)
281
# print L
282
283
ret = ""
284
for i,row in enumerate(L):
285
ret += ' '*i*2 + ' '.join('%3s'%x for x in row)
286
#ret += ' '*i*2 + ' '.join("{:>10}".format(x) for x in row)
287
ret += '\n'
288
#The following may be useful for infinite friezes arising from punctured polygons. This inserts a dashed line after every n = len(quiddity row), so that all entries in the same compartment, defined by these dashed lines, corresponds to an arc in the punctured polygon with the same number of self-crossings. The uppermost compartment corresponds to arcs with no self-crossings.
289
# if (i+1)%len(quiddity_row)==0:
290
# ret += ' '*i*2 + ' '
291
# ret += '--'*friezerow + '\n'
292
#ret +='\n'
293
294
return ret[:-1]
295
296
297
#print matrix(frieze_mat()).transpose()
298
299
# sage: matrix(frieze_mat((2,1,3),inputrow=15)).transpose() # type A3
300