Hadamard Gate

QSharp

On this page:

The Hadamard Gate

The Hadamard gate acts on a single qubit. It maps the basis state |0› to (|0› + |1›)/SQRT(2) and |1› to (|0› - |1›)/SQRT(2). The Hadamard gate is represented by the following matrix:

The Hadamard matrix

Let R = 1 / SQRT(2)

The Hadamard matrix

* Note the presence of a coefficient.

//	One-line notation
{{1, 1}, {1, -1}}

//	Expanded notation
{
{1, 1},
{1,-1}
}

* Note that the coefficient has been ommitted from the above one-line and expanded notation. This is for brevity only, and must be taken into account in all calculations.

Manipulation of a register takes the form of matrix algebra. In order for the mathematics to take place, matricies of appropriate size must be constructed. This can be a tedious and time consuming process.

Thankfully, there is an easier way to compute these outcomes, as will be demonstrated.

If you are unfamiliar with either tensor products or matrix multiplication, then I would suggest revising those topics first, otherwise a lot of this will look like magic.

Syntax

The Quantum Console syntax for this operation is:

H(n);

Where n specifies the number (or index) of the qubit we wish to manipulate.

* Note that this index is 0 based, not 1 based as represented in most examples.

1 Qubit Register

Performing this calculation on a single qubit is fairly straight forward, as the rules for matrix multiplication (number of columns from matrix A must match the number of rows from matrix B) are satisfied.

In other words, the number of columns in the Hadamard matrix match the number of rows in the state vector.

Matrix mathematics

{
{1, 1},
{1,-1}
}
*
{
{0.884A|0›},
{0.468B|1›}
}
=
Show intermediate working
{
{0.956A|0›}
{0.294B|1›},
}
Show amplitude values

* Note that for these examples, it is necessary to include state vector element coefficients in order to track state vector modification.

* Note that in these examples, only the first three decimal places are displayed, however the default precision is that of the System.Double type, a 64 bit floating point value type.

Performing the operation in Quantum Console

//	Qubits
(A|0› + B|1›)

//	Computational Basis States - Input
0.884A|0› + 0.468B|1›

//	Quantum Console syntax
//	Apply H to qubit 0
H(0);

//	Computational Basis States - Ouput
0.956A|0› + 0.294B|1›

2 Qubit Register

Performing this calculation becomes a little bit trickier, as our state vector is now larger (2n, n = 2) at 4 rows.

Consequently, as the state vector now has 4 rows, so an H gate cannot be applied to it, as the number of columns from matrix A (2) does not match the number of rows from matrix B (4).

To work around this, it is necessary to tensor an I (identity) matrix for each other qubit in order to construct the matrix of the appropriate size.

In this example, the H gate is applied to the qubit in position 1, and as the identity matrices are inferred, the operation could be written as:

IH

If the H gate was to be applied to the qubit in position 0, and as the identity matrices are inferred, the operation could be written as:

HI

Matrix mathematics

First, tensor the gate with an identity matrix:

{
{1, 1},
{1,-1}
}
(x)
{
{1, 0},
{0, 1}
}
=
{
{1, 0, 1, 0}
{0, 1, 0, 1}
{1, 0,-1, 0}
{0, 1, 0,-1}
}

This 'steps up' the H gate to be appropriately sized for the state vector. Don't forget that our coefficient R is sitting out the front of this matrix.

Now the result can be applied to the state vector:

{
{1, 0, 1, 0}
{0, 1, 0, 1}
{1, 0,-1, 0}
{0, 1, 0,-1}
}
*
{
{0.303AC|00›},
{0.365AD|01›},
{0.563BC|10›},
{0.677BD|11›}
}
=
Show intermediate working
{
{ 0.612AC|00›},
{ 0.736AD|01›},
{-0.184BC|10›},
{-0.221BD|11›}
}

Performing the operation in Quantum Console

//	Qubits
(A|0› + B|1›) (x) (C|0› + D|1›)

//	Computational Basis States - Input
0.303AC|00› + 0.365AD|01› + 0.563BC|10› + 0.677BD|11›

//	Quantum Console syntax
//	Apply H to qubit 1
H(1);

//	Computational Basis States - Ouput
0.612AC|00› + 0.736AD|01› + -0.184BC|10› + -0.221BD|11›

3 Qubit Register

This time, the state vector is larger again (2n, n = 3), at 8 rows, and due to this an H gate cannot be applied as the number of columns from matrix A (2) does not match the number of rows from matrix B (8).

To work around this, as before, tensor an I (identity) matrix for each qubit involved that is not being manipulated in order to construct the matrix of the appropriate size.

In this example, the H gate is applied to the qubit in position 1, and as the identity matrices are inferred, the operation could be written as:

IHI

If the H gate was to be applied to the qubit in position 0, and as the identity matrices are inferred, the operation could be written as:

HII

Matrix mathematics

Tensor the gate with an identity.

Tensor products are produced by applying the left matrix to the right. So in this instance, the I is applied to the X first, then IX to I.

I (step 1: tensor) H (step 2: tensor) I

{
{1, 1},
{1,-1}
}
(x)
{
{1, 0},
{0, 1}
}
=
{
{1, 0, 1, 0}
{0, 1, 0, 1}
{1, 0,-1, 0}
{0, 1, 0,-1}
}

Tensor the product with another identity:

{
{1, 0, 1, 0}
{0, 1, 0, 1}
{1, 0,-1, 0}
{0, 1, 0,-1}
}
(x)
{
{1, 0},
{0, 1}
}
=
{
{1, 0, 1, 0, 0, 0, 0, 0}
{0, 1, 0, 1, 0, 0, 0, 0}
{1, 0,-1, 0, 0, 0, 0, 0}
{0, 1, 0,-1, 0, 0, 0, 0}
{0, 0, 0, 0, 1, 0, 1, 0}
{0, 0, 0, 0, 0, 1, 0, 1}
{0, 0, 0, 0, 1, 0,-1, 0}
{0, 0, 0, 0, 0, 1, 0,-1}
}

The matrix is now the correct size to be applied to the state vector:

{
{1, 0, 1, 0, 0, 0, 0, 0}
{0, 1, 0, 1, 0, 0, 0, 0}
{1, 0,-1, 0, 0, 0, 0, 0}
{0, 1, 0,-1, 0, 0, 0, 0}
{0, 0, 0, 0, 1, 0, 1, 0}
{0, 0, 0, 0, 0, 1, 0, 1}
{0, 0, 0, 0, 1, 0,-1, 0}
{0, 0, 0, 0, 0, 1, 0,-1}
}
*
{
{0.048ACE|000›},
{0.099ACF|001›},
{0.256ADE|010›},
{0.525ADF|011›},
{0.065BCE|100›},
{0.134BCF|101›},
{0.347BDE|110›},
{0.710BDF|111›}
}
=
Show intermediate working
{
{ 0.215ACE|000›},
{ 0.441ACF|001›},
{-0.147ADE|010›},
{-0.302ADF|011›},
{ 0.291BCE|100›},
{ 0.596BCF|101›},
{-0.199BDE|110›},
{-0.408BDF|111›}
}

Performing the operation in Quantum Console

//	Qubits
(A|0› + B|1›) (x) (C|0› + D|1›) (x) (E|0› + F|1›)

//	Computational Basis States - Input
0.048ACE|000› + 0.099ACF|001› + 0.256ADE|010› + 0.525ADF|011› + 0.065BCE|100› + 0.134BCF|101› + 0.347BDE|110› + 0.710BDF|111›

//	Quantum Console syntax
//	Apply H to qubit 1
H(1);

//	Computational Basis States - Ouput
0.215ACE|000› + 0.441ACF|001› + -0.147ADE|010› + -0.302ADF|011› + 0.291BCE|100› + 0.596BCF|101› + -0.199BDE|110› + -0.408BDF|111›

n Qubit Register

As you can see from the previous examples, performing manual matrix arthimetic for each step becomes tedious and time consuming, however it is important to acknowledge that this process takes place in the first instance.

Thankfully, there is a much simpler way of working out these operations as we shall discover for an n qubit register.

Suppose an H gate is to be applied to qubit 1 in a register, as with the previous examples.

For a 2 qubit system, apply the H logic to the each bit indicated in the operation. H(1) for example, applies an H gate to every bit in position 1.

//	State vector
|ψ› = (0.303AC|00› + 0.365AD|01› + 0.563BC|10› + 0.677BD|11›)

//	1 bit positions bolded - these are the bits that will be affected by the X operation
(0.303AC|00› + 0.365AD|01› + 0.563BC|10› + 0.677BD|11›)

//	Apply the H to every bit that occupies the 1 position
H(1);

//	State vector - compare this to the matrix calculations above
|ψ› = (0.612AC|00› + 0.736AD|01› + -0.184BC|10› + -0.221BD|11›)

Using the same methodology on a larger system reduces the amount of manual work. For a 3 qubit register:

//	State vector
|ψ› = (0.048ACE|000› + 0.099ACF|001› + 0.256ADE|010› + 0.525ADF|011› + 0.065BCE|100› + 0.134BCF|101› + 0.347BDE|110› + 0.710BDF|111›)

//	1 bit positions bolded
(0.048ACE|000› + 0.099ACF|001› + 0.256ADE|010› + 0.525ADF|011› + 0.065BCE|100› + 0.134BCF|101› + 0.347BDE|110› + 0.710BDF|111›)

//	Apply the H to every bit that occupies the 1 position
H(1);

//	State vector - compare this to the matrix calculations above
|ψ› = (0.215ACE|000› + 0.441ACF|001› + -0.147ADE|010› + -0.302ADF|011› + 0.291BCE|100› + 0.596BCF|101› + -0.199BDE|110› + -0.408BDF|111›)

The Column Method

You might find that using the column method is easier and faster - it took a while for me to develop, but now I find it easier to use than other methods.

To use the column method:

  1. Write the state vector vertically down the page
  2. Write an index over each bit column
  3. Write the gate over the bit to be operated on
  4. Now, work out the result of the operation, one element at a time, and write these into a new column

Applying the column method to the 3 qubit example from above:

//	H(1);
//	Apply the H gate, one element at a time

 H
012

000  000	//	Remember the H takes 0 to 0 and 1 to 1 (there are also other operations to consider)
001  001	//	As such, the order of vector elements remains unchanged
010  010
011  011
100  100
101  101
110  110
111  111

Now, all that is left is to take the values from the left column and plug them into the right column:

     H
    012

ACE|000  ACE|000
ACF|001  ACF|001
ADE|010  ADE|010
ADF|011  ADF|011
BCE|100  BCE|100
BCF|101  BCF|101
BDE|110  BDE|110
BDF|111  BDF|111

No adjustement of the state vector (using the binary index) to match the new order is required, as the ordering of element is unchanged.

The manipulation of the state vector is now complete.


 

Copyright © 2024 carlbelle.com