def modifyRegGivenChrom(self): """Modifiy self.reg based on self.regChrom """ # Loop through self.reg and update 'newState' for r, regData in self.reg.items(): for phase, phaseData in regData['phases'].items(): # Extract the binary representation of tap position. tapBin = \ self.regChrom[phaseData['chromInd'][0]:\ phaseData['chromInd'][1]] # Convert the binary to an integer posInt = helper.bin2int(tapBin) # Get the tap position. tap = gld.translateTaps(lowerTaps=self.reg[r]['lower_taps'], pos=posInt) # Fix the tap position if it's out of bounds. if tap < -self.reg[r]['lower_taps']: tap = -self.reg[r]['lower_taps'] elif tap > self.reg[r]['raise_taps']: tap = self.reg[r]['raise_taps'] # Convert integer to tap position and assign to new position self.reg[r]['phases'][phase]['newState'] = tap # Increment the tap change counter (previous pos - this pos) self.tapChangeCount += \ abs(self.reg[r]['phases'][phase]['prevState'] - self.reg[r]['phases'][phase]['newState'])
def genRegChrom(self, flag): """Method to randomly generate an individual's regulator chromosome INPUTS: flag: dictates how regulator tap positions are created. 0: All regulator taps set to their minimum tap position 1: All regulator taps set to their maximum tap position 2: Regulator tap positions will be biased (via a Gaussian distribution and the TAPSIGMAPCT constant) toward the previous tap positions 3: Regulator state unchanged - simply reflects what's in the reg input's 'prevState' 4: Regulator state given in reg input's 'newState' - just need to generate chromosome and count tap changes 5: Regulator tap positions will be determined randomly NOTE: the individual's controlFlag will be used to determine whether or not the individual's tapChangeCount should be updated. """ # Initialize chromosome for regulator and dict to store list indices. self.regChrom = () # Intialize index counters. s = 0 e = 0 # Loop through the regs and create binary representation of taps. for r, v in self.reg.items(): # Define the upper tap bound (tb). tb = v['raise_taps'] + v['lower_taps'] # Compute the needed field width to represent the upper tap bound # Use + 1 to account for 2^0 width = helper.binaryWidth(tb) # Define variables as needed based on the flag. I started to try to # make micro-optimizations for code factoring, but let's go for # readable instead. if flag == 0: newState = 0 elif flag == 1: newState = tb elif flag == 2: # If we're biasing from the previous position, get a sigma for # the Gaussian distribution. tapSigma = round(TAPSIGMAPCT * (tb + 1)) elif flag == 3: state = 'prevState' elif flag == 4: state = 'newState' # Loop through the phases for phase, phaseData in v['phases'].items(): # If we're biasing new positions based on previous positions: if flag == 2: # Randomly draw tap position from gaussian distribution. # Translate previous position to integer on interval [0,tb] prevState = \ gld.inverseTranslateTaps(lowerTaps=v['lower_taps'], pos=phaseData['prevState']) # Initialize the newState for while loop. newState = -1 # The standard distribution runs from (-inf, +inf) - draw # until position is valid. Recall valid positions are # [0, tb] while (newState < 0) or (newState > tb): # Draw the tap position from the normal distribution. # Here oure 'mu' is the previous value newState = round(random.gauss(prevState, tapSigma)) elif (flag == 3) or (flag == 4): # Translate position to integer on interval [0, tb] newState = \ gld.inverseTranslateTaps(lowerTaps=v['lower_taps'], pos=phaseData[state]) elif flag == 5: # Randomly draw. newState = random.randint(0, tb) # Express tap setting as binary list with consistent width. binTuple = tuple([ int(x) for x in "{0:0{width}b}".format(newState, width=width) ]) # Extend the regulator chromosome. self.regChrom += binTuple # Increment end index. e += len(binTuple) # Translate newState for GridLAB-D. self.reg[r]['phases'][phase]['newState'] = \ gld.translateTaps(lowerTaps=v['lower_taps'], pos=newState) # Increment the tap change counter (previous pos - this pos) if # this individual is using MANUAL control. Otherwise, tap # changes must be computed after the model run. if self.controlFlag == 0: self.tapChangeCount += \ abs(self.reg[r]['phases'][phase]['prevState'] - self.reg[r]['phases'][phase]['newState']) # Ensure the indices for this phase match what was originally # built. if self.reg[r]['phases'][phase]['chromInd'] != (s, e): raise UserWarning(('The original regulator chromosome ' 'indices do not match what individual ' 'calculated!')) # Increment start index. s += len(binTuple)
def test_translateTaps(self): """translateTaps translates tap position on [0, t + t] to [-t, t]""" for el in TRANSLATETAPSLIST: with self.subTest(tapList=el): out = gld.translateTaps(el[0], el[1]) self.assertEqual(el[2], out)