# This file describes the analogue of "DrawNeighbourhoods1" for real quadratic number fields
#
# Z[sqrt(d)] (Change the parameter 'd' below according to your needs)
#
# What's happening here is also described in the video
# The main differences are: instead of working with a single complex embedding, we now have two real embeddings
# ...and then the norm looks different. The shapes of "norm <= 1"-sets are no longer circles, but hyperbola-bounded regions. But see for yourself...
x,y = var('x','y') # variables we shall later use for the plotting only, so these are coordinates
xx = var('xx') # variable for the polynomial ring
d = 5 # must be a positive integer # <---------- HERE IS WHERE THE INPUT GOES
K. = NumberField(xx^2 - d) # create a number field as SAGE understands it
w = t # if you change this, you can investigate the subring generated by the element w instead of sqrt(d) [not used at present]
print("The generator we use for Z[w] is:", w) # we output w, just to be sure what it is (because this is a likely source of errors)
#print("[Note that we're not necessarily working with the ring of integers here]")
# now we extract two homomorphisms from the number field to the real numbers, these are our real embeddings
emb1 = K.complex_embeddings()[0]
emb2 = K.complex_embeddings()[1] # the function complex_embeddings() just returns a list of them, so using "[0]" and "[1]" we take the zeroth and first element out of this list
# the next bits are unchanged from "DrawNeighbourhoods1":
# parameters for the plotting
RANGELIM = 12 # what range of values should we cover (so this is unrelated to the maths, and just about drawing the little circles...)
MAXX = 12 # we specify what ranges we wanna look at for x and y (a more careful programming would estimate the required RANGELIM value from this data, but we're feeling lazy today...)
MINX = -12
MAXY = 12
MINY = -12
def PlotNormOneRegionCenteredAt(algint): # returns a plot of the abs(norm(x-algint))<=1 region around an input algebraic integer in K
cx = emb1(algint)
cy = emb2(algint)
return region_plot(abs((cx - x)*(cy - y)) < 0.999, (MINX, MAXX), (MINY,MAXY), plot_points=140, incol='blue', borderwidth=0, frame=False, alpha=0.18)
p = circle((0,0),0.01) # draw a circle at the original... this is just to start a 2d plot so that we can add new circles to our graphic by using "+"
p += PlotNormOneRegionCenteredAt(0)
p += PlotNormOneRegionCenteredAt(-w)
p += PlotNormOneRegionCenteredAt(1)
for a in range(-RANGELIM,RANGELIM+1):
for b in range(-RANGELIM,RANGELIM+1):
# here some things change a bit from "DrawNeighbourhoods1":
# point under the the two real embeddings
z = a + b * w # as a and b range through the integers in the interval [-RANGELIM,+RANGELIM], set z to a + b*w.
# in comparison to "DrawNeighbourhoods1" z is no longer a complex number. Here it is an element of the number field
cx = emb1(z) # emb1 and emb2 were defined as the ring homomorphisms sending the number field to the two real embeddings
cy = emb2(z)
# now draw a little circle around the point with coordinates (cx,cy)
p += circle( (cx,cy), 0.05, color='red')
p.show(xmin=MINX, ymin=MINY, xmax=MAXX, ymax=MAXY, figsize=29)