Skip to content

Commit b8b83ae

Browse files
author
Christopher J. Wood
committed
2 parents 63107b8 + 21591f3 commit b8b83ae

10 files changed

+16266
-9832
lines changed

doc/api-doc/GRAPE.nb

+13,059-8,452
Large diffs are not rendered by default.

doc/api-doc/Perturbation.nb

+198-148
Large diffs are not rendered by default.

doc/api-doc/QSim.nb

+431-281
Large diffs are not rendered by default.

doc/api-doc/QuantumChannel.nb

+1,259-421
Large diffs are not rendered by default.

doc/api-doc/Tensor.nb

+803-367
Large diffs are not rendered by default.

src/GRAPE.m

+409-122
Large diffs are not rendered by default.

src/QSim.m

+7-7
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
ObservableListQ,FunctionListQ,
7373
DistributionQ
7474
},
75-
$Usages
75+
$QSimUsages
7676
];
7777

7878

@@ -91,7 +91,7 @@
9191
StepSize,PollingInterval,InitialState,SimulationOutput,SequenceMode,NumericEvaluation,ForceSuperoperator,
9292
TimeVector,Superoperators,Unitaries,States,Functions,Observables
9393
},
94-
$Usages
94+
$QSimUsages
9595
];
9696

9797

@@ -112,7 +112,7 @@
112112
GetPulseShapeMatrix,
113113
GetStepSize,GetPollingInterval,DivideEvenly,MakeMultipleOf
114114
},
115-
$Usages
115+
$QSimUsages
116116
];
117117

118118

@@ -121,7 +121,7 @@
121121

122122

123123
Unprotect[PulseSim];
124-
AssignUsage[PulseSim,$Usages];
124+
AssignUsage[PulseSim,$QSimUsages];
125125

126126

127127
PulseSim::badControlDim = "The internal Hamiltonian dimension, `1`, is neither equal to nor a multiple of (one of) the control Hamiltonian dimension(s), `2`.";
@@ -132,7 +132,7 @@
132132

133133

134134
Unprotect[DrawSequence];
135-
AssignUsage[DrawSequence,$Usages];
135+
AssignUsage[DrawSequence,$QSimUsages];
136136

137137

138138
(* ::Section:: *)
@@ -909,7 +909,7 @@
909909
(*We give each kind of pulse its own width weight for aesthetics.*)
910910

911911

912-
DrawSequence[seq_?PulseSequenceQ]:=
912+
DrawSequence[seq_?PulseSequenceQ,opt:OptionsPattern[Graphics]]:=
913913
Module[{shapedFrac=0.3,uFrac=0.07,sFrac=0.07,driftFrac=0.63,width=500,height=100,widths},
914914
widths=shapedFrac*(ShapedPulseQ/@seq)/.{True->1,False->0};
915915
widths=widths+uFrac*(UnitaryPulseQ/@seq)/.{True->1,False->0};
@@ -921,7 +921,7 @@
921921
Arrow[{{0,0},{width,0}},-width/20],
922922
Text["t",{width+width/15,0}],
923923
Table[DrawPulse[seq[[k]],widths[[k]],height*0.8,Total[Take[widths,k]]-widths[[k]]],{k,Length[seq]}]
924-
}]
924+
},opt]
925925
]
926926

927927

src/QuantumChannel.m

+55-22
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
$QuantumChannelUsages = LoadUsages[FileNameJoin[{$QUDocumentationPath, "api-doc", "QuantumChannel.nb"}]];
3737

3838

39-
(* ::Section::Closed:: *)
39+
(* ::Section:: *)
4040
(*Usage Declarations*)
4141

4242

@@ -66,10 +66,10 @@
6666

6767

6868
(* ::Subsection::Closed:: *)
69-
(*Channel Functions*)
69+
(*Channel Functions and Metrics*)
7070

7171

72-
Unprotect[GateFidelity,AverageGateFidelity,EntanglementFidelity,ChannelVolume, Unitarity];
72+
Unprotect[GateFidelity,AverageGateFidelity,EntanglementFidelity,ChannelVolume,Unitarity,DiamondNormDistance];
7373

7474

7575
AssignUsage[ProcessFidelity,$QuantumChannelUsages];
@@ -84,12 +84,13 @@
8484
(*Predicates*)
8585

8686

87-
Unprotect[CompletelyPositiveQ,TracePreservingQ,HermitianPreservingQ,UnitalQ,PauliChannelQ];
87+
Unprotect[CompletelyPositiveQ,TracePreservingQ,HermitianPreservingQ,UnitaryQ,UnitalQ,PauliChannelQ];
8888

8989

9090
AssignUsage[CompletelyPositiveQ,$QuantumChannelUsages];
9191
AssignUsage[TracePreservingQ,$QuantumChannelUsages];
9292
AssignUsage[HermitianPreservingQ,$QuantumChannelUsages];
93+
AssignUsage[UnitaryQ,$QuantumChannelUsages];
9394
AssignUsage[UnitalQ,$QuantumChannelUsages];
9495
AssignUsage[PauliChannelQ,$QuantumChannelUsages];
9596

@@ -109,7 +110,7 @@
109110
AssignUsage[FunctionChannel,$QuantumChannelUsages];
110111

111112

112-
(* ::Subsection:: *)
113+
(* ::Subsection::Closed:: *)
113114
(*Error Messages*)
114115

115116

@@ -148,7 +149,7 @@
148149
Begin["`Private`"];
149150

150151

151-
(* ::Subsection:: *)
152+
(* ::Subsection::Closed:: *)
152153
(*Predicates*)
153154

154155

@@ -163,7 +164,7 @@
163164
KrausPairQ[set_]:=And[First[Dimensions[set]]===2,AllQ[KrausSingleQ,set]]
164165
KrausSingleQ[set_]:=AllQ[MatrixQ,set]
165166
KrausQ[set_]:=Or[KrausPairQ[set],KrausSingleQ[set]];
166-
KrausUnitaryQ[set_]:=And[KrausSingleQ[set],Length[set]===1]
167+
KrausUnitaryQ[set_]:=And[KrausSingleQ[set],Length[set]===1,UnitaryMatrixQ[First@set,Tolerance->10^(-12)]]
167168

168169

169170
StinespringPairQ[set_]:=And[Length[set]==2,AllQ[MatrixQ,set]];
@@ -214,8 +215,8 @@
214215
choi=First[Choi[chan]],
215216
assum=And[$Assumptions,OptionValue[Assumptions]],
216217
eigen,boole},
217-
If[NumericQ[choi],
218-
PositiveSemidefiniteMatrixQ[choi],
218+
If[AllQ[NumericQ,Flatten[choi]],
219+
PositiveSemidefiniteMatrixQ[choi,Tolerance->10^(-12)],
219220
eigen=Simplify[Eigenvalues[choi],Assumptions->assum];
220221
boole=FullSimplify[And@@NonNegative[eigen],Assumptions->assum];
221222
Which[
@@ -238,17 +239,32 @@
238239

239240
TracePreservingQ[chan_QuantumChannel,opts:OptionsPattern[CompletelyPositiveQ]]:=
240241
With[{
241-
op=PartialTr[
242-
First[Choi[chan,Basis->"Col"]],
243-
{InputDim[chan],OutputDim[chan]},{2}],
244-
assum=And[$Assumptions,OptionValue[Assumptions]],
245-
id=IdentityMatrix[InputDim[chan]]},
246-
AllMatchQ[0,
242+
op=PartialTr[First[Choi[chan,Basis->"Col"]],{InputDim[chan],OutputDim[chan]},{2}],
243+
assum=And[$Assumptions,OptionValue[Assumptions]],
244+
id=IdentityMatrix[InputDim[chan]]
245+
},
246+
AllQ[FullSimplify[#*#\[Conjugate],Assumptions->assum]<10.^-12&,
247247
FullSimplify[Flatten[op-id],Assumptions->assum]
248248
]
249249
]
250250

251251

252+
253+
UnitaryQ[chan_QuantumChannel,opts:OptionsPattern[CompletelyPositiveQ]]:=Or[
254+
(ChannelRep/.ChannelParameters[chan])===Unitary,
255+
And[
256+
TracePreservingQ[chan,Assumptions->OptionValue[Assumptions]],
257+
Module[{unitarity=FullSimplify[Unitarity[chan],And[$Assumptions,OptionValue[Assumptions]]]},
258+
If[NumericQ[unitarity],
259+
Abs[unitarity-1]<10^-12,
260+
TrueQ[unitarity==1]
261+
]
262+
],
263+
CompletelyPositiveQ[chan,Assumptions->OptionValue[Assumptions]]
264+
]
265+
];
266+
267+
252268
UnitalQ[chan_QuantumChannel,opts:OptionsPattern[CompletelyPositiveQ]]:=
253269
With[{
254270
op=PartialTr[
@@ -434,7 +450,7 @@
434450
]]
435451

436452

437-
(* ::Subsection:: *)
453+
(* ::Subsection::Closed:: *)
438454
(*Transforming Representations*)
439455

440456

@@ -681,7 +697,7 @@
681697
TransformChannel[Kraus->Unitary,op_,opts:OptionsPattern[TransformChannel]]:=First[op]
682698

683699

684-
(* ::Subsubsection:: *)
700+
(* ::Subsubsection::Closed:: *)
685701
(*From Choi*)
686702

687703

@@ -1018,7 +1034,7 @@
10181034

10191035

10201036
(* ::Subsection::Closed:: *)
1021-
(*Fidelity and Volume*)
1037+
(*Channel Functions and Metrics*)
10221038

10231039

10241040
ChannelVolume[chan_QuantumChannel]:=Det[MatrixPower[Part[Super[chan,Basis->"Pauli"],1,2;;All,2;;All],1/2]];
@@ -1062,10 +1078,27 @@
10621078

10631079
Unitarity[chan_QuantumChannel] :=
10641080
With[{
1065-
Eu = First[Super[chan, Basis -> "Pauli"]][[2;;, 2;;]]
1081+
Eu = First[Super[chan, Basis -> "Weyl"[InputDim[chan]]]][[2;;, 2;;]]
10661082
},
1067-
Tr[Eu\[HermitianConjugate].Eu] / (First @ Dimensions @ Eu)
1083+
Chop[Tr[Eu\[HermitianConjugate].Eu]] / (First @ Dimensions @ Eu)
1084+
]
1085+
1086+
1087+
DiamondNormDistance[U_?SquareMatrixQ]:=Module[{eiglist, minangle},
1088+
eiglist = Sort[Arg[Eigenvalues[U]]];
1089+
minangle = Min[\[Pi],2\[Pi]-Max@Differences[{##, #1 + 2 \[Pi]} & @@ eiglist]];
1090+
2*Sin[minangle/2]
1091+
];
1092+
DiamondNormDistance[U_?SquareMatrixQ,V_?SquareMatrixQ]:=DiamondNormDistance[U\[ConjugateTranspose].V]
1093+
GetFirstKraus[chan_]:=If[
1094+
ChannelRep[chan]===Unitary,
1095+
First@chan,
1096+
With[{K=First@Kraus@chan},
1097+
If[KrausSingleQ[K],First@K,First@First@K]
1098+
]
10681099
]
1100+
DiamondNormDistance[U_QuantumChannel?UnitaryQ]:=DiamondNormDistance@GetFirstKraus[U]
1101+
DiamondNormDistance[U_QuantumChannel?UnitaryQ,V_QuantumChannel?UnitaryQ]:=DiamondNormDistance[GetFirstKraus[U],GetFirstKraus[V]]
10691102

10701103

10711104
(* ::Subsection::Closed:: *)
@@ -1175,8 +1208,8 @@
11751208

11761209
Protect[Choi,Super,Chi,Kraus,Stinespring,Unitary,SysEnv];
11771210
Protect[QuantumChannel,ChannelRep,InputDim,OutputDim,Basis];
1178-
Unprotect[GateFidelity,AverageGateFidelity,EntanglementFidelity,ChannelVolume];
1179-
Protect[CompletelyPositiveQ,TracePreservingQ,HermitianPreservingQ,UnitalQ,PauliChannelQ];
1211+
Unprotect[GateFidelity,AverageGateFidelity,EntanglementFidelity,ChannelVolume,Unitarity,DiamondNormDistance];
1212+
Protect[CompletelyPositiveQ,TracePreservingQ,HermitianPreservingQ,UnitaryQ,UnitalQ,PauliChannelQ];
11801213
Unprotect[ComChannel,AComChannel,LindbladDissipator,Lindblad,PartialTrChannel,FunctionChannel];
11811214

11821215

src/Tensor.m

+21-10
Original file line numberDiff line numberDiff line change
@@ -582,32 +582,42 @@
582582
(*Matrix Bases*)
583583

584584

585-
(* ::Subsubsection:: *)
585+
(* ::Subsubsection::Closed:: *)
586586
(*Named Bases*)
587587

588588

589589
$POBasis=(PauliMatrix/@Range[0,3]);
590590
$PauliBasis=(PauliMatrix/@Range[0,3])/Sqrt[2];
591+
$WeylBasis[d_]:=Flatten[Table[RotateLeft[DiagonalMatrix[Table[Exp[2\[Pi]*I*n*b/d],{n,0,d-1}]],a]/Sqrt[d],{a,0,d-1},{b,0,d-1}],1];
592+
593+
594+
$NamedBasis={"Pauli"->$PauliBasis,"PO"->$POBasis,"Weyl"[d_]:>$WeylBasis[d]};
591595

592596

593-
$NamedBasis={"Pauli"->$PauliBasis,"PO"->$POBasis};
597+
(*We need to be fancier than MemberQ because of possible dimension arguments*)
598+
NamedBasisMemberQ[basis_]:=(basis/.Thread[RuleDelayed[Keys[$NamedBasis],True]])===True
594599

595600

596601
CheckNamedBasis[basis_]:=
597-
If[MemberQ[Keys[$NamedBasis],basis],
602+
If[NamedBasisMemberQ[basis],
598603
basis/.$NamedBasis,
599604
basis]
600605

601606

602607
$POBasisLabels={"I","X","Y","Z"};
603608
$PauliBasisLabels={"I","X","Y","Z"}/Sqrt[2];
609+
$WeylBasisLabels[d_]:=Flatten[Table["W["<>ToString[a]<>","<>ToString[b]<>"]",{a,0,d-1},{b,0,d-1}],1]
604610

605611

606-
$NamedBasisLabels={"Pauli"->$PauliBasisLabels,"PO"->$POBasisLabels};
612+
$NamedBasisLabels={"Pauli"->$PauliBasisLabels,"PO"->$POBasisLabels,"Weyl"[d_]:>$WeylBasisLabels[d]};
613+
614+
615+
(*We need to be fancier than MemberQ because of possible dimension arguments*)
616+
NamedBasisLabelsMemberQ[basis_]:=(basis/.Thread[RuleDelayed[Keys[$NamedBasisLabels],True]])===True
607617

608618

609619
CheckNamedBasisLabels[basis_]:=
610-
If[MemberQ[Keys[$NamedBasisLabels],basis],
620+
If[NamedBasisLabelsMemberQ[basis],
611621
basis/.$NamedBasisLabels,
612622
basis]
613623

@@ -711,7 +721,7 @@
711721
Which[
712722
basis==="Col",funcs[[1]][args],
713723
basis==="Row",funcs[[2]][args],
714-
MemberQ[Keys[$NamedBasis],basis],funcs[[3]][(basis/.$NamedBasis),args],
724+
NamedBasisMemberQ[basis],funcs[[3]][(basis/.$NamedBasis),args],
715725
True,funcs[[3]][basis,args]]]
716726

717727

@@ -769,7 +779,7 @@
769779
Which[
770780
basis==="Row",BasisMatrixCol["Row",arg],
771781
ListQ[basis],BasisMatrixCol[basis,arg],
772-
MemberQ[Keys[$NamedBasis],basis],BasisMatrixCol[basis/.$NamedBasis,arg],
782+
NamedBasisMemberQ[basis],BasisMatrixCol[basis/.$NamedBasis,arg],
773783
True,Message[BasisMatrix::input]
774784
]
775785
BasisMatrix[Rule[basis_,"Col"],arg___]:=ConjugateTranspose@BasisMatrix[Rule["Col",basis],arg]
@@ -801,7 +811,7 @@
801811

802812

803813
BasisMatrixColList[basis_,op_]:=
804-
If[MemberQ[Keys[$NamedBasis],basis],
814+
If[NamedBasisMemberQ[basis],
805815
BasisMatrixColList[basis/.$NamedBasis,op],
806816
Message[BasisMatrix::keys]
807817
]
@@ -831,8 +841,9 @@
831841

832842
BasisTransformation[op_,Rule[basis1_,basis2_]]:=
833843
BasisTransformation[
834-
BasisTransformation[op,Rule[basis1,"Col"],
835-
Rule["Col",basis2]]]
844+
BasisTransformation[op,Rule[basis1,"Col"]],
845+
Rule["Col",basis2]
846+
]
836847

837848

838849
(* ::Subsection::Closed:: *)

test/QuantumChannelTests.m

+24-2
Original file line numberDiff line numberDiff line change
@@ -875,8 +875,8 @@
875875
]]];
876876

877877

878-
(* ::Subsection:: *)
879-
(*Channel Functions*)
878+
(* ::Subsection::Closed:: *)
879+
(*Channel Functions and Metrics*)
880880

881881

882882
Module[{a,b,chan1,chan2},
@@ -923,6 +923,13 @@
923923
];
924924

925925

926+
TestCase[$RegisteredTests, "QuantumChannel:DiamondNormDistance",
927+
And[
928+
Module[{\[Theta]},FullSimplify[DiamondNormDistance[Unitary[MatrixExp[-I \[Theta] {{0,1},{1,0}}/2]]]-2*Sin[\[Theta]/2],Assumptions->0<=\[Theta]<2\[Pi]]==0]
929+
]
930+
]
931+
932+
926933
TestCase[$RegisteredTests, "QuantumChannel:Unitarity",
927934
And[
928935
Unitarity[
@@ -994,6 +1001,21 @@
9941001
]];
9951002

9961003

1004+
TestCase[$RegisteredTests,"QuantumChannel:UnitaryQ",
1005+
Module[{a,b,p0,p1,p2,p3},
1006+
And[
1007+
UnitaryQ[Unitary[{{0,1},{1,0}}]],
1008+
UnitaryQ[Kraus[{{{Cos[a],Sin[a]},{-Sin[a],Cos[a]}}}],Assumptions->a\[Element]Reals],
1009+
UnitaryQ[Kraus[{{{a,b},{-b\[Conjugate],a\[Conjugate]}}}],Assumptions->Abs[a]^2+Abs[b]^2==1],
1010+
Not@UnitaryQ[Kraus[{{{a,b},{-b\[Conjugate],a\[Conjugate]}}}],Assumptions->Abs[a]^2+Abs[b]^2==2],
1011+
Not@UnitaryQ[Chi[DiagonalMatrix[{p0,p1,p2,p3}]]],
1012+
UnitaryQ[Chi[DiagonalMatrix[{2,0,0,0}]]],
1013+
UnitaryQ[Kraus[{{{-0.15655368690078914`+ 0.3430921066545964` I,-0.2348331888076826`- 0.05351542084751404` I,0.15434364097586445` -0.7761828151024415` I,0.4126091294603258` +0.05692281573291967` I},{-0.20161584271439267`+ 0.19817760822741248` I,-0.16484366732378541`- 0.4753872264482968` I,-0.3635752839999726`+ 0.43813126093787663` I,0.5287549284414077` +0.2513612431126086` I},{0.8487976714138722` +0.03598473246540806` I,-0.10339410593987132`- 0.09547646392229023` I,0.10895450613616803` -0.029258702335285096` I,0.05717734865987785` +0.49238715504781155` I},{-0.042404220777264696`- 0.23303418445576338` I,-0.6832106295507965`- 0.44971119932859627` I,-0.12711459846245918`- 0.14382980174948` I,-0.4835653853512809`- 0.06480284622646271` I}}}]],
1014+
Not@UnitaryQ[Kraus[{{{0.062322322567051225` +0.4499103526192444` I,-0.0030534708049662967`+ 0.7475381561426192` I,-0.36536281946601035`- 0.3184085336398186` I},{-0.7251449050775644`- 0.06243481298569527` I,0.39685356189665594` +0.36971092879610457` I,0.2807315180487294` +0.31189365989100587` I},{0.5135328388272068` -0.0157285386936368` I,-0.03753268853883381`+ 0.3815622600004384` I,0.7607430120380767` +0.10152952864202755` I}}/Sqrt[2],{{-0.3385280862506501`- 0.11148473131686024` I,-0.09839679668003078`- 0.20068656570790783` I,0.7898784700625915` +0.44621168158367813` I},{0.47420455444381676` -0.7834563570746536` I,0.11075193848722416` +0.007811711947949143` I,0.2662964187271937` -0.2794376133502603` I},{0.18364835205881913` +0.023861043414192033` I,-0.444049899273856`- 0.8605438077054051` I,-0.14114688592590158`- 0.08980830675081206` I}}/Sqrt[2]}]]
1015+
]]
1016+
];
1017+
1018+
9971019
TestCase[$RegisteredTests,"QuantumChannel:UnitalQ",
9981020
And[
9991021
Not@UnitalQ[

0 commit comments

Comments
 (0)