Example #1
0
def minimalCommutatorDistance(c1, c2, sdp=None, relaxation_level = 2):
	# No sdp passed, create one
	if sdp is None:
		D = ncp.generate_operators('D', 1)[0]
		X = ncp.generate_operators('X', 1)[0]

		# The sdp will ignore the +1 term, we have to add it on at the end
		obj = Dagger(commutator(D,X) - 1)*(commutator(D,X) - 1)

		inequality_cons = [c1**2 - Dagger(X)*X >= 0,
						   c2**2 - Dagger(D)*D >= 0]
		sdp = ncp.SdpRelaxation([D,X], normalized = True)
		sdp.get_relaxation(level = relaxation_level,
						   objective = obj,
						   inequalities = inequality_cons)
	else:
		# sdp object passed. Use process_constraints instead
		D = sdp.monomial_sets[0][1]
		X = sdp.monomial_sets[0][2]
		inequality_cons = [c1**2 - Dagger(X)*X >= 0,
						   c2**2 - Dagger(D)*D >= 0]
		sdp.process_constraints(inequalities = inequality_cons)

	# Now solve
	sdp.solve(solver = SOLVER_NAME, solverparameters = SOLVER_EXE)
	if sdp.status == 'optimal':
		return sqrt(sdp.primal + 1), sdp
	else:
		return None, sdp
Example #2
0
 def test_ground_state(self):
     length, n, h, U, t = 2, 0.8, 3.8, -6, 1
     fu = generate_operators('fu', length)
     fd = generate_operators('fd', length)
     _b = flatten([fu, fd])
     monomials = [[ci for ci in _b]]
     monomials[-1].extend([Dagger(ci) for ci in _b])
     monomials.append([cj*ci for ci in _b for cj in _b])
     monomials.append([Dagger(cj)*ci for ci in _b for cj in _b])
     monomials[-1].extend([cj*Dagger(ci)
                           for ci in _b for cj in _b])
     monomials.append([Dagger(cj)*Dagger(ci)
                       for ci in _b for cj in _b])
     hamiltonian = 0
     for j in range(length):
         hamiltonian += U * (Dagger(fu[j])*Dagger(fd[j]) * fd[j]*fu[j])
         hamiltonian += -h/2*(Dagger(fu[j])*fu[j] - Dagger(fd[j])*fd[j])
         for k in get_neighbors(j, len(fu), width=1):
             hamiltonian += -t*Dagger(fu[j])*fu[k]-t*Dagger(fu[k])*fu[j]
             hamiltonian += -t*Dagger(fd[j])*fd[k]-t*Dagger(fd[k])*fd[j]
     momentequalities = [n-sum(Dagger(br)*br for br in _b)]
     sdpRelaxation = SdpRelaxation(_b, verbose=0)
     sdpRelaxation.get_relaxation(-1,
                                  objective=hamiltonian,
                                  momentequalities=momentequalities,
                                  substitutions=fermionic_constraints(_b),
                                  extramonomials=monomials)
     sdpRelaxation.solve()
     s = 0.5*(sum((Dagger(u)*u) for u in fu) -
              sum((Dagger(d)*d) for d in fd))
     magnetization = sdpRelaxation[s]
     self.assertTrue(abs(magnetization-0.021325317328560453) < 10e-5)
Example #3
0
    def test_apply_substitutions(self):

        def apply_correct_substitutions(monomial, substitutions):
            if isinstance(monomial, int) or isinstance(monomial, float):
                return monomial
            original_monomial = monomial
            changed = True
            while changed:
                for lhs, rhs in substitutions.items():
                    monomial = monomial.subs(lhs, rhs)
                if original_monomial == monomial:
                    changed = False
                original_monomial = monomial
            return monomial

        length, h, U, t = 2, 3.8, -6, 1
        fu = generate_operators('fu', length)
        fd = generate_operators('fd', length)
        _b = flatten([fu, fd])
        hamiltonian = 0
        for j in range(length):
            hamiltonian += U * (Dagger(fu[j])*Dagger(fd[j]) * fd[j]*fu[j])
            hamiltonian += -h/2*(Dagger(fu[j])*fu[j] - Dagger(fd[j])*fd[j])
            for k in get_neighbors(j, len(fu), width=1):
                hamiltonian += -t*Dagger(fu[j])*fu[k]-t*Dagger(fu[k])*fu[j]
                hamiltonian += -t*Dagger(fd[j])*fd[k]-t*Dagger(fd[k])*fd[j]
        substitutions = fermionic_constraints(_b)
        monomials = expand(hamiltonian).as_coeff_mul()[1][0].as_coeff_add()[1]
        substituted_hamiltonian = sum([apply_substitutions(monomial,
                                                           substitutions)
                                       for monomial in monomials])
        correct_hamiltonian = sum([apply_correct_substitutions(monomial,
                                                               substitutions)
                                   for monomial in monomials])
        self.assertTrue(substituted_hamiltonian == expand(correct_hamiltonian))
Example #4
0
 def test_ground_state(self):
     length, n, h, U, t = 2, 0.8, 3.8, -6, 1
     fu = generate_operators('fu', length)
     fd = generate_operators('fd', length)
     _b = flatten([fu, fd])
     monomials = [[ci for ci in _b]]
     monomials[-1].extend([Dagger(ci) for ci in _b])
     monomials.append([cj * ci for ci in _b for cj in _b])
     monomials.append([Dagger(cj) * ci for ci in _b for cj in _b])
     monomials[-1].extend([cj * Dagger(ci) for ci in _b for cj in _b])
     monomials.append([Dagger(cj) * Dagger(ci) for ci in _b for cj in _b])
     hamiltonian = 0
     for j in range(length):
         hamiltonian += U * (Dagger(fu[j]) * Dagger(fd[j]) * fd[j] * fu[j])
         hamiltonian += -h / 2 * (Dagger(fu[j]) * fu[j] -
                                  Dagger(fd[j]) * fd[j])
         for k in get_neighbors(j, len(fu), width=1):
             hamiltonian += -t * Dagger(fu[j]) * fu[k] - t * Dagger(
                 fu[k]) * fu[j]
             hamiltonian += -t * Dagger(fd[j]) * fd[k] - t * Dagger(
                 fd[k]) * fd[j]
     momentequalities = [n - sum(Dagger(br) * br for br in _b)]
     sdpRelaxation = SdpRelaxation(_b, verbose=0)
     sdpRelaxation.get_relaxation(-1,
                                  objective=hamiltonian,
                                  momentequalities=momentequalities,
                                  substitutions=fermionic_constraints(_b),
                                  extramonomials=monomials)
     sdpRelaxation.solve()
     s = 0.5 * (sum((Dagger(u) * u) for u in fu) - sum(
         (Dagger(d) * d) for d in fd))
     magnetization = sdpRelaxation[s]
     self.assertTrue(abs(magnetization - 0.021325317328560453) < 10e-5)
Example #5
0
def isFeasible(c1, c2, eps, sdp = None, relaxation_level = 2):
	# No sdp passed, create one
	if sdp is None:
		D = ncp.generate_operators('D', 1)[0]
		X = ncp.generate_operators('X', 1)[0]

		obj = 1.0

		inequality_cons = [c1**2 - Dagger(X)*X >= 0,
						   c2**2 - Dagger(D)*D >= 0,
						   eps**2 - Dagger(commutator(D,X))*commutator(D,X) +
									Dagger(commutator(D,X)) + commutator(D,X) - 1 >= 0]
		sdp = ncp.SdpRelaxation([D,X], normalized = True)
		sdp.get_relaxation(level = relaxation_level,
						   objective = obj,
						   inequalities = inequality_cons)
	else:
		# sdp object passed. Use process_constraints instead
		D = sdp.monomial_sets[0][1]
		X = sdp.monomial_sets[0][2]
		inequality_cons = [c1**2 - Dagger(X)*X >= 0,
						   c2**2 - Dagger(D)*D >= 0,
						   eps**2 - Dagger(commutator(D,X))*commutator(D,X) +
									Dagger(commutator(D,X)) + commutator(D,X) - 1 >= 0]
		sdp.process_constraints(inequalities = inequality_cons)

	# Now solve
	sdp.solve(solver = SOLVER_NAME, solverparameters = SOLVER_EXE)
	if sdp.status == 'optimal':
		return True, sdp
	else:
		return False, sdp
    def test_apply_substitutions(self):

        def apply_correct_substitutions(monomial, substitutions):
            if isinstance(monomial, int) or isinstance(monomial, float):
                return monomial
            original_monomial = monomial
            changed = True
            while changed:
                for lhs, rhs in substitutions.items():
                    monomial = monomial.subs(lhs, rhs)
                if original_monomial == monomial:
                    changed = False
                original_monomial = monomial
            return monomial

        length, h, U, t = 2, 3.8, -6, 1
        fu = generate_operators('fu', length)
        fd = generate_operators('fd', length)
        _b = flatten([fu, fd])
        hamiltonian = 0
        for j in range(length):
            hamiltonian += U * (Dagger(fu[j])*Dagger(fd[j]) * fd[j]*fu[j])
            hamiltonian += -h/2*(Dagger(fu[j])*fu[j] - Dagger(fd[j])*fd[j])
            for k in get_neighbors(j, len(fu), width=1):
                hamiltonian += -t*Dagger(fu[j])*fu[k]-t*Dagger(fu[k])*fu[j]
                hamiltonian += -t*Dagger(fd[j])*fd[k]-t*Dagger(fd[k])*fd[j]
        substitutions = fermionic_constraints(_b)
        monomials = expand(hamiltonian).as_coeff_mul()[1][0].as_coeff_add()[1]
        substituted_hamiltonian = sum([apply_substitutions(monomial,
                                                           substitutions)
                                       for monomial in monomials])
        correct_hamiltonian = sum([apply_correct_substitutions(monomial,
                                                               substitutions)
                                   for monomial in monomials])
        self.assertTrue(substituted_hamiltonian == expand(correct_hamiltonian))
Example #7
0
    def test_maximum_violation(self):

        def expectation_values(measurement, outcomes):
            exp_values = []
            for k in range(len(measurement)):
                exp_value = 0
                for j in range(len(measurement[k])):
                    exp_value += outcomes[k][j] * measurement[k][j]
                exp_values.append(exp_value)
            return exp_values

        E = generate_operators('E', 8, hermitian=True)
        M, outcomes = [], []
        for i in range(4):
            M.append([E[2 * i], E[2 * i + 1]])
            outcomes.append([1, -1])
        A = [M[0], M[1]]
        B = [M[2], M[3]]
        substitutions = projective_measurement_constraints(A, B)
        C = expectation_values(M, outcomes)
        chsh = -(C[0] * C[2] + C[0] * C[3] + C[1] * C[2] - C[1] * C[3])
        sdpRelaxation = SdpRelaxation(E, verbose=0)
        sdpRelaxation.get_relaxation(1, objective=chsh,
                                     substitutions=substitutions)
        sdpRelaxation.solve()
        self.assertTrue(abs(sdpRelaxation.primal + 2*np.sqrt(2)) < 10e-5)
Example #8
0
    def test_maximum_violation(self):
        def expectation_values(measurement, outcomes):
            exp_values = []
            for k in range(len(measurement)):
                exp_value = 0
                for j in range(len(measurement[k])):
                    exp_value += outcomes[k][j] * measurement[k][j]
                exp_values.append(exp_value)
            return exp_values

        E = generate_operators('E', 8, hermitian=True)
        M, outcomes = [], []
        for i in range(4):
            M.append([E[2 * i], E[2 * i + 1]])
            outcomes.append([1, -1])
        A = [M[0], M[1]]
        B = [M[2], M[3]]
        substitutions = projective_measurement_constraints(A, B)
        C = expectation_values(M, outcomes)
        chsh = -(C[0] * C[2] + C[0] * C[3] + C[1] * C[2] - C[1] * C[3])
        sdpRelaxation = SdpRelaxation(E, verbose=0)
        sdpRelaxation.get_relaxation(1,
                                     objective=chsh,
                                     substitutions=substitutions)
        sdpRelaxation.solve()
        self.assertTrue(abs(sdpRelaxation.primal + 2 * np.sqrt(2)) < 10e-5)
Example #9
0
 def setUp(self):
     X = generate_operators('x', 2, hermitian=True)
     self.sdpRelaxation = SdpRelaxation(X)
     self.sdpRelaxation.get_relaxation(2,
                                       objective=X[0] * X[1] + X[1] * X[0],
                                       inequalities=[-X[1]**2 + X[1] + 0.5],
                                       substitutions={X[0]**2: X[0]})
Example #10
0
 def test_ground_state_energy(self):
     N = 3
     a = generate_operators('a', N)
     substitutions = bosonic_constraints(a)
     hamiltonian = sum(Dagger(a[i]) * a[i] for i in range(N))
     sdpRelaxation = SdpRelaxation(a, verbose=0)
     sdpRelaxation.get_relaxation(1, objective=hamiltonian,
                                  substitutions=substitutions)
     sdpRelaxation.solve()
     self.assertTrue(abs(sdpRelaxation.primal) < 10e-5)
Example #11
0
 def test_ground_state_energy(self):
     N = 3
     a = generate_operators('a', N)
     substitutions = bosonic_constraints(a)
     hamiltonian = sum(Dagger(a[i]) * a[i] for i in range(N))
     sdpRelaxation = SdpRelaxation(a, verbose=0)
     sdpRelaxation.get_relaxation(1, objective=hamiltonian,
                                  substitutions=substitutions)
     sdpRelaxation.solve()
     self.assertTrue(abs(sdpRelaxation.primal) < 10e-5)
Example #12
0
 def test_fast_substitute(self):
     f = generate_operators('f', 2)
     substitutions = {}
     substitutions[Dagger(f[0])*f[0]] = -f[0]*Dagger(f[0])
     monomial = Dagger(f[0])*f[0]
     lhs = Dagger(f[0])*f[0]
     rhs = -f[0]*Dagger(f[0])
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])*f[0]**2
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2*f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2*f[0]
     lhs = Dagger(f[0])**2
     rhs = -f[0]*Dagger(f[0])
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     g = generate_operators('g', 2)
     monomial = 2*g[0]**3*g[1]*Dagger(f[0])**2*f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = S.One
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = 5
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial)
     monomial = 2*g[0]**3*g[1]*Dagger(f[0])**2*f[0] + f[1]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     monomial.subs(lhs, rhs))
     monomial = f[1]*Dagger(f[0])**2*f[0]
     lhs = f[1]
     rhs = 1.0 + f[0]
     self.assertTrue(fast_substitute(monomial, lhs, rhs) ==
                     expand(monomial.subs(lhs, rhs)))
     monomial = f[1]**2*Dagger(f[0])**2*f[0]
     result = fast_substitute(fast_substitute(monomial, lhs, rhs), lhs, rhs)
     self.assertTrue(result == expand(monomial.subs(lhs, rhs)))
Example #13
0
 def test_fast_substitute(self):
     f = generate_operators('f', 2)
     substitutions = {}
     substitutions[Dagger(f[0]) * f[0]] = -f[0] * Dagger(f[0])
     monomial = Dagger(f[0]) * f[0]
     lhs = Dagger(f[0]) * f[0]
     rhs = -f[0] * Dagger(f[0])
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = Dagger(f[0]) * f[0]**2
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2 * f[0]
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = Dagger(f[0])**2 * f[0]
     lhs = Dagger(f[0])**2
     rhs = -f[0] * Dagger(f[0])
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     g = generate_operators('g', 2)
     monomial = 2 * g[0]**3 * g[1] * Dagger(f[0])**2 * f[0]
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = S.One
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = 5
     self.assertTrue(fast_substitute(monomial, lhs, rhs) == monomial)
     monomial = 2 * g[0]**3 * g[1] * Dagger(f[0])**2 * f[0] + f[1]
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == monomial.subs(lhs, rhs))
     monomial = f[1] * Dagger(f[0])**2 * f[0]
     lhs = f[1]
     rhs = 1.0 + f[0]
     self.assertTrue(
         fast_substitute(monomial, lhs, rhs) == expand(
             monomial.subs(lhs, rhs)))
     monomial = f[1]**2 * Dagger(f[0])**2 * f[0]
     result = fast_substitute(fast_substitute(monomial, lhs, rhs), lhs, rhs)
     self.assertTrue(result == expand(monomial.subs(lhs, rhs)))
Example #14
0
 def setUp(self):
     X = generate_operators('x', 2, hermitian=True)
     self.sdpRelaxation = SdpRelaxation(X)
     self.sdpRelaxation.get_relaxation(2, objective=X[0]*X[1] + X[1]*X[0],
                                       inequalities=[-X[1]**2 + X[1] + 0.5],
                                       substitutions={X[0]**2: X[0]})
Example #15
0
LEVEL = 2

# Defining the measurement scheme we add additional operators to the inputs
# X=0 as the package ncpol2sdpa will automatically remove a
# projector for efficiency purposes. However, we need all projectors
# for the randomness certification inputs to ensure certain Cauchy-Schwarz
# relations are enforced.
# We also don't need to specify Bobs third input as we can lower bound H(A|E)
# using only the measurements on inputs {0,1}
A_config = [3, 2]
B_config = [2, 2]

# Measurement operators
A = [Ai for Ai in ncp.generate_measurements(A_config, 'A')]
B = [Bj for Bj in ncp.generate_measurements(B_config, 'B')]
V1 = ncp.generate_operators('V1', 2, hermitian=False)
V2 = ncp.generate_operators('V2', 2, hermitian=False)

substitutions = {}
moment_ineqs = []
moment_eqs = []
operator_eqs = []
operator_ineqs = []

# Projectors sum to identity
# We can speed up the computation (for potentially worse rates) by imposing these
# as moment equalities.
moment_eqs += [A[0][0] + A[0][1] - 1]

# Adding the constraints for the measurement operators
substitutions.update(ncp.projective_measurement_constraints(A, B))
# Global level of NPA relaxation
LEVEL = 2
# Maximum CHSH score
WMAX = 0.5 + sqrt(2) / 4

# Defining the measurement scheme we add additional operators to the inputs
# (X,Y) = (0,0) as the package ncpol2sdpa will automatically remove a
# projector for efficiency purposes. However, we need all projectors
# for the randomness certification inputs to ensure certain Cauchy-Schwarz
# relations are enforced.
A_config = [3, 2]
B_config = [3, 2]
# Measurement operators
A = [Ax for Ax in ncp.generate_measurements(A_config, 'A')]
B = [By for By in ncp.generate_measurements(B_config, 'B')]
V = ncp.generate_operators('V', 4, hermitian=False)

# Collecting all monomials of form AB for later
AB = []
for Ax, By in product(A, B):
    AB += [a * b for a, b in product(Ax, By)]

substitutions = {}
moment_ineqs = []
moment_eqs = []
operator_eqs = []
operator_ineqs = []
localizing_monos = [
]  # op_eqs are processed last so need to add three Nones to end

# Projectors sum to identity