# tfq.differentiators.ForwardDifference

Stay organized with collections Save and categorize content based on your preferences.

Differentiate a circuit using forward differencing.

Inherits From: `LinearCombination`, `Differentiator`

### Used in the notebooks

Used in the tutorials

Forward differencing computes a derivative at a point x using only points larger than x (in this way, it is 'one sided'). A closed form for the coefficients of this derivative for an arbitrary positive error order is used here, which is described in the following article: https://www.sciencedirect.com/science/article/pii/S0377042799000886

````my_op = tfq.get_expectation_op()`
`linear_differentiator = tfq.differentiators.ForwardDifference(2, 0.01)`
`# Get an expectation op, with this differentiator attached.`
`op = linear_differentiator.generate_differentiable_op(`
`    analytic_op=my_op`
`)`
`qubit = cirq.GridQubit(0, 0)`
`circuit = tfq.convert_to_tensor([`
`    cirq.Circuit(cirq.X(qubit) ** sympy.Symbol('alpha'))`
`])`
`psums = tfq.convert_to_tensor([[cirq.Z(qubit)]])`
`symbol_values_array = np.array([[0.123]], dtype=np.float32)`
`# Calculate tfq gradient.`
`symbol_values_tensor = tf.convert_to_tensor(symbol_values_array)`
`with tf.GradientTape() as g:`
`    g.watch(symbol_values_tensor)`
`    expectations = op(circuit, ['alpha'], symbol_values_tensor, psums)`
`# Gradient would be: -50 * f(x + 0.02) +  200 * f(x + 0.01) - 150 * f(x)`
`grads = g.gradient(expectations, symbol_values_tensor)`
`grads`
`tf.Tensor([[-1.184372]], shape=(1, 1), dtype=float32)`
```

`error_order` A positive `int` specifying the error order of this differentiator. This corresponds to the smallest power of `grid_spacing` remaining in the series that was truncated to generate this finite differencing expression.
`grid_spacing` A positive `float` specifying how large of a grid to use in calculating this finite difference.

## Methods

### `differentiate_analytic`

View source

Differentiate a circuit with analytical expectation.

This is called at graph runtime by TensorFlow. `differentiate_analytic` calls he inheriting differentiator's `get_gradient_circuits` and uses those components to construct the gradient.

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 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.
`forward_pass_vals` `tf.Tensor` of real numbers with shape [batch_size, n_ops] containing the output of the forward pass through the op you are differentiating.
`grad` `tf.Tensor` of real numbers with shape [batch_size, n_ops] representing the gradient backpropagated to the output of the op you are differentiating through.

Returns
A `tf.Tensor` with the same shape as `symbol_values` representing the gradient backpropageted to the `symbol_values` input of the op you are differentiating through.

### `differentiate_sampled`

View source

Differentiate a circuit with sampled expectation.

This is called at graph runtime by TensorFlow. `differentiate_sampled` calls he inheriting differentiator's `get_gradient_circuits` and uses those components to construct the gradient.

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 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` of positive integers representing the number of samples per term in each term of pauli_sums used during the forward pass.
`forward_pass_vals` `tf.Tensor` of real numbers with shape [batch_size, n_ops] containing the output of the forward pass through the op you are differentiating.
`grad` `tf.Tensor` of real numbers with shape [batch_size, n_ops] representing the gradient backpropagated to the output of the op you are differentiating through.

Returns
A `tf.Tensor` with the same shape as `symbol_values` representing the gradient backpropageted to the `symbol_values` input of the op you are differentiating through.

### `generate_differentiable_op`

View source

Generate a differentiable op by attaching self to an op.

This function returns a `tf.function` that passes values through to `forward_op` during the forward pass and this differentiator (`self`) to backpropagate through the op during the backward pass. If sampled_op is provided the differentiators `differentiate_sampled` method will be invoked (which requires sampled_op to be a sample based expectation op with num_samples input tensor). If analytic_op is provided the differentiators `differentiate_analytic` method will be invoked (which requires analytic_op to be an analytic based expectation op that does NOT have num_samples as an input). If both sampled_op and analytic_op are provided an exception will be raised.

This `generate_differentiable_op()` can be called only ONCE because of the `one differentiator per op` policy. You need to call `refresh()` to reuse this differentiator with another op.

Args
`sampled_op` A `callable` op that you want to make differentiable using this differentiator's `differentiate_sampled` method.
`analytic_op` A `callable` op that you want to make differentiable using this differentiators `differentiate_analytic` method.

Returns
A `callable` op that who's gradients are now registered to be a call to this differentiators `differentiate_*` function.

### `get_gradient_circuits`

View source

See base class description.

### `refresh`

View source

Refresh this differentiator in order to use it with other ops.

[{ "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" }]