public void Gate1(Complex[,] matrix, int target, int?control = null) { Validate(target, "Gate1", "target"); if (control.HasValue) { Validate(control.Value, "Gate1", "control"); } ValidateMatrix(matrix, "Gate1", "matrix"); RegisterRefModel targetRef; RegisterRefModel?controlRef; if (control == null) { controlRef = null; if (_model == null) { targetRef = _compModel.GetRefFromOffset(target); } else { targetRef = new RegisterRefModel() { Register = _model, Offset = _offsetToModel + target }; } } else { if (_model == null) { controlRef = _compModel.GetRefFromOffset(control.Value); targetRef = _compModel.GetRefFromOffset(target); } else { controlRef = new RegisterRefModel() { Register = _model, Offset = _offsetToModel + control.Value }; targetRef = new RegisterRefModel() { Register = _model, Offset = _offsetToModel + target }; } } UnitaryGate gate = new UnitaryGate(matrix, targetRef, controlRef); AddGate(gate); }
private string GenerateGateCode(ComputerModel model, Gate gate, int column, string indent, string defaultRegName = null) { Func <string, Gate, string> appendControlTarget = (string begin, Gate g) => { if (g.Control.HasValue) { string namedC = "control: "; string namedT = "target: "; if (g.Name != GateName.CNot) { namedC = ""; namedT = ""; } if (g.Control.Value.Register == g.Target.Register) { return(String.Format("{0}.{1}{4}{2}, {5}{3});", GetRegName(g.Target.Register, defaultRegName), begin, g.Target.Offset, g.Control.Value.Offset, namedT, namedC)); } else { return(String.Format("comp.{0}{5}{1}[{2}], {6}{3}[{4}]);", begin, GetRegName(g.Target.Register, defaultRegName), g.Target.Offset, GetRegName(g.Control.Value.Register, defaultRegName), g.Control.Value.Offset, namedT, namedC)); } } else { return(String.Format("{0}.{1}{2});", GetRegName(g.Target.Register, defaultRegName), begin, g.Target.Offset)); } }; Func <string, string, Gate, RegisterRefModel[], string> appendMoreControls = (string begin, string beginComment, Gate g, RegisterRefModel[] controls) => { if (controls.All <RegisterRefModel>(x => x.Register == g.Target.Register) && (g.Control == null || g.Control.Value.Register == g.Target.Register)) { StringBuilder format = new StringBuilder(GetRegName(g.Target.Register, defaultRegName)).Append(".").Append(begin); format.Append(g.Target.Offset); if (g.Control.HasValue) { format.Append(", ").Append(g.Control.Value.Offset); } for (int i = 0; i < controls.Length; i++) { format.Append(", ").Append(controls[i].Offset); } format.Append(");"); format.Append("\t\t// ").Append(beginComment).Append("<target_bit>, ... <control_bits> ...)"); return(format.ToString()); } else { StringBuilder format = new StringBuilder("comp.").Append(begin); format.Append(GetRegName(g.Target.Register, defaultRegName)) .Append("[").Append(g.Target.Offset).Append("]"); if (g.Control.HasValue) { format.Append(", ") .Append(GetRegName(g.Control.Value.Register, defaultRegName)).Append("[") .Append(g.Control.Value.Offset).Append("]"); } for (int i = 0; i < controls.Length; i++) { format.Append(", ") .Append(GetRegName(controls[i].Register, defaultRegName)).Append("[") .Append(controls[i].Offset).Append("]"); } format.Append(");"); format.Append("\t\t// ").Append(beginComment).Append("<target_bit>, ... <control_bits> ...)"); return(format.ToString()); } }; switch (gate.Name) { case GateName.Hadamard: return(appendControlTarget("Hadamard(", gate)); case GateName.SigmaX: return(appendControlTarget("SigmaX(", gate)); case GateName.SigmaY: return(appendControlTarget("SigmaY(", gate)); case GateName.SigmaZ: return(appendControlTarget("SigmaZ(", gate)); case GateName.SqrtX: return(appendControlTarget("SqrtX(", gate)); case GateName.RotateX: RotateXGate rx = gate as RotateXGate; return(appendControlTarget(String.Format("RotateX({0}, ", rx.Gamma), gate)); case GateName.RotateY: RotateYGate ry = gate as RotateYGate; return(appendControlTarget(String.Format("RotateY({0}, ", ry.Gamma), gate)); case GateName.RotateZ: RotateZGate rz = gate as RotateZGate; return(appendControlTarget(String.Format("RotateZ({0}, ", rz.Gamma), gate)); case GateName.PhaseKick: PhaseKickGate pk = gate as PhaseKickGate; if (pk.Controls.Length > 0) { return(appendMoreControls( String.Format("PhaseKick({0}, ", pk.Gamma), "PhaseKick(<gamma_value>, ", gate, pk.Controls)); } else { return(appendControlTarget(String.Format("PhaseKick({0}, ", pk.Gamma), gate)); } case GateName.PhaseScale: PhaseScaleGate ps = gate as PhaseScaleGate; return(appendControlTarget(String.Format("PhaseScale({0}, ", ps.Gamma), gate)); case GateName.CNot: return(appendControlTarget("CNot(", gate)); case GateName.CPhaseShift: CPhaseShiftGate cps = gate as CPhaseShiftGate; if (cps.Controls.Length > 0) { return(appendMoreControls( String.Format("CPhaseShift({0}, ", cps.Dist), "CPhaseShift(<phase_distance_value>, ", gate, cps.Controls)); } else { return(appendControlTarget(String.Format("CPhaseShift({0}, ", cps.Dist), gate)); } case GateName.InvCPhaseShift: InvCPhaseShiftGate icps = gate as InvCPhaseShiftGate; if (icps.Controls.Length > 0) { return(appendMoreControls( String.Format("InverseCPhaseShift({0}, ", icps.Dist), "InverseCPhaseShift(<phase_distance_value>, ", gate, icps.Controls)); } else { return(appendControlTarget(String.Format("InverseCPhaseShift({0}, ", icps.Dist), gate)); } case GateName.Toffoli: ToffoliGate t = gate as ToffoliGate; return(appendMoreControls( "Toffoli(", "Toffoli(", gate, t.Controls)); case GateName.Measure: MeasureGate m = gate as MeasureGate; if (m.Begin == m.End) { return(String.Format("{0}.Measure({1});", GetRegName(m.Target.Register, defaultRegName), m.Target.Offset)); } else if (m.BeginRow.Register == m.EndRow.Register) { string regName = GetRegName(m.BeginRow.Register, defaultRegName); if (m.BeginRow.Register != null) { if (m.End - m.Begin + 1 == m.BeginRow.Register.Qubits.Count) { return(String.Format("{0}.Measure();", regName)); } else { StringBuilder builder = new StringBuilder(); for (int i = m.BeginRow.Offset; i <= m.EndRow.Offset; i++) { builder.AppendFormat("{0}.Measure({1});\n", regName, i); } return(builder.ToString()); } } else { if (m.End - m.Begin + 1 == model.TotalWidth) { return(String.Format("{0}.Measure();", regName)); } else { StringBuilder builder = new StringBuilder(); for (int i = m.BeginRow.Offset; i <= m.EndRow.Offset; i++) { builder.AppendFormat("{0}.Measure({1});\n", regName, i); } return(builder.ToString()); } } } else { StringBuilder builder = new StringBuilder(); int i = m.Begin; while (i <= m.End) { RegisterRefModel regRef = model.GetRefFromOffset(i); if (i + regRef.Register.Qubits.Count < m.End + 2) { builder.AppendFormat("{0}.Measure();\n", regRef.Register.Name); i += regRef.Register.Qubits.Count; } else { builder.AppendFormat("{0}.Measure({1});\n", regRef.Register.Name, regRef.Offset); i++; } } return(builder.ToString()); } case GateName.Unitary: UnitaryGate u = gate as UnitaryGate; string uMatrixName = "unitary_" + column + "_" + u.Target.OffsetToRoot; string matrixDef = GenerateMatrixDefinition(uMatrixName, u.Matrix, indent); string gateDef = appendControlTarget(String.Format("Gate1({0}, ", uMatrixName), gate); return(String.Format("{0}\n{1}{2}", matrixDef, indent, gateDef)); case GateName.Parametric: return(GenerateParametricGateCode(gate as ParametricGate, defaultRegName)); case GateName.Composite: return(GenerateCompositeGateCode(gate as CompositeGate, defaultRegName)); case GateName.Empty: default: return(String.Empty); } }
public bool RunStep(IList <Gate> gates, bool runBackward = false, bool runComposite = false) { Quantum.Register root = _comp.GetSourceRoot(); bool somethingChanged = false; int i = 0; int maxI = (runComposite ? 1 : gates.Count); while (i < maxI) { Gate gate = gates[i]; int? control = null; if (gate.Control.HasValue) { control = gate.Control.Value.OffsetToRoot; } switch (gate.Name) { case GateName.Hadamard: // the same as inversion root.Hadamard(gate.Target.OffsetToRoot, control); somethingChanged = true; i = gate.End + 1; break; case GateName.SigmaX: // the same as inversion root.SigmaX(gate.Target.OffsetToRoot); somethingChanged = true; i = gate.End + 1; break; case GateName.SigmaY: // the same as inversion root.SigmaY(gate.Target.OffsetToRoot, control); somethingChanged = true; i = gate.End + 1; break; case GateName.SigmaZ: // the same as inversion root.SigmaZ(gate.Target.OffsetToRoot, control); somethingChanged = true; i = gate.End + 1; break; case GateName.SqrtX: if (runBackward) { Complex[,] m = new Complex[2, 2]; Complex a = new Complex(0.5, -0.5); Complex b = new Complex(0.5, 0.5); m[0, 0] = b; m[0, 1] = a; m[1, 0] = a; m[1, 1] = b; root.Gate1(m, gate.Target.OffsetToRoot, control); } else { root.SqrtX(gate.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.RotateX: RotateXGate rx = gate as RotateXGate; if (runBackward) { root.RotateX(-rx.Gamma, rx.Target.OffsetToRoot, control); } else { root.RotateX(rx.Gamma, rx.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.RotateY: RotateYGate ry = gate as RotateYGate; if (runBackward) { root.RotateY(-ry.Gamma, ry.Target.OffsetToRoot, control); } else { root.RotateY(ry.Gamma, ry.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.RotateZ: RotateZGate rz = gate as RotateZGate; if (runBackward) { root.RotateZ(-rz.Gamma, rz.Target.OffsetToRoot, control); } else { root.RotateZ(rz.Gamma, rz.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.PhaseKick: PhaseKickGate pk = gate as PhaseKickGate; if (pk.Controls.Length > 0) { int[] controls1 = pk.Controls.Select <RegisterRefModel, int>(x => x.OffsetToRoot).ToArray <int>(); if (runBackward) { root.PhaseKick(-pk.Gamma, pk.Target.OffsetToRoot, controls1); } else { root.PhaseKick(pk.Gamma, pk.Target.OffsetToRoot, controls1); } } else { if (runBackward) { root.PhaseKick(-pk.Gamma, pk.Target.OffsetToRoot); } else { root.PhaseKick(pk.Gamma, pk.Target.OffsetToRoot); } } somethingChanged = true; i = gate.End + 1; break; case GateName.PhaseScale: PhaseScaleGate ps = gate as PhaseScaleGate; if (runBackward) { root.PhaseScale(-ps.Gamma, ps.Target.OffsetToRoot, control); } else { root.PhaseScale(ps.Gamma, ps.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.CPhaseShift: CPhaseShiftGate cps = gate as CPhaseShiftGate; if (cps.Controls.Length > 0) { int[] controls1 = cps.Controls.Select <RegisterRefModel, int>(x => x.OffsetToRoot).ToArray <int>(); if (runBackward) { root.InverseCPhaseShift(cps.Dist, cps.Target.OffsetToRoot, controls1); } else { root.CPhaseShift(cps.Dist, cps.Target.OffsetToRoot, controls1); } } else { if (runBackward) { root.InverseCPhaseShift(cps.Dist, cps.Target.OffsetToRoot); } else { root.CPhaseShift(cps.Dist, cps.Target.OffsetToRoot); } } somethingChanged = true; i = gate.End + 1; break; case GateName.InvCPhaseShift: InvCPhaseShiftGate icps = gate as InvCPhaseShiftGate; if (icps.Controls.Length > 0) { int[] controls1 = icps.Controls.Select <RegisterRefModel, int>(x => x.OffsetToRoot).ToArray <int>(); if (runBackward) { root.CPhaseShift(icps.Dist, icps.Target.OffsetToRoot, controls1); } else { root.InverseCPhaseShift(icps.Dist, icps.Target.OffsetToRoot, controls1); } } else { if (runBackward) { root.CPhaseShift(icps.Dist, icps.Target.OffsetToRoot); } else { root.InverseCPhaseShift(icps.Dist, icps.Target.OffsetToRoot); } } somethingChanged = true; i = gate.End + 1; break; case GateName.CNot: CNotGate cn = gate as CNotGate; root.CNot(cn.Target.OffsetToRoot, cn.Control.Value.OffsetToRoot); somethingChanged = true; i = gate.End + 1; break; case GateName.Toffoli: ToffoliGate t = gate as ToffoliGate; int[] controls = t.Controls.Select <RegisterRefModel, int>(x => x.OffsetToRoot).ToArray <int>(); root.Toffoli(t.Target.OffsetToRoot, controls); somethingChanged = true; i = gate.End + 1; break; case GateName.Unitary: UnitaryGate u = gate as UnitaryGate; if (runBackward) { Complex[,] m = new Complex[2, 2]; m[0, 0] = Complex.Conjugate(u.Matrix[0, 0]); m[0, 1] = Complex.Conjugate(u.Matrix[1, 0]); m[1, 0] = Complex.Conjugate(u.Matrix[0, 1]); m[1, 1] = Complex.Conjugate(u.Matrix[1, 1]); root.Gate1(m, gate.Target.OffsetToRoot, control); } else { root.Gate1(u.Matrix, u.Target.OffsetToRoot, control); } somethingChanged = true; i = gate.End + 1; break; case GateName.Measure: MeasureGate mg = gate as MeasureGate; for (int j = mg.Begin; j <= mg.End; j++) { root.Measure(j); } somethingChanged = true; i = gate.End + 1; break; case GateName.Parametric: ParametricGate pg = gate as ParametricGate; _comp.Evaluate(pg, runBackward); somethingChanged = true; i = gate.End + 1; break; case GateName.Composite: CompositeGate cg = gate as CompositeGate; List <Gate> actual = _comp.GetActualGates(cg); if (runBackward) { actual.Reverse(); } foreach (Gate g in actual) { // TODO refactor RunStep() into RunGate() List <Gate> toRun = new List <Gate>() { g }; RunStep(toRun, runBackward, true); } somethingChanged = true; i = gate.End + 1; break; case GateName.Empty: default: i++; break; } } return(somethingChanged); }