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, Dict 

19 

20import numpy 

21 

22 

23@dataclass 

24class AnnealingQuantumTaskResult: 

25 """ 

26 Result of an annealing problem quantum task execution. This class is intended 

27 to be initialized by a QuantumTask class. 

28 

29 Args: 

30 record_array (numpy.recarray): numpy array with keys 'solution' (numpy.ndarray) 

31 where row is solution, column is value of the variable, 'solution_count' (numpy.ndarray) 

32 the number of times the solutions occurred, and 'value' (numpy.ndarray) the 

33 output or energy of the solutions. 

34 variable_count (int): the number of variables 

35 problem_type (str): the type of problem ('ising' or 'qubo') 

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

37 additional_metadata (Dict[str, Any]): A dictionary of additional device-specific metadata 

38 """ 

39 

40 record_array: numpy.recarray 

41 variable_count: int 

42 problem_type: str 

43 task_metadata: Dict[str, Any] 

44 additional_metadata: Dict[str, Any] 

45 

46 def data(self, selected_fields=None, sorted_by="value", reverse=False): 

47 """ 

48 Iterate over the data in record_array 

49 

50 Args: 

51 selected_fields (List[str], optional, default=None): selected fields to return. 

52 Options are 'solution', 'value', and 'solution_count' 

53 sorted_by (str, optional, default='value'): Sorts the data by this field. 

54 Options are 'solution', 'value', and 'solution_count' 

55 reverse (bool, optional, default=False): If True, returns the data in reverse order. 

56 

57 Yields: 

58 tuple: data in record_array 

59 """ 

60 if selected_fields is None: 

61 selected_fields = ["solution", "value", "solution_count"] 

62 

63 if sorted_by is None: 

64 order = numpy.arange(len(self.record_array)) 

65 else: 

66 order = numpy.argsort(self.record_array[sorted_by]) 

67 

68 if reverse: 

69 order = numpy.flip(order) 

70 

71 for i in order: 

72 yield tuple(self.record_array[field][i] for field in selected_fields) 

73 

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

75 if isinstance(other, AnnealingQuantumTaskResult): 

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

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

78 # elements in the array are equal. 

79 self_fields = ( 

80 self.variable_count, 

81 self.problem_type, 

82 self.task_metadata, 

83 self.additional_metadata, 

84 ) 

85 other_fields = ( 

86 other.variable_count, 

87 other.problem_type, 

88 other.task_metadata, 

89 other.additional_metadata, 

90 ) 

91 return (self.record_array == other.record_array).all() and self_fields == other_fields 

92 return NotImplemented 

93 

94 @staticmethod 

95 def from_string(result: str) -> AnnealingQuantumTaskResult: 

96 """ 

97 Create AnnealingQuantumTaskResult from string 

98 

99 Args: 

100 result (str): JSON object string 

101 

102 Returns: 

103 AnnealingQuantumTaskResult: An AnnealingQuantumTaskResult based on a string. 

104 """ 

105 json_obj = json.loads(result) 

106 solutions = numpy.asarray(json_obj["Solutions"], dtype=int) 

107 values = numpy.asarray(json_obj["Values"], dtype=float) 

108 if json_obj["SolutionCounts"] is None: 

109 solution_counts = numpy.ones(len(solutions), dtype=int) 

110 else: 

111 solution_counts = numpy.asarray(json_obj["SolutionCounts"], dtype=int) 

112 record_array = AnnealingQuantumTaskResult.create_record_array( 

113 solutions, solution_counts, values 

114 ) 

115 variable_count = json_obj["VariableCount"] 

116 problem_type = json_obj["ProblemType"] 

117 task_metadata = json_obj["TaskMetadata"] 

118 additional_metadata = {} 

119 for key in json_obj.keys(): 

120 if key.endswith("Metadata") and key != "TaskMetadata": 

121 additional_metadata[key] = json_obj[key] 

122 return AnnealingQuantumTaskResult( 

123 record_array=record_array, 

124 variable_count=variable_count, 

125 problem_type=problem_type, 

126 task_metadata=task_metadata, 

127 additional_metadata=additional_metadata, 

128 ) 

129 

130 @staticmethod 

131 def create_record_array( 

132 solutions: numpy.ndarray, solution_counts: numpy.ndarray, values: numpy.ndarray 

133 ) -> numpy.recarray: 

134 """ 

135 Create a solutions record for AnnealingQuantumTaskResult 

136 

137 Args: 

138 solutions (numpy.ndarray): row is solution, column is value of the variable 

139 solution_counts (numpy.ndarray): list of number of times the solutions occurred 

140 values (numpy.ndarray): list of the output or energy of the solutions 

141 """ 

142 num_solutions, variable_count = solutions.shape 

143 datatypes = [ 

144 ("solution", solutions.dtype, (variable_count,)), 

145 ("value", values.dtype), 

146 ("solution_count", solution_counts.dtype), 

147 ] 

148 

149 record = numpy.rec.array(numpy.zeros(num_solutions, dtype=datatypes)) 

150 record["solution"] = solutions 

151 record["value"] = values 

152 record["solution_count"] = solution_counts 

153 return record