




import pickle

import numpy as np
from matplotlib import pyplot as plt


class 							__UpperCamelCase			:





				'''simple docstring'''



				def __init__( self       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_=0.2       , UpperCAmelCase_=0.2						):
											lowerCAmelCase   =		bp_numa
											lowerCAmelCase   =		bp_numa
											lowerCAmelCase   =		bp_numa
											lowerCAmelCase   =		conva_get[:2]
											lowerCAmelCase   =		conva_get[2]
											lowerCAmelCase   =		size_pa
											lowerCAmelCase   =		rate_w
											lowerCAmelCase   =		rate_t
											lowerCAmelCase   =		[
											    np.mat(-1 * np.random.rand(self.conva[0]       , self.conva[0]						) + 0.5						)
											    for i in range(self.conva[1]						)
											]
											lowerCAmelCase   =		np.mat(-1 * np.random.rand(self.num_bpa       , self.num_bpa						) + 0.5						)
											lowerCAmelCase   =		np.mat(-1 * np.random.rand(self.num_bpa       , self.num_bpa						) + 0.5						)
											lowerCAmelCase   =		-2 * np.random.rand(self.conva[1]						) + 1
											lowerCAmelCase   =		-2 * np.random.rand(self.num_bpa						) + 1
											lowerCAmelCase   =		-2 * np.random.rand(self.num_bpa						) + 1



				def       __snake_case		( self       , UpperCAmelCase_						):
											# save model dict with pickle
											lowerCAmelCase   =		{
											    '''num_bp1''': self.num_bpa,
											    '''num_bp2''': self.num_bpa,
											    '''num_bp3''': self.num_bpa,
											    '''conv1''': self.conva,
											    '''step_conv1''': self.step_conva,
											    '''size_pooling1''': self.size_poolinga,
											    '''rate_weight''': self.rate_weight,
											    '''rate_thre''': self.rate_thre,
											    '''w_conv1''': self.w_conva,
											    '''wkj''': self.wkj,
											    '''vji''': self.vji,
											    '''thre_conv1''': self.thre_conva,
											    '''thre_bp2''': self.thre_bpa,
											    '''thre_bp3''': self.thre_bpa,
											}
											with open(UpperCAmelCase_       , '''wb'''						) as f:
																		pickle.dump(UpperCAmelCase_       , UpperCAmelCase_						)

											print(F"""Model saved： {save_path}"""						)



				@classmethod
				def       __snake_case		( cls       , UpperCAmelCase_						):
											# read saved model
											with open(UpperCAmelCase_       , '''rb'''						) as f:
																		lowerCAmelCase   =		pickle.load(UpperCAmelCase_						)  # noqa: S301

											lowerCAmelCase   =		model_dic.get('''conv1'''						)
											conv_get.append(model_dic.get('''step_conv1'''						)						)
											lowerCAmelCase   =		model_dic.get('''size_pooling1'''						)
											lowerCAmelCase   =		model_dic.get('''num_bp1'''						)
											lowerCAmelCase   =		model_dic.get('''num_bp2'''						)
											lowerCAmelCase   =		model_dic.get('''num_bp3'''						)
											lowerCAmelCase   =		model_dic.get('''rate_weight'''						)
											lowerCAmelCase   =		model_dic.get('''rate_thre'''						)
											# create model instance
											lowerCAmelCase   =		CNN(UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_						)
											# modify model parameter
											lowerCAmelCase   =		model_dic.get('''w_conv1'''						)
											lowerCAmelCase   =		model_dic.get('''wkj'''						)
											lowerCAmelCase   =		model_dic.get('''vji'''						)
											lowerCAmelCase   =		model_dic.get('''thre_conv1'''						)
											lowerCAmelCase   =		model_dic.get('''thre_bp2'''						)
											lowerCAmelCase   =		model_dic.get('''thre_bp3'''						)
											return conv_ins



				def       __snake_case		( self       , UpperCAmelCase_						):
											return 1 / (1 + np.exp(-1 * x						))



				def       __snake_case		( self       , UpperCAmelCase_						):
											return round(UpperCAmelCase_       , 3						)



				def       __snake_case		( self       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_						):
											# convolution process
											lowerCAmelCase   =		convs[0]
											lowerCAmelCase   =		convs[1]
											lowerCAmelCase   =		np.shape(UpperCAmelCase_						)[0]
											# get the data slice of original image data, data_focus
											lowerCAmelCase   =		[]
											for i_focus in range(0       , size_data - size_conv + 1       , UpperCAmelCase_						):
																		for j_focus in range(0       , size_data - size_conv + 1       , UpperCAmelCase_						):
																									lowerCAmelCase   =		data[
																									    i_focus : i_focus + size_conv, j_focus : j_focus + size_conv
																									]
																									data_focus.append(UpperCAmelCase_						)
        # calculate the feature map of every single kernel, and saved as list of matrix
											lowerCAmelCase   =		[]
											lowerCAmelCase   =		int((size_data - size_conv) / conv_step + 1						)
											for i_map in range(UpperCAmelCase_						):
																		lowerCAmelCase   =		[]
																		for i_focus in range(len(UpperCAmelCase_						)						):
																									lowerCAmelCase   =		(
																									    np.sum(np.multiply(data_focus[i_focus]       , w_convs[i_map]						)						)
																									    - thre_convs[i_map]
																									)
																									featuremap.append(self.sig(UpperCAmelCase_						)						)
																		lowerCAmelCase   =		np.asmatrix(UpperCAmelCase_						).reshape(
																		    UpperCAmelCase_       , UpperCAmelCase_						)
																		data_featuremap.append(UpperCAmelCase_						)

											# expanding the data slice to One dimenssion
											lowerCAmelCase   =		[]
											for each_focus in data_focus:
																		focusa_list.extend(self.Expand_Mat(UpperCAmelCase_						)						)
											lowerCAmelCase   =		np.asarray(UpperCAmelCase_						)
											return focus_list, data_featuremap



				def       __snake_case		( self       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_="average_pool"						):
											# pooling process
											lowerCAmelCase   =		len(featuremaps[0]						)
											lowerCAmelCase   =		int(size_map / size_pooling						)
											lowerCAmelCase   =		[]
											for i_map in range(len(UpperCAmelCase_						)						):
																		lowerCAmelCase   =		featuremaps[i_map]
																		lowerCAmelCase   =		[]
																		for i_focus in range(0       , UpperCAmelCase_       , UpperCAmelCase_						):
																									for j_focus in range(0       , UpperCAmelCase_       , UpperCAmelCase_						):
																																lowerCAmelCase   =		feature_map[
																																    i_focus : i_focus + size_pooling,
																																    j_focus : j_focus + size_pooling,
																																]
																																if pooling_type == "average_pool":
																																							# average pooling
																																							map_pooled.append(np.average(UpperCAmelCase_						)						)
																																elif pooling_type == "max_pooling":
																																							# max pooling
																																							map_pooled.append(np.max(UpperCAmelCase_						)						)
																		lowerCAmelCase   =		np.asmatrix(UpperCAmelCase_						).reshape(UpperCAmelCase_       , UpperCAmelCase_						)
																		featuremap_pooled.append(UpperCAmelCase_						)
											return featuremap_pooled



				def       __snake_case		( self       , UpperCAmelCase_						):
											# expanding three dimension data to one dimension list
											lowerCAmelCase   =		[]
											for i in range(len(UpperCAmelCase_						)						):
																		lowerCAmelCase   =		np.shape(data[i]						)
																		lowerCAmelCase   =		data[i].reshape(1       , shapes[0] * shapes[1]						)
																		lowerCAmelCase   =		data_listed.getA().tolist()[0]
																		data_expanded.extend(UpperCAmelCase_						)
											lowerCAmelCase   =		np.asarray(UpperCAmelCase_						)
											return data_expanded



				def       __snake_case		( self       , UpperCAmelCase_						):
											# expanding matrix to one dimension list
											lowerCAmelCase   =		np.asarray(UpperCAmelCase_						)
											lowerCAmelCase   =		np.shape(UpperCAmelCase_						)
											lowerCAmelCase   =		data_mat.reshape(1       , shapes[0] * shapes[1]						)
											return data_expanded



				def       __snake_case		( self       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_						):
											lowerCAmelCase   =		[]
											lowerCAmelCase   =		0
											for i_map in range(UpperCAmelCase_						):
																		lowerCAmelCase   =		np.ones((size_map, size_map)						)
																		for i in range(0       , UpperCAmelCase_       , UpperCAmelCase_						):
																									for j in range(0       , UpperCAmelCase_       , UpperCAmelCase_						):
																																lowerCAmelCase   =		pd_pool[
																																    i_pool
																																]
																																lowerCAmelCase   =		i_pool + 1
																		lowerCAmelCase   =		np.multiply(
																		    UpperCAmelCase_       , np.multiply(out_map[i_map]       , (1 - out_map[i_map])						)						)
																		pd_all.append(UpperCAmelCase_						)
											return pd_all



				def       __snake_case		( self       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_       , UpperCAmelCase_=bool						):
											# model traning
											print('''----------------------Start Training-------------------------'''						)
											print((''' - - Shape: Train_Data  ''', np.shape(UpperCAmelCase_						))						)
											print((''' - - Shape: Teach_Data  ''', np.shape(UpperCAmelCase_						))						)
											lowerCAmelCase   =		0
											lowerCAmelCase   =		[]
											lowerCAmelCase   =		1_00_00
											while rp < n_repeat and mse >= error_accuracy:
																		lowerCAmelCase   =		0
																		print(F"""-------------Learning Time {rp}--------------"""						)
																		for p in range(len(UpperCAmelCase_						)						):
																									# print('------------Learning Image: %d--------------'%p)
																									lowerCAmelCase   =		np.asmatrix(datas_train[p]						)
																									lowerCAmelCase   =		np.asarray(datas_teach[p]						)
																									lowerCAmelCase   ,     lowerCAmelCase   =		self.convolute(
																									    UpperCAmelCase_       , self.conva       , self.w_conva       , self.thre_conva       , conv_step=self.step_conva       , )
																									lowerCAmelCase   =		self.pooling(UpperCAmelCase_       , self.size_poolinga						)
																									lowerCAmelCase   =		np.shape(UpperCAmelCase_						)
																									lowerCAmelCase   =		self._expand(UpperCAmelCase_						)
																									lowerCAmelCase   =		data_bp_input

																									lowerCAmelCase   =		np.dot(UpperCAmelCase_       , self.vji.T						) - self.thre_bpa
																									lowerCAmelCase   =		self.sig(UpperCAmelCase_						)
																									lowerCAmelCase   =		np.dot(UpperCAmelCase_       , self.wkj.T						) - self.thre_bpa
																									lowerCAmelCase   =		self.sig(UpperCAmelCase_						)

																									# --------------Model Leaning ------------------------
																									# calculate error and gradient---------------
																									lowerCAmelCase   =		np.multiply(
																									    (data_teach - bp_outa)       , np.multiply(UpperCAmelCase_       , (1 - bp_outa)						)						)
																									lowerCAmelCase   =		np.multiply(
																									    np.dot(UpperCAmelCase_       , self.wkj						)       , np.multiply(UpperCAmelCase_       , (1 - bp_outa)						)						)
																									lowerCAmelCase   =		np.dot(UpperCAmelCase_       , self.vji						)

																									lowerCAmelCase   =		pd_i_all / (self.size_poolinga * self.size_poolinga)
																									lowerCAmelCase   =		pd_conva_pooled.T.getA().tolist()
																									lowerCAmelCase   =		self._calculate_gradient_from_pool(
																									    UpperCAmelCase_       , UpperCAmelCase_       , shape_featuremapa[0]       , shape_featuremapa[1]       , self.size_poolinga       , )
																									# weight and threshold learning process---------
																									# convolution layer
																									for k_conv in range(self.conva[1]						):
																																lowerCAmelCase   =		self._expand_mat(pd_conva_all[k_conv]						)
																																lowerCAmelCase   =		self.rate_weight * np.dot(UpperCAmelCase_       , UpperCAmelCase_						)

																																lowerCAmelCase   =		self.w_conva[k_conv] + delta_w.reshape(
																																    (self.conva[0], self.conva[0])						)

																																lowerCAmelCase   =		(
																																    self.thre_conva[k_conv]
																																    - np.sum(pd_conva_all[k_conv]						) * self.rate_thre
																																)
																									# all connected layer
																									lowerCAmelCase   =		self.wkj + pd_k_all.T * bp_outa * self.rate_weight
																									lowerCAmelCase   =		self.vji + pd_j_all.T * bp_outa * self.rate_weight
																									lowerCAmelCase   =		self.thre_bpa - pd_k_all * self.rate_thre
																									lowerCAmelCase   =		self.thre_bpa - pd_j_all * self.rate_thre
																									# calculate the sum error of all single image
																									lowerCAmelCase   =		np.sum(abs(data_teach - bp_outa						)						)
																									error_count += errors
																									# print('   ----Teach      ',data_teach)
																									# print('   ----BP_output  ',bp_out3)
																		lowerCAmelCase   =		rp + 1
																		lowerCAmelCase   =		error_count / patterns
																		all_mse.append(UpperCAmelCase_						)

											def draw_error():
																		lowerCAmelCase   =		[error_accuracy for i in range(int(n_repeat * 1.2						)						)]
																		plt.plot(UpperCAmelCase_       , '''+-'''						)
																		plt.plot(UpperCAmelCase_       , '''r--'''						)
																		plt.xlabel('''Learning Times'''						)
																		plt.ylabel('''All_mse'''						)
																		plt.grid(UpperCAmelCase_       , alpha=0.5						)
																		plt.show()

											print('''------------------Training Complished---------------------'''						)
											print((''' - - Training epoch: ''', rp, F"""     - - Mse: {mse:.6f}""")						)
											if draw_e:
																		draw_error()
											return mse



				def       __snake_case		( self       , UpperCAmelCase_						):
											# model predict
											lowerCAmelCase   =		[]
											print('''-------------------Start Testing-------------------------'''						)
											print((''' - - Shape: Test_Data  ''', np.shape(UpperCAmelCase_						))						)
											for p in range(len(UpperCAmelCase_						)						):
																		lowerCAmelCase   =		np.asmatrix(datas_test[p]						)
																		lowerCAmelCase   ,     lowerCAmelCase   =		self.convolute(
																		    UpperCAmelCase_       , self.conva       , self.w_conva       , self.thre_conva       , conv_step=self.step_conva       , )
																		lowerCAmelCase   =		self.pooling(UpperCAmelCase_       , self.size_poolinga						)
																		lowerCAmelCase   =		self._expand(UpperCAmelCase_						)

																		lowerCAmelCase   =		data_bp_input
																		lowerCAmelCase   =		bp_outa * self.vji.T - self.thre_bpa
																		lowerCAmelCase   =		self.sig(UpperCAmelCase_						)
																		lowerCAmelCase   =		bp_outa * self.wkj.T - self.thre_bpa
																		lowerCAmelCase   =		self.sig(UpperCAmelCase_						)
																		produce_out.extend(bp_outa.getA().tolist()						)
											lowerCAmelCase   =		[list(map(self.do_round       , UpperCAmelCase_						)						) for each in produce_out]
											return np.asarray(UpperCAmelCase_						)






				def       __snake_case		( self       , UpperCAmelCase_						):
											# return the data of image after convoluting process so we can check it out
											lowerCAmelCase   =		np.asmatrix(UpperCAmelCase_						)
											lowerCAmelCase   ,     lowerCAmelCase   =		self.convolute(
											    UpperCAmelCase_       , self.conva       , self.w_conva       , self.thre_conva       , conv_step=self.step_conva       , )
											lowerCAmelCase   =		self.pooling(UpperCAmelCase_       , self.size_poolinga						)

											return data_conveda, data_pooleda


if __name__ == "__main__":
		pass









import math

import numpy as np
import qiskit
from qiskit import Aer, ClassicalRegister, QuantumCircuit, QuantumRegister, execute



def       UpperCAmelCase       (     _snake_case = 3							):
							if isinstance(_snake_case						, _snake_case							):
														raise TypeError('''number of qubits must be a integer.'''							)
							if number_of_qubits <= 0:
														raise ValueError('''number of qubits must be > 0.'''							)
							if math.floor(_snake_case							) != number_of_qubits:
														raise ValueError('''number of qubits must be exact integer.'''							)
							if number_of_qubits > 10:
														raise ValueError('''number of qubits too large to simulate(>10).'''							)

							lowerCAmelCase   =		QuantumRegister(_snake_case						, '''qr'''							)
							lowerCAmelCase   =		ClassicalRegister(_snake_case						, '''cr'''							)

							lowerCAmelCase   =		QuantumCircuit(_snake_case						, _snake_case							)

							lowerCAmelCase   =		number_of_qubits

							for i in range(_snake_case							):
														quantum_circuit.h(number_of_qubits - i - 1							)
														counter -= 1
														for j in range(_snake_case							):
																					quantum_circuit.cp(np.pi / 2 ** (counter - j)						, _snake_case						, _snake_case							)

							for k in range(number_of_qubits // 2							):
														quantum_circuit.swap(_snake_case						, number_of_qubits - k - 1							)

							# measure all the qubits
							quantum_circuit.measure(_snake_case						, _snake_case							)
							# simulate with 10000 shots
							lowerCAmelCase   =		Aer.get_backend('''qasm_simulator'''							)
							lowerCAmelCase   =		execute(_snake_case						, _snake_case						, shots=10000							)

							return job.result().get_counts(_snake_case							)


if __name__ == "__main__":
		print(
		    F'''Total count for quantum fourier transform state is: \
    {quantum_fourier_transform(3)}'''
		)



