# This is the Website's Title

## IBM Quantum Challenge Africa 2021

IBM's Quantum Challenge Africa just wrapped up. I had kept the 9th and 10th cleared on my calendar to participate, but ended up knocking it out on day one.

### The Good

Overall I think these type of events are a good tool for IBM to push awareness of its Qiskit platform.

They need to put a bit more time into the development process of the event materials.

The three labs contain their share of spelling errors and things like "[INSERT LINK]". The kind of stuff that should be caught by a good proofreader.

Some of the exercises (specifically in Lab 3) were impossible to complete if you followed the instructions in the text.

In one case you are told to "Uncomment your answers to these multiple choice questions in the code-cell below. Run the cell to submit your answers." and given the following code:

## Q1
##
## Q2
##



If the submitter does as instructed the variable's value will be immediately overwritten and the submitted answer will never be correct. Anyone experienced with Python would immediately see the problem with this code and fix it, but the challenge was specifically targeted towards an non-expert audience. The prepratory materials sent out before the event even include a Python crash course.

Similar problems occur on the next exercise when you are told explicitly to "Change the values for all parameters, except energy_surface..." and given the code:

grade_ex3c(
energy_surface=None, #q1_energy_surface_result.energies,
molecule=None,
num_electrons=None,
num_molecular_orbitals=None,
chemistry_inspired=None,
hardware_inspired_trial=None,
vqe=None,
perturbation_steps=None,
)


The stated purpose of the problem is to solve for and provide the correct energy surface, so if you do not change energy_surface you cannot complete the exercise...

This stuff is super simple. It is obvious that no one with "fresh eyes" was used to dry run the content before release. This is about the same level of quality that I have experienced with all of IBM's Qiskit materials.

None of these issues are terrible, but if your goal is to win academics and professionals over to your product, then this type of thing is not going to leave a good impression.

### The Ugly

The content for the challenge have been posted by the qiskit-community account on GitHub.

The event is over, and the grading function no longer seems to work on the Jupyter notebook. So I feel like posting solutions here would not be much of a spoiler:

1. Lab 1 - Crop Yields

• The first exercise asks you to list the four new names for Qiskit modules and points you to an IBM Research blog post that lists them.

   qiskit_module_names = [
"Qiskit Nature",
"Qiskit Finance",
"Qiskit Machine Learning",
"Qiskit Optimization"
]

• The second problem is to update the example QuadraticProgram() in the lab to solve for additional variables/constraints. I got the feeling from reading help requests in the Slack channel that most people were not using the correct variable names. I am not sure that binary_var() was necessary. The problem does specify each variable can only be 0 or 1, so using integer_var() with the correct lowerbound and upperbound should also work...

def cropyield_quadratic_program():
cropyield.binary_var(name="Wheat")
cropyield.binary_var(name="Soybeans")
cropyield.binary_var(name="Maize")
cropyield.binary_var(name="PushPull")
cropyield.maximize(
linear={"Wheat": 2, "Soybeans": 1, "Maize": 4},
quadratic={("Wheat", "Soybeans"): 2.4, ("Wheat", "Maize"): 4, ("Wheat", "PushPull"): 4, ("Soybeans", "Maize"): 2, ("Soybeans", "PushPull"): 1, ("Maize", "PushPull"): 5},
)
cropyield.linear_constraint(linear={"Wheat": 1, "Soybeans": 1, "Maize": 1, "PushPull": 1}, sense="<=", rhs=3)
return cropyield

• As far as I can tell, the third exercise is just to prove that you have run the code above it? There does not seem to be anything you actually edit or do...

• The fourth exercise is graded by submitting the job_id for the job you submit in the code above the exercise. Again, you do not really do anything for the exercise.

2. Lab 2 - Finance Models

• The first exercise is to try to lower the estimation error when pricing a call option as much as possible. On the simulator, using two qubits, this set of parameters gave me an estimation error of 0.0057, but it looks like I used three qubits in my actual submission:

num_uncertainty_qubits = 3
low  = np.maximum(0, mean - 1*stddev)
high = mean + 1*stddev
epsilon = 0.01
alpha = 0.05
shots = 100
simulator = 'qasm_simulator'

• The second exercise is for a put option instead of a call option. The three objects I submitted were:

uncertainty_model = LogNormalDistribution(num_uncertainty_qubits, mu=mu, sigma=sigma**2, bounds=(low, high))
european_put_objective = LinearAmplitudeFunction(
num_uncertainty_qubits,
slopes,
offsets,
domain=(low, high),
image=(f_min, f_max),
breakpoints=breakpoints,
rescaling_factor=rescaling_factor,
)
ae = IterativeAmplitudeEstimation(epsilon, alpha=alpha, quantum_instance=qi)

3. Lab 3 - HIV

• The first exercise is to extend the two atom example scenario to a more complicated one. Based on the Slack channel posts, I would say that the major confusion here is new programmers not knowing how indexes work in Python, not updating the specific_molecular_variation variable, or possibly leaving off degrees_of_freedom entirely.

specific_molecular_variation = apply_variation_to_atom_pair(molecular_variation, atom_pair=(0, 2))
macromolecule = Molecule(geometry=[['C', [-0.1805, 1.3955, 0.0000]],
['O', [ 1.1280, 0.2091, 0.0000]],
['N', [-1.1878, 0.1791, 0.0000]],
['C', [0.0598, -0.3882, 0.0000]],
['H', [-1.3085, 1.1864, 0.0001]],
['H', [-2.0305, -0.3861, -0.0001]],
['H', [-0.0014, -1.4883, -0.0001]]],
charge=0, multiplicity=1,
degrees_of_freedom=[specific_molecular_variation])

• The next exercise is two multiple choice questions; they are general physics facts applied to the scenario under discussion. The inner electrons of the atom do not interact strongly with things outside of the atom, so they do not need the quantum treatment (answer C). The more orbitals the electrons have access to the easier it will be for them to find lower ground energy states (answer A).

• The third exercise caused a lot of questions in the Slack channel. The multiple choice segment is simply asking you to look at the plot of the energy surface (it ends up being answer D). For the rest:

• The energy_surface parameter needs to be fixed.

• The number of electrons and number of orbitals are given in the problem description.

• The perturbation_steps are dictated by the problem description and an example exists earlier in the document. I helped at least one person in the Slack channel who had the sign flipped for the -0.5 boundary. I guess the idea that this is an offset from the starting position was not clear??

• The fact that the construct_hamiltonian_solve_ground_state() function did not require you to specify hardware_inspired_trial=None seems to hace tripped up quite a few people (since the grader function DID require it to be specified). Many of them also seem to not have understood what the expected values for the parameter might be.

• Really the chemistry_inspired, hardware_inspired_trial, and vqe all just end up being the defaults to the construct_hamiltonian_solve_ground_state() function.

• Obnoxiously, the problem makes you repeat quite a bit of your statements to first run the function to generate the energy surface and then submit them all to the grader function... Not my favorite design choice.

q1_energy_surface_result=construct_hamiltonian_solve_ground_state(
molecule=macromolecule,
num_electrons=2,
num_molecular_orbitals=2,
chemistry_inspired=True,
hardware_inspired_trial=None,
vqe=True,
perturbation_steps=np.linspace(-0.5, 5, 30),
)
energy_surface=q1_energy_surface_result.energies,
molecule=macromolecule,
num_electrons=2,
num_molecular_orbitals=2,
chemistry_inspired=True,
hardware_inspired_trial=None,
vqe=True,
perturbation_steps=np.linspace(-0.5, 5, 30),
q2_multiple_choice='D'
)

• The fourth exercise asks you to re-run prior code with slightly updated parameters and compare the results. (It decreases and introduce four parameters per round.)

• The final exercise asks you to minimize the value of the energy error. I got mine down to 5.72696535527939e-07 with the following values:

num_electrons =2
num_molecular_orbitals = 2
hardware_inspired_trial = TwoLocal(rotation_blocks = ['ry'],
entanglement_blocks = 'cz',
entanglement='linear', reps=10)


### That's a Wrap

Overall, the challenge was fine.

Room for improvement certainly exists, but it was a good time. I ended up talking to some people about it in a professional context, so it is at least fulfilling some of the event's objectives.

2021-09-23