def test_natural_gradient4(self, grad_method, qfi_method, regularization): """Test the natural gradient 4""" # Avoid regularization = lasso intentionally because it does not converge try: ham = 0.5 * X - 1 * Z a = Parameter("a") params = a q = QuantumRegister(1) qc = QuantumCircuit(q) qc.h(q) qc.rz(a, q[0]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0) nat_grad = NaturalGradient(grad_method=grad_method, qfi_method=qfi_method, regularization=regularization).convert( operator=op, params=params) values_dict = [{a: np.pi / 4}] correct_values = [[0.0]] if regularization == "ridge" else [[ -1.41421342 ]] for i, value_dict in enumerate(values_dict): np.testing.assert_array_almost_equal( nat_grad.assign_parameters(value_dict).eval(), correct_values[i], decimal=3) except MissingOptionalLibraryError as ex: self.skipTest(str(ex))
def test_grad_combo_fn_chain_rule_nat_grad(self): """Test the chain rule for a custom gradient combo function.""" np.random.seed(2) def combo_fn(x): amplitudes = x[0].primitive.data pdf = np.multiply(amplitudes, np.conj(amplitudes)) return np.sum(np.log(pdf)) / (-len(amplitudes)) def grad_combo_fn(x): amplitudes = x[0].primitive.data pdf = np.multiply(amplitudes, np.conj(amplitudes)) grad = [] for prob in pdf: grad += [-1 / prob] return grad try: qc = RealAmplitudes(2, reps=1) grad_op = ListOp([StateFn(qc)], combo_fn=combo_fn, grad_combo_fn=grad_combo_fn) grad = NaturalGradient(grad_method='lin_comb', regularization='ridge' ).convert(grad_op, qc.ordered_parameters) value_dict = dict( zip(qc.ordered_parameters, np.random.rand(len(qc.ordered_parameters)))) correct_values = [[0.20777236], [-18.92560338], [-15.89005475], [-10.44002031]] np.testing.assert_array_almost_equal(grad.assign_parameters(value_dict).eval(), correct_values, decimal=3) except MissingOptionalLibraryError as ex: self.skipTest(str(ex))
def test_natural_gradient(self, method, regularization): """Test the natural gradient""" try: for params in (ParameterVector("a", 2), [Parameter("a"), Parameter("b")]): ham = 0.5 * X - 1 * Z q = QuantumRegister(1) qc = QuantumCircuit(q) qc.h(q) qc.rz(params[0], q[0]) qc.rx(params[1], q[0]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0) nat_grad = NaturalGradient( grad_method=method, regularization=regularization).convert(operator=op) values_dict = [{params[0]: np.pi / 4, params[1]: np.pi / 2}] # reference values obtained by classically computing the natural gradients correct_values = [[ -3.26, 1.63 ]] if regularization == "ridge" else [[-4.24, 0]] for i, value_dict in enumerate(values_dict): np.testing.assert_array_almost_equal( nat_grad.assign_parameters(value_dict).eval(), correct_values[i], decimal=1) except MissingOptionalLibraryError as ex: self.skipTest(str(ex))
def test_natural_gradient(self, method, regularization): """Test the natural gradient""" try: for params in (ParameterVector('a', 2), [Parameter('a'), Parameter('b')]): ham = 0.5 * X - 1 * Z q = QuantumRegister(1) qc = QuantumCircuit(q) qc.h(q) qc.rz(params[0], q[0]) qc.rx(params[1], q[0]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.) nat_grad = NaturalGradient(grad_method=method, regularization=regularization)\ .convert(operator=op, params=params) values_dict = [{params[0]: np.pi / 4, params[1]: np.pi / 2}] correct_values = [[-2.36003979, 2.06503481]] \ if regularization == 'ridge' else [[-4.2, 0]] for i, value_dict in enumerate(values_dict): np.testing.assert_array_almost_equal( nat_grad.assign_parameters(value_dict).eval(), correct_values[i], decimal=0) except MissingOptionalLibraryError as ex: self.skipTest(str(ex))