Skip to content

Commit 6c6af62

Browse files
committed
fix PrintCircuit for mathematica 12
1 parent 3aa1cfe commit 6c6af62

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed

UniversalQCompiler.m

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -908,58 +908,51 @@
908908
]
909909

910910
Options[drawGraphFromGridForm]={DrawRotationAngles->False,Digits->2};
911-
drawGraphFromGridForm[gridForm1_,OptionsPattern[]]:= Module[{post,init,out,postSelSet,initSet,newTraceOuts,traceOutWires,positions,gridForm,edgeRenderingFunction,actQubits,text, posTemp,longestWireLength,vertexCoordRules,edges,wire, gateIndex,sortTarget,box,vertexRenderingFunction,vertexName},
912-
longestWireLength = Max[Map[Length, gridForm1[[1]]]];
913-
(*Move tracing out operations to the end (Remark: Removing this leads to a "cutting" of the white lines drawn after the tracing out operations
914-
with the control line of C-NOT gates. ToDo: Do not move tracing out to the end and fix the mentioned "bug".*)
915-
initSet=gridForm1[[2]];
916-
postSelSet=gridForm1[[3]];
917-
positions=Position[gridForm1[[1]],{measType,0,_}];
918-
gridForm=ReplacePart[gridForm1[[1]],positions->"mustBeLeftBlank"];
919-
Do[
920-
gridForm[[pos[[1]],longestWireLength-1]]=gridForm1[[1]][[Delete[pos,0]]]
921-
,{pos,positions}];
922-
(*Create vertexCoordRules*)
923-
vertexCoordRules = {};
924-
vertexName[wire_, gateIndex_]:= ((wire -1)*longestWireLength+gateIndex-1);
925-
For[wire =1, wire <= Length[gridForm], wire ++,
926-
For[gateIndex = 1, gateIndex <= Length[gridForm[[wire]]], gateIndex++,
927-
AppendTo[vertexCoordRules, vertexName[wire,gateIndex]-> {gateIndex,-wire}];
928-
];
929-
];
911+
drawGraphFromGridForm[gridForm_,OptionsPattern[]]:= Module[{post,init,out,postSelSet,initSet,newTraceOuts,traceOutWires,positions,edgeRenderingFunction,actQubits,text, posTemp,numWires,longestWireLength,vertexCoordRules,edges,wire, gateIndex,sortTarget,box,vertexRenderingFunction,
912+
vertexName,vertexCoordinates,vertices,vetexShapeFunction,edgeShapeFunction},
913+
longestWireLength = Max[Map[Length, gridForm[[1]]]];
914+
numWires = Length[gridForm[[1]]];
915+
initSet=gridForm[[2]];
916+
postSelSet=gridForm[[3]];
917+
918+
(*Create vertexCoordinates. As of mathematica 12 this information takes the form of a list rather than a function.
919+
So we also explicitly create a list of vertices as well as one of their coordinates to ensure the two lists are ordered the same.*)
920+
vertices = Flatten[Table[{w,g}, {w,1,numWires}, {g,1,longestWireLength}],1];
921+
vertexCoordinates = Map[Function[{#[[2]],-#[[1]]}], vertices]; (*we get the y coordinate from the wire the gate is on lowest wire at the top*)
922+
930923
edges = {};
924+
For[wire =1, wire <= Length[gridForm[[1]]], wire++,
931925
(*edges between adjacent gates on the same wire*)
932-
For[wire =1, wire <= Length[gridForm], wire++,
933-
For[gateIndex = 1, gateIndex < Length[gridForm[[wire]]], gateIndex++,
934-
AppendTo[edges, vertexName[wire, gateIndex]-> vertexName[wire, gateIndex+1]];
926+
For[gateIndex = 1, gateIndex < Length[gridForm[[1]][[wire]]], gateIndex++,
927+
AppendTo[edges, {wire, gateIndex}-> {wire, gateIndex+1}];
935928
];
936929
(*edges for controls*)
937-
For[gateIndex = 1, gateIndex <= Length[gridForm[[wire]]], gateIndex++,
938-
If[Head[gridForm[[wire, gateIndex]]]=== List &&
939-
(gridForm[[wire, gateIndex]][[1]]==cnotType||gridForm[[wire, gateIndex]][[1]]==czType)&&
940-
gridForm[[wire, gateIndex]][[3]]==wire,
941-
AppendTo[edges, vertexName[wire, gateIndex]-> vertexName[gridForm[[wire, gateIndex]][[2]],gateIndex]];
930+
For[gateIndex = 1, gateIndex <= Length[gridForm[[1]][[wire]]], gateIndex++,
931+
If[Head[gridForm[[1]][[wire, gateIndex]]]=== List &&
932+
(gridForm[[1]][[wire, gateIndex]][[1]]==cnotType||gridForm[[1]][[wire, gateIndex]][[1]]==czType)&&
933+
gridForm[[1]][[wire, gateIndex]][[3]]==wire,
934+
AppendTo[edges, {wire, gateIndex}-> {gridForm[[1]][[wire, gateIndex]][[2]],gateIndex}];
942935
];
943936
];
944937
];
945-
vertexRenderingFunction[pos_, name_] := Module[{wireIndex, positionAlongWire,type, controlOrParameter,gate,target},
946-
{wireIndex,positionAlongWire} = QuotientRemainder[name, longestWireLength] + {1,1};
947-
gate = gridForm[[wireIndex, positionAlongWire]];
938+
939+
vetexShapeFunction[{x_,y_},v_,{w_,h_}] := Module[{vsWireIndex=v[[1]], vsGateIndex=v[[2]],pos={x,y}, gate,type, controlOrParameter,target},
940+
gate = gridForm[[1]][[vsWireIndex, vsGateIndex]];
948941
(*If a qubits starts in a fixed state, draw \ket{0}*)
949-
init={};
950-
If[positionAlongWire==1&&MemberQ[initSet,{_,_,wireIndex}],
951-
If[MemberQ[initSet,{_,0,wireIndex}],
952-
init={Black, Text["|0>", pos-{0.2,0}]},
953-
init={Black, Text["|1>", pos-{0.2,0}]}
954-
]
942+
init=If[vsGateIndex==1&&MemberQ[initSet,{_,_,vsWireIndex}],
943+
If[MemberQ[initSet,{_,0,vsWireIndex}],
944+
{Black, Text["|0>", pos-{0.2,0}]},
945+
{Black, Text["|1>", pos-{0.2,0}]}
946+
],
947+
{}
955948
];
956949
(*If a qubits are postSelSetected in a fixed state, draw \bra{0}*)
957-
post={};
958-
If[positionAlongWire==longestWireLength&&MemberQ[postSelSet,{_,_,wireIndex}],
959-
If[MemberQ[postSelSet,{_,0,wireIndex}],
960-
post={Black, Text["<0|", pos+{0.2,0}]},
961-
post={Black, Text["<1|", pos+{0.2,0}]}
962-
]
950+
post= If[vsGateIndex==longestWireLength&&MemberQ[postSelSet,{_,_,vsWireIndex}],
951+
If[MemberQ[postSelSet,{_,0,vsWireIndex}],
952+
{Black, Text["<0|", pos+{0.2,0}]},
953+
{Black, Text["<1|", pos+{0.2,0}]}
954+
],
955+
{}
963956
];
964957
out=Which[TrueQ[gate == "mustBeLeftBlank"],{},TrueQ[gate == "blankWhichCanBeOverwritten"],{},
965958
{type, controlOrParameter,target} = gate;TrueQ[(type==cnotType ||type==czType)&& controlOrParameter==-pos[[2]]],
@@ -1001,7 +994,7 @@
1001994
If[OptionValue[DrawRotationAngles],ToStringStandard[StringForm["XX(`1`)",DrawCircuitNumberFormat[controlOrParameter,OptionValue[Digits]]]],"XX"]],
1002995
pos+{0,-(sortTarget[[-1]]-sortTarget[[1]])/2.}]}
1003996
];
1004-
(*Do print the wire for the qubits where the diagonal gate is anot cting on*)
997+
(*Do print the wire for the qubits where the diagonal gate is not acting on*)
1005998
actQubits={};
1006999
Do[
10071000
posTemp=pos;posTemp[[2]]=-act;
@@ -1018,22 +1011,30 @@
10181011
Join[init,out,post]
10191012
];
10201013

1021-
edgeRenderingFunction[pos_,name_,a_] :=Module[{wireIndex,positionAlongWire,positionMst,out},
1022-
{wireIndex,positionAlongWire} = QuotientRemainder[name[[1]], longestWireLength] + {1,1};
1023-
(*Find position of last measurement gate*)
1024-
positionMst=Position[gridForm[[wireIndex,1;;positionAlongWire]],_?(If[Length[#]==0,False,MemberQ[{measType},#[[1]]]]&),{1},Heads->False];
1014+
1015+
edgeShapeFunction[pos_,edge_] :=Module[{v1=edge[[1]],v2=edge[[2]],wireIndex,positionAlongWire,positionMst,esOut},
1016+
{wireIndex,positionAlongWire} = v1;
1017+
positionMst=Position[gridForm[[1]][[wireIndex,1;;positionAlongWire]],_?(If[Length[#]==0,False,MemberQ[{measType},#[[1]]]]&),{1},Heads->False];
10251018
If[Length[positionMst]==0,
1026-
out={Directive[Thick, Black], Line[pos]},(*No measurement on the wire before the current position*)
1019+
esOut={Directive[Thick, Black], Line[pos]},(*No measurement on the wire before the current position*)
10271020
positionMst=positionMst[[1]][[1]];
1028-
If[gridForm[[wireIndex,positionMst]][[2]]==0,
1029-
out={Directive[Thick, White], Line[pos]},(*qubit was traced out earlier*)
1030-
out={ Black, Line[pos+{{0,0.05},{0,0.05}}],Line[pos-{{0,0.05},{0,0.05}}]}(*qubit was measured out earlier*)
1021+
If[gridForm[[1]][[wireIndex,positionMst]][[2]]==0,
1022+
esOut={},(*qubit was traced out earlier*)
1023+
esOut={ Black, Line[pos+{{0,0.05},{0,0.05}}],Line[pos-{{0,0.05},{0,0.05}}]}(*qubit was measured out earlier*)
10311024
];
10321025
];
1033-
out
1026+
esOut
10341027
];
10351028

1036-
Return[GraphPlot[edges,VertexCoordinateRules->vertexCoordRules ,VertexRenderingFunction->vertexRenderingFunction, EdgeRenderingFunction->edgeRenderingFunction]];
1029+
If[$VersionNumber >= 12,
1030+
Return[GraphPlot[Graph[vertices, edges],VertexCoordinates->vertexCoordinates ,VertexShapeFunction->vetexShapeFunction, EdgeShapeFunction-> edgeShapeFunction]];
1031+
,
1032+
(*Pre mathematica 12 EdgeRenderingFunction and VertexRenderingFunction are passed the indices of the vertices, rather than their actual names in the second argument*)
1033+
Return[GraphPlot[Graph[vertices, edges],VertexCoordinateRules->vertexCoordinates,
1034+
VertexRenderingFunction->Function[{pos, edge}, vetexShapeFunction[pos,vertices[[edge]],{1,1}]],
1035+
EdgeRenderingFunction-> Function[{pos,edge,a}, edgeShapeFunction[pos,vertices[[edge]]]]]];
1036+
]
1037+
10371038
];
10381039

10391040
Options[qCircuitFromGridForm]={DrawRotationAngles->False,Digits->2};

0 commit comments

Comments
 (0)