Esempio n. 1
0
    def losses(self, wghts, step, gargs_batch):
        """Compute PDE and Lyapunov losses separately."""
        xM, xdM, LM = gargs_batch[0]      # (Un)batched data
        wghts_agg = gargs_batch[1]        # Previous modes
        kotd = len(wghts_agg)
        npts, ndim = np.shape(xM)

        l_pde=0.0
        OUT = self.nnet(wghts, xM, wghts_agg)
        LU  = np.einsum('abi,ai->ab', LM, OUT)
        UtLU = np.einsum('ai,ai->a', OUT, LU)
        UUtLU = OUT*UtLU[:,np.newaxis]
        RHS = LU - UUtLU
        for jj in range(kotd):
            OUTjj = self.nnet(wghts_agg[jj], xM, wghts_agg[0:jj])
            LUjj = np.einsum('abi,ai->ab', LM, OUTjj)
            PROJ1 = np.einsum('ai,ai->a', OUTjj, LU)
            PROJ2 = np.einsum('ai,ai->a', OUT, LUjj)
            RHS = RHS - OUTjj*(PROJ1[:,np.newaxis] + PROJ2[:,np.newaxis])
        for ii in range(npts):
            dudx = jacobian(self.nnet,1)(wghts, xM[ii,:], wghts_agg)
            LHS = np.dot(dudx,xdM[ii,:])
            l_pde = l_pde + np.sum((LHS-RHS[ii,:])**2)/npts
        l_lya = -np.sinh(np.mean(UtLU))  # Lyapunov regularization
        return l_pde, l_lya
Esempio n. 2
0
    def test_first_order_cv(self, tol):
        """Test variance of a first order CV expectation value"""
        dev = qml.device('default.gaussian', wires=1)

        @qml.qnode(dev)
        def circuit(r, phi):
            qml.Squeezing(r, 0, wires=0)
            qml.Rotation(phi, wires=0)
            return qml.var(qml.X(0))

        r = 0.543
        phi = -0.654

        var = circuit(r, phi)
        expected = np.exp(2 * r) * np.sin(phi)**2 + np.exp(
            -2 * r) * np.cos(phi)**2
        assert np.allclose(var, expected, atol=tol, rtol=0)

        # circuit jacobians
        gradA = circuit.jacobian([r, phi], method='A')
        gradF = circuit.jacobian([r, phi], method='F')
        expected = np.array([
            2 * np.exp(2 * r) * np.sin(phi)**2 -
            2 * np.exp(-2 * r) * np.cos(phi)**2,
            2 * np.sinh(2 * r) * np.sin(2 * phi)
        ])
        assert np.allclose(gradA, expected, atol=tol, rtol=0)
        assert np.allclose(gradF, expected, atol=tol, rtol=0)
Esempio n. 3
0
def test_function_overloading():
    a = pe.pseudo_Obs(17, 2.9, 'e1')
    b = pe.pseudo_Obs(4, 0.8, 'e1')

    fs = [
        lambda x: x[0] + x[1], lambda x: x[1] + x[0], lambda x: x[0] - x[1],
        lambda x: x[1] - x[0], lambda x: x[0] * x[1], lambda x: x[1] * x[0],
        lambda x: x[0] / x[1], lambda x: x[1] / x[0], lambda x: np.exp(x[0]),
        lambda x: np.sin(x[0]), lambda x: np.cos(x[0]), lambda x: np.tan(x[0]),
        lambda x: np.log(x[0]), lambda x: np.sqrt(np.abs(x[0])),
        lambda x: np.sinh(x[0]), lambda x: np.cosh(x[0]),
        lambda x: np.tanh(x[0])
    ]

    for i, f in enumerate(fs):
        t1 = f([a, b])
        t2 = pe.derived_observable(f, [a, b])
        c = t2 - t1
        assert c.is_zero()

    assert np.log(np.exp(b)) == b
    assert np.exp(np.log(b)) == b
    assert np.sqrt(b**2) == b
    assert np.sqrt(b)**2 == b

    np.arcsin(1 / b)
    np.arccos(1 / b)
    np.arctan(1 / b)
    np.arctanh(1 / b)
    np.sinc(1 / b)
Esempio n. 4
0
def _sinch(x):
    """
    Stably evaluate sinch.

    Notes
    -----
    The strategy of falling back to a sixth order Taylor expansion
    was suggested by the Spallation Neutron Source docs
    which was found on the internet by google search.
    http://www.ornl.gov/~t6p/resources/xal/javadoc/gov/sns/tools/math/ElementaryFunction.html
    The details of the cutoff point and the Horner-like evaluation
    was picked without reference to anything in particular.

    Note that sinch is not currently implemented in scipy.special,
    whereas the "engineer's" definition of sinc is implemented.
    The implementation of sinc involves a scaling factor of pi
    that distinguishes it from the "mathematician's" version of sinc.

    """

    # If x is small then use sixth order Taylor expansion.
    # How small is small? I am using the point where the relative error
    # of the approximation is less than 1e-14.
    # If x is large then directly evaluate sinh(x) / x.
    x2 = x * x
    if abs(x) < 0.0135:
        return 1 + (x2 / 6.) * (1 + (x2 / 20.) * (1 + (x2 / 42.)))
    else:
        return np.sinh(x) / x
Esempio n. 5
0
    def test_cv_gradients_multiple_gate_parameters(self, gaussian_dev, tol):
        "Tests that gates with multiple free parameters yield correct gradients."
        par = [0.4, -0.3, -0.7, 0.2]

        def qf(r0, phi0, r1, phi1):
            qml.Squeezing(r0, phi0, wires=[0])
            qml.Squeezing(r1, phi1, wires=[0])
            return qml.expval(qml.NumberOperator(0))

        q = qml.QNode(qf, gaussian_dev)
        grad_F = q.jacobian(par, method='F')
        grad_A = q.jacobian(par, method='A')
        grad_A2 = q.jacobian(par, method='A', force_order2=True)

        # analytic method works for every parameter
        assert q.grad_method_for_par == {i:'A' for i in range(4)}
        # the different methods agree
        assert grad_A == pytest.approx(grad_F, abs=tol)
        assert grad_A2 == pytest.approx(grad_F, abs=tol)

        # check against the known analytic formula
        r0, phi0, r1, phi1 = par
        dn = np.zeros([4])
        dn[0] = np.cosh(2 * r1) * np.sinh(2 * r0) + np.cos(phi0 - phi1) * np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[1] = -0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)
        dn[2] = np.cos(phi0 - phi1) * np.cosh(2 * r1) * np.sinh(2 * r0) + np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[3] = 0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)

        assert dn[np.newaxis, :] == pytest.approx(grad_F, abs=tol)
Esempio n. 6
0
    def test_cv_gradients_multiple_gate_parameters(self):
        "Tests that gates with multiple free parameters yield correct gradients."
        self.logTestName()
        par = [0.4, -0.3, -0.7, 0.2]

        def qf(r0, phi0, r1, phi1):
            qml.Squeezing(r0, phi0, wires=[0])
            qml.Squeezing(r1, phi1, wires=[0])
            return qml.expval(qml.NumberOperator(0))

        q = qml.QNode(qf, self.gaussian_dev)
        grad_F = q.jacobian(par, method='F')
        grad_A = q.jacobian(par, method='A')
        grad_A2 = q.jacobian(par, method='A', force_order2=True)

        # analytic method works for every parameter
        self.assertTrue(q.grad_method_for_par == {i:'A' for i in range(4)})
        # the different methods agree
        self.assertAllAlmostEqual(grad_A, grad_F, delta=self.tol)
        self.assertAllAlmostEqual(grad_A2, grad_F, delta=self.tol)

        # check against the known analytic formula
        r0, phi0, r1, phi1 = par
        dn = np.zeros([4])

        dn[0] = np.cosh(2 * r1) * np.sinh(2 * r0) + np.cos(phi0 - phi1) * np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[1] = -0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)
        dn[2] = np.cos(phi0 - phi1) * np.cosh(2 * r1) * np.sinh(2 * r0) + np.cosh(2 * r0) * np.sinh(2 * r1)
        dn[3] = 0.5 * np.sin(phi0 - phi1) * np.sinh(2 * r0) * np.sinh(2 * r1)

        self.assertAllAlmostEqual(grad_A, dn, delta=self.tol)
Esempio n. 7
0
    def test_number_state_gradient(self, gaussian_dev, tol):
        "Tests that the automatic gradient of a squeezed state with number state expectation is correct."

        @qml.qnode(gaussian_dev)
        def circuit(y):
            qml.Squeezing(y, 0., wires=[0])
            return qml.expval(qml.FockStateProjector(np.array([2, 0]), wires=[0, 1]))

        grad_fn = autograd.grad(circuit, 0)

        # (d/dr) |<2|S(r)>|^2 = 0.5 tanh(r)^3 (2 csch(r)^2 - 1) sech(r)
        for r in sqz_vals[1:]: # formula above is not valid for r=0
            autograd_val = grad_fn(r)
            manualgrad_val = 0.5*np.tanh(r)**3 * (2/(np.sinh(r)**2)-1) / np.cosh(r)
            assert autograd_val == pytest.approx(manualgrad_val, abs=tol)
Esempio n. 8
0
    def test_number_state_gradient(self):
        "Tests that the automatic gradient of a squeezed state with number state expectation is correct."
        self.logTestName()

        @qml.qnode(self.gaussian_dev)
        def circuit(y):
            qml.Squeezing(y, 0., wires=[0])
            return qml.expval(qml.NumberState(np.array([2, 0]), wires=[0, 1]))

        grad_fn = autograd.grad(circuit, 0)

        # (d/dr) |<2|S(r)>|^2 = 0.5 tanh(r)^3 (2 csch(r)^2 - 1) sech(r)
        for r in sqz_vals[1:]: # formula above is not valid for r=0
            autograd_val = grad_fn(r)
            manualgrad_val = 0.5*np.tanh(r)**3 * (2/(np.sinh(r)**2)-1) / np.cosh(r)
            self.assertAlmostEqual(autograd_val, manualgrad_val, delta=self.tol)
Esempio n. 9
0
def test_man_grad():
    a = pe.pseudo_Obs(17, 2.9, 'e1')
    b = pe.pseudo_Obs(4, 0.8, 'e1')

    fs = [
        lambda x: x[0] + x[1], lambda x: x[1] + x[0], lambda x: x[0] - x[1],
        lambda x: x[1] - x[0], lambda x: x[0] * x[1], lambda x: x[1] * x[0],
        lambda x: x[0] / x[1], lambda x: x[1] / x[0], lambda x: np.exp(x[0]),
        lambda x: np.sin(x[0]), lambda x: np.cos(x[0]), lambda x: np.tan(x[0]),
        lambda x: np.log(x[0]), lambda x: np.sqrt(x[0]),
        lambda x: np.sinh(x[0]), lambda x: np.cosh(x[0]),
        lambda x: np.tanh(x[0])
    ]

    for i, f in enumerate(fs):
        t1 = f([a, b])
        t2 = pe.derived_observable(f, [a, b])
        c = t2 - t1
        assert c.value == 0.0, str(i)
        assert np.all(np.abs(c.deltas['e1']) < 1e-14), str(i)
Esempio n. 10
0
def inv_sa(par, x):
    return np.sinh((np.arcsinh(x) - par[1]) / par[0])
Esempio n. 11
0
def test_sinh():
    fun = lambda x: 3.0 * np.sinh(x)
    check_grads(fun)(npr.randn())
Esempio n. 12
0
anp.reciprocal.defjvp(lambda g, ans, gvs, vs, x: -g / x**2)
anp.exp.defjvp(lambda g, ans, gvs, vs, x: ans * g)
anp.exp2.defjvp(lambda g, ans, gvs, vs, x: ans * anp.log(2) * g)
anp.expm1.defjvp(lambda g, ans, gvs, vs, x: (ans + 1) * g)
anp.log.defjvp(lambda g, ans, gvs, vs, x: g / x)
anp.log2.defjvp(lambda g, ans, gvs, vs, x: g / x / anp.log(2))
anp.log10.defjvp(lambda g, ans, gvs, vs, x: g / x / anp.log(10))
anp.log1p.defjvp(lambda g, ans, gvs, vs, x: g / (x + 1))
anp.sin.defjvp(lambda g, ans, gvs, vs, x: g * anp.cos(x))
anp.cos.defjvp(lambda g, ans, gvs, vs, x: -g * anp.sin(x))
anp.tan.defjvp(lambda g, ans, gvs, vs, x: g / anp.cos(x)**2)
anp.arcsin.defjvp(lambda g, ans, gvs, vs, x: g / anp.sqrt(1 - x**2))
anp.arccos.defjvp(lambda g, ans, gvs, vs, x: -g / anp.sqrt(1 - x**2))
anp.arctan.defjvp(lambda g, ans, gvs, vs, x: g / (1 + x**2))
anp.sinh.defjvp(lambda g, ans, gvs, vs, x: g * anp.cosh(x))
anp.cosh.defjvp(lambda g, ans, gvs, vs, x: g * anp.sinh(x))
anp.tanh.defjvp(lambda g, ans, gvs, vs, x: g / anp.cosh(x)**2)
anp.arcsinh.defjvp(lambda g, ans, gvs, vs, x: g / anp.sqrt(x**2 + 1))
anp.arccosh.defjvp(lambda g, ans, gvs, vs, x: g / anp.sqrt(x**2 - 1))
anp.arctanh.defjvp(lambda g, ans, gvs, vs, x: g / (1 - x**2))
anp.rad2deg.defjvp(lambda g, ans, gvs, vs, x: g / anp.pi * 180.0)
anp.degrees.defjvp(lambda g, ans, gvs, vs, x: g / anp.pi * 180.0)
anp.deg2rad.defjvp(lambda g, ans, gvs, vs, x: g * anp.pi / 180.0)
anp.radians.defjvp(lambda g, ans, gvs, vs, x: g * anp.pi / 180.0)
anp.square.defjvp(lambda g, ans, gvs, vs, x: g * 2 * x)
anp.sqrt.defjvp(lambda g, ans, gvs, vs, x: g * 0.5 * x**-0.5)
anp.sinc.defjvp(lambda g, ans, gvs, vs, x: g * (anp.cos(
    anp.pi * x) * anp.pi * x - anp.sin(anp.pi * x)) / (anp.pi * x**2))
anp.reshape.defjvp(lambda g, ans, gvs, vs, x, shape, order=None: anp.reshape(
    g, vs.shape, order=order))
anp.roll.defjvp(
Esempio n. 13
0
def inv_asinh(par, x):
    return (np.sinh((x - par[0]) / par[1]) * par[3]) + par[2]
Esempio n. 14
0
def sa(par, y):
    return np.sinh(par[0] * np.arcsinh(y) + par[1])
Esempio n. 15
0
def test_sinh():
    fun = lambda x : 3.0 * np.sinh(x)
    check_grads(fun)(npr.randn())
Esempio n. 16
0
def sal(par, y):
    return par[0] + par[1] * np.sinh(par[2] * np.arcsinh(y) + par[3])
Esempio n. 17
0
def test_sinh():
    fun = lambda x : 3.0 * np.sinh(x)
    d_fun = grad(fun)
    check_grads(fun, npr.randn())
    check_grads(d_fun, npr.randn())
Esempio n. 18
0
def test_sinh():
    fun = lambda x : 3.0 * np.sinh(x)
    d_fun = grad(fun)
    check_grads(fun, npr.randn())
    check_grads(d_fun, npr.randn())
Esempio n. 19
0
def inv_sal(par, x):
    return np.sinh((np.arcsinh((x - par[0]) / par[1]) - par[3]) / par[2])