Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/Simulation/Simulators.Tests/Circuits/ExpTest.qs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits {

open Microsoft.Quantum.Intrinsic;

open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;

// At some point, this was causing the simulator to crash.

Expand All @@ -26,7 +27,31 @@ namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits {
ResetAll(qubits);
}
}


/// Verify that Exp behaves as expected by using it in two decompositions: SWAP and CNOT.
operation VerifyExpUsingDecompositions() : Unit {
AssertOperationsEqualReferenced(2, (qs => SwapFromExp(qs[0], qs[1])), (qs => SWAP(qs[0], qs[1])));
AssertOperationsEqualReferenced(2, (qs => CnotFromExp(qs[0], qs[1])), (qs => CNOT(qs[0], qs[1])));
}

/// This decomposition only holds if the magnitude of the angle used in the Exp rotation is correct.
operation SwapFromExp(q0 : Qubit, q1 : Qubit) : Unit is Adj {
let qs = [q0, q1];
let theta = PI() / 4.0;
Exp([PauliX, PauliX], theta, qs);
Exp([PauliY, PauliY], theta, qs);
Exp([PauliZ, PauliZ], theta, qs);
}

/// This decomposition only holds if the magnitude of the angle used in Exp is correct and if the
/// sign convention between Rx, Rz, and Exp is consistent.
operation CnotFromExp(q0 : Qubit, q1 : Qubit) : Unit is Adj {
let qs = [q0, q1];
let theta = PI() / 4.0;
Rx(-2.0 * theta, q1);
Rz(-2.0 * theta, q0);
Adjoint Exp([PauliZ, PauliX], theta, qs);
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,20 @@ public void QSimVerifyExpX()
VerifyExp(Pauli.PauliX);
}

[Fact]
public void QSimVerifyExpUsingDecompositions()
{
var simulators = new CommonNativeSimulator[] {
new QuantumSimulator(),
new SparseSimulator()
};

foreach (var sim in simulators)
{
VerifyExpUsingDecompositions.Run(sim).Wait();
}
}

[Fact]
public void QSimVerifyExpFrac()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<QSharpCompile Include="..\Simulators.Tests\Circuits\AssertEqual.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\JointMeasureTest.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\VerifyUnitary.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\ExpTest.qs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<QSharpCompile Include="..\Simulators.Tests\Circuits\AssertEqual.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\JointMeasureTest.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\VerifyUnitary.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\ExpTest.qs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<QSharpCompile Include="..\Simulators.Tests\Circuits\AssertEqual.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\JointMeasureTest.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\VerifyUnitary.qs" />
<QSharpCompile Include="..\Simulators.Tests\Circuits\ExpTest.qs" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/Simulation/Simulators/CommonNativeSimulator/IsingXX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void IIntrinsicIsingXX.Body(double angle, Qubit target1, Qubit target2)
CheckAngle(angle);
this.CheckQubits(targets);

Exp((uint)targets.Length, paulis, angle * 2.0, targets.GetIds());
Exp((uint)targets.Length, paulis, angle / -2.0, targets.GetIds());
}

void IIntrinsicIsingXX.AdjointBody(double angle, Qubit target1, Qubit target2)
Expand All @@ -36,7 +36,7 @@ void IIntrinsicIsingXX.ControlledBody(IQArray<Qubit> controls, double angle, Qub
CheckAngle(angle);
this.CheckQubits(QArray<Qubit>.Add(controls, targets));

MCExp((uint)targets.Length, paulis, angle * 2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
MCExp((uint)targets.Length, paulis, angle / -2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Simulation/Simulators/CommonNativeSimulator/IsingYY.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void IIntrinsicIsingYY.Body(double angle, Qubit target1, Qubit target2)
CheckAngle(angle);
this.CheckQubits(targets);

Exp((uint)targets.Length, paulis, angle * 2.0, targets.GetIds());
Exp((uint)targets.Length, paulis, angle / -2.0, targets.GetIds());
}

void IIntrinsicIsingYY.AdjointBody(double angle, Qubit target1, Qubit target2)
Expand All @@ -36,7 +36,7 @@ void IIntrinsicIsingYY.ControlledBody(IQArray<Qubit> controls, double angle, Qub
CheckAngle(angle);
this.CheckQubits(QArray<Qubit>.Add(controls, targets));

MCExp((uint)targets.Length, paulis, angle * 2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
MCExp((uint)targets.Length, paulis, angle / -2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Simulation/Simulators/CommonNativeSimulator/IsingZZ.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void IIntrinsicIsingZZ.Body(double angle, Qubit target1, Qubit target2)
CheckAngle(angle);
this.CheckQubits(targets);

Exp((uint)targets.Length, paulis, angle * 2.0, targets.GetIds());
Exp((uint)targets.Length, paulis, angle / -2.0, targets.GetIds());
}

void IIntrinsicIsingZZ.AdjointBody(double angle, Qubit target1, Qubit target2)
Expand All @@ -36,7 +36,7 @@ void IIntrinsicIsingZZ.ControlledBody(IQArray<Qubit> controls, double angle, Qub
CheckAngle(angle);
this.CheckQubits(QArray<Qubit>.Add(controls, targets));

MCExp((uint)targets.Length, paulis, angle * 2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
MCExp((uint)targets.Length, paulis, angle / -2.0, (uint)controls.Length, controls.GetIds(), targets.GetIds());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ namespace Microsoft.Quantum.Intrinsic {
}
apply {
if (paulis[0] == PauliX) {
IsingXX(theta / 2.0, qubits[0], qubits[1]);
IsingXX(-2.0 * theta , qubits[0], qubits[1]);
} elif (paulis[0] == PauliY) {
IsingYY(theta / 2.0, qubits[0], qubits[1]);
IsingYY(-2.0 * theta, qubits[0], qubits[1]);
} elif (paulis[0] == PauliZ) {
IsingZZ(theta / 2.0, qubits[0], qubits[1]);
IsingZZ(-2.0 * theta, qubits[0], qubits[1]);
} else {
fail "Type2 decompositions do not support PauliI as an input to Exp";
}
Expand All @@ -35,7 +35,7 @@ namespace Microsoft.Quantum.Intrinsic {
SpreadZ(qubits[1], qubits[2 .. Length(qubits) - 1]);
}
apply {
IsingZZ(theta / 2.0, qubits[0], qubits[1]);
IsingZZ(-2.0 * theta, qubits[0], qubits[1]);
}
}
}
Expand Down