Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Release 0.2.1802.2202 - netcore & python preview (#32)
Browse files Browse the repository at this point in the history
* Switching repository to MIT License

* Release 0.2.1802.2202 - netcore & mit license

* Added license headers to H2 simulation sample.
  • Loading branch information
anpaz authored and cgranade committed Feb 26, 2018
1 parent 18cabfe commit 1789de8
Show file tree
Hide file tree
Showing 106 changed files with 4,213 additions and 3,026 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Expand Up @@ -2,6 +2,7 @@
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
*.sh text eol=lf

###############################################################################
# Set default behavior for command prompt diff.
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
@@ -1,3 +1,6 @@
# Python temporary files
.ipynb_checkpoints

# Git ignore file for the Solid project

# Build artifacts
Expand All @@ -11,12 +14,16 @@ packages/
*.pdb
*.exe
*.chm
*.html

# These files are generated by bootstrap from a .v.template (version template).
# Any changes must be done to the corresponding the .v.template file directly
Microsoft.Quantum.Canon/Microsoft.Quantum.Canon.nuspec

# Python interop build outputs:
Interoperability/python/build
Interoperability/python/dist
Interoperability/python/qsharp.egg-info
Interoperability/python/qsharp/version.py

# test outputs
TestResults/
Expand Down
2 changes: 1 addition & 1 deletion Docs/style-guide.md
Expand Up @@ -8,7 +8,7 @@

- Avoid using people's names in operation and function names where reasonable.
Consider using names that describe the implemented functionality;
e.g. `CCNOT` versus `Toffoli` or `CSWAP` versus `Fredikin `.
e.g. `CCNOT` versus `Toffoli` or `CSWAP` versus `Fredkin `.
In sample code, consider using names that are familiar to the community reading each particular example, even if that would otherwise run counter to these suggestions.
**NB:** names should still appear in documentation comments.
- If an operation or function is not intended for direct use, but rather should be used by a matching callable which acts by partial application, consider using a name ending with `Impl` for the callable that is partially applied.
Expand Down
19 changes: 19 additions & 0 deletions Interoperability/python/environment.yml
@@ -0,0 +1,19 @@
##
# environment.yml: Specification of a conda environment for use with
# the Q# interoperability package.
##
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
##

name: qsharp
channels:
- conda-forge
- pythonnet
dependencies:
- numpy
- pythonnet
- qutip
- matplotlib
- pip:
- qinfer
5 changes: 5 additions & 0 deletions Interoperability/python/packages.config
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Quantum.Development.Kit" version="0.2.1802.2202-preview" targetFramework="netstandard2.0" />
<package id="Microsoft.Quantum.Canon" version="0.2.1802.2202-preview" targetFramework="netstandard2.0" />
</packages>
230 changes: 230 additions & 0 deletions Interoperability/python/qsharp/__init__.py
@@ -0,0 +1,230 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# __init__.py: Root module for Q# interoperability package.
##
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
##

## IMPORTS ###################################################################

# Standard Library Imports #

from enum import IntEnum
from functools import partial, singledispatch
from abc import ABCMeta, abstractproperty
from random import randrange

# HACK: In order to make DLLs that we ship with visible to Python.NET
# in the next step, we need to add the directory containing __file__
# to sys.path.
import os.path
import sys
sys.path.append(os.path.split(__file__)[0])

# Version Information #
# We try to import version.py, and if not, set our version to None.
try:
import qsharp.version
__version__ = qsharp.version.version
except ImportError:
__version__ = "<unknown>"

# CLR Imports #

import clr

import System.Threading.Tasks
import Microsoft.Quantum.Simulation.Simulators as mqss

# External Python Imports #

try:
import colorama as ca
ca.init()

SIMULATOR_COLOR = ca.Fore.BLUE + ca.Back.WHITE
RESET_COLOR = ca.Style.RESET_ALL
except:
ca = None
SIMULATOR_COLOR = ""
RESET_COLOR = ""

try:
import qutip as qt
except:
qt = None

try:
from IPython.display import display
except:
def display(value):
pass

import qsharp.tomography
from qsharp.clr_wrapper import *


## ENUMERATIONS ##############################################################

class SampleableEnum(IntEnum):
"""
Extends integer-valued enumerations to allow for uniformly sampling from
enumeration members.
"""
@classmethod
def random(cls):
"""
Returns a member of the enumeration uniformly at random.
"""
return cls(randrange(len(cls)))

class Pauli(SampleableEnum):
"""
Represents the `Pauli` Q# type.
"""
I = 0
X = 1
Y = 2
Z = 3

def as_qobj(self):
"""
Returns a representation of the given Pauli operator as a QuTiP
Qobj instance.
"""
if qt is None:
raise RuntimeError("Requires QuTiP.")
if self == Pauli.I:
return qt.qeye(2)
elif self == Pauli.X:
return qt.sigmax()
elif self == Pauli.Y:
return qt.sigmay()
else:
return qt.sigmaz()

class Result(SampleableEnum):
"""
Represents the `Result` Q# type.
"""

#: Represents a measurement corresponding to the $+1 = (-1)^0$ eigenvalue
#: of a Pauli operator.
Zero = 0

#: Represents a measurement corresponding to the $-1 = (-1)^1$ eigenvalue
#: of a Pauli operator.
One = 1

## FUNCTIONS #################################################################

@singledispatch
def wrap_clr_object(clr_object):
return WrappedCLRObject(clr_object)

@wrap_clr_object.register(type(None))
def _(none):
return None

@wrap_clr_object.register(System.Threading.Tasks.Task)
def _(clr_object):
return Task(clr_object)

## CLASSES ###################################################################

class SimulatorOutput(object):
"""
Wraps a string for pretty-printing to Jupyter outputs.
"""
@classmethod
def display_output(cls, data):
display(cls(data))

def __init__(self, data):
self.data = data

def __repr__(self):
return repr(self.data)
def __str__(self):
return "{}[Simulator]{} {}".format(
SIMULATOR_COLOR, RESET_COLOR, self.data
)

def _repr_html_(self):
return """
<pre class="simulator-output">{}</pre>
""".format(self.data)

class Task(WrappedCLRObject):
_detailed_repr = False

@property
def _friendly_name(self):
return "Asynchronous {} Task".format(
self.clr_type.GetGenericArguments()[0]
)

def result(self):
# Wait for the response first. This should be implied by self.Result,
# but we've seen some bugs occur related to that.
self.clr_object.Wait()
return wrap_clr_object(self.clr_object.Result)

class Simulator(WrappedCLRObject):
_friendly_name = "Simulator"

def __init__(self, clr_simulator):
if isinstance(clr_simulator, CLR_METATYPE):
clr_simulator = clr_simulator()
super(Simulator, self).__init__(clr_simulator)

# Register a delegate to handle Message calls.
self.clr_object.OnLog += SimulatorOutput.display_output

def get(self, clr_type):
return Callable(self, self.clr_object.Get[clr_type, clr_type]())

def run(self, clr_type, *args):
if isinstance(clr_type, Callable):
# Check if the passed in type is already wrapped in a Callable Python
# class.
return clr_type(*args)
else:
# We need to get the callable ourselves, then.
callable = self.get(clr_type)
return callable(*args)

class QuantumSimulator(Simulator):
_friendly_name = "Quantum Simulator"
def __init__(self):
super(QuantumSimulator, self).__init__(mqss.QuantumSimulator)

class Callable(WrappedCLRObject):
_detailed_repr = False
_parent = None
_include_plain_repr = False

@property
def _friendly_name(self):
# TODO: extract operation signature!
return self.ToString()

def __init__(self, parent, clr_callable):
self._parent = parent
super(Callable, self).__init__(clr_callable)

def __call__(self, *args):
output = self.clr_object.Run(
unwrap_clr(self._parent),
*map(unwrap_clr, args)
)

if isinstance(type(output), CLR_METATYPE):
# Try to wrap the output as best as we can.
# We provide convienence wrappers for a few, so we call the
# single-dispatched convienence function above.
return wrap_clr_object(output)
else:
return output
19 changes: 19 additions & 0 deletions Interoperability/python/qsharp/__main__.py
@@ -0,0 +1,19 @@
#!/bin/env python
# -*- coding: utf-8 -*-
##
# __main__.py: Main script for the Q# interoperability package.
##
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
##

import qsharp

from qsharp.tomography import single_qubit_process_tomography
from Microsoft.Quantum.Primitive import I

qsim = qsharp.QuantumSimulator()
noise_channel = qsim.get(I)
estimation_results = single_qubit_process_tomography(qsim, noise_channel, n_measurements=2000)

print(estimation_results['est_channel'])

0 comments on commit 1789de8

Please sign in to comment.