# PennyLane Challenge: Recoherence query

Hi Pennlane Team,

I’m trying to solve this challenge, but facing a problem related to time variable. I’m using qml.ApproxTimeEvaluation for generating the time evolve sate and qml.math.purity to check the purity of the state. But in the main function, I’m not sure how to increase the time and get the incoherence time. Can some one help me with it? Below is my code and please provide any suggestions for improvement.

import json
import pennylane as qml
import pennylane.numpy as np

dev = qml.device("default.qubit", wires=5)

@qml.qnode(dev)
def evolve_state(coeffs, time):
"""
Args:
coeffs (list(float)): A list of the coupling constants g_1, g_2, g_3, and g_4
time (float): The evolution time of th system under the given Hamiltonian

Returns:
(numpy.tensor): The density matrix for the evolved state of the central spin.
"""

# We build the Hamiltonian for you

operators = [
qml.PauliZ(0) @ qml.PauliZ(1),
qml.PauliZ(0) @ qml.PauliZ(2),
qml.PauliZ(0) @ qml.PauliZ(3),
qml.PauliZ(0) @ qml.PauliZ(4),
]
hamiltonian = qml.dot(coeffs, operators)

# Put your code here #
qml.ApproxTimeEvolution(hamiltonian, time, 1)
# Return the required density matrix.
return qml.density_matrix([0])

def purity(rho):
"""
Args:
rho (array(array(complex))): An array-like object representing a density matrix

Returns:
(float): The purity of the density matrix rho

"""

# Return the purity
return qml.math.purity(rho, [0])

def recoherence_time(coeffs):
"""
Args:
coeffs (list(float)): A list of the coupling constants g_1, g_2, g_3, and g_4.

Returns:
(float): The recoherence time of the central spin.

"""

# Return the recoherence time
time=0.1
while purity(evolve_state(coeffs, time))!=1:
time=time+0.15
return time

# These functions are responsible for testing the solution.
def run(test_case_input: str) -> str:
output = recoherence_time(params)

return str(output)

def check(solution_output: str, expected_output: str) -> None:

assert np.isclose(solution_output, expected_output, rtol=5e-2)

# These are the public test cases
test_cases = [
('[5,5,5,5]', '0.314'),
('[1.1,1.3,1,2.3]', '15.71')
]

# This will run the public test cases locally
for i, (input_, expected_output) in enumerate(test_cases):
print(f"Running test case {i} with input '{input_}'...")

try:
output = run(input_)

except Exception as exc:
print(f"Runtime Error. {exc}")

else:
if message := check(output, expected_output):
print(f"Wrong Answer. Have: '{output}'. Want: '{expected_output}'.")

else:
print("Correct!")


While you can try a bit more advanced things like Bisection method, utilizing the fact that the purity function is continuous, I think start with time=0 and using a time step of 0.001 to brutal force search the solution should not be too bad an idea to pass the tests.

Actually, I have just tried the challenge myself, and with the right evolve_state and purity function,

time = 0.01
while abs(purity(evolve_state(coeffs,time)) - 1) > 1e-5:
time += 0.001
return time


does pass the tests.

2 Likes

Actually, for the evolve_state function, you have forget something important: setup the initial state for spin, before apply qml.ApproxTimeEvolution. If you don’t setup the initial spin, the returned density matrix will not change at all because apply the time evolution to the initial state of all zeros will always results in a measured state of all zeros, (recall for state |\phi\rangle the density matrix is |\phi\rangle \langle\phi|), that the purity measured will always be 1 and recoherence_time will not give sensible values.

2 Likes

Great suggestions @LdBeth !

Thanks @LdBeth , actually I missed out the initialization of the state, and also a bit modification on the density matrix has been done. Thanks for the help