def __init__(self, mesh, input_values, output_target): # initialization for both Triangular and Clements Mesh self.mesh = mesh self.input_values = normalize_vec(input_values) self.output_target = normalize_vec(output_target) self.N = mesh.N self.M = mesh.M
def input_couple(self, input_values): """ Specify input coupling (complex) values to mesh. Compute the fields at each layer of the structure. And at the output of the structure """ self.input_values = normalize_vec(input_values) self.partial_values = [] for p_mat in self.partial_matrices: layer_value = np.dot(p_mat, self.input_values) self.partial_values.append(layer_value) self.output_values = np.dot(self.full_matrix, self.input_values) self.coupled = True
def test_IO(self): """ Tests basic coupling""" # first on the zeros initialized clements mesh input_values = normalize_vec(npr.random((self.N, 1))) self.mesh_c_z.input_couple(input_values) output_values = self.mesh_c_z.output_values # because the matrix was initialized with zeros, output should be identical to input np.testing.assert_array_almost_equal(input_values, output_values) # same goes for the partial values within MZI for partial_value in self.mesh_c_z.partial_values: np.testing.assert_array_almost_equal(input_values, partial_value) # then on the random initialized clements mesh input_values = npr.random((self.N, )) self.mesh_c_r.input_couple(input_values) output_values = self.mesh_c_r.output_values # should not be equal for random initialization assert_array_compare(operator.__ne__, input_values, output_values) # same goes for the partial values within MZI for partial_value in self.mesh_c_r.partial_values: assert_array_compare(operator.__ne__, input_values, output_values) # finally on the random initialized triangular mesh input_values = normalize_vec(npr.random((self.N, 1))) self.mesh_t.input_couple(input_values) output_values = self.mesh_t.output_values # should not be equal for random initialization assert_array_compare(operator.__ne__, input_values, output_values) # same goes for the partial values within MZI for partial_value in self.mesh_t.partial_values: assert_array_compare(operator.__ne__, input_values, output_values)
def test_spread_rand_rand(self): # random input to rand N = self.N mesh = Mesh(N, mesh_type='triangular', initialization='random', M=None) input_values = npr.random((N, 1)) output_target = normalize_vec(npr.random((N, 1))) TO = TriangleOptimizer(mesh, input_values=input_values, output_target=output_target) TO.optimize(algorithm='spread') # mesh.plot_powers(); plt.show() self.check_power(mesh, output_target)
def setUp(self): self.N = 10 self.mesh_t = Mesh(self.N, mesh_type='triangular', initialization='random', M=None) self.mesh_c_r = Mesh(self.N, mesh_type='clements', initialization='random', M=None) self.mesh_c_z = Mesh(self.N, mesh_type='clements', initialization='zeros', M=None) self.one = normalize_vec(np.ones((self.N, 1))) self.top = np.zeros((self.N, 1)) self.top[0] = 1 self.mid = np.zeros((self.N, 1)) self.mid[self.N // 2] = 1 self.bot = np.zeros((self.N, 1)) self.bot[-1] = 1
# stores the convergences. convergences = np.zeros((N_max, N_max)) # for each mesh size for N in N_list: M = N_max # construct an NxN clements mesh. mesh = Mesh(N, mesh_type='clements', initialization='random', M=M) print('N = {} / {}:'.format(N, N_max)) print(mesh) # uniform output target output_target = np.ones((N, )) target_power = power_vec(normalize_vec(output_target)) # store MSE of each layer in each run in averaging mses = M * [0.] # for N_avg random inputs (to average over) for _ in range(N_avg): # make random inputs and couple them in input_values = npr.random((N, 1)) mesh.input_couple(input_values) # make a clements mesh and optimize using the 'smart' algorithm CO = ClementsOptimizer(mesh, input_values=input_values, output_target=output_target)