/// <summary>
        /// Controlled not (CNOT) gate.
        /// [ 1 0 0 0 ]
        /// [ 0 1 0 0 ]
        /// [ 0 0 0 1 ]
        /// [ 0 0 1 0 ]
        ///
        /// The CNOT gate works by combining the two input qubits (control and target) into a vector (of length 4, using tensor product).
        /// Then it uses the assumption that the output control qubit is constant to calculate the target output qubit.
        /// </summary>
        /// <returns>Target qubit affected by the CNOT gate. The target qubit os constant (and is therefore not returned).</returns>
        public static Qubit CNOT(Qubit control, Qubit target)   // TODO: introduce qubit pair? or Qubit vector?
        {
            // First get tensor product of the two qubits
            complex[] tensorProduct = TensorProduct(control, target);

            // Put result here
            complex[] result = new complex[4];

            // Multiply with CNOT gate matrix
            result[0] = tensorProduct[0];
            result[1] = tensorProduct[1];
            result[2] = tensorProduct[3];
            result[3] = tensorProduct[2];

            // Assumptions
            // 1) control output qubit α equals control qubit α
            // 2) control output qubit β equals control qubit β
            // =>
            // result[0] = α_control * α2 => α2 = result[0] / α_control
            // result[1] = α_control * β2 => β2 = result[1] / α_control
            // => (or, if α_control is zero)
            // result[2] = β_control * α2 => α2 = result[2] / β_control
            // result[3] = β_control * β2 => β2 = result[3] / β_control
            if (control.Alpha != complex.Zero)
            {
                return(new Qubit(result[0] / control.Alpha, result[1] / control.Alpha));
            }
            else
            {
                return(new Qubit(result[2] / control.Beta, result[3] / control.Beta));
            }
        }
        public override bool Equals(object obj)
        {
            complex c = (complex)obj;

            return(c.Real == Real && c.Imaginary == Imaginary);
        }
 public complex(complex c)
 {
     this.Real      = c.Real;
     this.Imaginary = c.Imaginary;
 }
 /// <summary>
 /// Constructs a qubit.
 /// </summary>
 /// <param name="alpha"></param>
 /// <param name="beta"></param>
 public Qubit(complex alpha, complex beta)
 {
     Debug.Assert(Math.Pow(alpha.Abs(), 2) + Math.Pow(beta.Abs(), 2) - 1 < 0.000001);
     this.Alpha = alpha;
     this.Beta  = beta;
 }