#quantum SVM

import qiskit
from matplotlib import pyplot as plt
import numpy as np
from qiskit.ml.datasets import ad_hoc_data
from qiskit import BasicAer
from qiskit.aqua import QuantumInstance
from qiskit.circuit.library import ZZFeatureMap
from qiskit.aqua.algorithms import QSVM
from qiskit.aqua.utils import split_dataset_to_data_and_labels, map_label_to_class_name

feature_dim =2
training_dataset=20
testing_dataset_size = 10
random_seed = 10598
shots=10000

#data
sample_Total, training_input, test_input, class_labels= ad_hoc_data(training_size=training_dataset,
                                                                    test_size=testing_dataset_size,
                                                                    gap= 0.5, #gap in higher dim space,
                                                                    n=feature_dim,
                                                                    plot_data=True)
datapoints , class_to_label = split_dataset_to_data_and_labels(test_input)
print(class_to_label)

#run on simulator 
backend = BasicAer.get_backend('qasm_simulator')
feature_map =ZZFeatureMap(feature_dim,reps=2)
svm= QSVM(feature_map,training_input,test_input,None)
svm.random_seed = random_seed
quantim_instance = QuantumInstance(backend,shots=shots, seed_simulator=random_seed,seed_transpiler=random_seed)
result=svm.run(quantim_instance)

#distance between points in higher dimensional space

print('kernal Matrix during training:')
kernel_matrix= result['kernel_matrix_training']
img = plt.imshow(np.asmatrix(kernel_matrix),interpolation='nearest', origin='upper',cmap='bone_r')
plt.show()

#validating accuracy 

predicted_labels = svm.predict(datapoints[0])
predicted_classes= map_label_to_class_name(predicted_labels, svm.label_to_class)
print("ground truth: {}".format(datapoints[0]))
print("prediction :  {}".format(predicted_labels))
print("testing success ratio: ", result['testing_accuracy'])

