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

feature_dim = 2    # Number of input features
sample_total, train_data, test_data, labels = ad_hoc_data(training_size=20, test_size=10,
                                                         n=feature_dim, gap=0.3, plot_data=True)

sample_test_data = sample_ad_hoc_data(sample_total, 10, n=feature_dim)
data_pts, class2label = split_dataset_to_data_and_labels(sample_test_data)
print("Classes and corresponding labels are:")
for c in class2label:
    print(f"Class: {c}, Label: {class2label[c]}")

seed = 10598  # Setting seed to ensure reproducable results

feature_map = ZZFeatureMap(feature_dimension=feature_dim, reps=2, entanglement='linear')
qsvm = QSVM(feature_map, train_data, test_data, data_pts[0])

backend = Aer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend, shots=1024, seed_simulator=seed, seed_transpiler=seed)

result = qsvm.run(quantum_instance)

print(f"Testing Accuracy: {result['testing_accuracy'] * 100}%")
print("Prediction on Datapoints:")
print(f"Ground Truth: {map_label_to_class_name(data_pts[1], qsvm.label_to_class)}")
print(f"Predictions:  {result['predicted_classes']}")

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

feature_dim = 2    # Number of input features
sample_total_bc, train_data_bc, test_data_bc, labels_bc = breast_cancer(training_size=20, test_size=10,
                                                         n=feature_dim, plot_data=True)

seed = 10598  # Setting seed to ensure reproducable results

feature_map_bc = ZZFeatureMap(feature_dimension=feature_dim, reps=2, entanglement='linear')
qsvm_bc = QSVM(feature_map_bc, train_data_bc, test_data_bc)

backend = Aer.get_backend('qasm_simulator')
quantum_instance_bc = QuantumInstance(backend, shots=1024, seed_simulator=seed, seed_transpiler=seed)

result_bc = qsvm_bc.run(quantum_instance_bc)
print(f"Testing Accuracy: {result_bc['testing_accuracy'] * 100}%")

print("Trained Kernel Matrix:")
kernel_matrix_bc = result_bc['kernel_matrix_training']
img = plt.imshow(np.asmatrix(kernel_matrix_bc),interpolation='nearest',origin='upper',cmap='bone_r')
plt.show()