Skip to main content

A quantum random number generator for arbitrary probability distributions

Project description

Unitary Fund YouTube PyPI Apache-2.0 License

qrand

A quantum random number generator for arbitrary probability distributions

Random numbers are everywhere.

Computer algorithms, data encryption, physical simulations, and even the arts use them all the time. There is one problem though: it turns out that they are actually very difficult to produce in large amounts. Classical computers can only implement mathematical tricks to emulate randomness, while measuring it out of physical processes turns out to be too slow.

Luckily, the probabilistic nature of quantum computers makes these devices particularly useful for the task. Nonetheless, most of the current efforts in producing quantum random numbers have been focused on uniform probability distributions. Despite this fact, many applications actually need to sample from more complex distributions (e.g. gaussian, poisson).

This software introduces an interface layer between NumPy and Qiskit, along with some useful functionality that enables the production of quantum random numbers (QRN) for a wide variety of probability distributions. This is ultimately accomplished by transforming uniform probability distributions produced in IBMQ's quantum devices, through NumPy's random module.

from qrand import QiskitBitGenerator
from numpy.random import Generator
from qiskit import IBMQ

provider = IBMQ.load_account()
bitgen = QiskitBitGenerator(provider)
gen = Generator(bitgen)

print(f"Random Raw: {bitgen.random_raw()}")
print(f"Random Bitstring: {bitgen.random_bitstring()}")
print(f"Random Unsigned Int: {bitgen.random_uint()}")
print(f"Random Double: {bitgen.random_double()}")

print(f"Random Binomial: {gen.binomial(4, 1/4)}")
print(f"Random Exponential: {gen.exponential()}")
print(f"Random Logistic: {gen.logistic()}")
print(f"Random Poisson: {gen.poisson()}")
print(f"Random Std. Normal: {gen.standard_normal()}")
print(f"Random Triangular: {gen.triangular(-1, 0, 1)}")
# ...

Documentation

QiskitBitGenerator

A quantum random bit-generator based on Qiskit, which can interface with NumPy's random module (e.g. to instantiate Generator objects). It implements an efficient strategy to retrieve random bits from IBMQ's quantum backends.

On each request to a backend, it retrieves as many bits as possible and stores them in a cache. This way, the number of internet connections leading to overheads is greatly reduced and, while the cache is loaded, random bits can be retrieved "instantaneously". The user can limit the number of bits to retrieve on each request through the max_bits_per_request argument.

Additionally, it always chooses the least busy backend from the list of available machines. This list can be filtered by the user through the backend_filter argument, which defaults to history-enabled non-simulators. If a Qiskit Backend is explicitly passed in as argument, no backend selection will be performed: effectively ignoring any Qiskit Provider object passed. If neither provider nor backend are passed as inputs, it will default to running Qiskit BasicAer's 'qasm_simulator' locally.

CLASS ARGUMENTS

  • provider: Optional[Provider] = None
    A Qiskit Provider object to access quantum backends. If None it defaults to BasicAer.
  • backend: Optional[Backend] = None
    A Qiskit Backend object to produce random bits. If not None, provider will be ignored.
  • backend_filter: Optional[BackendFilter] = None
    A Callable that takes in a Qiskit Backend object and returns True if it meets certain requirements, False otherwise. This is used to filter the list of available backends from which to dynamically choose on each request to the provider (if no backend is explicitly input). If None it defaults to QiskitBitGenerator.default_backend_filter.
  • max_bits_per_request: int = 0
    A limit to the number of bits to be retrieved on each request to any Qiskit Backend. If less than one, no bound will be applied and the maximum allowed number of bits will be retrieved.
  • ISRAW32: Final[bool] = False
    Toggle 32-bit BitGenerator mode. If False the BitGenerator will be 64-bit. This determines the number of bits returned by NumPy's random_raw() method, and the default number of bits to output on random_uint() and random_double(). Once an object is instantiated, this cannot be overridden.

STATIC / CLASS METHODS

  • default_backend_filter (b: Backend) -> bool:
    Default backend filter Callable.
    • ARGUMENTS
      • b: Backend
        A Qiskit Backend object.
    • RETURNS
      • out: bool
        True if b is not a simulator and has memory enabled, False otherwise.
  • get_best_backend (cls, provider: Provider, backend_filter: Optional[BackendFilter] = None) -> Backend:
    Returns the least busy backend available to an input provider, and according to certain filter(s).
    • ARGUMENTS
      • provider: Provider
        A Qiskit Provider object to access quantum backends.
      • backend_filter: Optional[BackendFilter] = None
        A Callable that takes in a Qiskit Backend object and returns True if it meets certain requirements, False otherwise. If None it defaults to cls.default_backend_filter.
    • RETURNS
      • out: Backend
        Least busy backend from the filtered list of available backends.

PUBLIC METHODS

  • dump_cache (self, flush: bool = False) -> str:
    Returns all the contents stored in the cache.
    • ARGUMENTS
      • flush: bool = False
        If True erase the cache after dumping.
    • RETURNS
      • out: str
        The bitstring stored in cache.
  • flush_cache (self) -> bool:
    Erase the cache.
    • RETURNS
      • out: bool
        True if succeeds, False otherwise.
  • load_cache (self, bitstring: str, flush: bool = False) -> bool:
    Load cache contents from bitstring.
    • ARGUMENTS
      • bitstring: str
        The bitstring to load to cache.
      • flush: bool = False
        If True erase cache before loading.
    • RETURNS
      • out: bool
        True if succeeds, False otherwise.
    • RAISES
      • TypeError
        If input bitstring is not str
      • ValueError
        If input bitstring is not a valid bitstring
  • random_bitstring (self, n_bits: int = 0) -> str:
    Returns a random bitstring of a given lenght.
    • ARGUMENTS
      • n_bits: int = 0
        Number of bits to retrieve. If less than one it defaults to the raw number of bits for the instance QiskitBitGenerator (i.e. 32 or 64).
    • RETURNS
      • out: str
        Bitstring of lenght n_bits.
  • random_double (self, n: float = 1) -> float:
    Returns a random double from a uniform distribution in the range [0,n). Defaults to [0,1).
    • ARGUMENTS
      • n: float = 1
        Size of the range [0,n) from which to draw the random number.
    • RETURNS
      • out: float
        Random float in the range [0,n).
  • random_raw (self) -> int:
    Returns a random unsigned int of either 32 or 64 bits.
    • RETURNS
      • out: int
        Unsigned int of either 32 or 64 bits.
  • random_uint (self, n_bits: int = 0) -> int:
    Returns a random unsigned int of a given size in bits.
    • ARGUMENTS
      • n_bits: int = 0
        Number of bits to retrieve. If less than one it defaults to the raw number of bits for the instance QiskitBitGenerator (i.e. 32 or 64).
    • RETURNS
      • out: int
        Unsigned int of n_bits bits.
  • set_state (self, provider: Optional[Provider] = None, backend: Optional[Backend] = None, backend_filter: Optional[BackendFilter] = None, max_bits_per_request: Optional[int] = None) -> bool:
    Override constructor arguments. Any change must be explicitly passed as input (i.e. not None).
    • ARGUMENTS
      • provider: Optional[Provider] = None
        Same as constructor.
      • backend: Optional[Backend] = None
        Same as constructor.
      • backend_filter: Optional[BackendFilter] = None
        Same as constructor.
      • max_bits_per_request: Optional[int] = None
        Same as constructor.
    • RETURNS
      • out: bool
        True if any changes were made, False otherwise.

PUBLIC PROPERTIES

  • BITS: Final[int]
    Either 32 or 64. The number of bits output by NumPy's random_raw() method. Final, it cannot be modified after instantiation through the ISRAW32 argument.
  • state: dict
    Parsed information about the current state of the QiskitBitGenerator.

Acknowledgements

Parts of this software's source code have been borrowed from the qRNG project, which is licensed under the GNU GPLv3 license. Copyright notice and specific changes can be found as a docstring wherever this applies.


(c) Copyright 2020 Pedro Rivero

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qrand-0.1.0.tar.gz (14.9 kB view hashes)

Uploaded Source

Built Distribution

qrand-0.1.0-py3-none-any.whl (14.4 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page