def CollectStatis(_map): Sigma=weight.Weight("SmoothT", _map, "TwoSpins", "AntiSymmetric") SigmaSmoothT=WeightEstimator(Sigma) Polar=weight.Weight("SmoothT", _map, "FourSpins", "Symmetric") PolarSmoothT=WeightEstimator(Polar) _FileList=GetFileList() if len(_FileList)==0: raise CollectStatisFailure("No statistics files to read!") log.info("Collect statistics from {0}".format(_FileList)) Total=len(_FileList) Success=0.0 for f in _FileList: try: log.info("Merging {0} ...".format(f)); Dict=IO.LoadBigDict(f) SigmaSmoothT.MergeFromDict(Dict['Sigma']['Histogram']) PolarSmoothT.MergeFromDict(Dict['Polar']['Histogram']) except: log.info("Fails to merge\n {0}".format(traceback.format_exc())) else: Success+=1.0 log.info("{0}/{1} statistics files read!".format(int(Success), Total)) if float(Success)/Total<AcceptRatio: raise CollectStatisFailure("More than {0}% statistics files fail to read!".format(100.0*AcceptRatio)) return (SigmaSmoothT, PolarSmoothT)
def FullGammaG(IrGammaG, W0, _map): sub = 0 BKPolar = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") UPUP = _map.Spin2Index(UP, UP) DOWNDOWN = _map.Spin2Index(DOWN, DOWN) UPDOWN = _map.Spin2Index(UP, DOWN) DOWNUP = _map.Spin2Index(DOWN, UP) IrGammaGuu = np.zeros((_map.Vol, _map.MaxTauBin)) + 0.0 * 1j IrGammaGdu = np.zeros((_map.Vol, _map.MaxTauBin)) + 0.0 * 1j for i in range(_map.MaxTauBin): IrGammaGuu[:, i] = IrGammaG[UP, :, i, i] IrGammaGdu[:, i] = IrGammaG[DOWN, :, i, i] BKPolar.Data[UPUP, sub, UPUP, sub, :, :] = IrGammaGuu BKPolar.Data[DOWNDOWN, sub, DOWNDOWN, sub, :, :] = IrGammaGuu BKPolar.Data[DOWNDOWN, sub, UPUP, sub, :, :] = IrGammaGdu BKPolar.Data[UPUP, sub, DOWNDOWN, sub, :, :] = IrGammaGdu # print "BKPolar[UP,UP]=\n", BKPolar.Data[UPUP,0,UPUP,0,0,:] BKPolar.FFT("K", "W") W0.FFT("K") Denorm, JP = calc.Calculate_Denorminator(W0, BKPolar, _map) # JPJ=np.einsum("ijklvt,klmnv->ijmnvt", JP, W0.Data) BKChiTensor = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "K", "W") lu_piv, Determ = weight.LUFactor(Denorm) Check_Denorminator(Denorm, Determ, _map) BKChiTensor.LUSolve(lu_piv, -BKPolar.Data) return BKChiTensor, Determ
def Build(self): #self.BareG and self.BareW must be reinitialized at every time Build() is called self.BareG=weight.Weight("SmoothT", self.__Map, "TwoSpins", "AntiSymmetric", "R", "T") self.BareW=weight.Weight("DeltaT", self.__Map, "FourSpins", "Symmetric", "R", "T") LatName=self.Lat.Name try: getattr(self, self.__Model)(LatName) except: Assert(False, "Model {0} has not been implemented!".format(self.__Model)) return (self.BareG,self.BareW)
def W_Dyson(W0, Polar, map, Lat): W=weight.Weight("SmoothT", map, "FourSpins", "Symmetric", "K","W") ChiTensor=weight.Weight("SmoothT", map, "FourSpins", "Symmetric", "K","W") Polar.FFT("K","W") Denorm,JP=Calculate_Denorminator(W0, Polar, map) W0.FFT("K") JPJ=np.einsum("ijklvt,klmnv->ijmnvt", JP, W0.Data) lu_piv,Determ=weight.LUFactor(Denorm) Check_Denorminator(Determ,map) W.LUSolve(lu_piv, JPJ) ChiTensor.LUSolve(lu_piv, -Polar.Data) return W, ChiTensor, Determ
def FastFourierWWGammaW(GGammaG, W0, W, _map): import gamma3 # GGammaG=np.array(GGammaG) sub = 0 UPUP = _map.Spin2Index(UP, UP) DOWNDOWN = _map.Spin2Index(DOWN, DOWN) UPDOWN = _map.Spin2Index(UP, DOWN) DOWNUP = _map.Spin2Index(DOWN, UP) spinindex, spin2index = GenerateSpinIndex(_map) W.FFT("R", "T") W0.FFT("R", "T") Wshift = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") for t in range(_map.MaxTauBin): t1 = t - 1 if t1 < 0: t1 += _map.MaxTauBin Wshift.Data[:, :, :, :, :, t] = 0.5 * (W.Data[:, :, :, :, :, t1] + W.Data[:, :, :, :, :, t]) Wtot = np.array(Wshift.Data[:, 0, :, 0, :, :]) * _map.Beta / _map.MaxTauBin Wtot[:, :, :, 0] += W0.Data[:, 0, :, 0, :] Wtot = FFTWshift(Wtot, _map, 1) GGammaG = FFTGammaW(GGammaG, _map, 1) WWGammaW = gamma3.fast_fourier_wwgammaw(GGammaG, Wtot, _map.Beta, spinindex, spin2index, _map.Vol, _map.MaxTauBin) WWGammaW = FFTGammaW(WWGammaW, _map, -1) W0.FFT("R", "T") W.FFT("R", "T") return WWGammaW
def G_Dyson(G0, SigmaDeltaT, Sigma, map): Beta = map.Beta G = weight.Weight("SmoothT", map, "TwoSpins", "AntiSymmetric", "K", "W") G0.FFT("K", "W") SigmaDeltaT.FFT("K") Sigma.FFT("K", "W") NSpin, NSub = G.NSpin, G.NSublat G0SigmaDeltaT = np.einsum("ijklvt,klmnv->ijmnvt", G0.Data, SigmaDeltaT.Data) G0Sigma = np.einsum("ijklvt,klmnvt->ijmnvt", G0.Data, Sigma.Data) ####correction term for tau in range(map.MaxTauBin): G0SigmaDeltaT[..., tau] *= np.cos(np.pi * map.IndexToTau(tau) / Beta) GS = Beta / map.MaxTauBin * (Beta / map.MaxTauBin * G0Sigma + G0SigmaDeltaT) #GS shape: NSpin,NSub,NSpin,NSub,Vol,Tau I = np.eye(NSpin * NSub).reshape([NSpin, NSub, NSpin, NSub]) Denorm = I[..., np.newaxis, np.newaxis] - GS lu_piv, Determ = weight.LUFactor(Denorm) Check_Denorminator(Denorm, Determ, map) G.LUSolve(lu_piv, G0.Data) return G
def Calculate_Chi(ChiTensor, map): NSpin, NSublat = ChiTensor.NSpin, ChiTensor.NSublat SxSx = np.zeros((NSpin, NSpin)) SySy = np.zeros((NSpin, NSpin)) SzSz = np.zeros((NSpin, NSpin)) UU = map.Spin2Index(UP, UP) UD = map.Spin2Index(UP, DOWN) DU = map.Spin2Index(DOWN, UP) DD = map.Spin2Index(DOWN, DOWN) SxSx[UD, UD] = SxSx[DU, DU] = 1 SxSx[UD, DU] = SxSx[DU, UD] = 1 SySy[UD, UD] = SySy[DU, DU] = -1 SySy[UD, DU] = SySy[DU, UD] = 1 SzSz[UU, UU] = SzSz[DD, DD] = 1 SzSz[UU, DD] = SzSz[DD, UU] = -1 Chi = weight.Weight("SmoothT", map, "NoSpin", "Symmetric", ChiTensor.SpaceDomain, ChiTensor.TimeDomain) Chi.Data = 0.0 #SS=[SxSx/4.0, SySy/4.0, SzSz/4.0] #for i in range(3): #temp=np.einsum("ik, kminvt->mnvt", SS[i], ChiTensor.Data) #Chi.Data+=temp.reshape([1, NSublat, 1, NSublat, map.Vol, map.MaxTauBin]) SS = [SzSz / 4.0] for i in range(1): temp = np.einsum("ik, kminvt->mnvt", SS[i], ChiTensor.Data) Chi.Data += temp.reshape( [1, NSublat, 1, NSublat, map.Vol, map.MaxTauBin]) return Chi
def SigmaDeltaT_FirstOrder(G, W0, map): '''Hatree-Fock diagram, assume Spin Conservation''' ########Fock Diagram OrderSign = -1 AntiSymmetricFactor = -1 SigmaDeltaT = weight.Weight("DeltaT", map, "TwoSpins", "AntiSymmetric", "R") G.FFT("R", "T") W0.FFT("R") for spin1 in range(2): for spin2 in range(2): #############G(tau==-0) spinW = (map.Spin2Index(spin1, spin2), map.Spin2Index(spin2, spin1)) spinG = (spin2, spin2) spinSigma = (spin1, spin1) SigmaDeltaT.Data[spinSigma[IN], :, spinSigma[OUT], :, :]+= OrderSign \ *AntiSymmetricFactor*(1.5*G.Data[spinG[IN], :, spinG[OUT], :, :, -1]\ -0.5*G.Data[spinG[IN], :,spinG[OUT], :, :,-2])\ *W0.Data[spinW[IN], :, spinW[OUT], :, :] ########Hatree Diagram, or bubble diagram FermiLoopSign = -1 for sp1 in range(2): for sp2 in range(2): spinW = (map.Spin2Index(sp1, sp1), map.Spin2Index(sp2, sp2)) for sub1 in range(map.NSublat): for sub2 in range(map.NSublat): for r in range(map.Vol): G1 = 1.5 * G.Data[sp2, sub2, sp2, sub2, 0, -1] - 0.5 * G.Data[sp2, sub2, sp2, sub2, 0, -2] SigmaDeltaT.Data[sp1, sub1, sp1, sub1, 0]+= OrderSign*FermiLoopSign \ *AntiSymmetricFactor*G1*W0.Data[spinW[IN], sub1, spinW[OUT], sub2, r] return SigmaDeltaT
def W_FirstOrder(W0, Polar, map): W = weight.Weight("SmoothT", map, "FourSpins", "Symmetric", "K", "W") W0.FFT("K") Polar.FFT("K", "W") Beta = map.Beta TauRange = range(map.MaxTauBin) SubRange = range(W.NSublat) SubList = [(a, b, c, d) for a in SubRange for b in SubRange for c in SubRange for d in SubRange] SpinList=[(Wtuple,Polartuple) for Wtuple in map.GetConservedSpinTuple("FourSpins") \ for Polartuple in map.GetConservedSpinTuple("FourSpins") \ if map.IsConserved(4, (Wtuple[IN], Polartuple[IN]))] #make sure spin conservation on W0 for spWt, spPolart in SpinList: spW0L = (map.Spin2Index(*spWt[IN]), map.Spin2Index(*spPolart[IN])) spW0R = (map.Spin2Index(*spPolart[OUT]), map.Spin2Index(*spWt[IN])) spW = (map.Spin2Index(*spWt[IN]), map.Spin2Index(*spWt[OUT])) spPolar = (map.Spin2Index(*spPolart[IN]), map.Spin2Index(*spPolart[OUT])) for e in SubList: for tau in TauRange: W.Data[spW[IN],e[0],spW[OUT],e[3],:,tau]+=\ W0.Data[spW0L[IN],e[0],spW0L[OUT],e[1],:] \ *Polar.Data[spPolar[IN],e[1],spPolar[OUT],e[2],:,tau]\ *W0.Data[spW0R[IN],e[2],spW0R[OUT],e[3],:] return W
def Build(self): #self.BareG and self.BareW must be reinitialized at every time Build() is called self.BareG = weight.Weight("SmoothT", self.__Map, "TwoSpins", "AntiSymmetric", "R", "T") self.BareW = weight.Weight("DeltaT", self.__Map, "FourSpins", "Symmetric", "R", "T") LatName = self.Lat.Name # getattr(self, self.__Model)(LatName) try: getattr(self, self.__Model)(LatName) except: log.error( blue("Model construction fails {0}".format( traceback.format_exc()))) # Assert(False, "Model {0} has not been implemented!".format(self.__Model)) return (self.BareG, self.BareW)
def SigmaSmoothT_FirstOrder(G, W, map): '''Fock diagram, assume Spin Conservation''' OrderSign=-1 Sigma=weight.Weight("SmoothT", map, "TwoSpins", "AntiSymmetric", "R", "T") TauRange = range(map.MaxTauBin) G.FFT("R", "T") W.FFT("R", "T") for spin1 in range(2): for spin2 in range(2): spinW = (map.Spin2Index(spin1,spin2),map.Spin2Index(spin2,spin1)) spinG = (spin2, spin2) spinSigma = (spin1, spin1) Sigma.Data[spinSigma[IN], :, spinSigma[OUT], :, :] \ += OrderSign*G.Data[spinG[IN], :, spinG[OUT], :, :]\ *W.Data[spinW[IN], :, spinW[OUT], :, :] return Sigma
def Polar_FirstOrder(G, map): OrderSign = -1 FermiLoopSign = -1 AntiSymmetricFactor = -1 Polar = weight.Weight("SmoothT", map, "FourSpins", "Symmetric", "R", "T") G.FFT("R", "T") NSublat = map.NSublat NSpin = G.NSpin SubList = [(a, b) for a in range(NSublat) for b in range(NSublat)] SpList = [(a, b) for a in range(NSpin) for b in range(NSpin)] for spin1, spin2 in SpList: spinPolar = ((spin1, spin2), (spin2, spin1)) spinG1 = (spin1, spin1) spinG2 = (spin2, spin2) for subA, subB in SubList: Polar.Data[map.Spin2Index(*spinPolar[IN]),subA, \ map.Spin2Index(*spinPolar[OUT]),subB,:,:]+=OrderSign*FermiLoopSign \ *AntiSymmetricFactor*G.Data[spinG1[IN], subB, spinG1[OUT], subA, :, ::-1] \ *G.Data[spinG2[IN], subA, spinG2[OUT], subB, :, :] return Polar
def GGW(GammaG, W, _map): W.FFT("R", "T") #GammaG=SimpleGG(G,_map) OrderSign = -1 spinUP = _map.Spin2Index(UP, UP) spinDOWN = _map.Spin2Index(DOWN, DOWN) spinUPDOWN = _map.Spin2Index(UP, DOWN) spinDOWNUP = _map.Spin2Index(DOWN, UP) sub = 0 GGW = np.zeros([2, _map.Vol, _map.MaxTauBin, _map.MaxTauBin]) + 0.0 * 1j Wshift = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") for t in range(_map.MaxTauBin): t1 = t - 1 if t1 < 0: t1 += _map.MaxTauBin Wshift.Data[:, :, :, :, :, t] = 0.5 * (W.Data[:, :, :, :, :, t1] + W.Data[:, :, :, :, :, t]) for t1 in range(_map.MaxTauBin): for t2 in range(_map.MaxTauBin): dt = t1 - t2 if dt < 0: dt = dt + _map.MaxTauBin GGW[UP, :, t1, t2] = GammaG[UP, :, t1, t2] * Wshift.Data[spinUP, sub, spinUP, sub, 0, dt] GGW[UP, :, t1, t2] += GammaG[DOWN, :, t1, t2] * Wshift.Data[spinUPDOWN, sub, spinDOWNUP, sub, 0, dt] GGW[DOWN, :, t1, t2] = GammaG[UP, :, t1, t2] * Wshift.Data[spinDOWNUP, sub, spinUPDOWN, sub, 0, dt] GGW[DOWN, :, t1, t2] += GammaG[DOWN, :, t1, t2] * Wshift.Data[spinDOWN, sub, spinDOWN, sub, 0, dt] return GGW * OrderSign
def AddTwoW_To_GammaW(GammaW, W0, W, _map): # import gamma3 sub = 0 UPUP = _map.Spin2Index(UP, UP) DOWNDOWN = _map.Spin2Index(DOWN, DOWN) UPDOWN = _map.Spin2Index(UP, DOWN) DOWNUP = _map.Spin2Index(DOWN, UP) TauBin = _map.MaxTauBinTiny spinindex, spin2index = GenerateSpinIndex(_map) W.FFT("R", "T") W0.FFT("R", "T") # W.Data=(W.Data+W.Data[:,:,:,:,:,::-1])/2 #when necessary, one may need to symmetrize W Wshift = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") for t in range(_map.MaxTauBin): t1 = t - 1 if t1 < 0: t1 += _map.MaxTauBin Wshift.Data[:, :, :, :, :, t] = 0.5 * (W.Data[:, :, :, :, :, t1] + W.Data[:, :, :, :, :, t]) Wtot = np.array(Wshift.Data[:, 0, :, 0, :, :]) * _map.Beta / TauBin Interval = _map.MaxTauBin / TauBin Wtot = Wtot[:, :, :, ::Interval] #compress Wtot from MaxTauBin to TauBin Wtot[:, :, :, 0] += W0.Data[:, 0, :, 0, :] Wtot = FFTWshift(Wtot, _map, 1) #Wtot shape: spin1, spin2, dr, dt Wout = np.zeros((Wtot.shape[2], 1, Wtot.shape[3], 1), dtype=np.complex64) Wout[:, 0, :, 0] = Wtot[UPUP, UPUP, :, :] # r1, r2=0, t1, t2=0 Win = np.zeros((1, Wtot.shape[2], 1, Wtot.shape[3]), dtype=np.complex64) Win[0, :, 0, :] = Wtot[UPUP, UPUP, :, :] # r1=0, r2, t1=0, t2 GammaW = UnCompressGammaW(GammaW, _map) print GammaW.shape print Wout.shape # print "Compressing GammaW" # GammaW1=CompressGammaW(GammaW, _map) # print "UnCompressing GammaW" # GammaW2=UnCompressGammaW(GammaW1, _map) # print "UnCompressing GammaW is done" # for r1 in range(8): # # for r2 in range(8): # print "0", r1, np.amax(np.abs(GammaW[0,r1,:,:,:]-GammaW2[0,r1,:,:,:])) # for r1 in range(8): # print "1", r1,t, np.amax(np.abs(GammaW[1,r1,:,:,:]-GammaW2[1,r1,:,:,:])) #Type 0 and 1 WWGammaW = GammaW for s in range(2): print "Calculate GammaW {0}".format(s) WWGammaW[s, ...] = FFTGammaW(GammaW[s, ...], _map, 1) print "Calculate GammaW FFT done" gc.collect() # WWGammaW=Wout*WWGammaW*Win if s == 0: WWGammaW[s, ...] *= Wout WWGammaW[s, ...] *= Win else: #s==1 WWGammaW[s, ...] *= Wout * 2 WWGammaW[s, ...] *= Win * 2 # TempGammaW=Wout*TempGammaW*Win print "Calculate WWGammaW FFT back" WWGammaW[s, ...] = FFTGammaW(WWGammaW[s, ...], _map, -1) log.info( green("Memory Usage before collecting: {0} MB".format( memory_usage()))) gc.collect() log.info(green("Memory Usage : {0} MB".format(memory_usage()))) W0.FFT("R", "T") W.FFT("R", "T") # print "WWGammaW Compress" # WWGammaW1=CompressGammaW(WWGammaW, _map) # WWGammaW2=UnCompressGammaW(WWGammaW1, _map) # print (WWGammaW[1,0,1,2,:]) # print (WWGammaW2[1,0,1,2,:]) # print (WWGammaW[1,0,1,2,:]-WWGammaW2[1,0,1,2,:]) # for r1 in range(8): # print "0", r1, np.amax(np.abs(WWGammaW[0,r1,:,:,:]-WWGammaW2[0,r1,:,:,:])) # for r1 in range(8): # print "1", r1, np.amax(np.abs(WWGammaW[1,r1,:,:,:]-WWGammaW2[1,r1,:,:,:])) return -1.0 * WWGammaW
def FourierWWGammaW(GGammaG, W0, W, _map): # import gamma3 GGammaG = np.array(GGammaG) sub = 0 UPUP = _map.Spin2Index(UP, UP) DOWNDOWN = _map.Spin2Index(DOWN, DOWN) UPDOWN = _map.Spin2Index(UP, DOWN) DOWNUP = _map.Spin2Index(DOWN, UP) spinindex, spin2index = GenerateSpinIndex(_map) W.FFT("R", "T") W0.FFT("R", "T") Wshift = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") for t in range(_map.MaxTauBin): t1 = t - 1 if t1 < 0: t1 += _map.MaxTauBin Wshift.Data[:, :, :, :, :, t] = 0.5 * (W.Data[:, :, :, :, :, t1] + W.Data[:, :, :, :, :, t]) Wtot = np.array(Wshift.Data[:, 0, :, 0, :, :]) * _map.Beta / _map.MaxTauBin Wtot[:, :, :, 0] += W0.Data[:, 0, :, 0, :] Wtot = FFTWshift(Wtot, _map, 1) GGammaG = FFTGammaW(GGammaG, _map, 1) WGammaW = np.zeros([6, _map.Vol, _map.Vol, _map.MaxTauBin, _map.MaxTauBin ]) + 0.0 * 1j print "calculating WGammaW with fourier..." TempGammaW = np.array(GGammaG) TempGammaW[0, :, :, :, :] = GGammaG[0, :, :, :, :] TempGammaW[1, :, :, :, :] = GGammaG[1, :, :, :, :] TempGammaW[2, :, :, :, :] = GGammaG[1, :, :, :, :] TempGammaW[3, :, :, :, :] = GGammaG[0, :, :, :, :] TempGammaW[4, :, :, :, :] = GGammaG[5, :, :, :, :] TempGammaW[5, :, :, :, :] = GGammaG[4, :, :, :, :] Wout = np.zeros((6, Wtot.shape[2], 1, Wtot.shape[3], 1)) + 0.0 * 1j Wout[0, :, 0, :, 0] = Wtot[UPUP, UPUP, :, :] Wout[1, :, 0, :, 0] = Wtot[DOWNDOWN, DOWNDOWN, :, :] Wout[2, :, 0, :, 0] = Wtot[UPUP, DOWNDOWN, :, :] Wout[3, :, 0, :, 0] = Wtot[DOWNDOWN, UPUP, :, :] Wout[4, :, 0, :, 0] = Wtot[UPDOWN, DOWNUP, :, :] Wout[5, :, 0, :, 0] = Wtot[DOWNUP, UPDOWN, :, :] WGammaW = Wout * TempGammaW # for kout in range(_map.Vol): # for wout in range(_map.MaxTauBin): # # UPUP UPUP # WGammaW[0, kout, :, wout, :] = Wout[UPUP, UPUP, kout, wout] * GGammaG[0, kout, :, wout, :] # # DOWNDOWN DOWNDOWN # WGammaW[1, kout, :, wout, :] = Wout[DOWNDOWN, DOWNDOWN, kout, wout] * GGammaG[1, kout, :, wout, :] # # out:UPUP in:DOWNDOWN # WGammaW[2, kout, :, wout, :] = Wout[UPUP, DOWNDOWN, kout, wout] * GGammaG[1, kout, :, wout, :] # # out:DOWNDOWN in:UPUP # WGammaW[3, kout, :, wout, :] = Wout[DOWNDOWN, UPUP, kout, wout] * GGammaG[0, kout, :, wout, :] # # out:UPDOWN in:DOWNUP # WGammaW[4, kout, :, wout, :] = Wout[UPDOWN, DOWNUP, kout, wout] * GGammaG[5, kout, :, wout, :] # # out:DOWNUP in:UPDOWN # WGammaW[5, kout, :, wout, :] = Wout[DOWNUP, UPDOWN, kout, wout] * GGammaG[4, kout, :, wout, :] print "calculating WWGammaW with fourier..." Win = np.zeros((6, 1, Wtot.shape[2], 1, Wtot.shape[3])) + 0.0 * 1j Win[0, 0, :, 0, :] = Wtot[UPUP, UPUP, :, :] Win[1, 0, :, 0, :] = Wtot[DOWNDOWN, UPUP, :, :] Win[2, 0, :, 0, :] = Wtot[DOWNDOWN, UPUP, :, :] Win[3, 0, :, 0, :] = Wtot[UPUP, UPUP, :, :] Win[4, 0, :, 0, :] = Wtot[UPDOWN, DOWNUP, :, :] Win[5, 0, :, 0, :] = Wtot[DOWNUP, UPDOWN, :, :] TempGammaW[0, :, :, :, :] = WGammaW[0, :, :, :, :] TempGammaW[1, :, :, :, :] = WGammaW[3, :, :, :, :] TempGammaW[2, :, :, :, :] = WGammaW[0, :, :, :, :] TempGammaW[3, :, :, :, :] = WGammaW[3, :, :, :, :] TempGammaW[4, :, :, :, :] = WGammaW[4, :, :, :, :] TempGammaW[5, :, :, :, :] = WGammaW[5, :, :, :, :] WWGammaW = Win * TempGammaW Win[0, 0, :, 0, :] = Wtot[UPUP, DOWNDOWN, :, :] Win[1, 0, :, 0, :] = Wtot[DOWNDOWN, DOWNDOWN, :, :] Win[2, 0, :, 0, :] = Wtot[DOWNDOWN, DOWNDOWN, :, :] Win[3, 0, :, 0, :] = Wtot[UPUP, DOWNDOWN, :, :] TempGammaW[0, ...] = WGammaW[2, ...] TempGammaW[1, ...] = WGammaW[1, ...] TempGammaW[2, ...] = WGammaW[2, ...] TempGammaW[3, ...] = WGammaW[1, ...] WWGammaW[0:4, ...] += Win[0:4, ...] * TempGammaW[0:4, ...] # WWGammaW = np.zeros([6, _map.Vol, _map.Vol, _map.MaxTauBin, _map.MaxTauBin]) + 0.0*1j # for kin in range(_map.Vol): # for win in range(_map.MaxTauBin): # ## out:UPUP in:UPUP # WWGammaW[0, :, kin, :, win] = Win[UPUP, UPUP, kin, win] * WGammaW[0, :, kin, :, win] + Win[UPUP, DOWNDOWN,kin, win] * WGammaW[2, :, kin, :, win] # ## out:DOWNDOWN in:DOWNDOWN # WWGammaW[1, :, kin, :, win] = Win[DOWNDOWN, UPUP,kin, win] * WGammaW[3, :, kin, :, win] + Win[DOWNDOWN, DOWNDOWN,kin, win] * WGammaW[1, :, kin, :, win] # ## out:UPUP in:DOWNDOWN # WWGammaW[2, :, kin, :, win] = Win[DOWNDOWN, UPUP,kin, win] * WGammaW[0, :, kin, :, win] + Win[DOWNDOWN, DOWNDOWN,kin, win] * WGammaW[2, :, kin, :, win] # ## out:DOWNDOWN in:UPUP # WWGammaW[3, :, kin, :, win] = Win[UPUP, UPUP,kin, win] * WGammaW[3, :, kin, :, win] + Win[UPUP, DOWNDOWN, kin, win] * WGammaW[1, :, kin, :, win] # ## out:UPDOWN in:DOWNUP # WWGammaW[4, :, kin, :, win] = Win[UPDOWN, DOWNUP, kin, win] * WGammaW[4, :, kin, :, win] # ## out:DOWNUP in:UPDOWN # WWGammaW[5, :, kin, :, win] = Win[DOWNUP, UPDOWN, kin, win] * WGammaW[5, :, kin, :, win] WWGammaW = FFTGammaW(WWGammaW, _map, -1) W0.FFT("R", "T") W.FFT("R", "T") print "calculating WWGammaW with fourier done!" return -1.0 * WWGammaW
from operator import itemgetter # Main caller program_name = sys.argv[0] if len(sys.argv) < 6: print("usage: " + program_name + " <debug_level : 1-4> <amfi.csv> <weight.csv> ... ") sys.exit(1) debug_level = int(sys.argv[1]) in_weight_filename = sys.argv[2] out_filename_phase1 = sys.argv[3] out_filename_phase2 = sys.argv[4] out_filename_phase3 = sys.argv[5] if debug_level > 1: print('args :', len(sys.argv)) weight = weight.Weight() weight.set_debug_level(debug_level) weight.amfi_load_db() weight.weight_load_data(in_weight_filename) weight.weight_dump_ticker(out_filename_phase1) weight.weight_dump_sorted_units(out_filename_phase2) weight.weight_dump_sorted_name(out_filename_phase3)
def Dyson(IsDysonOnly, IsNewCalculation, para, Map, Lat): ParaDyson=para["Dyson"] if not para.has_key("Version"): para["Version"]=0 ########## Calulation INITIALIZATION ########################## Factory=model.BareFactory(Map, Lat, para["Model"], ParaDyson["Annealing"]) G0,W0=Factory.Build() IO.SaveDict("Coordinates","w", Factory.ToDict()) Observable=measure.Observable(Map, Lat) W=weight.Weight("SmoothT", Map, "FourSpins", "Symmetric","R","T") SigmaDeltaT=weight.Weight("DeltaT", Map, "TwoSpins", "AntiSymmetric","R") Sigma=weight.Weight("SmoothT", Map, "TwoSpins", "AntiSymmetric","R","T") Polar=weight.Weight("SmoothT", Map, "FourSpins", "Symmetric","R","T") if IsNewCalculation: #not load WeightFile log.info("Start from bare G, W") G=G0.Copy() else: #load WeightFile, load G,W log.info("Load G, W, Sigma, Polar from {0}".format(WeightFile)) data=IO.LoadBigDict(WeightFile) G=weight.Weight("SmoothT", Map, "TwoSpins", "AntiSymmetric", "R", "T").FromDict(data["G"]) W.FromDict(data["W"]) SigmaDeltaT.FromDict(data["SigmaDeltaT"]) Sigma.FromDict(data["Sigma"]) Polar.FromDict(data["Polar"]) Gold, Wold = G, W #while para["Version"]<2: while True: para["Version"]+=1 log.info(green("Start Version {0}...".format(para["Version"]))) try: ratio=None #set this will not use accumulation! #ratio = para["Version"]/(para["Version"]+10.0) G0,W0=Factory.Build() log.info("calculating SigmaDeltaT..") SigmaDeltaT.Merge(ratio, calc.SigmaDeltaT_FirstOrder(G, W0, Map)) log.info("SigmaDeltaT is done") if IsDysonOnly or IsNewCalculation: log.info("accumulating Sigma/Polar statistics...") Sigma.Merge(ratio, calc.SigmaSmoothT_FirstOrder(G, W, Map)) log.info("calculating G...") G = calc.G_Dyson(G0, SigmaDeltaT, Sigma, Map) Polar.Merge(ratio, calc.Polar_FirstOrder(G, Map)) else: log.info("Collecting Sigma/Polar statistics...") Statis=collect.CollectStatis(Map) Sigma, Polar, ParaDyson["OrderAccepted"]=collect.UpdateWeight(Statis, ParaDyson["ErrorThreshold"], ParaDyson["OrderAccepted"]) log.info("calculating G...") G = calc.G_Dyson(G0, SigmaDeltaT, Sigma, Map) #######DYSON FOR W AND G########################### log.info("calculating W...") W, ChiTensor, Determ = calc.W_Dyson(W0, Polar, Map, Lat) except calc.DenorminatorTouchZero as err: #failure due to denorminator touch zero log.info(green("Version {0} fails due to:\n{1}".format(para["Version"],err))) Factory.RevertField(ParaDyson["Annealing"]) G, W = Gold, Wold SigmaDeltaT.RollBack() Sigma.RollBack() Polar.RollBack() except collect.CollectStatisFailure as err: #failure due to statis files collection log.info(green("Version {0} fails due to:\n{1}".format(para["Version"],err))) G, W = Gold, Wold SigmaDeltaT.RollBack() Sigma.RollBack() Polar.RollBack() except KeyboardInterrupt, SystemExit: #exit log.info("Terminating Dyson\n {1}".format(para["Version"], traceback.format_exc())) sys.exit(0) except:
def test_weight_conversion_against_same_type(self): weight = w.Weight(5, 'lb') self.assertEqual(weight.convert('lb').value, 5)
def Dyson(IsDysonOnly, IsNewCalculation, EnforceSumRule, para, Map, Lat): ParaDyson = para["Dyson"] if not para.has_key("Version"): para["Version"] = 0 ########## Calulation INITIALIZATION ########################## Factory = model.BareFactory(Map, Lat, para["Model"], ParaDyson["Annealing"]) G0, W0 = Factory.Build() # G0.FFT("K","W") # print G0.Data[UP,0,UP,0,0,:] # print "Comparison 1" # for n in range(Map.MaxTauBin): # wn=1j*(2*n+1)*np.pi/Map.Beta # print 1.0/(wn-4.0), G0.Data[UP,0,UP,0,0,n]*Map.Beta/Map.MaxTauBin # print "Comparison 2" # G0.FFT("K","T") # for t in range(Map.MaxTauBin): # tau=Map.IndexToTau(t) # G0w=-np.exp(4*tau)*(1.0-1.0/(1.0+np.exp(-Map.Beta*4))) # print G0.Data[UP,0,UP,0,0,t], G0w # print "Comparison 3" # for n in range(Map.MaxTauBin): # Gw=0.0 # wn=(2*n+1)*np.pi/Map.Beta # for t in range(Map.MaxTauBin): # tau=Map.IndexToTau(t) # G0w=-np.exp(4*tau)*(1.0-1.0/(1.0+np.exp(-Map.Beta*4))) # Gw+=G0w*np.exp(-1j*wn*tau)*Map.Beta/Map.MaxTauBin # # Gw+=G0.Data[UP,0,UP,0,0,t]*np.exp(-1j*wn*tau)*Map.Beta/Map.MaxTauBin # print 1.0/(1j*wn-4.0), Gw G0.FFT("K", "T") print G0.Data[UP, 0, UP, 0, 0, :] plot.PlotTimeForList("G0UPUP_r", G0, UP, 0, UP, 0, range(Map.L[0])) plot.PlotBand(G0, Lat) IO.SaveDict("Coordinates", "w", Factory.ToDict()) Observable = measure.Observable(Map, Lat) W = weight.Weight("SmoothT", Map, "FourSpins", "Symmetric", "R", "T") SigmaDeltaT = weight.Weight("DeltaT", Map, "TwoSpins", "AntiSymmetric", "R") Sigma = weight.Weight("SmoothT", Map, "TwoSpins", "AntiSymmetric", "R", "T") Polar = weight.Weight("SmoothT", Map, "FourSpins", "Symmetric", "R", "T") if IsNewCalculation: #not load WeightFile log.info("Start from bare G, W") G = G0.Copy() if para["Gamma3"]: GGGammaG = gamma3.SimpleGG(G, Map) else: #load WeightFile, load G,W log.info("Load G, W from {0}".format(WeightFile)) data = IO.LoadBigDict(WeightFile) G = weight.Weight("SmoothT", Map, "TwoSpins", "AntiSymmetric", "R", "T").FromDict(data["G"]) W.FromDict(data["W"]) SigmaDeltaT.FromDict(data["SigmaDeltaT"]) Sigma.FromDict(data["Sigma"]) Polar.FromDict(data["Polar"]) if para["Gamma3"]: if data.has_key("GGGammaG"): GGGammaG = data["GGGammaG"]["SmoothT"] print "Read existing GGGammaG" else: GGGammaG = gamma3.SimpleGG(G, Map) Gold, Wold = G, W #while para["Version"]==0: while True: para["Version"] += 1 log.info(green("Start Version {0}...".format(para["Version"]))) try: # ratio=None #set this will not use accumulation! ratio = para["Version"] / (para["Version"] + 10.0) G0, W0 = Factory.Build() # print W0.Data[:,0,:,0,1] log.info("calculating SigmaDeltaT..") SigmaDeltaT.Merge(ratio, calc.SigmaDeltaT_FirstOrder(G, W0, Map)) log.info("SigmaDeltaT is done") # print "Polar[UP,UP]=\n", Polar.Data[spinUP,0,spinUP,0,0,:] # print "GammaG[UP,UP]=\n", GammaG[UP,0,:,-1] if IsDysonOnly or IsNewCalculation: log.info("accumulating Sigma/Polar statistics...") G = calc.G_Dyson(G0, SigmaDeltaT, Sigma, Map) Sigma.Merge(ratio, calc.SigmaSmoothT_FirstOrder(G, W, Map)) log.info("calculating G...") G = calc.G_Dyson(G0, SigmaDeltaT, Sigma, Map) Polar.Merge(ratio, calc.Polar_FirstOrder(G, Map)) if para["Gamma3"]: # irreducible GGGammaG = simpleGG + GGGammaG_2 + GGGammaG_3 # the second term GammaG: the term from dSigma/dG # GGGammaG_2 = G*(W*GGGammaG)*G print "Attach W to GGGammaG" GammaG = gamma3.AddW_To_GGGammaG(GGGammaG, W, G.Map) print "Calculate GammaG contribution to GGGammaG" GGGammaG_2 = gamma3.AddTwoG_To_GammaG(GammaG, G, G.Map) if Map.MaxTauBin == Map.MaxTauBinTiny: # the third term: the term from dSigma/dW # GGGammaG_3 = G*((W*(G*GGGammaG)*W)*G)*G print "Calculate GammaW" GammaW = gamma3.AddG_To_GGGammaG(GGGammaG, G, G.Map) print "Calculate WWGammaW" WWGammaW = gamma3.AddTwoW_To_GammaW( GammaW, W0, W, G.Map) print "Calculate GammaG from WWGammaW" GammaG_FromWWGammaW = gamma3.AddG_To_WWGammaW( WWGammaW, G, G.Map) print "Calculate WWGammaW contribution to GGGammaG" GGGammaG_3 = gamma3.AddTwoG_To_GammaG( GammaG_FromWWGammaW, G, G.Map) else: WWGammaW = None GGGammaG_3 = 0.0 SimpleGGGammaG = gamma3.SimpleGG(G, Map) GGGammaG = SimpleGGGammaG GGGammaG += +GGGammaG_2 - GGGammaG_3 else: log.info("Collecting Sigma/Polar statistics...") SigmaStatis, PolarStatis, GammaG_MC, GammaW_MC = collect.CollectStatis( Map, para["Gamma3"]) Sigma, Polar_MC, ParaDyson[ "OrderAccepted"] = collect.UpdateWeight( [SigmaStatis, PolarStatis], ParaDyson["ErrorThreshold"], ParaDyson["OrderAccepted"]) #print Sigma.Data[0,0,0,0,0,0], Sigma.Data[0,0,0,0,0,-1] log.info("calculating G...") G = calc.G_Dyson(G0, SigmaDeltaT, Sigma, Map) SigmaDyson = calc.SigmaSmoothT_FirstOrder(G, W, Map) print "SigmaFromDyson=\n", SigmaDyson.Data[UP, 0, UP, 0, 0, :] Polar.Merge(ratio, Polar_MC) if para["Gamma3"]: print "Calculate WWGammaW contribution to GGGammaG" WWGammaW = gamma3.AddTwoW_To_GammaW( GammaW_MC, W0, W, G.Map) print "Calculate GGGammaW contribution to GGGammaG" GGGammaG_MC = gamma3.AddTwoG_To_GammaG(GammaG_MC, G, G.Map) print "Add Simple GG contribution to GGGammaG" GGGammaG = gamma3.SimpleGG(G, Map) + GGGammaG_MC # print "GammaG, mc=\n", 0.5*(np.sum(GGGammaG_MC[DOWN, :, :, :]-GGGammaG_MC[UP, :, :, :], axis=0)).diagonal() #######DYSON FOR W AND G########################### log.info("calculating W...") Wtmp, ChiTensor, Determ = calc.W_Dyson(W0, Polar, Map, Lat) if EnforceSumRule: ChiTensor = calc.Add_ChiTensor_ZerothOrder(ChiTensor, G, Map) Chi = calc.Calculate_Chi(ChiTensor, Map) Chi.FFT("R", "T") while abs(Chi.Data[0, 0, 0, 0, 0, 0] - 0.75) > 1.e-3: SumRuleRatio = np.sqrt(0.75 / Chi.Data[0, 0, 0, 0, 0, 0]) PolarSumRule = Polar PolarSumRule.Data = PolarSumRule.Data * SumRuleRatio Wtmp, ChiTensor, Determ = calc.W_Dyson(W0, Polar, Map, Lat) ChiTensor = calc.Add_ChiTensor_ZerothOrder( ChiTensor, G, Map) Chi = calc.Calculate_Chi(ChiTensor, Map) Chi.FFT("R", "T") print "Chi(r=0,t=0)", Chi.Data[0, 0, 0, 0, 0, 0] W = Wtmp except calc.DenorminatorTouchZero as err: #failure due to denorminator touch zero log.info( green("Version {0} fails due to:\n{1}".format( para["Version"], err))) Factory.RevertField(ParaDyson["Annealing"]) G, W = Gold, Wold SigmaDeltaT.RollBack() Sigma.RollBack() Polar.RollBack() except collect.CollectStatisFailure as err: #failure due to statis files collection log.info( green("Version {0} fails due to:\n{1}".format( para["Version"], err))) G, W = Gold, Wold SigmaDeltaT.RollBack() Sigma.RollBack() Polar.RollBack() except KeyboardInterrupt, SystemExit: #exit log.info("Terminating Dyson\n {1}".format(para["Version"], traceback.format_exc())) sys.exit(0) except:
def test_instantiation(self): weight = w.Weight(5, 'lb')
def test_weight_subtraction_against_different_type(self): weight = w.Weight(5, 'kg') other_weight = w.Weight(5, 'lb') self.assertEqual((weight - other_weight).value, 2.7320381499999997)
def AddTwoW_To_GammaW_basis(GammaW, W0, W, _map): # import gamma3 sub = 0 UPUP = _map.Spin2Index(UP, UP) DOWNDOWN = _map.Spin2Index(DOWN, DOWN) UPDOWN = _map.Spin2Index(UP, DOWN) DOWNUP = _map.Spin2Index(DOWN, UP) spinindex, spin2index = GenerateSpinIndex(_map) W.FFT("R", "T") W0.FFT("R", "T") Wshift = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric", "R", "T") for t in range(_map.MaxTauBin): t1 = t - 1 if t1 < 0: t1 += _map.MaxTauBin Wshift.Data[:, :, :, :, :, t] = 0.5 * (W.Data[:, :, :, :, :, t1] + W.Data[:, :, :, :, :, t]) Wshift = np.array(Wshift.Data[:, 0, :, 0, :, :]) * _map.Beta / _map.MaxTauBin Wtot = np.zeros([_map.Vol, _map.MaxTauBin, _map.MaxTauBin], dtype=np.complex) Wshift[:, :, :, 0] += W0.Data[:, 0, :, 0, :] for t1 in range(_map.MaxTauBin): for t2 in range(_map.MaxTauBin): dt = t1 - t2 if dt < 0: dt += _map.MaxTauBin Wtot[:, t1, t2] = Wshift[0, 0, :, dt] Wtot = FFTWshift_Space(Wtot, _map, 1) Wtot = FitW(Wtot, _map) GammaW1 = RestoreGammaW(GammaW, _map) print "GammaW" print GammaW1[0, 0, 0, 0, :] print GammaW1[1, 0, 0, 15, :] WWGammaW = np.zeros([2, _map.Vol, _map.Vol, _map.BasisNum, _map.BasisNum], dtype=np.complex) # FittedGammaW=FitGammaW(GammaW, _map) for s in range(2): TempGammaW = FFTGammaW_Space(GammaW[s, ...], _map, 1) TempGammaW = np.einsum("ijkl, imk->ijml", TempGammaW, Wtot) TempGammaW = np.einsum("ijml, jnl->ijmn", TempGammaW, Wtot) TempGammaW = FFTGammaW_Space(TempGammaW, _map, -1) if s == 1: TempGammaW *= 4.0 WWGammaW[s, ...] = TempGammaW # WWGammaW=RestoreGammaW(WWGammaW, _map) log.info( green("Memory Usage before collecting: {0} MB".format(memory_usage()))) gc.collect() log.info(green("Memory Usage : {0} MB".format(memory_usage()))) W0.FFT("R", "T") W.FFT("R", "T") return -1.0 * WWGammaW
Ktemp = [(-3, 0), (3, 0), (0, 3), (0, -3)] k, ChiK = lat.FourierTransformation( Chi.Data[0, :, 0, :, :, omega] * map.Beta / map.MaxTauBin, Ktemp, "Integer") else: log.warn("Lattice PlotChi_2D not implemented yet!") if DoesSave: plt.savefig("chiK_{0}.pdf".format(lat.Name)) else: plt.show() plt.close() log.info("Plotting done!") if __name__ == "__main__": import weight import IO WeightPara = {"NSublat": 4, "L": [8, 8, 8], "Beta": 6.0, "MaxTauBin": 64} Map = weight.IndexMap(**WeightPara) l = lat.Lattice("Pyrochlore", Map) Dict = IO.LoadBigDict("Weight")["Chi"] Chi = weight.Weight("SmoothT", Map, "NoSpin", "Symmetric", "R", "T").FromDict(Dict) PlotChiAlongPath(Chi, l) PlotChi_2D(Chi, l) PlotWeightvsR("\chi", Chi, l, 0, 0)
def test_simple_weight_addition(self): weight = w.Weight(5, 'lb') other_weight = w.Weight(5, 'lb') self.assertEqual(weight.value + other_weight.value, 10)
def test_weight_conversion_thats_circular(self): weight = w.Weight(5, 'lb') self.assertEqual(weight.convert('kg').convert('lb').value, 5)
def __init__(self, io): self.proximity = proximity.Proximity() self.inductive = inductive.Inductive(io) self.weight = weight.Weight(io)
def test_weight_addition_against_different_types(self): weight = w.Weight(5, 'lb') other_weight = w.Weight(5, 'kg') self.assertEqual((weight + other_weight).value, 16.02311310924388)
def test_weight_conversion(self): weight = w.Weight(5, 'lb') self.assertEqual(weight.convert('kg').value, 2.2679618500000003)
def CollectStatis(_map, runGamma3=False): Sigma = weight.Weight("SmoothT", _map, "TwoSpins", "AntiSymmetric") SigmaSmoothT = WeightEstimator(Sigma) Polar = weight.Weight("SmoothT", _map, "FourSpins", "Symmetric") PolarSmoothT = WeightEstimator(Polar) GammaGAccu = None GammaWAccu = None if runGamma3: GammaGAccu = None GammaWAccu = None GammaGNorm = None GammaWNorm = None GammaGNormAccu = 1.e-8 GammaWNormAccu = 1.e-8 # GammaWFluc=[] _FileList = GetFileList() if len(_FileList) == 0: raise CollectStatisFailure("No statistics files to read!") log.info("Collect statistics from {0}".format(_FileList)) Total = len(_FileList) Success = 0.0 for f in _FileList: try: log.info("Merging {0} ...".format(f)) Dict = IO.LoadBigDict(f) SigmaSmoothT.MergeFromDict(Dict['Sigma']['Histogram']) PolarSmoothT.MergeFromDict(Dict['Polar']['Histogram']) if runGamma3: dataG = Dict["GammaGStatis"] if GammaGNorm is not None: GammaGAccu += dataG['WeightAccu'] GammaGNormAccu += dataG['NormAccu'] Assert(GammaGNorm == dataG['Norm'], "Norm have to be the same to merge statistics") else: GammaGAccu = dataG['WeightAccu'] GammaGNormAccu = dataG['NormAccu'] GammaGNorm = dataG['Norm'] dataW = Dict["GammaWStatis"] if GammaWNorm is not None: GammaWAccu += dataW['WeightAccu'] GammaWNormAccu += dataW['NormAccu'] Assert(GammaWNorm == dataW['Norm'], "Norm have to be the same to merge statistics") # GammaWFluc.append(dataW['WeightAccu'][0,0,0,0,:]/dataW['NormAccu']*dataW['Norm']) else: GammaWAccu = dataW['WeightAccu'] GammaWNormAccu = dataW['NormAccu'] GammaWNorm = dataW['Norm'] # GammaWFluc.append(dataW['WeightAccu'][0,0,0,0,:]/dataW['NormAccu']*dataW['Norm']) except: log.info("Fails to merge\n {0}".format(traceback.format_exc())) else: Success += 1.0 log.info("{0}/{1} statistics files read!".format(int(Success), Total)) if float(Success) / Total < AcceptRatio: raise CollectStatisFailure( "More than {0}% statistics files fail to read!".format( 100.0 * AcceptRatio)) if runGamma3: GammaGAccu *= 1.0 / GammaGNormAccu * GammaGNorm GammaWAccu *= 1.0 / GammaWNormAccu * GammaWNorm GammaWAccu = np.array(GammaWAccu, dtype=np.complex64) # GammaWFluc=np.array(GammaWFluc) # print np.std(GammaWFluc, axis=0) # print np.mean(GammaWFluc, axis=0) return (SigmaSmoothT, PolarSmoothT, GammaGAccu, GammaWAccu)
def test_simple_weight_subtraction(self): weight = w.Weight(5, 'lb') other_weight = w.Weight(2, 'lb') self.assertEqual((weight - other_weight).value, 3)