@@ -24,48 +24,86 @@ def inner_product_hessian(programs, symbol_names, symbol_values, other_programs,
2424 programs_coeffs , other_programs_coeffs ):
2525 """Calculate the adjoint Hessian of the inner product between circuits.
2626
27- Compute the gradients of the (potentially many) inner products between
28- the given circuits and the symbol free comparison circuits.
29-
30- Calculates out[i][j][k] = $\t ext{programs_coeffs[i]} \t imes \langle
31- \f rac{\partial^2 \psi_{\t ext{programs[i]}}(\t ext{symbol_values[i]})}
32- {\partial \t ext{symbol_names[j]}\partial \t ext{symbol_names[k]}} |
33- \sum_l \t ext{other_programs_coeffs[l]}\t imes |
34- \psi_{\t ext{other_programs[l]}} \r angle$
35-
36-
37- Note: `other_programs` must not contain any free symbols. These can
38- be resolved beforehand with `tfq.resolve_parameters`.
39-
40- Note: len(symbol_names) (=n_params) should be a positive integer.
41-
42- Args:
43- programs: `tf.Tensor` of strings with shape [batch_size] containing
44- the string representations of the circuits
45- symbol_names: `tf.Tensor` of strings with shape [n_params], which
46- is used to specify the order in which the values in
47- `symbol_values` should be placed inside of the circuits in
48- `programs`.
49- symbol_values: `tf.Tensor` of real numbers with shape
50- [batch_size, n_params] specifying parameter values to resolve
51- into the circuits specificed by programs, following the ordering
52- dictated by `symbol_names`.
53- other_programs: `tf.Tensor` of strings with shape [batch_size, n_others]
54- containing the string representations of the circuits with which to
55- compute the overlap on `programs` with. Must not contain any free
56- symbols.
57- programs_coeffs: `tf.Tensor` of real numbers with shape [batch_size]
58- of weights on `programs`.
59- other_programs_coeffs: `tf.Tensor` of real numbers with shape
60- [batch_size, n_others] of weights on `other_programs`.
61-
62- Returns:
63- tf.Tensor` with shape [batch_size, n_symbols, n_symbols] where `out[i]` is
64- equal to the hessian of the inner product between programs[i] and all
65- other_programs[i] w.r.t. `symbol_names[j]` and `symbol_names[k]`.
66- `programs[i]` is resolved with `symbol_values[i]` and each
67- (other_)programs[i] is weighted by (other_)programs_coeffs[i].
68- """
27+ Compute the gradients of the (potentially many) inner products between
28+ the given circuits and the symbol free comparison circuits.
29+
30+ Calculates out[i][j][k] = $\t ext{programs_coeffs[i]} \t imes \langle
31+ \f rac{\partial^2 \psi_{\t ext{programs[i]}}(\t ext{symbol_values[i]})}
32+ {\partial \t ext{symbol_names[j]}\partial \t ext{symbol_names[k]}} |
33+ \sum_l \t ext{other_programs_coeffs[l]}\t imes |
34+ \psi_{\t ext{other_programs[l]}} \r angle$
35+
36+
37+ >>> symbols = sympy.symbols('alpha beta')
38+ >>> qubits = cirq.GridQubit.rect(1, 2)
39+ >>> reference_circuits = [
40+ ... cirq.Circuit((cirq.H**symbols[0]).on_each(qubits)),
41+ ... cirq.Circuit(
42+ ... cirq.X(qubits[0]) ** symbols[0],
43+ ... cirq.Y(qubits[1]) ** symbols[1])
44+ ... ]
45+ >>> other_circuits = [
46+ ... cirq.Circuit(cirq.X.on_each(qubits)),
47+ ... cirq.Circuit((cirq.Y**0.125).on_each(qubits)),
48+ ... cirq.Circuit((cirq.X**0.5).on_each(qubits))
49+ ... ]
50+ >>> reference_tensor = tfq.convert_to_tensor(reference_circuits)
51+ >>> symbol_tensor = tf.convert_to_tensor([s.name for s in symbols])
52+ >>> values_tensor = tf.convert_to_tensor(np.arange(4).reshape(2, 2))
53+ >>> other_tensor = tfq.convert_to_tensor([other_circuits, other_circuits])
54+ >>> reference_coeff_tensor = tf.ones((len(reference_circuits,)))
55+ >>> other_coeff_tensor = tf.ones((len(reference_circuits),
56+ ... len(other_circuits)))
57+ >>> ip = tfq.math.inner_product_hessian(reference_tensor, symbol_tensor,
58+ ... values_tensor, other_tensor,
59+ ... reference_coeff_tensor,
60+ ... other_coeff_tensor)
61+ >>> ip
62+ tf.Tensor(
63+ [[[ 0.6069082-1.0185852j 0. +0.j ]
64+ [ 0. +0.j 0. +0.j ]]
65+
66+ [[-2.7567296-1.7676406j -0.8554697+1.0770144j]
67+ [-0.8554697+1.0770144j 4.0239005+7.6238985j]]], shape=(2, 2, 2),
68+ dtype=complex64)
69+
70+
71+
72+ Note: `other_programs` must not contain any free symbols. These can
73+ be resolved beforehand with `tfq.resolve_parameters`.
74+
75+ Note: `programs` must not contain `cirq.PhasedXPowGate` due to precision
76+ issue.
77+
78+ Note: len(symbol_names) (=n_params) should be a positive integer.
79+
80+ Args:
81+ programs: `tf.Tensor` of strings with shape [batch_size] containing
82+ the string representations of the circuits
83+ symbol_names: `tf.Tensor` of strings with shape [n_params], which
84+ is used to specify the order in which the values in
85+ `symbol_values` should be placed inside of the circuits in
86+ `programs`.
87+ symbol_values: `tf.Tensor` of real numbers with shape
88+ [batch_size, n_params] specifying parameter values to resolve
89+ into the circuits specificed by programs, following the ordering
90+ dictated by `symbol_names`.
91+ other_programs: `tf.Tensor` of strings with shape [batch_size, n_others]
92+ containing the string representations of the circuits with which to
93+ compute the overlap on `programs` with. Must not contain any free
94+ symbols.
95+ programs_coeffs: `tf.Tensor` of real numbers with shape [batch_size]
96+ of weights on `programs`.
97+ other_programs_coeffs: `tf.Tensor` of real numbers with shape
98+ [batch_size, n_others] of weights on `other_programs`.
99+
100+ Returns:
101+ tf.Tensor` with shape [batch_size, n_params, n_params] where `out[i]`
102+ is equal to the hessian of the inner product between programs[i] and all
103+ other_programs[i] w.r.t. `symbol_names[j]` and `symbol_names[k]`.
104+ `programs[i]` is resolved with `symbol_values[i]` and each
105+ (other_)programs[i] is weighted by (other_)programs_coeffs[i].
106+ """
69107 return MATH_OP_MODULE .tfq_inner_product_hessian (
70108 programs , symbol_names , tf .cast (symbol_values , tf .float32 ),
71109 other_programs , tf .cast (programs_coeffs , tf .float32 ),
0 commit comments