Join TensorFlow at Google I/O, May 11-12

# tfq.get_sampled_expectation_op

Get a TensorFlow op that will calculate sampled expectation values.

### Used in the notebooks

Used in the tutorials

This function produces a non-differentiable TF op that will calculate batches of expectation values given tensor batches of `cirq.Circuit`s, parameter values, and `cirq.PauliSum` operators to measure. Expectation is estimated by taking num_samples shots per term in the corresponding PauliSum.

````# Simulate circuits with C++.`
`my_op = tfq.get_sampled_expectation_op()`
`# 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)`
`])`
`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 = my_op(`
`    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 my_op from the above code block differentiable:

````diff = tfq.differentiators.ForwardDifference()`
`my_differentiable_op = diff.generate_differentiable_op(`
`    analytic_op=my_op`
`)`
```

`backend` Optional Python `object` that specifies what backend this op should use when evaluating circuits. Can be any `cirq.Sampler`. If not provided the default C++ sampled expectation op is returned.
`quantum_concurrent` Optional Python `bool`. True indicates that the returned op should not block graph level parallelism on itself when executing. False indicates that graph level parallelism on itself should be blocked. Defaults to value specified in `tfq.get_quantum_concurrent_op_mode` which defaults to True (no blocking). This flag is only needed for advanced users when using TFQ for very large simulations, or when running on a real chip.

A `callable` with the following signature:

`op(programs, symbol_names, symbol_values, pauli_sums, num_samples)`

`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 specified 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 samples to draw in each term of `pauli_sums[i][j]` when estimating the expectation. Therefore, `num_samples` must have the same shape as `pauli_sums`.
`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).

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Missing the information I need" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Too complicated / too many steps" },{ "type": "thumb-down", "id": "outOfDate", "label":"Out of date" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Samples / code issue" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }]
[{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]