def pos(self,poscel,par): ipar = 1 - int(par) x = poscel[0] - 1 * abs(poscel[0] % 2 - ipar) y = poscel[1] - 1 * abs(poscel[1] % 2 - ipar) z = poscel[2] - 1 * abs(poscel[2] % 2 - ipar) debg(x,y,z) return x,y,z
def walled(self): """ returns a walled copy of the Cube """ pos = self.positions() x0, x1, y0, y1, z0, z1 = parpos = partition(pos) # if there are five of them, a face is maybe full. # it could mean that one of those has 4 pos in it fullfaces = [gr for gr in parpos if len(gr.li) >= 4] if fullfaces: for gr in fullfaces: for p in pos: if p not in gr.li: if gr.c == 'x': p.y = int(not p.y) p.z = int(not p.z) if gr.c == 'y': p.x = int(not p.x) p.z = int(not p.z) if gr.c == 'z': p.y = int(not p.y) p.x = int(not p.x) # could use p.x ^ 1 (bitwise) z = self.copy() z.from_pos(pos) debg("Walled cube : ", z) return z else: debg("Not Walled cube : ", self) return self.reversed()
def add(self,poscel,par): """ Adds a cube to the defaultdict li if it was not already there. It activates the right cell. """ x,y,z = poscel xc,yc,zc = self.pos(poscel,par) self.li[xc,yc,zc][x-xc,y-yc,z-zc].activate() debg((x-xc,y-yc,z-zc,xc,yc,zc)) debg(self.li[xc,yc,zc])
def inL(self): """ checks whether the PosGroup is in a L shape or not. If it is, it returns the "top" of the L (which is, the one Cell that should be 'moving' ), the PosGroup of the other two things the InputValue (0 or 1)""" try: a, b, c = pos = self.li except ValueError: return False x0y0, x0y1, x1y0, x1y1, y0z0, y0z1, y1z0, y1z1, x0z0, x0z1, x1z0, x1z1 = parpos = partition_edge( [a, b, c]) inhab = [gr for gr in parpos if len(gr.li) >= 2] candi = [] if len(inhab) == 1: # Rotate until well placed, input is 1 gr = inhab[0] for p in (a, b, c): # p is not with the others if p not in gr.li: return p, gr, 1 else: #3 are in a face x0, x1, y0, y1, z0, z1 = faces = partition(pos) lihab = [gr for gr in faces if len(gr.li) >= 3] if lihab: fhab = lihab[0] #fhab = inhabited face for p in (a, b, c): if p not in fhab.li: raise BaseException( "Unexpected case happened. Contact us.") contcell = find_contam(a, b, c, fhab, pos) stablegroup = [ gr for gr in parpos if contcell not in gr.li and len(gr.li) == 2 ][0] return contcell, stablegroup, 0 else: # "dispersed" case. # no cubes share a face debg("Dispersed case") debg(str(lihab) + str(a) + str(b) + str(c)) return False return False
def create_li(qbsli, i, newsuper): """ all qcubes < i have been dealt with """ # newsuper is a list of amplitude,conf if i >= len(qbsli): # all qcubes have been tensored into configs return newsuper litot = [] # full list qcubepos, qcubes = qbsli[i] # position of the current qcube for qcube in qcubes.cubes: nl = [] alpha = qcube.alpha cube = qcube.cube x, y, z = qcubepos act = [cellpos.xyz() for cellpos in cube.positions()] debg("POSITIONS OF THE CELLS :", act) debg("POSITIONS OF THE QCUBE :", (x, y, z)) act = [(a + x, b + y, c + z) for (a, b, c) in act] for a, conf in newsuper: nc = conf.copy() for pos in act: nc[pos].activate() nl.append((a * alpha, nc)) litot += create_li(qbsli, i + 1, nl) return litot
def evolution(self, par, alpha): licube = Cubes() for pos, cell in self._c.items(): if cell.v: licube.add(pos, par) else: del self._c[pos] debg("Initial cubes ", licube) # here all the cubes have been created and cells have been activated qbsli = [] for pos, ac in licube.li.items(): qbsli.append((pos, ac.f())) debg("QBSLI (list of modified cubes (QCubes) and their position)", qbsli) cl = create_li(qbsli, 0, [(alpha, Econfig())]) debg("CREATED LI : ", str(cl)) return cl
def next(self): """ Executes a step H """ debg("STEP : ", self.step, "PARITY:", self.pstep()) debg("IPAR : ", 1 - self.pstep()) newsuper = Super() for conf, alpha in self.s.cs.items(): if alpha: li = conf.evolution(self.pstep(), alpha) debg(li) # extremely sub optimal, a list should never be used for a superposition # use a superposition (Super object) instead for a, conf in li: newsuper[conf] += a else: warn("step ", self.step, " ; Suppressed a conf:", conf) print("Suppressed a conf :", conf) self.s = newsuper self.step += 1
def apply(self, cube): """ Returns the obtained cubes, included in a QCubes object """ qbs = QCubes() if len(cube) == 1: qbs.addc(cube.reversed(), 1) elif len(cube) == 2: pos = cube.positions() a, b = pos if a.adjacent(b): qbs.addc(cube.copy(), 1) else: if cube.cross(): qbs.addc(cube.reversed(), (1 + 1j) * self.sq2) else: qbs.addc(cube.reversed(), 1) elif len(cube) == 3: debg("**********3************") pos = cube.positions() debg("INIT:", pos) a, b, c = pos inl = partition_edge(pos) if not inl: qbs.addc(cube.reversed(), 1) else: inLresult = PosGroup([a, b, c]).inL() if inLresult: inp, gr, inputval = inLresult x0, x1, y0, y1, z0, z1 = faces = partition(pos) pos1, pos2 = gr.li axes = gr.c if 'z' not in axes: xv, yv = gr.v if inputval: face1 = [ f for f in faces if f.c == 'x' and f.v == xv ][0] face2 = [ f for f in faces if f.c == 'y' and f.v == yv ][0] if find_contam(a, b, c, face1, pos) == inp: newinp = Position(xv, inp.y, inp.z) else: newinp = Position(inp.x, yv, inp.z) else: newinp = inp newpos1 = Position(newinp.x, newinp.y, not newinp.z) newpos2 = Position(not xv, not yv, not newinp.z) if 'x' not in axes: yv, zv = gr.v if inputval: face1 = [ f for f in faces if f.c == 'y' and f.v == yv ][0] face2 = [ f for f in faces if f.c == 'z' and f.v == zv ][0] if find_contam(a, b, c, face1, pos) == inp: newinp = Position(inp.x, yv, inp.z) else: newinp = Position(inp.x, inp.y, zv) else: newinp = inp newpos1 = Position(not newinp.x, newinp.y, newinp.z) newpos2 = Position(not newinp.x, not yv, not zv) if 'y' not in axes: zv, xv = gr.v if inputval: face1 = [ f for f in faces if f.c == 'z' and f.v == zv ][0] face2 = [ f for f in faces if f.c == 'x' and f.v == xv ][0] if find_contam(a, b, c, face1, pos) == inp: newinp = Position(inp.x, inp.y, zv) else: newinp = Position(xv, inp.y, inp.z) else: newinp = inp newpos1 = Position(newinp.x, not newinp.y, newinp.z) newpos2 = Position(not xv, not newinp.y, not zv) cube1 = Cube() cube1.from_pos([pos1, pos2, newpos1]) cube2 = Cube() cube2.from_pos([pos1, pos2, newpos2]) debg("Cube1:", [pos1, pos2, newpos1]) debg("Cube2:", [pos1, pos2, newpos2]) qbs.addc(cube1, self.sq2) qbs.addc(cube2, ((-1)**inputval) * self.sq2) else: #"Dispersed" case (no common face) debg("Dispersed case:", pos) qbs.addc(cube.reversed(), 1) debg("***********************") elif len(cube) == 4: debg("cube of size 4, qbs was:", qbs) debg('adding : ', cube.walled()) qbs.addc(cube.walled(), 1) # reverse, identity if wall debg("cube of size 4, qbs is:", qbs) elif len(cube) == 5: qbs.addc(cube.walled(), 1) else: # if no special configuration is met, # it's as if they were alone. However, with 6 # active cells or more, there is a wall, so # nothing should move to avoid wall destruction ! # (it could be possible to make everything move - anyway) qbs.addc(cube.reversed(), 1) debg("in .apply : Calculating from ", cube, "\nto:\n", qbs) return qbs
def cellconservation(self): """ Tests whether no configuration has a different number of cells """ confnum = [len(k) for k, v in self.s.cs.items() if v] debg([(k, len(k)) for k, v in self.s.cs.items() if v]) assert not [False for n in confnum if n != confnum[0]]