{ "cells": [ { "cell_type": "markdown", "id": "651d4174", "metadata": {}, "source": [ "## mat_maker" ] }, { "cell_type": "markdown", "id": "e7dc0741", "metadata": {}, "source": [ "### **Outline**\n", "This function generates the matrix that sets the coefficients of the linear combination into the ancillary qubit part.\\\n", "Since the matrix used in the quantum circuit must be unitary, the construction process is nontrivial; however, by simply providing the first column elements and the corresponding coefficients, the function automatically generates a valid unitary matrix." ] }, { "cell_type": "markdown", "id": "7141942c", "metadata": {}, "source": [ "### **Index List**\n", "|argument name|type|role|\n", "|---|---|---|\n", "|elelist|list(element:float)|Coefficient List for the Linear Combination|\n", "|coeff_list|list(element:float)|Parameters Used in Matrix Computation|" ] }, { "cell_type": "markdown", "id": "7246a4aa", "metadata": {}, "source": [ "### **Return**\n", "mat_ele_list(np.array):\\\n", "`np.array` storing the generated unitary matrix (elements of type float)." ] }, { "cell_type": "markdown", "id": "eaf17109", "metadata": {}, "source": [ "### **Python code**\n", "```python\n", "def mat_maker(elelist, coeff_lst):\n", " mat_ele_list = []\n", " # append the first colum of the desired matrix\n", " mat_ele_list.append(elelist)\n", " # search the border between non-zero elements and zero elements\n", " for i in range(len(elelist)//2):\n", " zero_num = i*2\n", " if np.abs(elelist[i*2]) == 0: \n", " break\n", " if elelist[zero_num] != 0:\n", " zero_num = len(elelist)\n", " # copy list of coeffcients to use \".reverse()\"\n", " cf_copy = copy.deepcopy(coeff_lst)\n", " cf_copy.reverse()\n", " for i in range(len(coeff_lst)):\n", " # copy elements of matrix, this copy will be append to returned matrix after some process\n", " mat_copy = copy.deepcopy(mat_ele_list)\n", " for j in range(len(mat_copy)):\n", " # calculate non-zero elements of unitary matrix as list\n", " app_list = vec_make(mat_copy[j], cf_copy[i])\n", " # append elemnets zero to list of non-zero elements\n", " if i < (len(coeff_lst) - 1.1):\n", " if zero_num < (len(elelist) - 0.1):\n", " if zero_num%2**(i+2) != 0:\n", " input_ele = 0\n", " for s in range(2**(i+1) + 2*j):\n", " input_ele += mat_copy[i][(zero_num//(2**(i+2)))*(2**(i+2)) + s]**2\n", " app_list[(zero_num//(2**(i+2)))*(2**(i+2)) + s] = 0\n", " app_list[zero_num] = np.sqrt(input_ele)\n", " zero_num += 2\n", " mat_ele_list.append(np.array(app_list))\n", " base_mat = [[0, -1], [1, 0]]\n", " unit = np.eye(2)\n", " convert = np.kron(unit, base_mat)\n", " # exchange ith line and i+1th line (i = 0, 1, 2, ..., len(coeff_lst) - 1) \n", " for i in range(len(coeff_lst) - 1):\n", " convert = np.kron(unit, convert)\n", " mel_len = len(mat_ele_list)\n", " if (np.log2(len(elelist)) > 1):\n", " for i in range(mel_len):\n", " mat_ele_list.append(np.dot(convert, mat_ele_list[i]))\n", " if (np.log2(len(elelist)) < 1.1):\n", " mat_ele_list = [[elelist[0], elelist[1]], [elelist[1], -elelist[0]]]\n", " # transpose the matrix to make it the optimal shape for sandwiching between quantum states\n", " return np.array(mat_ele_list).T\n", "```" ] }, { "cell_type": "markdown", "id": "55ecf79c", "metadata": {}, "source": [ "### **Sample Run**" ] }, { "cell_type": "code", "execution_count": null, "id": "05eb3252", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pitbe" ] }, { "cell_type": "code", "execution_count": null, "id": "7ecbeea7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0.5 -0.3782 -0.3372 0.255 -0.433 0.3275 0.292 -0.2209]\n", " [ 0.433 -0.3275 -0.292 0.2209 0.5 -0.3782 -0.3372 0.255 ]\n", " [ 0.25 0.3305 -0.1686 -0.2229 -0.433 -0.5724 0.292 0.386 ]\n", " [ 0.433 0.5724 -0.292 -0.386 0.25 0.3305 -0.1686 -0.2229]\n", " [ 0.433 0. 0.6421 0. -0.3536 0. -0.5244 0. ]\n", " [ 0.3536 0. 0.5244 0. 0.433 0. 0.6421 0. ]\n", " [ 0. 0.559 0. 0.8291 0. 0. 0. 0. ]\n", " [ 0. 0. 0. 0. 0. 0.559 0. 0.8291]]\n" ] } ], "source": [ "ele_lst = [0.5, 0.433, 0.25, 0.433, 0.433, 0.3536, 0., 0.]\n", "cf_lst = [[1.483], [1.322, 0.5590]]\n", "unit_mat = pitbe.mat_maker(ele_lst, cf_lst)\n", "print(np.round(unit_mat, 4))" ] }, { "cell_type": "markdown", "id": "7ae70190", "metadata": {}, "source": [ "The unitarity of the constructed matrix can be verified as follows." ] }, { "cell_type": "code", "execution_count": null, "id": "168702dd", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.0\n", "1.0\n", "1.0\n", "1.0\n", "1.0\n", "1.0\n", "1.0\n", "1.0\n" ] } ], "source": [ "# Norm of all eigenvalues are one.\n", "eigenvalue = np.linalg.eig(unit_mat)[0]\n", "for i in range(len(eigenvalue)):\n", " print(np.round(np.linalg.norm(eigenvalue[i]), 3))" ] }, { "cell_type": "code", "execution_count": null, "id": "efbb4121", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1. -0. -0. 0. 0. 0. -0. -0.]\n", " [-0. 1. 0. 0. 0. 0. 0. 0.]\n", " [-0. 0. 1. -0. 0. 0. 0. 0.]\n", " [ 0. 0. -0. 1. 0. 0. -0. 0.]\n", " [ 0. 0. 0. 0. 1. -0. -0. 0.]\n", " [ 0. 0. 0. 0. -0. 1. 0. 0.]\n", " [-0. 0. 0. -0. -0. 0. 1. -0.]\n", " [-0. 0. 0. 0. 0. 0. -0. 1.]]\n" ] } ], "source": [ "# The product with the complex conjugate of the matrix is the identity matrix. \n", "print(np.round(np.dot(unit_mat.T, unit_mat), 3))" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }