Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# Copyright 2019-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"). You 

4# may not use this file except in compliance with the License. A copy of 

5# the License is located at 

6# 

7# http://aws.amazon.com/apache2.0/ 

8# 

9# or in the "license" file accompanying this file. This file is 

10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

11# ANY KIND, either express or implied. See the License for the specific 

12# language governing permissions and limitations under the License. 

13 

14from __future__ import annotations 

15 

16import json 

17from dataclasses import dataclass 

18from typing import Any, Counter, Dict 

19 

20import numpy as np 

21 

22 

23@dataclass 

24class GateModelQuantumTaskResult: 

25 """ 

26 Result of a gate model quantum task execution. This class is intended 

27 to be initialized by a QuantumTask class. 

28 

29 Args: 

30 measurements (numpy.ndarray): 2d array - row is shot, column is qubit. 

31 measurement_counts (Counter): A Counter of measurements. Key is the measurements 

32 in a big endian binary string. Value is the number of times that measurement occurred. 

33 measurement_probabilities (Dict[str, float]): A dictionary of probabilistic results. 

34 Key is the measurements in a big endian binary string. 

35 Value is the probability the measurement occurred. 

36 measurements_copied_from_device (bool): flag whether `measurements` were copied from device. 

37 If false, `measurements` are calculated from device data. 

38 measurement_counts_copied_from_device (bool): flag whether `measurement_counts` were copied 

39 from device. If false, `measurement_counts` are calculated from device data. 

40 measurement_probabilities_copied_from_device (bool): flag whether 

41 `measurement_probabilities` were copied from device. If false, 

42 `measurement_probabilities` are calculated from device data. 

43 task_metadata (Dict[str, Any]): Dictionary of task metadata. 

44 state_vector (Dict[str, complex]): Dictionary where Key is state and Value is amplitude. 

45 """ 

46 

47 measurements: np.ndarray 

48 measurement_counts: Counter 

49 measurement_probabilities: Dict[str, float] 

50 measurements_copied_from_device: bool 

51 measurement_counts_copied_from_device: bool 

52 measurement_probabilities_copied_from_device: bool 

53 task_metadata: Dict[str, Any] 

54 state_vector: Dict[str, complex] = None 

55 

56 def __eq__(self, other) -> bool: 

57 if isinstance(other, GateModelQuantumTaskResult): 

58 # __eq__ on numpy arrays results in an array of booleans and therefore can't use 

59 # the default dataclass __eq__ implementation. Override equals to check if all 

60 # elements in the array are equal. 

61 self_fields = (self.task_metadata, self.state_vector) 

62 other_fields = (other.task_metadata, other.state_vector) 

63 return (self.measurements == other.measurements).all() and self_fields == other_fields 

64 return NotImplemented 

65 

66 @staticmethod 

67 def measurement_counts_from_measurements(measurements: np.ndarray) -> Counter: 

68 """ 

69 Creates measurement counts from measurements 

70 

71 Args: 

72 measurements (numpy.ndarray): 2d array - row is shot, column is qubit. 

73 

74 Returns: 

75 Counter: A Counter of measurements. Key is the measurements in a big endian binary 

76 string. Value is the number of times that measurement occurred. 

77 """ 

78 bitstrings = [] 

79 for j in range(len(measurements)): 

80 bitstrings.append("".join([str(element) for element in measurements[j]])) 

81 return Counter(bitstrings) 

82 

83 @staticmethod 

84 def measurement_probabilities_from_measurement_counts( 

85 measurement_counts: Counter, 

86 ) -> Dict[str, float]: 

87 """ 

88 Creates measurement probabilities from measurement counts 

89 

90 Args: 

91 measurement_counts (Counter): A Counter of measurements. Key is the measurements 

92 in a big endian binary string. Value is the number of times that measurement 

93 occurred. 

94 

95 Returns: 

96 Dict[str, float]: A dictionary of probabilistic results. Key is the measurements 

97 in a big endian binary string. Value is the probability the measurement occurred. 

98 """ 

99 measurement_probabilities = {} 

100 shots = sum(measurement_counts.values()) 

101 

102 for key, count in measurement_counts.items(): 

103 measurement_probabilities[key] = count / shots 

104 return measurement_probabilities 

105 

106 @staticmethod 

107 def measurements_from_measurement_probabilities( 

108 measurement_probabilities: Dict[str, float], shots: int 

109 ) -> np.ndarray: 

110 """ 

111 Creates measurements from measurement probabilities 

112 

113 Args: 

114 measurement_probabilities (Dict[str, float]): A dictionary of probabilistic results. 

115 Key is the measurements in a big endian binary string. 

116 Value is the probability the measurement occurred. 

117 shots (int): number of iterations on device 

118 

119 Returns: 

120 Dict[str, float]: A dictionary of probabilistic results. 

121 Key is the measurements in a big endian binary string. 

122 Value is the probability the measurement occurred. 

123 """ 

124 measurements_list = [] 

125 for bitstring in measurement_probabilities: 

126 measurement = list(bitstring) 

127 individual_measurement_list = [measurement] * int( 

128 round(measurement_probabilities[bitstring] * shots) 

129 ) 

130 measurements_list.extend(individual_measurement_list) 

131 return np.asarray(measurements_list, dtype=int) 

132 

133 @staticmethod 

134 def from_string(result: str) -> GateModelQuantumTaskResult: 

135 """ 

136 Create GateModelQuantumTaskResult from string 

137 

138 Args: 

139 result (str): JSON object string, with GateModelQuantumTaskResult attributes as keys. 

140 

141 Returns: 

142 GateModelQuantumTaskResult: A GateModelQuantumTaskResult based on a string 

143 """ 

144 json_obj = json.loads(result) 

145 task_metadata = json_obj["TaskMetadata"] 

146 state_vector = json_obj.get("StateVector", None) 

147 if state_vector: 

148 for state in state_vector: 

149 state_vector[state] = complex(*state_vector[state]) 

150 if "Measurements" in json_obj: 

151 measurements = np.asarray(json_obj["Measurements"], dtype=int) 

152 m_counts = GateModelQuantumTaskResult.measurement_counts_from_measurements(measurements) 

153 m_probs = GateModelQuantumTaskResult.measurement_probabilities_from_measurement_counts( 

154 m_counts 

155 ) 

156 measurements_copied_from_device = True 

157 m_counts_copied_from_device = False 

158 m_probabilities_copied_from_device = False 

159 elif "MeasurementProbabilities" in json_obj: 159 ↛ 169line 159 didn't jump to line 169, because the condition on line 159 was never false

160 shots = task_metadata["Shots"] 

161 m_probs = json_obj["MeasurementProbabilities"] 

162 measurements = GateModelQuantumTaskResult.measurements_from_measurement_probabilities( 

163 m_probs, shots 

164 ) 

165 m_counts = GateModelQuantumTaskResult.measurement_counts_from_measurements(measurements) 

166 measurements_copied_from_device = False 

167 m_counts_copied_from_device = False 

168 m_probabilities_copied_from_device = True 

169 return GateModelQuantumTaskResult( 

170 state_vector=state_vector, 

171 task_metadata=task_metadata, 

172 measurements=measurements, 

173 measurement_counts=m_counts, 

174 measurement_probabilities=m_probs, 

175 measurements_copied_from_device=measurements_copied_from_device, 

176 measurement_counts_copied_from_device=m_counts_copied_from_device, 

177 measurement_probabilities_copied_from_device=m_probabilities_copied_from_device, 

178 )