mirror of
https://github.com/libquantum/libquantum.git
synced 2025-10-03 08:42:01 +00:00
updated libquantum 0.2.0 source files
This commit is contained in:
10
CHANGES
10
CHANGES
@@ -1,3 +1,13 @@
|
|||||||
|
libquantum 0.2.0:
|
||||||
|
- Added Quantum Error Correction
|
||||||
|
- Included an Implementation of Grover's algorithm
|
||||||
|
- Added some inverse functions and conditional phase kick
|
||||||
|
- Improved speed of the decoherence simulation
|
||||||
|
- Fixed a memory leak in the quantum register deletion routine
|
||||||
|
- Fixed a segfault in the sigma functions
|
||||||
|
- Fixed a typo in the configure script that could result in a build
|
||||||
|
failure
|
||||||
|
|
||||||
libquantum 0.1.1:
|
libquantum 0.1.1:
|
||||||
- Completed rotation gates (quantum_r_z)
|
- Completed rotation gates (quantum_r_z)
|
||||||
- Fixed a build problem with the demo program
|
- Fixed a build problem with the demo program
|
||||||
|
25
INSTALL
25
INSTALL
@@ -1,4 +1,4 @@
|
|||||||
libquantum 0.1.1 installation guide
|
libquantum 0.2.0 installation guide
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
@@ -37,16 +37,24 @@ Now you can build the beast:
|
|||||||
|
|
||||||
make
|
make
|
||||||
|
|
||||||
By now, you can create a sample program which implements Shor's
|
By now, you can create two demo programs which show Shor's factoring
|
||||||
factoring algorithm:
|
algorithm and Grover's search algorithm:
|
||||||
|
|
||||||
make shor
|
make demos
|
||||||
|
|
||||||
The number to be factored is given on the command line as the first
|
For the Shor algorithm demo, the number to be factored is given on the
|
||||||
parameter. To factor 15, simply type:
|
command line as the first parameter. To factor 15, simply type:
|
||||||
|
|
||||||
./shor 15
|
./shor 15
|
||||||
|
|
||||||
|
The demo for Grover's algorithm requires the number of the marked
|
||||||
|
element (i.e. the desired result of the search) as the first argument
|
||||||
|
on the command line. The number of qubits may be given as a second
|
||||||
|
arguments. To mark element No. 42 in a database of 10 qubits (which
|
||||||
|
means 2^10 = 1024 elements):
|
||||||
|
|
||||||
|
./grover 42 10
|
||||||
|
|
||||||
|
|
||||||
2. Installation of the library
|
2. Installation of the library
|
||||||
------------------------------
|
------------------------------
|
||||||
@@ -57,8 +65,9 @@ For this step you will need to have superuser privileges. Just type
|
|||||||
|
|
||||||
to get libquantum installed into the default directory, which is
|
to get libquantum installed into the default directory, which is
|
||||||
usually /usr/local/bin. Note that on some systems this directories is
|
usually /usr/local/bin. Note that on some systems this directories is
|
||||||
not in the standard search path. Take a look at the output of the last
|
not in the standard search path for libraries. Take a look at the
|
||||||
command to get some advice on how to deal with this.
|
output of the last command to get some advice on how to deal with
|
||||||
|
this.
|
||||||
|
|
||||||
3. Writing your own programs
|
3. Writing your own programs
|
||||||
----------------------------
|
----------------------------
|
||||||
|
33
Makefile.in
33
Makefile.in
@@ -36,29 +36,29 @@ top_builddir=.
|
|||||||
# Release information
|
# Release information
|
||||||
|
|
||||||
MAJOR=0
|
MAJOR=0
|
||||||
MINOR=1
|
MINOR=2
|
||||||
RELEASE=1
|
RELEASE=0
|
||||||
|
|
||||||
# Tools needed to build libquantum
|
# Tools needed to build libquantum
|
||||||
|
|
||||||
CC=@CC@
|
CC=@CC@ -O2 -g -pg
|
||||||
INSTALL=@INSTALL@
|
INSTALL=@INSTALL@
|
||||||
LIBTOOL=@LIBTOOL@
|
LIBTOOL=@LIBTOOL@
|
||||||
|
|
||||||
# Flags passed to C compiler
|
# Flags passed to C compiler
|
||||||
|
|
||||||
CFLAGS=@CFLAGS@
|
CFLAGS=@CFLAGS@
|
||||||
LDFLAGS=-rpath $(LIBDIR) -version-info 1:1:1
|
LDFLAGS=-rpath $(LIBDIR) -version-info 2:0:2
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
all: libquantum.la
|
all: libquantum.la
|
||||||
|
|
||||||
libquantum.la: complex.lo measure.lo matrix.lo gates.lo qft.lo classic.lo\
|
libquantum.la: complex.lo measure.lo matrix.lo gates.lo qft.lo classic.lo\
|
||||||
qureg.lo decoherence.lo oaddn.lo omuln.lo expn.lo Makefile
|
qureg.lo decoherence.lo oaddn.lo omuln.lo expn.lo qec.lo Makefile
|
||||||
$(LIBTOOL) $(CC) $(LDFLAGS) -o libquantum.la complex.lo measure.lo\
|
$(LIBTOOL) $(CC) $(LDFLAGS) -o libquantum.la complex.lo measure.lo\
|
||||||
matrix.lo gates.lo oaddn.lo omuln.lo expn.lo qft.lo classic.lo\
|
matrix.lo gates.lo oaddn.lo omuln.lo expn.lo qft.lo classic.lo\
|
||||||
qureg.lo decoherence.lo -lm
|
qureg.lo decoherence.lo qec.lo -lm
|
||||||
|
|
||||||
complex.lo: complex.c complex.h Makefile
|
complex.lo: complex.c complex.h Makefile
|
||||||
$(LIBTOOL) $(CC) $(CFLAGS) -c complex.c
|
$(LIBTOOL) $(CC) $(CFLAGS) -c complex.c
|
||||||
@@ -90,21 +90,30 @@ classic.lo: classic.c classic.h Makefile
|
|||||||
qureg.lo: qureg.c qureg.h matrix.h config.h complex.h Makefile
|
qureg.lo: qureg.c qureg.h matrix.h config.h complex.h Makefile
|
||||||
$(LIBTOOL) $(CC) $(CFLAGS) -c qureg.c
|
$(LIBTOOL) $(CC) $(CFLAGS) -c qureg.c
|
||||||
|
|
||||||
decoherence.lo: decoherence.c decoherence.h measure.h gates.h qureg.h config.h\
|
decoherence.lo: decoherence.c decoherence.h measure.h gates.h qureg.h\
|
||||||
Makefile
|
complex.h config.h Makefile
|
||||||
$(LIBTOOL) $(CC) $(CFLAGS) -c decoherence.c
|
$(LIBTOOL) $(CC) $(CFLAGS) -c decoherence.c
|
||||||
|
|
||||||
|
qec.lo: qec.c qec.h gates.h qureg.h config.h Makefile
|
||||||
|
$(LIBTOOL) $(CC) $(CFLAGS) -c qec.c
|
||||||
|
|
||||||
# Bring this savage back home
|
# Bring this savage back home
|
||||||
|
|
||||||
install: libquantum.la
|
install: libquantum.la
|
||||||
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
|
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
|
||||||
$(INSTALL) -m 0644 quantum.h $(INCLUDEDIR)
|
$(INSTALL) -m 0644 quantum.h $(INCLUDEDIR)
|
||||||
|
|
||||||
# Build a demo showing Shor's factoring algorithm
|
# Build demos of Shor's and Grover's algorithms
|
||||||
|
|
||||||
|
demos: shor grover
|
||||||
|
|
||||||
shor: libquantum.la shor.c Makefile
|
shor: libquantum.la shor.c Makefile
|
||||||
$(LIBTOOL) $(CC) $(CFLAGS) -o shor shor.c -I./ -lquantum -static -lm
|
$(LIBTOOL) $(CC) $(CFLAGS) -o shor shor.c -I./ -lquantum -static -lm
|
||||||
|
|
||||||
|
grover: libquantum.la grover.c Makefile
|
||||||
|
$(LIBTOOL) $(CC) $(CFLAGS) -o grover grover.c -I./ -lquantum -static\
|
||||||
|
-lm
|
||||||
|
|
||||||
# Make everything neat and tidy
|
# Make everything neat and tidy
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@@ -119,9 +128,9 @@ distclean:
|
|||||||
dist:
|
dist:
|
||||||
-rm quantum.h config.h
|
-rm quantum.h config.h
|
||||||
mkdir libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
mkdir libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||||
cp *.c *.h quantum.h.in Makefile.in config.h.in configure COPYING\
|
cp *.c *.h quantum.h.in Makefile.in config.h.in configure configure.in\
|
||||||
install-sh ltmain.sh config.sub config.guess README INSTALL CHANGES\
|
COPYING install-sh ltmain.sh config.sub config.guess README INSTALL\
|
||||||
libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
CHANGES libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||||
tar czf libquantum-$(MAJOR).$(MINOR).$(RELEASE).tar.gz\
|
tar czf libquantum-$(MAJOR).$(MINOR).$(RELEASE).tar.gz\
|
||||||
libquantum-$(MAJOR).$(MINOR).$(RELEASE)/
|
libquantum-$(MAJOR).$(MINOR).$(RELEASE)/
|
||||||
rm -rf libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
rm -rf libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||||
|
12
README
12
README
@@ -1,4 +1,4 @@
|
|||||||
libquantum 0.1.1 README file
|
libquantum 0.2.0 README file
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
libquantum is a C library for quantum computing. It provides quantum
|
libquantum is a C library for quantum computing. It provides quantum
|
||||||
@@ -6,16 +6,16 @@ registers, unitary operations and measurement functions. The main goal
|
|||||||
is a physically precise simulation of a quantum computer with high
|
is a physically precise simulation of a quantum computer with high
|
||||||
performance.
|
performance.
|
||||||
|
|
||||||
An implementation of Shor's factoring algorithm is included with this
|
Implementations of Shor's factoring algorithm and Grover's search
|
||||||
release.
|
algorithm are included with this release.
|
||||||
|
|
||||||
See the file INSTALL for help on the installation.
|
See the file INSTALL for help on the installation.
|
||||||
|
|
||||||
guardian is distributed under the terms of the GNU General Public
|
libquantum is distributed under the terms of the GNU General Public
|
||||||
License (GPL), which is located in the file COPYING.
|
License (GPL), which is located in the file COPYING.
|
||||||
|
|
||||||
Send inquiries, comments, bug reports, suggestions, patches, etc. to:
|
Send inquiries, comments, bug reports, suggestions, patches, etc. to:
|
||||||
libquantum@enyo.de
|
libquantum@enyo.de
|
||||||
|
|
||||||
See also the guardian website:
|
See also the libquantum website:
|
||||||
http://www.enyo.de/libquantum
|
http://www.enyo.de/libquantum
|
||||||
|
@@ -3,6 +3,9 @@
|
|||||||
/* Complex data type */
|
/* Complex data type */
|
||||||
#undef COMPLEX_FLOAT
|
#undef COMPLEX_FLOAT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
#undef HAVE_FCNTL_H
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
21
configure
vendored
21
configure
vendored
@@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.57 for libquantum 0.1.1.
|
# Generated by GNU Autoconf 2.57 for libquantum 0.2.0.
|
||||||
#
|
#
|
||||||
# Report bugs to <libquantum@enyo.de>.
|
# Report bugs to <libquantum@enyo.de>.
|
||||||
#
|
#
|
||||||
@@ -427,8 +427,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='libquantum'
|
PACKAGE_NAME='libquantum'
|
||||||
PACKAGE_TARNAME='libquantum'
|
PACKAGE_TARNAME='libquantum'
|
||||||
PACKAGE_VERSION='0.1.1'
|
PACKAGE_VERSION='0.2.0'
|
||||||
PACKAGE_STRING='libquantum 0.1.1'
|
PACKAGE_STRING='libquantum 0.2.0'
|
||||||
PACKAGE_BUGREPORT='libquantum@enyo.de'
|
PACKAGE_BUGREPORT='libquantum@enyo.de'
|
||||||
|
|
||||||
ac_unique_file="classic.c"
|
ac_unique_file="classic.c"
|
||||||
@@ -938,7 +938,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures libquantum 0.1.1 to adapt to many kinds of systems.
|
\`configure' configures libquantum 0.2.0 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@@ -999,7 +999,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of libquantum 0.1.1:";;
|
short | recursive ) echo "Configuration of libquantum 0.2.0:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@@ -1092,7 +1092,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit 0
|
test -n "$ac_init_help" && exit 0
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
libquantum configure 0.1.1
|
libquantum configure 0.2.0
|
||||||
generated by GNU Autoconf 2.57
|
generated by GNU Autoconf 2.57
|
||||||
|
|
||||||
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
|
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
|
||||||
@@ -1107,7 +1107,7 @@ cat >&5 <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by libquantum $as_me 0.1.1, which was
|
It was created by libquantum $as_me 0.2.0, which was
|
||||||
generated by GNU Autoconf 2.57. Invocation command line was
|
generated by GNU Autoconf 2.57. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@@ -7877,7 +7877,7 @@ if test $ac_cv_type_uint_64t = yes; then
|
|||||||
#define MAX_UNSIGNED uint_64t
|
#define MAX_UNSIGNED uint_64t
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
MU_TYPE="unint_64t"
|
MU_TYPE="uint_64t"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$MU_TYPE" = "none"
|
if test "$MU_TYPE" = "none"
|
||||||
@@ -8620,7 +8620,7 @@ _ASBOX
|
|||||||
} >&5
|
} >&5
|
||||||
cat >&5 <<_CSEOF
|
cat >&5 <<_CSEOF
|
||||||
|
|
||||||
This file was extended by libquantum $as_me 0.1.1, which was
|
This file was extended by libquantum $as_me 0.2.0, which was
|
||||||
generated by GNU Autoconf 2.57. Invocation command line was
|
generated by GNU Autoconf 2.57. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@@ -8680,7 +8680,7 @@ _ACEOF
|
|||||||
|
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF
|
cat >>$CONFIG_STATUS <<_ACEOF
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
libquantum config.status 0.1.1
|
libquantum config.status 0.2.0
|
||||||
configured by $0, generated by GNU Autoconf 2.57,
|
configured by $0, generated by GNU Autoconf 2.57,
|
||||||
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
|
||||||
|
|
||||||
@@ -9358,4 +9358,3 @@ if test "$no_create" != yes; then
|
|||||||
# would make configure fail if this is the last instruction.
|
# would make configure fail if this is the last instruction.
|
||||||
$ac_cs_success || { (exit 1); exit 1; }
|
$ac_cs_success || { (exit 1); exit 1; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
79
configure.in
Normal file
79
configure.in
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
AC_INIT([libquantum], [0.2.0], [libquantum@enyo.de])
|
||||||
|
AC_CONFIG_SRCDIR([classic.c])
|
||||||
|
AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
|
# The language of our choice
|
||||||
|
AC_LANG([C])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_INSTALL
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
# FIXME: Replace `main' with a function in `-lm':
|
||||||
|
AC_CHECK_LIB([m], [sqrt])
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS([fcntl.h stdlib.h unistd.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_INLINE
|
||||||
|
|
||||||
|
# Check for 64-bit integer
|
||||||
|
MU_TYPE="none"
|
||||||
|
AC_CHECK_TYPE([uint_64t], [AC_DEFINE([MAX_UNSIGNED], [uint_64t])
|
||||||
|
MU_TYPE="uint_64t"])
|
||||||
|
if test "$MU_TYPE" = "none"
|
||||||
|
then
|
||||||
|
AC_CHECK_TYPE([u_int_64t], [AC_DEFINE([MAX_UNSIGNED], [u_int_64t])
|
||||||
|
MU_TYPE="u_int_64t"])
|
||||||
|
fi
|
||||||
|
if test "$MU_TYPE" = "none"
|
||||||
|
then
|
||||||
|
AC_CHECK_TYPE([unsigned long long], [AC_DEFINE(MAX_UNSIGNED,
|
||||||
|
[unsigned long long], [Integer type for quantum registers])
|
||||||
|
MU_TYPE="unsigned long long"])
|
||||||
|
fi
|
||||||
|
if test "$MU_TYPE" = "none"
|
||||||
|
then
|
||||||
|
AC_MSG_ERROR([No 64-bit integer type!])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for complex number type
|
||||||
|
CF_TYPE="none"
|
||||||
|
AC_CHECK_TYPE([float _Complex], [AC_DEFINE([COMPLEX_FLOAT], [float _Complex])
|
||||||
|
CF_TYPE="float _Complex"])
|
||||||
|
if test "$CF_TYPE" = "none"
|
||||||
|
then
|
||||||
|
AC_CHECK_TYPE([__complex__ float], [AC_DEFINE([COMPLEX_FLOAT],
|
||||||
|
[__complex__ float], [Complex data type])
|
||||||
|
CF_TYPE="__complex__ float"])
|
||||||
|
fi
|
||||||
|
if test "$CF_TYPE" = "none"
|
||||||
|
then
|
||||||
|
AC_MSG_ERROR([No complex number type!])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for the imaginary unit
|
||||||
|
AC_MSG_CHECKING([for the imaginary unit])
|
||||||
|
I="none"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=I;])],
|
||||||
|
[AC_DEFINE([IMAGINARY], [I], [Imaginary unit]) I="I"])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=_Complex_I;])],
|
||||||
|
[AC_DEFINE([IMAGINARY], [_Complex_I]) I="_Complex_I"])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=1i;])],
|
||||||
|
[AC_DEFINE([IMAGINARY], [1i]) I="1i"])
|
||||||
|
if test $I = "none"
|
||||||
|
then
|
||||||
|
AC_MSG_ERROR([No imaginary unit!])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($I)
|
||||||
|
|
||||||
|
AC_SUBST(MU_TYPE)
|
||||||
|
AC_SUBST(CF_TYPE)
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile quantum.h])
|
||||||
|
AC_OUTPUT
|
@@ -40,6 +40,12 @@ int status = 0;
|
|||||||
|
|
||||||
float lambda = 0;
|
float lambda = 0;
|
||||||
|
|
||||||
|
float
|
||||||
|
quantum_get_decoherence()
|
||||||
|
{
|
||||||
|
return lambda;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the decoherence simulation and set the decoherence
|
/* Initialize the decoherence simulation and set the decoherence
|
||||||
parameter. */
|
parameter. */
|
||||||
|
|
||||||
@@ -63,7 +69,8 @@ void
|
|||||||
quantum_decohere(quantum_reg *reg)
|
quantum_decohere(quantum_reg *reg)
|
||||||
{
|
{
|
||||||
float u, v, s, x;
|
float u, v, s, x;
|
||||||
COMPLEX_FLOAT c0, c1;
|
float *nrands;
|
||||||
|
float angle;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
/* Increase the gate counter */
|
/* Increase the gate counter */
|
||||||
@@ -72,9 +79,19 @@ quantum_decohere(quantum_reg *reg)
|
|||||||
|
|
||||||
if(status)
|
if(status)
|
||||||
{
|
{
|
||||||
for(j=0; j<reg->width; j++)
|
|
||||||
|
nrands = calloc(reg->width, sizeof(float));
|
||||||
|
if(!nrands)
|
||||||
{
|
{
|
||||||
/* Generate a normal distributed random number */
|
printf("Not enough memory for %i-sized array of float!\n",
|
||||||
|
reg->width);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
quantum_memman(reg->width * sizeof(float));
|
||||||
|
|
||||||
|
for(i=0; i<reg->width; i++)
|
||||||
|
{
|
||||||
|
/* Generate normal distributed random numbers */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
u = 2 * quantum_frand() - 1;
|
u = 2 * quantum_frand() - 1;
|
||||||
@@ -85,20 +102,30 @@ quantum_decohere(quantum_reg *reg)
|
|||||||
x = u * sqrt(-2 * log(s) / s);
|
x = u * sqrt(-2 * log(s) / s);
|
||||||
|
|
||||||
x *= sqrt(2 * lambda);
|
x *= sqrt(2 * lambda);
|
||||||
|
|
||||||
/* Apply the phase shift gate for decoherence simulation */
|
|
||||||
|
|
||||||
c0 = quantum_cexp(-x / 2);
|
nrands[i] = x/2;
|
||||||
c1 = quantum_cexp(x / 2);
|
}
|
||||||
|
|
||||||
for(i=0; i<reg->size; i++)
|
|
||||||
|
/* Apply the phase shifts for decoherence simulation */
|
||||||
|
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
angle = 0;
|
||||||
|
|
||||||
|
for(j=0; j<reg->width; j++)
|
||||||
{
|
{
|
||||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << j))
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << j))
|
||||||
reg->node[i].amplitude *= c1;
|
angle += nrands[j];
|
||||||
|
|
||||||
else
|
else
|
||||||
reg->node[i].amplitude *= c0;
|
angle -= nrands[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg->node[i].amplitude *= quantum_cexp(angle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
free(nrands);
|
||||||
|
quantum_memman(reg->width * sizeof(float));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#define __DECOHERENCE_H
|
#define __DECOHERENCE_H
|
||||||
|
|
||||||
|
extern float quantum_get_decoherence();
|
||||||
|
|
||||||
extern void quantum_set_decoherence(float lambda);
|
extern void quantum_set_decoherence(float lambda);
|
||||||
|
|
||||||
extern void quantum_decohere(quantum_reg *reg);
|
extern void quantum_decohere(quantum_reg *reg);
|
||||||
|
185
gates.c
185
gates.c
@@ -1,4 +1,4 @@
|
|||||||
/* gates.c: Basic gates for quantum register manipulation
|
/* gates.c: Basic gates for quantum register manipulation
|
||||||
|
|
||||||
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "complex.h"
|
#include "complex.h"
|
||||||
#include "qureg.h"
|
#include "qureg.h"
|
||||||
#include "decoherence.h"
|
#include "decoherence.h"
|
||||||
|
#include "qec.h"
|
||||||
|
|
||||||
/* Apply a controlled-not gate */
|
/* Apply a controlled-not gate */
|
||||||
|
|
||||||
@@ -37,15 +38,23 @@ void
|
|||||||
quantum_cnot(int control, int target, quantum_reg *reg)
|
quantum_cnot(int control, int target, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int qec;
|
||||||
for(i=0; i<reg->size; i++)
|
|
||||||
|
quantum_qec_get_status(&qec, NULL);
|
||||||
|
|
||||||
|
if(qec)
|
||||||
|
quantum_cnot_ft(control, target, reg);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Flip the target bit of a base state if the control bit is set */
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
/* Flip the target bit of a base state if the control bit is set */
|
||||||
|
|
||||||
if((reg->node[i].state & ((MAX_UNSIGNED) 1 << control)))
|
if((reg->node[i].state & ((MAX_UNSIGNED) 1 << control)))
|
||||||
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
||||||
|
}
|
||||||
|
quantum_decohere(reg);
|
||||||
}
|
}
|
||||||
quantum_decohere(reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a toffoli (or controlled-controlled-not) gate */
|
/* Apply a toffoli (or controlled-controlled-not) gate */
|
||||||
@@ -54,21 +63,29 @@ void
|
|||||||
quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
|
quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int qec;
|
||||||
|
|
||||||
for(i=0; i<reg->size; i++)
|
quantum_qec_get_status(&qec, NULL);
|
||||||
|
|
||||||
|
if(qec)
|
||||||
|
quantum_toffoli_ft(control1, control2, target, reg);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Flip the target bit of a base state if both control bits are
|
for(i=0; i<reg->size; i++)
|
||||||
set */
|
|
||||||
|
|
||||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1))
|
|
||||||
{
|
{
|
||||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control2))
|
/* Flip the target bit of a base state if both control bits are
|
||||||
|
set */
|
||||||
|
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1))
|
||||||
{
|
{
|
||||||
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control2))
|
||||||
|
{
|
||||||
|
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
quantum_decohere(reg);
|
||||||
}
|
}
|
||||||
quantum_decohere(reg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a sigma_x (or not) gate */
|
/* Apply a sigma_x (or not) gate */
|
||||||
@@ -77,20 +94,28 @@ void
|
|||||||
quantum_sigma_x(int target, quantum_reg *reg)
|
quantum_sigma_x(int target, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int qec;
|
||||||
for(i=0; i<reg->size; i++)
|
|
||||||
{
|
|
||||||
/* Flip the target bit of each base state */
|
|
||||||
|
|
||||||
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
quantum_qec_get_status(&qec, NULL);
|
||||||
}
|
|
||||||
quantum_decohere(reg);
|
if(qec)
|
||||||
|
quantum_sigma_x_ft(target, reg);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
/* Flip the target bit of each base state */
|
||||||
|
|
||||||
|
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
||||||
|
}
|
||||||
|
quantum_decohere(reg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply a sigma_y gate */
|
/* Apply a sigma_y gate */
|
||||||
|
|
||||||
void
|
void
|
||||||
quantum_sigma_y(int target, int width, quantum_reg *reg)
|
quantum_sigma_y(int target, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -113,7 +138,7 @@ quantum_sigma_y(int target, int width, quantum_reg *reg)
|
|||||||
/* Apply a sigma_y gate */
|
/* Apply a sigma_y gate */
|
||||||
|
|
||||||
void
|
void
|
||||||
quantum_sigma_z(int target, int width, quantum_reg *reg)
|
quantum_sigma_z(int target, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -128,34 +153,49 @@ quantum_sigma_z(int target, int width, quantum_reg *reg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Swap the first WIDTH bits of the quantum register. This is done
|
/* Swap the first WIDTH bits of the quantum register. This is done
|
||||||
classically by renaming the bits. */
|
classically by renaming the bits, unless QEC is enabled. */
|
||||||
|
|
||||||
void
|
void
|
||||||
quantum_swaptheleads(int width, quantum_reg *reg)
|
quantum_swaptheleads(int width, quantum_reg *reg)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int pat1, pat2;
|
int pat1, pat2;
|
||||||
|
int qec;
|
||||||
MAX_UNSIGNED l;
|
MAX_UNSIGNED l;
|
||||||
|
|
||||||
for(i=0; i<reg->size; i++)
|
quantum_qec_get_status(&qec, NULL);
|
||||||
|
|
||||||
|
if(qec)
|
||||||
{
|
{
|
||||||
/* calculate left bit pattern */
|
for(i=0; i<width; i++)
|
||||||
|
{
|
||||||
pat1 = reg->node[i].state % ((MAX_UNSIGNED) 1 << width);
|
quantum_cnot(i, width+i, reg);
|
||||||
|
quantum_cnot(width+i, i, reg);
|
||||||
|
quantum_cnot(i, width+i, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
/* calculate left bit pattern */
|
||||||
|
|
||||||
|
pat1 = reg->node[i].state % ((MAX_UNSIGNED) 1 << width);
|
||||||
|
|
||||||
|
/*calculate right but pattern */
|
||||||
|
|
||||||
|
pat2 = 0;
|
||||||
|
|
||||||
/*calculate right but pattern */
|
for(j=0; j<width; j++)
|
||||||
|
pat2 += reg->node[i].state & ((MAX_UNSIGNED) 1 << (width + j));
|
||||||
pat2 = 0;
|
|
||||||
|
/* construct the new basis state */
|
||||||
for(j=0; j<width; j++)
|
|
||||||
pat2 += reg->node[i].state & ((MAX_UNSIGNED) 1 << (width + j));
|
l = reg->node[i].state - (pat1 + pat2);
|
||||||
|
l += (pat1 << width);
|
||||||
/* construct the new base state */
|
l += (pat2 >> width);
|
||||||
|
reg->node[i].state = l;
|
||||||
l = reg->node[i].state - (pat1 + pat2);
|
}
|
||||||
l += (pat1 << width);
|
|
||||||
l += (pat2 >> width);
|
|
||||||
reg->node[i].state = l;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +392,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quantum_delete_qureg(reg);
|
quantum_delete_qureg_hashpreserve(reg);
|
||||||
*reg = out;
|
*reg = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,6 +489,22 @@ quantum_r_z(int target, float gamma, quantum_reg *reg)
|
|||||||
quantum_decohere(reg);
|
quantum_decohere(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scale the phase of qubit */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_phase_scale(int target, float gamma, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
reg->node[i].amplitude *= quantum_cexp(gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_decohere(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Apply a phase kick by the angle GAMMA */
|
/* Apply a phase kick by the angle GAMMA */
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -485,6 +541,45 @@ quantum_cond_phase(int control, int target, quantum_reg *reg)
|
|||||||
quantum_decohere(reg);
|
quantum_decohere(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_cond_phase_inv(int control, int target, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control))
|
||||||
|
{
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
|
||||||
|
reg->node[i].amplitude
|
||||||
|
*= quantum_cexp(-pi / ((MAX_UNSIGNED) 1 << (control - target)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_decohere(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0; i<reg->size; i++)
|
||||||
|
{
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control))
|
||||||
|
{
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
|
||||||
|
reg->node[i].amplitude *= quantum_cexp(gamma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
quantum_decohere(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Increase the gate counter by INC steps or reset it if INC < 0. The
|
/* Increase the gate counter by INC steps or reset it if INC < 0. The
|
||||||
current value of the counter is returned. */
|
current value of the counter is returned. */
|
||||||
|
|
||||||
@@ -497,6 +592,6 @@ quantum_gate_counter(int inc)
|
|||||||
counter += inc;
|
counter += inc;
|
||||||
else if(inc < 0)
|
else if(inc < 0)
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
6
gates.h
6
gates.h
@@ -48,8 +48,14 @@ extern void quantum_r_z(int target, float gamma, quantum_reg *reg);
|
|||||||
extern void quantum_hadamard(int target, quantum_reg *reg);
|
extern void quantum_hadamard(int target, quantum_reg *reg);
|
||||||
extern void quantum_walsh(int target, quantum_reg *reg);
|
extern void quantum_walsh(int target, quantum_reg *reg);
|
||||||
|
|
||||||
|
extern void quantum_phase_scale(int target, float gamma, quantum_reg *reg);
|
||||||
extern void quantum_phase_kick(int target, float gamma, quantum_reg *reg);
|
extern void quantum_phase_kick(int target, float gamma, quantum_reg *reg);
|
||||||
|
|
||||||
extern void quantum_cond_phase(int control, int target, quantum_reg *reg);
|
extern void quantum_cond_phase(int control, int target, quantum_reg *reg);
|
||||||
|
extern void quantum_cond_phase_inv(int control, int target, quantum_reg *reg);
|
||||||
|
|
||||||
|
extern void quantum_cond_phase_kick(int control, int target, float gamma,
|
||||||
|
quantum_reg *reg);
|
||||||
|
|
||||||
extern int quantum_gate_counter(int inc);
|
extern int quantum_gate_counter(int inc);
|
||||||
|
|
||||||
|
183
grover.c
Normal file
183
grover.c
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/* grover.c: Implementation of Grover's search algorithm
|
||||||
|
|
||||||
|
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||||
|
|
||||||
|
This file is part of libquantum
|
||||||
|
|
||||||
|
libquantum is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 2 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
libquantum is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with libquantum; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <quantum.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define pi 3.141592654
|
||||||
|
|
||||||
|
void oracle(int state, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
{
|
||||||
|
if(!(state & (1 << i)))
|
||||||
|
{
|
||||||
|
quantum_sigma_x(i, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_toffoli(0, 1, reg->width+1, reg);
|
||||||
|
|
||||||
|
for(i=1;i<reg->width;i++)
|
||||||
|
{
|
||||||
|
quantum_toffoli(i, reg->width+i, reg->width+i+1, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_cnot(reg->width+i, reg->width, reg);
|
||||||
|
|
||||||
|
for(i=reg->width-1;i>0;i--)
|
||||||
|
{
|
||||||
|
quantum_toffoli(i, reg->width+i, reg->width+i+1, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_toffoli(0, 1, reg->width+1, reg);
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
{
|
||||||
|
if(!(state & (1 << i)))
|
||||||
|
quantum_sigma_x(i, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void inversion(quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
quantum_sigma_x(i, reg);
|
||||||
|
|
||||||
|
quantum_phase_scale(0, pi/2, reg);
|
||||||
|
quantum_hadamard(reg->width-1, reg);
|
||||||
|
|
||||||
|
if(reg->width==3)
|
||||||
|
quantum_toffoli(0, 1, 2, reg);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quantum_toffoli(0, 1, reg->width+1, reg);
|
||||||
|
|
||||||
|
for(i=1;i<reg->width-1;i++)
|
||||||
|
{
|
||||||
|
quantum_toffoli(i, reg->width+i, reg->width+i+1, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_cnot(reg->width+i, reg->width-1, reg);
|
||||||
|
|
||||||
|
for(i=reg->width-2;i>0;i--)
|
||||||
|
{
|
||||||
|
quantum_toffoli(i, reg->width+i, reg->width+i+1, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_toffoli(0, 1, reg->width+1, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_hadamard(reg->width-1, reg);
|
||||||
|
quantum_phase_scale(0, pi/2, reg);
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
quantum_sigma_x(i, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void grover(int target, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
oracle(target, reg);
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
quantum_hadamard(i, reg);
|
||||||
|
|
||||||
|
inversion(reg);
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
quantum_hadamard(i, reg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_grover(quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<reg->size;i++)
|
||||||
|
printf("%llu %f\n", reg->node[i].state, __real__ reg->node[i].amplitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
quantum_reg reg;
|
||||||
|
int i, N, width=0;
|
||||||
|
|
||||||
|
if(argc==1)
|
||||||
|
{
|
||||||
|
printf("Usage: grover [number] [[qubits]]\n\n");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
N=atoi(argv[1]);
|
||||||
|
|
||||||
|
if(argc > 2)
|
||||||
|
width = atoi(argv[2]);
|
||||||
|
|
||||||
|
if(width < quantum_getwidth(N+1))
|
||||||
|
width = quantum_getwidth(N+1);
|
||||||
|
|
||||||
|
reg = quantum_new_qureg(0, width);
|
||||||
|
|
||||||
|
quantum_sigma_x(reg.width, ®);
|
||||||
|
|
||||||
|
for(i=0;i<reg.width;i++)
|
||||||
|
quantum_hadamard(i, ®);
|
||||||
|
|
||||||
|
quantum_hadamard(reg.width, ®);
|
||||||
|
|
||||||
|
printf("Iterating %i times\n", (int) (pi/4*sqrt(1<<reg.width)));
|
||||||
|
|
||||||
|
for(i=1; i<=pi/4*sqrt(1 << reg.width); i++)
|
||||||
|
{
|
||||||
|
printf("Iteration #%i\n", i);
|
||||||
|
grover(N, ®);
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_hadamard(reg.width, ®);
|
||||||
|
|
||||||
|
reg.width++;
|
||||||
|
|
||||||
|
quantum_bmeasure(reg.width-1, ®);
|
||||||
|
|
||||||
|
for(i=0; i<reg.size; i++)
|
||||||
|
{
|
||||||
|
if(reg.node[i].state == N)
|
||||||
|
printf("\nFound %i with a probability of %f\n\n", N,
|
||||||
|
quantum_prob(reg.node[i].amplitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_delete_qureg(®);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
2
matrix.c
2
matrix.c
@@ -39,7 +39,7 @@ unsigned long quantum_memman(long change)
|
|||||||
if(mem > max)
|
if(mem > max)
|
||||||
max = mem;
|
max = mem;
|
||||||
|
|
||||||
return max;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new COLS x ROWS matrix */
|
/* Create a new COLS x ROWS matrix */
|
||||||
|
@@ -169,7 +169,7 @@ quantum_bmeasure(int pos, quantum_reg *reg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
quantum_delete_qureg(reg);
|
quantum_delete_qureg_hashpreserve(reg);
|
||||||
*reg = out;
|
*reg = out;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
280
qec.c
Normal file
280
qec.c
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
/* qec.c: Quantum Error Correction
|
||||||
|
|
||||||
|
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||||
|
|
||||||
|
This file is part of libquantum
|
||||||
|
|
||||||
|
libquantum is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 2 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
libquantum is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with libquantum; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "qureg.h"
|
||||||
|
#include "gates.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "decoherence.h"
|
||||||
|
|
||||||
|
/* Type of the QEC. Currently implemented versions are:
|
||||||
|
|
||||||
|
0: no QEC (default)
|
||||||
|
1: Steane's 3-bit code */
|
||||||
|
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
/* How many qubits are protected */
|
||||||
|
|
||||||
|
int width = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Change the status of the QEC. */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_qec_set_status(int stype, int swidth)
|
||||||
|
{
|
||||||
|
type = stype;
|
||||||
|
width = swidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the current QEC status */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_qec_get_status(int *ptype, int *pwidth)
|
||||||
|
{
|
||||||
|
if(ptype)
|
||||||
|
*ptype = type;
|
||||||
|
if(pwidth)
|
||||||
|
*pwidth = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Encode a quantum register. All qubits up to SWIDTH are protected,
|
||||||
|
the rest is expanded with a repition code. */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_qec_encode(int type, int width, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
|
lambda = quantum_get_decoherence();
|
||||||
|
|
||||||
|
quantum_set_decoherence(0);
|
||||||
|
|
||||||
|
for(i=0;i<reg->width;i++)
|
||||||
|
{
|
||||||
|
if(i==reg->width-1)
|
||||||
|
quantum_set_decoherence(lambda);
|
||||||
|
|
||||||
|
if(i<width)
|
||||||
|
{
|
||||||
|
quantum_hadamard(reg->width+i, reg);
|
||||||
|
quantum_hadamard(2*reg->width+i, reg);
|
||||||
|
|
||||||
|
quantum_cnot(reg->width+i, i, reg);
|
||||||
|
quantum_cnot(2*reg->width+i, i, reg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quantum_cnot(i, reg->width+i, reg);
|
||||||
|
quantum_cnot(i, 2*reg->width+i, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_qec_set_status(1, reg->width);
|
||||||
|
|
||||||
|
reg->width *= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode a quantum register and perform Quantum Error Correction on
|
||||||
|
it */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_qec_decode(int type, int width, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i, a, b;
|
||||||
|
int swidth;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
|
lambda = quantum_get_decoherence();
|
||||||
|
|
||||||
|
quantum_set_decoherence(0);
|
||||||
|
|
||||||
|
swidth=reg->width/3;
|
||||||
|
|
||||||
|
quantum_qec_set_status(0, 0);
|
||||||
|
|
||||||
|
for(i=reg->width/3-1;i>=0;i--)
|
||||||
|
{
|
||||||
|
if(i==0)
|
||||||
|
quantum_set_decoherence(lambda);
|
||||||
|
|
||||||
|
if(i<width)
|
||||||
|
{
|
||||||
|
quantum_cnot(2*swidth+i, i, reg);
|
||||||
|
quantum_cnot(swidth+i, i, reg);
|
||||||
|
|
||||||
|
quantum_hadamard(2*swidth+i, reg);
|
||||||
|
quantum_hadamard(swidth+i, reg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quantum_cnot(i, 2*swidth+i, reg);
|
||||||
|
quantum_cnot(i, swidth+i, reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=1;i<=swidth;i++)
|
||||||
|
{
|
||||||
|
a = quantum_bmeasure(swidth, reg);
|
||||||
|
b = quantum_bmeasure(2*swidth-i, reg);
|
||||||
|
if(a == 1 && b == 1 && i-1 < width)
|
||||||
|
quantum_sigma_z(i-1, reg); /* Z = HXH */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Counter which can be used to apply QEC periodically */
|
||||||
|
|
||||||
|
int
|
||||||
|
quantum_qec_counter(int inc, int frequency, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
static int counter = 0;
|
||||||
|
static int freq = (1<<30);
|
||||||
|
|
||||||
|
if(inc > 0)
|
||||||
|
counter += inc;
|
||||||
|
else if(inc < 0)
|
||||||
|
counter = 0;
|
||||||
|
|
||||||
|
if(frequency > 0)
|
||||||
|
freq = frequency;
|
||||||
|
|
||||||
|
if(counter >= freq)
|
||||||
|
{
|
||||||
|
counter = 0;
|
||||||
|
quantum_qec_decode(type, width, reg);
|
||||||
|
quantum_qec_encode(type, width, reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fault-tolerant version of the NOT gate */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_sigma_x_ft(int target, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
|
tmp = type;
|
||||||
|
type = 0;
|
||||||
|
|
||||||
|
lambda = quantum_get_decoherence();
|
||||||
|
quantum_set_decoherence(0);
|
||||||
|
|
||||||
|
/* These operations can be performed simultaneously */
|
||||||
|
|
||||||
|
quantum_sigma_x(target, reg);
|
||||||
|
quantum_sigma_x(target+width, reg);
|
||||||
|
quantum_set_decoherence(lambda);
|
||||||
|
quantum_sigma_x(target+2*width, reg);
|
||||||
|
|
||||||
|
quantum_qec_counter(1, 0, reg);
|
||||||
|
|
||||||
|
type = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fault-tolerant version of the Controlled NOT gate */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_cnot_ft(int control, int target, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
|
tmp = type;
|
||||||
|
type = 0;
|
||||||
|
|
||||||
|
/* These operations can be performed simultaneously */
|
||||||
|
|
||||||
|
lambda = quantum_get_decoherence();
|
||||||
|
quantum_set_decoherence(0);
|
||||||
|
|
||||||
|
quantum_cnot(control, target, reg);
|
||||||
|
quantum_cnot(control+width, target+width, reg);
|
||||||
|
quantum_set_decoherence(lambda);
|
||||||
|
quantum_cnot(control+2*width, target+2*width, reg);
|
||||||
|
|
||||||
|
quantum_qec_counter(1, 0, reg);
|
||||||
|
|
||||||
|
type = tmp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fault-tolerant version of the Toffoli gate */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_toffoli_ft(int control1, int control2, int target, quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int c1, c2;
|
||||||
|
MAX_UNSIGNED mask;
|
||||||
|
|
||||||
|
mask = ((MAX_UNSIGNED) 1 << target)
|
||||||
|
+ ((MAX_UNSIGNED) 1 << (target+width))
|
||||||
|
+ ((MAX_UNSIGNED) 1 << (target+2*width));
|
||||||
|
|
||||||
|
for(i=0;i<reg->size;i++)
|
||||||
|
{
|
||||||
|
c1 = 0;
|
||||||
|
c2 = 0;
|
||||||
|
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1))
|
||||||
|
c1 = 1;
|
||||||
|
if(reg->node[i].state
|
||||||
|
& ((MAX_UNSIGNED) 1 << (control1+width)))
|
||||||
|
{
|
||||||
|
c1 ^= 1;
|
||||||
|
}
|
||||||
|
if(reg->node[i].state
|
||||||
|
& ((MAX_UNSIGNED) 1 << (control1+2*width)))
|
||||||
|
{
|
||||||
|
c1 ^= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control2))
|
||||||
|
c2 = 1;
|
||||||
|
if(reg->node[i].state
|
||||||
|
& ((MAX_UNSIGNED) 1 << (control2+width)))
|
||||||
|
{
|
||||||
|
c2 ^= 1;
|
||||||
|
}
|
||||||
|
if(reg->node[i].state
|
||||||
|
& ((MAX_UNSIGNED) 1 << (control2+2*width)))
|
||||||
|
{
|
||||||
|
c2 ^= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c1 == 1 && c2 == 1)
|
||||||
|
reg->node[i].state = reg->node[i].state ^ mask;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
quantum_decohere(reg);
|
||||||
|
|
||||||
|
quantum_qec_counter(1, 0, reg);
|
||||||
|
|
||||||
|
}
|
41
qec.h
Normal file
41
qec.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/* gates.h: Declarations for qec.c
|
||||||
|
|
||||||
|
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||||
|
|
||||||
|
This file is part of libquantum
|
||||||
|
|
||||||
|
libquantum is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 2 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
libquantum is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with libquantum; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __QEC_H
|
||||||
|
|
||||||
|
#define __QEC_H
|
||||||
|
|
||||||
|
#include "qureg.h"
|
||||||
|
|
||||||
|
extern void quantum_qec_set_status(int stype, int swidth);
|
||||||
|
extern void quantum_qec_get_status(int *ptype, int *pwidth);
|
||||||
|
|
||||||
|
extern void quantum_qec_encode(int type, int width, quantum_reg *reg);
|
||||||
|
extern void quantum_qec_decode(int type, int width, quantum_reg *reg);
|
||||||
|
|
||||||
|
extern void quantum_sigma_x_ft(int target, quantum_reg *reg);
|
||||||
|
extern void quantum_cnot_ft(int control, int target, quantum_reg *reg);
|
||||||
|
extern void quantum_toffoli_ft(int control1, int control2, int target,
|
||||||
|
quantum_reg *reg);
|
||||||
|
|
||||||
|
#endif
|
@@ -84,10 +84,14 @@ extern void quantum_gate1(int target, quantum_matrix m, quantum_reg *reg);
|
|||||||
extern void quantum_r_x(int target, float gamma, quantum_reg *reg);
|
extern void quantum_r_x(int target, float gamma, quantum_reg *reg);
|
||||||
extern void quantum_r_y(int target, float gamma, quantum_reg *reg);
|
extern void quantum_r_y(int target, float gamma, quantum_reg *reg);
|
||||||
extern void quantum_r_z(int target, float gamma, quantum_reg *reg);
|
extern void quantum_r_z(int target, float gamma, quantum_reg *reg);
|
||||||
|
extern void quantum_phase_scale(int target, float gamma, quantum_reg *reg);
|
||||||
extern void quantum_phase_kick(int target, float gamma, quantum_reg *reg);
|
extern void quantum_phase_kick(int target, float gamma, quantum_reg *reg);
|
||||||
extern void quantum_hadamard(int target, quantum_reg *reg);
|
extern void quantum_hadamard(int target, quantum_reg *reg);
|
||||||
extern void quantum_walsh(int target, quantum_reg *reg);
|
extern void quantum_walsh(int target, quantum_reg *reg);
|
||||||
extern void quantum_cond_phase(int control, int target, quantum_reg *reg);
|
extern void quantum_cond_phase(int control, int target, quantum_reg *reg);
|
||||||
|
extern void quantum_cond_phase_inv(int control, int target, quantum_reg *reg);
|
||||||
|
extern void quantum_cond_phase_kick(int control, int target, float gamma,
|
||||||
|
quantum_reg *reg);
|
||||||
extern int quantum_gate_counter(int inc);
|
extern int quantum_gate_counter(int inc);
|
||||||
|
|
||||||
extern void quantum_qft(int width, quantum_reg *reg);
|
extern void quantum_qft(int width, quantum_reg *reg);
|
||||||
@@ -109,10 +113,14 @@ extern int quantum_getwidth(int n);
|
|||||||
|
|
||||||
extern float quantum_prob(COMPLEX_FLOAT a);
|
extern float quantum_prob(COMPLEX_FLOAT a);
|
||||||
|
|
||||||
|
extern float quantum_get_decoherence();
|
||||||
extern void quantum_set_decoherence(float lambda);
|
extern void quantum_set_decoherence(float lambda);
|
||||||
extern void quantum_decohere(quantum_reg *reg);
|
extern void quantum_decohere(quantum_reg *reg);
|
||||||
|
|
||||||
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
|
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
|
||||||
extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
|
extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
|
||||||
|
|
||||||
|
extern void quantum_qec_encode(int type, int width, quantum_reg *reg);
|
||||||
|
extern void quantum_qec_decode(int type, int width, quantum_reg *reg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
39
qureg.c
39
qureg.c
@@ -156,17 +156,50 @@ quantum_qureg2matrix(quantum_reg reg)
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete a quantum register. Note that the hash table is still
|
/* Destroys the entire hash table of a quantum register */
|
||||||
alive. */
|
|
||||||
|
void
|
||||||
|
quantum_destroy_hash(quantum_reg *reg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
quantum_reg_hash *p;
|
||||||
|
|
||||||
|
for(i=0; i<(1 << reg->hashw); i++)
|
||||||
|
{
|
||||||
|
while(reg->hash[i])
|
||||||
|
{
|
||||||
|
p = reg->hash[i]->next;
|
||||||
|
free(reg->hash[i]);
|
||||||
|
quantum_memman(-sizeof(quantum_reg_hash));
|
||||||
|
reg->hash[i] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(reg->hash);
|
||||||
|
quantum_memman(-(1 << reg->hashw) * sizeof(quantum_reg_hash *));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a quantum register */
|
||||||
|
|
||||||
void
|
void
|
||||||
quantum_delete_qureg(quantum_reg *reg)
|
quantum_delete_qureg(quantum_reg *reg)
|
||||||
|
{
|
||||||
|
quantum_destroy_hash(reg);
|
||||||
|
free(reg->node);
|
||||||
|
quantum_memman(-reg->size * sizeof(quantum_reg_node));
|
||||||
|
reg->node = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a quantum register but leave the hash table alive */
|
||||||
|
|
||||||
|
void
|
||||||
|
quantum_delete_qureg_hashpreserve(quantum_reg *reg)
|
||||||
{
|
{
|
||||||
free(reg->node);
|
free(reg->node);
|
||||||
quantum_memman(-reg->size * sizeof(quantum_reg_node));
|
quantum_memman(-reg->size * sizeof(quantum_reg_node));
|
||||||
reg->node = 0;
|
reg->node = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the contents of a quantum register to stdout */
|
/* Print the contents of a quantum register to stdout */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
2
qureg.h
2
qureg.h
@@ -66,7 +66,9 @@ typedef struct quantum_reg_struct quantum_reg;
|
|||||||
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
|
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
|
||||||
extern quantum_reg quantum_new_qureg(MAX_UNSIGNED initval, int width);
|
extern quantum_reg quantum_new_qureg(MAX_UNSIGNED initval, int width);
|
||||||
extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
|
extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
|
||||||
|
extern void quantum_destroy_hash(quantum_reg *reg);
|
||||||
extern void quantum_delete_qureg(quantum_reg *reg);
|
extern void quantum_delete_qureg(quantum_reg *reg);
|
||||||
|
extern void quantum_delete_qureg_hashpreserve(quantum_reg *reg);
|
||||||
|
|
||||||
extern void quantum_print_qureg(quantum_reg reg);
|
extern void quantum_print_qureg(quantum_reg reg);
|
||||||
extern void quantum_print_expn(quantum_reg reg);
|
extern void quantum_print_expn(quantum_reg reg);
|
||||||
|
25
shor.c
25
shor.c
@@ -1,3 +1,26 @@
|
|||||||
|
/* shor.c: Implementation of Shor's factoring algorithm
|
||||||
|
|
||||||
|
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||||
|
|
||||||
|
This file is part of libquantum
|
||||||
|
|
||||||
|
libquantum is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published
|
||||||
|
by the Free Software Foundation; either version 2 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
libquantum is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with libquantum; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
USA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -119,7 +142,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
quantum_delete_qureg(&qr);
|
quantum_delete_qureg(&qr);
|
||||||
|
|
||||||
// printf("Memory usage: %i bytes\n", (int )memman(0));
|
// printf("Memory leak: %i bytes\n", (int) quantum_memman(0));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user