Quantum computing in action: IBM's Q experience and the quantum shell game(5)
- UID
- 1066743
|
Quantum computing in action: IBM's Q experience and the quantum shell game(5)
Step 3. Retrieve and parse the resultsThe ExecuteCode function we discussed earlier takes care of passing the code to the Q experience platform. If the code execution is successful, we should get back JSON similar to the following code listing:
Listing 10. JSON output1
2
3
4
5
6
7
8
9
| {"result":{"date":"2017-10-
03T17:07:21.819Z","data":{"creg_labels":"c[5]","p":
{"qubits":[1,2],"labels":["00110"],"values":[1]},
"additionalData":{"seed":1},"qasm
...
,"userDeleted":false,"id":"7012d29df79ba1fca3e5eda009069d3d",
"userId":"a3e5c196cb90688ba9a50dd7607999a6"}}
|
Lurking in that JSON output is the “labels” field containing our answer—in this case, “00110” (highlighted above). The “values” field lists the probability of the answer. Because we ran our simulation 500 times, the net result is close enough to 100% that the result comes back rounded to 1. Thus, parsing the result is as simple as rehydrating the JSON into an object and reading off the labels property:
Listing 11. Parsing the results1
2
3
| QExecutionOutput x= JsonConvert.DeserializeObject
<QExecutionOutput>(result.Message);
Debug.WriteLine("The values are: " + x.result.data.p.labels[0]);
|
Step 4. Map the result backMapping the result back is simply another switch statement as in the following code listing:
Listing 12. Mapping the results1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| //parse the result and output the location of the coin
QExecutionOutput x = qp.GetOutputFromMessageData(result.Message);
string labels = x.result.data.p.labels[0];
switch (labels)
{
case "00000":
Debug.WriteLine("The coin was under Shell #1");
ComputedShell.Value = "1";
break;
case "00100":
Debug.WriteLine("The coin was under Shell #2");
ComputedShell.Value = "2";
break;
case "00010":
Debug.WriteLine("The coin was under Shell #3");
ComputedShell.Value = "3";
break;
case "00110":
Debug.WriteLine("The coin was under Shell #4");
ComputedShell.Value = "4";
break;
default:
Debug.WriteLine("Something broke!");
ComputedShell.Value = "0";
break;
}
|
If you only run a couple of shots, you might get very different results. Perhaps we should inspect the values array and select the array index with the highest probability, then choose the label with the matching array index as our answer. But, because we run this 500 times, our result is almost always an array with a single answer. As in the JSON below:
"qubits":[1,2],"labels":["00110"],"values":[1]},"
with a probability rounded to 1, and a single label of “00110”, in our shell game, we just read the result at index 0. In this example, the ball was hiding under the fourth shell!
Putting it all togetherIn our ASP.NET web page, when the user presses the Submit button, the number of the shell is passed back in the “ShellSelected” property of the ShellGameModel class. We read this, create our QProcessor object (instantiating it with our token). Then we login.
If the login is successful, we instantiate our QCode object passing it the value of the shell selected. We then pass the code to our ExecuteCode function. We create a QExecutionOutput object from that code and read the labels property of the result.
Our labels, remember, are the qubits state (1 or 0) expressed classically. Another simple switch statement, and we can pass back what the quantum processor was able to deduce about the location of the ball.
Listing 13. Finding the location of the ball1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
| [HttpPost]
public IActionResult Index(ShellGameModel model)
{
model.ComputedShell = "0";
model.QASM = "";
model.ExecutionResults = "";
string token = "INSERTYOURTOKENHERE";
//Build the processor
QProcessor qp = new QProcessor(token);
//login
QResult result = qp.Login();
Debug.WriteLine(string.Format("Login result. Success={0} Message={1}", result.Success.ToString(), result.Message));
if (result.Success)
{
int shell = 0;
Int32.TryParse(model.ShellSelected, out shell);
//build the QASM code
QCode code = new QCode(shell);
code.name = string.Format("ExperimentID {0} with Shell at {1} ", System.Guid.NewGuid().ToString(), shell.ToString());
Debug.WriteLine("Code:" + Environment.NewLine + code.qasm);
//execute the code
result = qp.ExecuteCode(code);
Debug.WriteLine(string.Format("Code Executed Success={0}, Data={1}", result.Success.ToString(), result.Message));
//parse the result and output the location of the coin
QExecutionOutput x = qp.GetOutputFromMessageData(result.Message);
string labels = x.result.data.p.labels[0];
switch (labels)
{
case "00000":
Debug.WriteLine("The coin was under Shell #1");
model.ComputedShell = "1";
break;
case "00100":
Debug.WriteLine("The coin was under Shell #2");
model.ComputedShell = "2";
break;
case "00010":
Debug.WriteLine("The coin was under Shell #3");
model.ComputedShell = "3";
break;
case "00110":
Debug.WriteLine("The coin was under Shell #4");
model.ComputedShell = "4";
break;
default:
Debug.WriteLine("Something broke!");
model.ComputedShell = "0";
break;
}
model.QASM = JsonConvert.SerializeObject(x.code, Formatting.Indented);
model.ExecutionResults = JsonConvert.SerializeObject(x.result, Formatting.Indented);
//now cleanup and delete the results
QResult deleteResult = qp.DeleteExperiment(x.code.idCode);
}
return View(model);
}
|
Et viola! We have taken the real-world problem of the shell game, mapped it into code, executed it on a quantum processor, processed the result and mapped the solution back into the real world.
This may not be the most elegant work you have ever seen -- I can think of 100 ways to improve it -- but it’s simple and effective, and for the purposes of this demonstration, close enough. |
|
|
|
|
|