开头说两句

当初复变函数没认真学,,然后学习到模形式论中,涉及到了分式线性变换,搞得我一头雾水。。然后,我打算把python中的numpy的complex类重载了一下,加入了画图功能,可以明显地发现一些问题。

严格来说,这篇文章是关于程序的,只不过借助编程手段来理解数学。


虽说是关于编程,但还是要声明一下数学的东西

关于分式线性变换(linear fractional transformation),该变换是在模群同余子群(modular group congruence) mathfrak{sl}_2(mathbb{Z}) 上的,也就是说 mathfrak{sl}_2(mathbb{Z})={left[egin{matrix}a&b\c&dend{matrix}
ight]:ad-bc=1,a,b,c,din mathbb{Z}} 。其中,此为乘法群,由以两个矩阵生成,

gamma_1=left[egin{matrix}1&1\0&1end{matrix}
ight],gamma_2= left[egin{matrix}0&-1\1&0end{matrix}
ight]

然后关于分式线性变换,于是就有

gamma.	au = frac{a	au+b}{c	au+d},gammain mathfrak{sl}_2(mathbb{Z}),	au in mathbb{C}

然后,当时上课,我并不很清楚为啥要讨论在上半平面(upper half plane) H={	auin C,Im(tau)>0} 以及基本域(fundamental domain) D={	auin H:|Re(	au)|lefrac{1}{2},|	au|ge1} 然后用我的程序画了几张图,就能(直观地)发现这个原因~~

(下面会有六张图~~)

前五个图是关于 gamma_2 的,

从图2到图5,红色为原像,绿色为像

第一张图忘了区分颜色了

最后一张图是关于平移的 gamma_1 ,三种颜色分别对应不同的平移。

图1
图2

图3
图4
图5
图6


然后,放相关代码

(使用了numpy、matplotlab)

##调包
import numpy as np
import matplotlib.pyplot as plt

##重载numpy的complex,分别改一个左乘,和画图,右乘我就没有用(因为懒)
class Complex(np.complex):
def show(self,colour=black):
plt.scatter(self.real,self.imag,color=colour,alpha=0.4)

def mul(self, other):
return Complex((self*other).real,(self*other).imag)

##SL2群元素结构的构造,定义了元素之间的运算,以及与复数的运算
class SL_2():
def __init__(self,a,b,c,d):
assert a*d-b*c==1,not modular
self.tao = np.array([[a,b],[c,d]])

def __mul__(self, other):
if type(other)==SL_2:
r = self.tao.dot(other.tao)
return SL_2(r[0][0],r[0][1],r[1][0],r[1][1])
elif type(other)==Complex:
a = self.tao[0][0]
b = self.tao[0][1]
c = self.tao[1][0]
d = self.tao[1][1]
r = (a*other+b)/(c*other+d)
return Complex(r.real,r.imag)

def __rmul__(self, other):
r = other.tao.dot( self.tao)
return SL_2(r[0][0], r[0][1], r[1][0], r[1][1])

def __pow__(self, power, modulo=None):
if power==0:
return SL_2(1,0,0,1)

r = self.tao
for i in range(power-1):
r = r.dot(self.tao)
return SL_2(r[0][0], r[0][1], r[1][0], r[1][1])

def __str__(self):
return self.tao.__str__()

##画布
plt.figure()
##x,y轴
plt.xlabel(x)
plt.ylabel(y)

if __name__ == __main__:
##定义两个SL的矩阵
a = SL_2(1,1,0,1)
b = SL_2(0,-1,1,0)

##定义横轴
x = np.linspace(-2,2,19)
y = np.linspace(0.1,1.2,19)
##单位圆的横坐标
xc = np.linspace(-0.9,0.9,39)
##单位圆相应的纵坐标
circle = np.sqrt(1-xc**2)
##实轴为1和-1的直线(然而我懒了,画成散点了2333)定义
y1 = np.linspace(0,2,20)
y2 = np.linspace(0,2,20)
plt.scatter([1 for i in range(len(y1))],y1,color=black)
plt.scatter([-1 for i in range(len(y2))],y2,color=black)

##这部分就随意操作了
for k in range(3):
if k==1:
color = green
elif k==2:
color = red
else:
color = purple
c = [((a ** k) * Complex(i, j)).show(color) for i in x for j in y]##这里的条件可以限制原像的范围
##画单位圆
plt.scatter(xc, circle,color=black)
##程序最后显示图形
plt.show()

推荐阅读:

相关文章