Skip to content

Commit

Permalink
Merge branch 'master' into 515_ps_diff
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Martinez committed Apr 5, 2021
2 parents b6930f7 + 3980ee6 commit b838547
Show file tree
Hide file tree
Showing 11 changed files with 872 additions and 7 deletions.
1 change: 1 addition & 0 deletions release/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ sh_binary(
"//tensorflow_quantum/core/ops/math_ops:inner_product_op_py",
"//tensorflow_quantum/core/ops/noise:noisy_samples_op_py",
"//tensorflow_quantum/core/ops/noise:noisy_expectation_op_py",
"//tensorflow_quantum/core/ops/noise:noisy_sampled_expectation_op_py",
"//tensorflow_quantum/core/serialize:serializer",
"//tensorflow_quantum/datasets:cluster_state",
"//tensorflow_quantum/datasets:spin_system",
Expand Down
1 change: 1 addition & 0 deletions scripts/import_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def test_imports():

# Noisy simulation ops.
_ = tfq.noise.expectation
_ = tfq.noise.sampled_expectation
_ = tfq.noise.samples

# Util functions.
Expand Down
21 changes: 21 additions & 0 deletions tensorflow_quantum/core/ops/noise/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cc_binary(
name = "_tfq_noise_ops.so",
srcs = [
"tfq_noisy_expectation.cc",
"tfq_noisy_sampled_expectation.cc",
"tfq_noisy_samples.cc"
],
copts = select({
Expand Down Expand Up @@ -91,6 +92,26 @@ py_test(
],
)

py_library(
name = "noisy_sampled_expectation_op_py",
srcs = ["noisy_sampled_expectation_op.py"],
data = [":_tfq_noise_ops.so"],
deps = [
"//tensorflow_quantum/core/ops:load_module",
],
)

py_test(
name = "noisy_sampled_expectation_op_test",
srcs = ["noisy_sampled_expectation_op_test.py"],
python_version = "PY3",
deps = [
":noisy_sampled_expectation_op_py",
"//tensorflow_quantum/core/ops:batch_util",
"//tensorflow_quantum/python:util",
],
)

py_library(
name = "noisy_samples_op_py",
srcs = ["noisy_samples_op.py"],
Expand Down
2 changes: 2 additions & 0 deletions tensorflow_quantum/core/ops/noise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
"""Module for tfq.core.ops.noise.*"""

from tensorflow_quantum.core.ops.noise.noisy_expectation_op import expectation
from tensorflow_quantum.core.ops.noise.noisy_sampled_expectation_op import \
sampled_expectation
from tensorflow_quantum.core.ops.noise.noisy_samples_op import samples
97 changes: 97 additions & 0 deletions tensorflow_quantum/core/ops/noise/noisy_sampled_expectation_op.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Copyright 2020 The TensorFlow Quantum Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Module for high performance noisy circuit sampled epxectation ops."""
import os
import tensorflow as tf
from tensorflow_quantum.core.ops.load_module import load_module

NOISY_OP_MODULE = load_module(os.path.join("noise", "_tfq_noise_ops.so"))


def sampled_expectation(programs, symbol_names, symbol_values, pauli_sums,
num_samples):
"""Estimates (via sampling) expectation values using monte-carlo simulation.
Simulate the final state of `programs` given `symbol_values` are placed
inside of the symbols with the name in `symbol_names` in each circuit.
Channels in this simulation will be "tossed" to a certain realization
during simulation. This simulation is repeated `num_samples` times and
bitstring based expectation calculations with the given `pauli_sums` are
calculated after each run. Once all the runs are finished, these quantities
are averaged together.
>>> # Prepare some inputs.
>>> qubit = cirq.GridQubit(0, 0)
>>> my_symbol = sympy.Symbol('alpha')
>>> my_circuit_tensor = tfq.convert_to_tensor([
... cirq.Circuit(
... cirq.H(qubit) ** my_symbol,
... cirq.depolarize(0.01)(qubit)
... )
... ])
>>> my_values = np.array([[0.123]])
>>> my_paulis = tfq.convert_to_tensor([[
... 3.5 * cirq.X(qubit) - 2.2 * cirq.Y(qubit)
... ]])
>>> my_num_samples = np.array([[100]])
>>> # This op can now be run with:
>>> output = tfq.noise.sampled_expectation(
... my_circuit_tensor, ['alpha'], my_values, my_paulis, my_num_samples)
>>> output
tf.Tensor([[0.71530885]], shape=(1, 1), dtype=float32)
In order to make the op differentiable, a `tfq.differentiator` object is
needed. see `tfq.differentiators` for more details. Below is a simple
example of how to make the from the above code block differentiable:
>>> diff = tfq.differentiators.ForwardDifference()
>>> my_differentiable_op = diff.generate_differentiable_op(
... sampled_op=tfq.noise.sampled_expectation
... )
Args:
programs: `tf.Tensor` of strings with shape [batch_size] containing
the string representations of the circuits to be executed.
symbol_names: `tf.Tensor` of strings with shape [n_params], which
is used to specify the order in which the values in
`symbol_values` should be placed inside of the circuits in
`programs`.
symbol_values: `tf.Tensor` of real numbers with shape
[batch_size, n_params] specifying parameter values to resolve
into the circuits specificed by programs, following the ordering
dictated by `symbol_names`.
pauli_sums: `tf.Tensor` of strings with shape [batch_size, n_ops]
containing the string representation of the operators that will
be used on all of the circuits in the expectation calculations.
num_samples: `tf.Tensor` with `num_samples[i][j]` is equal to the
number of times `programs[i]` will be simulated to estimate
`pauli_sums[i][j]`. Therefore, `num_samples` must have the same
shape as `pauli_sums`. Note: internally this quantity can get
rounded up to the nearest multiple of the number of available
threads to TensorFlow. For best performance ensure that the
quantities in `num_samples` are a multiple of the number of
available threads.
Returns:
`tf.Tensor` with shape [batch_size, n_ops] that holds the
expectation value for each circuit with each op applied to it
(after resolving the corresponding parameters in).
"""
return NOISY_OP_MODULE.tfq_noisy_sampled_expectation(
programs, symbol_names, tf.cast(symbol_values, tf.float32), pauli_sums,
tf.cast(num_samples, dtype=tf.int32))
Loading

0 comments on commit b838547

Please sign in to comment.