예제 #1
0
    def header(self):
        """The header associated with the BQM."""
        # lazy construction

        try:
            return self._header
        except AttributeError:
            pass

        bqm = self.bqm
        prefix = BQM_MAGIC_PREFIX
        version = bytes(self.version)

        if self.ignore_labels:
            index_labeled = True
        else:
            index_labeled = all(i == v for i, v in enumerate(bqm.variables))

        if index_labeled:
            # if we're index labelled, then the variables section should be
            # empty
            self._variables_section = bytes()

        data = dict(
            shape=bqm.shape,
            dtype=bqm.dtype.name,
            itype=bqm.itype.name,
            ntype=bqm.ntype.name,
            vartype=bqm.vartype.name,
            type=type(bqm).__name__,
        )

        if self._variables_in_header:
            data.update(
                variables=list(iter_serialize_variables(bqm.variables)))
        else:
            data.update(variables=not index_labeled)

        header_data = json.dumps(data, sort_keys=True).encode('ascii')
        header_data += b'\n'

        # whole header length should be divisible by 16
        header_data += b' ' * (
            16 - (len(prefix) + len(version) + 4 + len(header_data)) % 16)

        header_len = np.dtype('<u4').type(len(header_data)).tobytes()

        self._header = header = prefix + version + header_len + header_data

        assert len(header) % 16 == 0  # sanity check

        return self.header
예제 #2
0
    def to_serializable(self):
        variables = list(iter_serialize_variables(self.keys()))
        variables.sort(key=lambda x: str(x))

        num_variables = len(variables)

        chains = []
        for v in variables:
            chain = list(iter_serialize_variables(self[v]))
            chain.sort(key=lambda x: str(x))
            chains.append(chain)

        doc = {  # metadata
            "type": 'Embedding',
            # embedding
            "num_variables": num_variables,
            "variable_labels": variables,
            "chains": chains,
            "properties": self.properties
        }

        return doc
예제 #3
0
    def to_serializable(self,
                        use_bytes=False,
                        bias_dtype=np.float32,
                        bytes_type=bytes):
        """Convert the binary quadratic model to a serializable object.

        Args:
            use_bytes (bool, optional, default=False):
                If True, a compact representation representing the biases as
                bytes is used. Uses :func:`~numpy.ndarray.tobytes`.

            bias_dtype (data-type, optional, default=numpy.float32):
                If `use_bytes` is True, this :class:`~numpy.dtype` will be used
                to represent the bias values in the serialized format.

            bytes_type (class, optional, default=bytes):
                This class will be used to wrap the bytes objects in the
                serialization if `use_bytes` is true.

        Returns:
            dict: An object that can be serialized.

        Examples:

            Encode using JSON

            >>> import json
            ...
            >>> bqm = dimod.BinaryQuadraticModel({'a': -1.0, 'b': 1.0}, {('a', 'b'): -1.0}, 0.0, dimod.SPIN)
            >>> s = json.dumps(bqm.to_serializable())

            Encode using BSON_

            >>> import bson
            ...
            >>> bqm = dimod.BinaryQuadraticModel({'a': -1.0, 'b': 1.0}, {('a', 'b'): -1.0}, 0.0, dimod.SPIN)
            >>> doc = bqm.to_serializable(use_bytes=True)
            >>> b = bson.BSON.encode(doc)  # doctest: +SKIP

        See also:
            :meth:`~.BinaryQuadraticModel.from_serializable`

            :func:`json.dumps`, :func:`json.dump` JSON encoding functions

            :meth:`bson.BSON.encode` BSON encoding method

        .. _BSON: http://bsonspec.org/

        """
        from dimod.package_info import __version__

        schema_version = "3.0.0"

        variables = list(iter_serialize_variables(self.variables))

        try:
            variables.sort()
        except TypeError:
            # cannot unlike types in py3
            pass

        num_variables = len(variables)

        # when doing byte encoding we can use less space depending on the
        # total number of variables
        index_dtype = np.uint16 if num_variables <= 2**16 else np.uint32

        ldata, (irow, icol, qdata), offset = self.to_numpy_vectors(
            dtype=bias_dtype,
            index_dtype=index_dtype,
            sort_indices=True,  # to make it deterministic for the order
            variable_order=variables)

        num_interactions = len(irow)

        doc = {
            # metadata
            "type":
            type(self).__name__,
            "version": {
                "bqm_schema": schema_version
            },
            "use_bytes":
            bool(use_bytes),
            "index_type":
            np.dtype(index_dtype).name,
            "bias_type":
            np.dtype(bias_dtype).name,

            # bqm
            "num_variables":
            num_variables,
            "num_interactions":
            num_interactions,
            "variable_labels":
            variables,
            "variable_type":
            self.vartype.name,
            "offset":
            float(offset),
            "info":
            serialize_ndarrays(self.info,
                               use_bytes=use_bytes,
                               bytes_type=bytes_type),
        }

        if use_bytes:
            # these are vectors so don't need to specify byte-order
            doc.update({
                'linear_biases': bytes_type(ldata.tobytes()),
                'quadratic_biases': bytes_type(qdata.tobytes()),
                'quadratic_head': bytes_type(irow.tobytes()),
                'quadratic_tail': bytes_type(icol.tobytes())
            })
        else:
            doc.update({
                'linear_biases': ldata.tolist(),
                'quadratic_biases': qdata.tolist(),
                'quadratic_head': irow.tolist(),
                'quadratic_tail': icol.tolist()
            })

        return doc
예제 #4
0
 def dump_data(self):
     serializable = list(iter_serialize_variables(self.variables))
     return json.dumps(serializable).encode('ascii')