Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #3
0
        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);
        }