def gradient(self, x): gradient = [] for i in range(len(x)): curPlus = x[:] curPlus[i] += self.delta samplePlus = structure.QuickStruct(self.matArray, curPlus, self.constraint, self.indices, self.indexdic, phase=False) mvPlus = samplePlus.meritFunction() curMinus = x[:] curMinus[i] -= self.delta sampleMinus = structure.QuickStruct(self.matArray, curMinus, self.constraint, self.indices, self.indexdic, phase=False) mvMinus = sampleMinus.meritFunction() gradient.append( min((mvPlus - mvMinus) / (2 * self.delta) * 400, 1.)) return gradient
def vectorization1D(self, iterations): for sam in self.sample: mvlist = [] curSample = structure.QuickStruct(self.limits, sam, phase=False) sam_init = sam[:] MV_init = curSample.MV sam_pre = sam[:] MV_pre = 1 iter = 0 while iter < iterations: iter += 1 gradient = [] for i in range(len(sam_pre)): curPlus = sam_pre[:] curPlus[i] += self.delta samplePlus = structure.QuickStruct(self.limits, curPlus, phase=False) mvPlus = samplePlus.MV curMinus = sam_pre[:] curMinus[i] -= self.delta sampleMinus = structure.QuickStruct(self.limits, curMinus, phase=False) mvMinus = sampleMinus.MV gradient.append( min((mvPlus - mvMinus) / (2 * self.delta) * 800, 1.)) sam_cur = sam_pre[:] sam_cur = np.array(sam_cur) - np.array( gradient) * self.learningRate * 2 * self.delta curSample = structure.QuickStruct(self.limits, sam_cur, phase=False) MV_cur = curSample.MV print('Gradient', gradient) print('Current Structure', list(sam_cur)) print('Previous MV is', MV_pre, 'Current MV is', MV_cur) mvlist.append(MV_cur) sam_pre = sam_cur[:] MV_pre = MV_cur print('Finished Current Sample, mv list is', mvlist)
def ros(self, x): curSample = structure.QuickStruct(self.matArray, x, self.constraint, self.indices, self.indexdic, phase=False) MV = curSample.meritFunction() return MV
def quickConverge(self, timeOut=50000): delta = 0.2 for sam in self.sample: startTime = time.time() mvlist = [] curThickness = np.array(sam[:]) while time.time() - startTime < timeOut: curSample = structure.QuickStruct(self.limits, curThickness, phase=False) curMV = curSample.MV mvlist.append(curMV) for i_t in range(len(curThickness)): curThicknessPlus = curThickness[:] curThicknessPlus[i_t] += delta curSamplePlus = structure.QuickStruct(self.limits, curThicknessPlus, phase=False) curMVPlus = curSamplePlus.MV if curMVPlus < curMV: curThickness[i_t] += delta mvlist.append(curMVPlus) curMV = curMVPlus else: curThicknessMinus = curThickness[:] curThicknessMinus[i_t] -= delta curSampleMinus = structure.QuickStruct( self.limits, curThicknessMinus, phase=False) curMVMinus = curSampleMinus.MV if curMVMinus < curMV: curMV = curMVMinus curThickness[i_t] -= delta mvlist.append(curMVMinus) print('Current thickness', list(curThickness)) print('curMV', curMV) print('mvList', mvlist) return mvlist
import numpy as np from src import structure, optimize, plotting, meritFunction # Quick Plot thickness = [218.79999999999981, 111.40000000000005, 118.2, 58.349999999999987, 161.29999999999984, 79.690000000000012, 99.600000000000009, 50.000000000000007, 225.90000000000001, 113.0, 174.5, 87.690000000000012, 128.79999999999998, 64.239999999999995, 131.09999999999999, 65.579999999999998, 155.59999999999999, 77.840000000000003, 133.0, 66.940000000000012, 185.29999999999998, 92.870000000000005, 124.7, 62.600000000000009, 157.59999999999997, 79.030000000000001, 115.3, 57.689999999999998, 138.80000000000001, 69.439999999999998, 149.69999999999999, 75.300000000000011, 204.19999999999996, 102.30000000000001, 116.50000000000001, 57.799999999999997, 127.0, 63.549999999999997, 157.09999999999997, 78.400000000000006, 171.59999999999999, 85.829999999999998, 160.19999999999999, 80.109999999999999, 139.89999999999998, 71.370000000000019, 104.10000000000002, 53.08000000000002, 184.39999999999992, 93.050000000000026] print(len(thickness)) # limit = structure.Limitations(material=['YAG.txt', 'SiO2.txt', 'Ta2O5.txt', 'Al2O3.txt', 'MgF2.txt', '19.txt'], constriant={'minWave': 430, # 'maxWave': 650, # 'waveStep': 1, # 'angle':range(90), # 'target':560 # }, defaultStructure=['Al2O3.txt'] + ['Ta2O5.txt', 'SiO2.txt']*15 + ['Ta2O5.txt', 'MgF2.txt']*14 +["19.txt"]+ ["YAG.txt"], # meritFunction=meritFunction.meritFunction3, padding=True) limit = structure.Limitations(material=['air.txt', 'Si.txt', 'Al2O3.txt', 'InP.txt'], constriant={'minWave': 1300, 'maxWave': 1340, 'waveStep': 1, 'angle':[0], 'target':1290 }, defaultStructure=['air.txt'] + ['Al2O3.txt', 'Si.txt']*25 + ["InP.txt"], meritFunction=meritFunction.meritFunction4, padding=False) # struct = structure.PlotStruct(limit, thickness, phase=False) # print(struct.MV) # plotting.surfaceplot(struct.R, RP=struct.RP, RS=struct.RS, waves=struct.waves, angles=struct.angle) structure = structure.QuickStruct(limit, thickness, phase=False) plotting.quickplot(structure.R, structure.waves, structure.angle)
def pairOptimize(ti1, ti2, thickness): rta = structure.QuickStruct(self.matArray, thickness, self.constraint, self.indices, self.indexdic, phase=False) mv_curmax = rta.meritFunction() print('Inputed material\'s index is {}'.format(mv_curmax)) mv_pre = 1 # initialize overall_iter = 0 while (overall_iter == 0 or mv_pre > mv_curmax) and overall_iter <= 20: print( 'last merit value is {}, overall iteration is {}, current mv is {}' .format(mv_pre, overall_iter, mv_curmax)) print('current structure is {}'.format([thickness])) mv_pre = mv_curmax inner_iter = 0 mv_pre_inner = 1 # initialize while (inner_iter == 0 or mv_pre_inner > mv_curmax) and inner_iter <= 50: mv_pre_inner = mv_curmax for thickindex in [ti1, ti2]: # determine directions thickness_temp = thickness[:] thickness_temp[thickindex] += 0.2 rta = structure.QuickStruct(self.matArray, thickness_temp, self.constraint, self.indices, self.indexdic, phase=False) mv_positive = rta.meritFunction() thickness_temp[thickindex] -= 0.4 rta = structure.QuickStruct(self.matArray, thickness_temp, self.constraint, self.indices, self.indexdic, phase=False) mv_negative = rta.meritFunction() thickness_temp[thickindex] += 0.2 # optimize if mv_positive >= mv_pre_inner and mv_negative >= mv_pre_inner: continue # early stop else: sign = (-1, 1)[mv_positive < mv_negative] initial_step = step = 0.2 mv_pre_singlelayer = 1 temp_count = 0 while mv_curmax < mv_pre_singlelayer or step > initial_step: # only end with the smallest increasement if mv_curmax == mv_pre_singlelayer or temp_count == 0: step = initial_step else: step = step * 2 # exponentially growth mv_pre_singlelayer = mv_curmax # record mv of last optimization thickness_temp = thickness[:] thickness_temp[thickindex] += sign * step rta = structure.QuickStruct(self.matArray, thickness_temp, self.constraint, self.indices, self.indexdic, phase=False) mv_current = rta.meritFunction() if mv_current < mv_curmax: # if mv is better, update thickness and mv_curmax mv_curmax = mv_current thickness = thickness_temp[:] print( 'thickness updated, {}, the inside count{}, current mv is {}' .format(thickness, temp_count, mv_curmax)) # else, nothing happends, last time. In next iteration, step would become initial_step. # if still nothing happends, this iteration would end temp_count += 1 inner_iter += 1 overall_iter += 1 return thickness[ti1], thickness[ti2]
def Ndimensionalauto(self, iterations=30): # method could be top N and pick by probability for sam in self.sample: mvlist = [] curIteration = 0 curThickness = np.array(sam[:]) N = [1, 2, 3, 5, 10] delta = [0.1, 0.2, 0.3, 0.5, 1.0] probability = np.array([[1.0] * 5 for _ in range(5)]) while curIteration < iterations: curSample = structure.StructJacobian(self.limits, curThickness) curMV = curSample.MV print('current cost {}, current thicknss{}'.format( curMV, list(curThickness))) mvlist.append(curMV) jacobian = curSample.Jacobian print('jacobian', jacobian) # select layers to update sortjacobian = sorted(enumerate(jacobian), key=lambda x: abs(x[1]))[::-1] print('sortedJacobian', sortjacobian) iterMV = curMV tempThickness = curThickness[:] nextThickness = [] selectIJ = [(0, 0)] for i in range(5): for j in range(5): if np.random.random() < probability[i][j]: curN = N[i] curDelta = delta[j] selectedLayers = sortjacobian[:curN] selectedIndex = [i[0] for i in selectedLayers] normalizeFactor = curDelta / sortjacobian[0][1] deltaThickness = [] for ii in range(len(jacobian)): if ii in selectedIndex: deltaThickness.append(jacobian[ii]) else: deltaThickness.append(0.0) deltaThickness = np.array( deltaThickness) * normalizeFactor tempThickness = curThickness + deltaThickness tempStruct = structure.QuickStruct(self.limits, tempThickness, phase=False) tempMV = tempStruct.MV if i == 0 and j == 0: nextThickness = tempThickness[:] if tempMV <= iterMV: iterMV = tempMV nextThickness = tempThickness[:] selectIJ = [(i, j)] curThickness = nextThickness[:] # update probability i, j = selectIJ[0] probability[i][j] = max(1.1, probability[i][j] * 1.1) for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]: if 0 <= x + i < 5 and 0 <= y + j < 5: probability[x + i][y + j] *= 1.0526 probability = probability * 0.95 # decay probability[0][2] = 1 print("iteration {}, currentThickness {}".format( curIteration, curThickness)) print("selected N, delta", N[i], delta[j]) print(probability) # update layers thickness by ratio of gradient, normalize the largest update to 1nm curIteration += 1 print('Finished, thickness', list(curThickness)) print('Cost data', mvlist) return mvlist
def main(self, c, conn): generationNumber = 0 lastgeneration = [] while generationNumber < self.loops: kept = min(24, 5 + generationNumber) # 1. Pad last generation to batch size for i in range(self.batchSize - len(lastgeneration)): lastgeneration.append( np.random.normal(loc=90, scale=15, size=(self.noPairs))) # 2.1 Evaluate the sample curResult = [] for sam in lastgeneration: t = time.time() curphase = sam cursample = structure.QuickStruct(self.limitation, curphase, phase=True) curMV = cursample.MV curResult.append([curMV, sam]) # 2.2 Pick good samples curResult.sort(key=lambda x: x[0]) curResult = curResult[:kept] lastgeneration = [s[1] for s in curResult] print('Current iteration {}, best merit value {}'.format( generationNumber, curResult[0])) tempsample = structure.QuickStruct(self.limitation, lastgeneration[0], phase=True) print('Current thickness is', tempsample.thickness) # 3.Implement crossover and mutation operation crossoverPosition = np.random.randint(1, self.noPairs - 1, size=(kept)) mutationPosition = np.random.randint(0, self.noPairs - 1, size=(kept)) mutationPosition2 = np.random.randint(0, self.noPairs - 1, size=(kept)) for i in range(kept): bp = crossoverPosition[i] # break point bp2 = mutationPosition[i] bp3 = mutationPosition2[i] if not i: lastgeneration.append( list(lastgeneration[0][:bp]) + list(lastgeneration[-1][bp:])) lastgeneration.append( list(lastgeneration[-1][:bp]) + list(lastgeneration[0][bp:])) else: lastgeneration.append( list(lastgeneration[i][:bp]) + list(lastgeneration[i - 1][bp:])) lastgeneration.append( list(lastgeneration[i - 1][:bp]) + list(lastgeneration[i][bp:])) lastgeneration.append( list(lastgeneration[i][:bp2]) + list(np.random.normal(loc=90, scale=15, size=(1))) + list(lastgeneration[i][bp2 + 1:])) lastgeneration.append( list(lastgeneration[i][:bp3]) + list(np.random.normal(loc=90, scale=15, size=(1))) + list(lastgeneration[i][bp3 + 1:])) print('Current generation {}'.format(generationNumber)) generationNumber += 1 # Save data curphase = lastgeneration[0] bestSample = structure.QuickStruct(self.limitation, curphase, phase=True) bestMV = bestSample.MV thickness = bestSample.thickness strthickness = ','.join([str(t)[:5] for t in thickness]) strthickness = '{}'.format(bestMV) + ',' + strthickness strthickness = '(' + strthickness + ')' print(strthickness) print(bestMV) print(self.limitation.matArray) print('thickness', thickness) print('##########################') query = '''INSERT INTO {} VALUES {}'''.format(self.tableName, strthickness) print('#', query) c.execute(query) conn.commit()