Skip to content

Commit

Permalink
Added comments in Classification relating to its limits. Added to res…
Browse files Browse the repository at this point in the history
…ources. Added SATOracle file which is simply a copy of a file from the aqua repo, with comments added for clarity
  • Loading branch information
maddytod committed Oct 9, 2018
1 parent b3a5aac commit 16655f5
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 10 deletions.
15 changes: 9 additions & 6 deletions Code/ACQUA/Classification/Classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
from datasets import *


def classify(location='',file='testClassify.csv',class_labels=[r'A', r'B']) :
def classify(location='',file='testClassify.csv',class_labels=[r'A', r'B'], train_size=200, test_size=50) :

# Title is defined in usedDefinedData function - can edit if needed but that file is from the
# tutorial
sample_Total, training_input, test_input, class_labels = userDefinedData(location,
file,
class_labels,
training_size=200,
test_size=50,
n=2,
training_size=train_size,
test_size=test_size,
n=2, # normally n = 2, but can be bigger - timed out with n = 3
PLOT_DATA=True)

# n = 2 is the dimension of each data pointtotal_array, label_to_labelclass = get_points(test_input, class_labels)
# n = 2 is the dimension of each data point
total_array, label_to_labelclass = get_points(test_input, class_labels)

"""
Expand Down Expand Up @@ -66,5 +66,8 @@ def classify(location='',file='testClassify.csv',class_labels=[r'A', r'B']) :

# Classifies a much larger dataset of banking data - more attributes and more rows so it takes much longer
# Trying to estimate based on a phone call if they will stay with the company
classify(file="bank1000.csv", class_labels=[r'Yes', r'No'])
# NB trained with 500 and tested with 100 and timed out, also with 400 and 100, and 400 and 50, and 300 and 50.
# 200 and 50 is fine, but timed out with 250 and 50
# 200 and 200 is fine - so it depends on the size of the training set
classify(file="bank1000.csv", class_labels=[r'Yes', r'No'], train_size=200, test_size=50)

16 changes: 16 additions & 0 deletions Code/ACQUA/Classification/data/bankText.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
15,16,"age","job","marital","education","default","balance","housing","loan","contact","day","month","duration","campaign","pdays","previous","poutcome","y"
30,"unemployed","married","primary","no",1787,"no","no","cellular",19,"oct",79,1,-1,0,"unknown","no"
33,"services","married","secondary","no",4789,"yes","yes","cellular",11,"may",220,1,339,4,"failure","no"
35,"management","single","tertiary","no",1350,"yes","no","cellular",16,"apr",185,1,330,1,"failure","no"
30,"management","married","tertiary","no",1476,"yes","yes","unknown",3,"jun",199,4,-1,0,"unknown","no"
59,"blue-collar","married","secondary","no",0,"yes","no","unknown",5,"may",226,1,-1,0,"unknown","no"
35,"management","single","tertiary","no",747,"no","no","cellular",23,"feb",141,2,176,3,"failure","no"
36,"self-employed","married","tertiary","no",307,"yes","no","cellular",14,"may",341,1,330,2,"other","no"
39,"technician","married","secondary","no",147,"yes","no","cellular",6,"may",151,2,-1,0,"unknown","no"
41,"entrepreneur","married","tertiary","no",221,"yes","no","unknown",14,"may",57,2,-1,0,"unknown","no"
43,"services","married","primary","no",-88,"yes","yes","cellular",17,"apr",313,1,147,2,"failure","no"
39,"services","married","secondary","no",9374,"yes","no","unknown",20,"may",273,1,-1,0,"unknown","no"
43,"admin.","married","secondary","no",264,"yes","no","cellular",17,"apr",113,2,-1,0,"unknown","no"
36,"technician","married","tertiary","no",1109,"no","no","cellular",13,"aug",328,2,-1,0,"unknown","no"
20,"student","single","secondary","no",502,"no","no","cellular",30,"apr",261,1,-1,0,"unknown","yes"
31,"blue-collar","married","secondary","no",360,"yes","yes","cellular",29,"jan",89,1,241,1,"failure","no"
1 change: 0 additions & 1 deletion Code/ACQUA/Classification/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,4 +590,3 @@ def userDefinedData(location, file, class_labels,training_size, test_size, n=2,
plt.show()

return sample_train, training_input, test_input, class_labels

1 change: 1 addition & 0 deletions Code/Basics/CoinFlip.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

# Show the results
print("simulation: ", sim_result)
print(type(sim_result))

currentMax = 0
currentVal = 0
Expand Down
181 changes: 181 additions & 0 deletions Code/Grover/SATOracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# -*- coding: utf-8 -*-

# Copyright 2018 IBM.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =============================================================================



# THIS IS A DIRECT COPY FROM https://github.com/Qiskit/aqua/blob/2fa314ce9a90a2060404cd5d46f2d45f0806918e/qiskit_aqua/algorithms/components/oracles/sat.py
# SIMPLY WITH COMMENTS ADDED FOR CLARITY


import itertools
import operator
import logging
from qiskit import QuantumRegister, QuantumCircuit
from qiskit_aqua.algorithms.components.oracles import Oracle

logger = logging.getLogger(__name__)


class SAT(Oracle):
SAT_CONFIGURATION = {
'name': 'SAT',
'description': 'Satisfiability Oracle',
'input_schema': {
'$schema': 'http://json-schema.org/schema#',
'id': 'sat_oracle_schema',
'type': 'object',
'properties': {
'cnf': {
'type': 'string',
},
},
'additionalProperties': False
}
}

def __init__(self, configuration=None):
super().__init__(configuration or self.SAT_CONFIGURATION.copy())
self._cnf = None
self._qr_ancilla = None
self._qr_clause = None
self._qr_outcome = None
self._qr_variable = None

def init_args(self, cnf):

# Remove all comments and blank lines
# ls is array of what is left
ls = [
l.strip() for l in cnf.split('\n')
if len(l) > 0 and not l.strip()[0] == 'c'
]

# Extract the info from the p line
headers = [l for l in ls if l[0] == 'p']
if len(headers) == 1:
p, sig, nv, nc = headers[0].split()
assert p == 'p' and sig == 'cnf'
else:
raise ValueError('Invalid cnf format for SAT.')

# num variables, num clauses
h_nv, h_nc = int(nv), int(nc)

# Split into arrays of strings, where each string represents a clause, store in overall array
cs = [
c.strip()
for c in ' '.join(
[l for l in ls if not l[0] == 'p']
).split(' 0') if len(c) > 0
]

# Store the cnf as arrays of ints, in an overall array
self._cnf = [
[int(v) for v in c.split() if not int(v) == 0]
for c in cs
if (
len(c.replace('0', '')) > 0
) and (
'0' <= c[0] <= '9' or c[0] == '-'
)
]

# Check that the counts given are correct with what was read
nv = max(set([abs(v) for v in list(itertools.chain.from_iterable(self._cnf))]))
nc = len(self._cnf)
if not h_nv == nv:
logger.warning('Inaccurate variable count {} in cnf header, actual count is {}.'.format(h_nv, nv))
if not h_nc == nc:
logger.warning('Inaccurate clause count {} in cnf header, actual count is {}.'.format(h_nc, nc))


# Initialise registers based on input info
self._qr_outcome = QuantumRegister(1, name='o')
self._qr_variable = QuantumRegister(nv, name='v')
self._qr_clause = QuantumRegister(nc, name='c')
num_ancillae = max(max(nc, nv) - 2, 0)
if num_ancillae > 0:
self._qr_ancilla = QuantumRegister(num_ancillae, name='a')

def variable_register(self):
return self._qr_variable

def ancillary_register(self):
return self._qr_ancilla

def outcome_register(self):
return self._qr_outcome

def _logic_or(self, circuit, conj_expr, conj_index):

# get the absolute values - ie turn -1 into 1
qs = [abs(v) for v in conj_expr]

# get the control, ancilla and target bits
# NB -1 as variables in CNF must start from 1
ctl_bits = [self._qr_variable[idx - 1] for idx in qs]
anc_bits = [self._qr_ancilla[idx] for idx in range(len(qs) - 2)]
tgt_bits = self._qr_clause[conj_index]

# Add X gates to all +ve variables
for idx in [v for v in conj_expr if v > 0]:
circuit.x(self._qr_variable[idx - 1])

# Add CNOT
circuit.cnx(ctl_bits, anc_bits, tgt_bits)

# Add more X gates to all +ve variables
for idx in [v for v in conj_expr if v > 0]:
circuit.x(self._qr_variable[idx - 1])

def construct_circuit(self):
# Add all the registers to the circuit
if self._qr_ancilla:
qc = QuantumCircuit(self._qr_variable, self._qr_clause, self._qr_ancilla, self._qr_outcome)
else:
qc = QuantumCircuit(self._qr_variable, self._qr_clause, self._qr_outcome)

# init all clause qubit to 1:
qc.x(self._qr_clause)

# build all clause
for conj_index, conj_expr in enumerate(self._cnf):
# add a logical or between all the values in that clause
self._logic_or(qc, conj_expr, conj_index)

# keep results
qc.cnx(
[self._qr_clause[i] for i in range(len(self._qr_clause))],
[self._qr_ancilla[i] for i in range(len(self._qr_ancilla))] if self._qr_ancilla else [],
self._qr_outcome[0]
)

# reverse, de-entanglement
for conj_index, conj_expr in reversed(list(enumerate(self._cnf))):
self._logic_or(qc, conj_expr, conj_index)
return qc

def evaluate_classically(self, assignment):
assignment_set = set(assignment)
for clause in self._cnf:
if assignment_set.isdisjoint(clause):
return False
return True

def interpret_measurement(self, measurement, *args, **kwargs):
top_measurement = max(measurement.items(), key=operator.itemgetter(1))[0]
return [(var + 1) * (int(tf) * 2 - 1) for tf, var in zip(top_measurement[::-1], range(len(top_measurement)))]
2 changes: 0 additions & 2 deletions Code/NoughtAndCrosses/GroverPlayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ def takeTurn(self, board):
currentConfig += "0"
currentRules += currentConfig



newBoard = self.runGrover(currentRules)

return self.convertFromSAT(newBoard, board)
Expand Down
5 changes: 4 additions & 1 deletion Notes/Resources.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# This file contains a list of useful videos to help you understand quantum
I would recommend starting by reading through the IBM Q beginners guide, using these videos to support your learning.
I would recommend starting by reading through the IBM Q beginners guide, using these videos/podcasts to support your learning.

## Introduction
[](https://soundcloud.com/stupidqubit/001-what-the-photonic-muck-is-a-quantum-computer)

## Qubits
[](https://www.youtube.com/watch?v=_P7K8jUbLU0)
Expand Down

0 comments on commit 16655f5

Please sign in to comment.