| 
908 | 908 | ]  | 
909 | 909 | 
 
  | 
910 | 910 | 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 | + | 
930 | 923 | edges = {};  | 
 | 924 | +For[wire =1, wire <= Length[gridForm[[1]]], wire++,  | 
931 | 925 | (*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}];  | 
935 | 928 | ];  | 
936 | 929 | (*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}];  | 
942 | 935 | ];  | 
943 | 936 | ];  | 
944 | 937 | ];  | 
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]];  | 
948 | 941 | (*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 | +{}  | 
955 | 948 | ];  | 
956 | 949 | (*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 | +{}  | 
963 | 956 | ];  | 
964 | 957 | out=Which[TrueQ[gate == "mustBeLeftBlank"],{},TrueQ[gate == "blankWhichCanBeOverwritten"],{},  | 
965 | 958 | {type, controlOrParameter,target} = gate;TrueQ[(type==cnotType ||type==czType)&& controlOrParameter==-pos[[2]]],  | 
 | 
1001 | 994 | If[OptionValue[DrawRotationAngles],ToStringStandard[StringForm["XX(`1`)",DrawCircuitNumberFormat[controlOrParameter,OptionValue[Digits]]]],"XX"]],  | 
1002 | 995 | pos+{0,-(sortTarget[[-1]]-sortTarget[[1]])/2.}]}  | 
1003 | 996 | ];  | 
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*)  | 
1005 | 998 | actQubits={};  | 
1006 | 999 | Do[  | 
1007 | 1000 | posTemp=pos;posTemp[[2]]=-act;  | 
 | 
1018 | 1011 | Join[init,out,post]  | 
1019 | 1012 | ];  | 
1020 | 1013 | 
 
  | 
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];  | 
1025 | 1018 | 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*)  | 
1027 | 1020 | 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*)  | 
1031 | 1024 | ];  | 
1032 | 1025 | ];  | 
1033 |  | -out  | 
 | 1026 | +esOut  | 
1034 | 1027 | ];  | 
1035 | 1028 | 
 
  | 
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 | + | 
1037 | 1038 | ];  | 
1038 | 1039 | 
 
  | 
1039 | 1040 | Options[qCircuitFromGridForm]={DrawRotationAngles->False,Digits->2};  | 
 | 
0 commit comments