mirror of
https://github.com/libquantum/libquantum.git
synced 2025-10-03 16:51:37 +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:
|
||||
- Completed rotation gates (quantum_r_z)
|
||||
- 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:
|
||||
@@ -37,16 +37,24 @@ Now you can build the beast:
|
||||
|
||||
make
|
||||
|
||||
By now, you can create a sample program which implements Shor's
|
||||
factoring algorithm:
|
||||
By now, you can create two demo programs which show Shor's factoring
|
||||
algorithm and Grover's search algorithm:
|
||||
|
||||
make shor
|
||||
make demos
|
||||
|
||||
The number to be factored is given on the command line as the first
|
||||
parameter. To factor 15, simply type:
|
||||
For the Shor algorithm demo, the number to be factored is given on the
|
||||
command line as the first parameter. To factor 15, simply type:
|
||||
|
||||
./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
|
||||
------------------------------
|
||||
@@ -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
|
||||
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
|
||||
command to get some advice on how to deal with this.
|
||||
not in the standard search path for libraries. Take a look at the
|
||||
output of the last command to get some advice on how to deal with
|
||||
this.
|
||||
|
||||
3. Writing your own programs
|
||||
----------------------------
|
||||
|
33
Makefile.in
33
Makefile.in
@@ -36,29 +36,29 @@ top_builddir=.
|
||||
# Release information
|
||||
|
||||
MAJOR=0
|
||||
MINOR=1
|
||||
RELEASE=1
|
||||
MINOR=2
|
||||
RELEASE=0
|
||||
|
||||
# Tools needed to build libquantum
|
||||
|
||||
CC=@CC@
|
||||
CC=@CC@ -O2 -g -pg
|
||||
INSTALL=@INSTALL@
|
||||
LIBTOOL=@LIBTOOL@
|
||||
|
||||
# Flags passed to C compiler
|
||||
|
||||
CFLAGS=@CFLAGS@
|
||||
LDFLAGS=-rpath $(LIBDIR) -version-info 1:1:1
|
||||
LDFLAGS=-rpath $(LIBDIR) -version-info 2:0:2
|
||||
|
||||
# Dependencies
|
||||
|
||||
all: libquantum.la
|
||||
|
||||
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\
|
||||
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
|
||||
$(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
|
||||
$(LIBTOOL) $(CC) $(CFLAGS) -c qureg.c
|
||||
|
||||
decoherence.lo: decoherence.c decoherence.h measure.h gates.h qureg.h config.h\
|
||||
Makefile
|
||||
decoherence.lo: decoherence.c decoherence.h measure.h gates.h qureg.h\
|
||||
complex.h config.h Makefile
|
||||
$(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
|
||||
|
||||
install: libquantum.la
|
||||
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
|
||||
$(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
|
||||
$(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
|
||||
|
||||
clean:
|
||||
@@ -119,9 +128,9 @@ distclean:
|
||||
dist:
|
||||
-rm quantum.h config.h
|
||||
mkdir libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||
cp *.c *.h quantum.h.in Makefile.in config.h.in configure COPYING\
|
||||
install-sh ltmain.sh config.sub config.guess README INSTALL CHANGES\
|
||||
libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||
cp *.c *.h quantum.h.in Makefile.in config.h.in configure configure.in\
|
||||
COPYING install-sh ltmain.sh config.sub config.guess README INSTALL\
|
||||
CHANGES libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||
tar czf libquantum-$(MAJOR).$(MINOR).$(RELEASE).tar.gz\
|
||||
libquantum-$(MAJOR).$(MINOR).$(RELEASE)/
|
||||
rm -rf libquantum-$(MAJOR).$(MINOR).$(RELEASE)
|
||||
|
10
README
10
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
|
||||
@@ -6,16 +6,16 @@ registers, unitary operations and measurement functions. The main goal
|
||||
is a physically precise simulation of a quantum computer with high
|
||||
performance.
|
||||
|
||||
An implementation of Shor's factoring algorithm is included with this
|
||||
release.
|
||||
Implementations of Shor's factoring algorithm and Grover's search
|
||||
algorithm are included with this release.
|
||||
|
||||
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.
|
||||
|
||||
Send inquiries, comments, bug reports, suggestions, patches, etc. to:
|
||||
libquantum@enyo.de
|
||||
|
||||
See also the guardian website:
|
||||
See also the libquantum website:
|
||||
http://www.enyo.de/libquantum
|
@@ -3,6 +3,9 @@
|
||||
/* Complex data type */
|
||||
#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. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
|
21
configure
vendored
21
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# 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>.
|
||||
#
|
||||
@@ -427,8 +427,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='libquantum'
|
||||
PACKAGE_TARNAME='libquantum'
|
||||
PACKAGE_VERSION='0.1.1'
|
||||
PACKAGE_STRING='libquantum 0.1.1'
|
||||
PACKAGE_VERSION='0.2.0'
|
||||
PACKAGE_STRING='libquantum 0.2.0'
|
||||
PACKAGE_BUGREPORT='libquantum@enyo.de'
|
||||
|
||||
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.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
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]...
|
||||
|
||||
@@ -999,7 +999,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of libquantum 0.1.1:";;
|
||||
short | recursive ) echo "Configuration of libquantum 0.2.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1092,7 +1092,7 @@ fi
|
||||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
libquantum configure 0.1.1
|
||||
libquantum configure 0.2.0
|
||||
generated by GNU Autoconf 2.57
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
@@ -7877,7 +7877,7 @@ if test $ac_cv_type_uint_64t = yes; then
|
||||
#define MAX_UNSIGNED uint_64t
|
||||
_ACEOF
|
||||
|
||||
MU_TYPE="unint_64t"
|
||||
MU_TYPE="uint_64t"
|
||||
fi
|
||||
|
||||
if test "$MU_TYPE" = "none"
|
||||
@@ -8620,7 +8620,7 @@ _ASBOX
|
||||
} >&5
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -8680,7 +8680,7 @@ _ACEOF
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
libquantum config.status 0.1.1
|
||||
libquantum config.status 0.2.0
|
||||
configured by $0, generated by GNU Autoconf 2.57,
|
||||
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.
|
||||
$ac_cs_success || { (exit 1); exit 1; }
|
||||
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
|
||||
quantum_get_decoherence()
|
||||
{
|
||||
return lambda;
|
||||
}
|
||||
|
||||
/* Initialize the decoherence simulation and set the decoherence
|
||||
parameter. */
|
||||
|
||||
@@ -63,7 +69,8 @@ void
|
||||
quantum_decohere(quantum_reg *reg)
|
||||
{
|
||||
float u, v, s, x;
|
||||
COMPLEX_FLOAT c0, c1;
|
||||
float *nrands;
|
||||
float angle;
|
||||
int i, j;
|
||||
|
||||
/* Increase the gate counter */
|
||||
@@ -72,9 +79,19 @@ quantum_decohere(quantum_reg *reg)
|
||||
|
||||
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 {
|
||||
u = 2 * quantum_frand() - 1;
|
||||
@@ -86,19 +103,29 @@ quantum_decohere(quantum_reg *reg)
|
||||
|
||||
x *= sqrt(2 * lambda);
|
||||
|
||||
/* Apply the phase shift gate for decoherence simulation */
|
||||
nrands[i] = x/2;
|
||||
}
|
||||
|
||||
c0 = quantum_cexp(-x / 2);
|
||||
c1 = quantum_cexp(x / 2);
|
||||
|
||||
/* Apply the phase shifts for decoherence simulation */
|
||||
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << j))
|
||||
reg->node[i].amplitude *= c1;
|
||||
angle = 0;
|
||||
|
||||
for(j=0; j<reg->width; j++)
|
||||
{
|
||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << j))
|
||||
angle += nrands[j];
|
||||
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
|
||||
|
||||
extern float quantum_get_decoherence();
|
||||
|
||||
extern void quantum_set_decoherence(float lambda);
|
||||
|
||||
extern void quantum_decohere(quantum_reg *reg);
|
||||
|
105
gates.c
105
gates.c
@@ -30,6 +30,7 @@
|
||||
#include "complex.h"
|
||||
#include "qureg.h"
|
||||
#include "decoherence.h"
|
||||
#include "qec.h"
|
||||
|
||||
/* Apply a controlled-not gate */
|
||||
|
||||
@@ -37,7 +38,14 @@ void
|
||||
quantum_cnot(int control, int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
int qec;
|
||||
|
||||
quantum_qec_get_status(&qec, NULL);
|
||||
|
||||
if(qec)
|
||||
quantum_cnot_ft(control, target, reg);
|
||||
else
|
||||
{
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
/* Flip the target bit of a base state if the control bit is set */
|
||||
@@ -47,6 +55,7 @@ quantum_cnot(int control, int target, quantum_reg *reg)
|
||||
}
|
||||
quantum_decohere(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply a toffoli (or controlled-controlled-not) gate */
|
||||
|
||||
@@ -54,7 +63,14 @@ void
|
||||
quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
int qec;
|
||||
|
||||
quantum_qec_get_status(&qec, NULL);
|
||||
|
||||
if(qec)
|
||||
quantum_toffoli_ft(control1, control2, target, reg);
|
||||
else
|
||||
{
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
/* Flip the target bit of a base state if both control bits are
|
||||
@@ -70,6 +86,7 @@ quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
|
||||
}
|
||||
quantum_decohere(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply a sigma_x (or not) gate */
|
||||
|
||||
@@ -77,7 +94,14 @@ void
|
||||
quantum_sigma_x(int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
int qec;
|
||||
|
||||
quantum_qec_get_status(&qec, NULL);
|
||||
|
||||
if(qec)
|
||||
quantum_sigma_x_ft(target, reg);
|
||||
else
|
||||
{
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
/* Flip the target bit of each base state */
|
||||
@@ -86,11 +110,12 @@ quantum_sigma_x(int target, quantum_reg *reg)
|
||||
}
|
||||
quantum_decohere(reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply a sigma_y gate */
|
||||
|
||||
void
|
||||
quantum_sigma_y(int target, int width, quantum_reg *reg)
|
||||
quantum_sigma_y(int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -113,7 +138,7 @@ quantum_sigma_y(int target, int width, quantum_reg *reg)
|
||||
/* Apply a sigma_y gate */
|
||||
|
||||
void
|
||||
quantum_sigma_z(int target, int width, quantum_reg *reg)
|
||||
quantum_sigma_z(int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -128,15 +153,29 @@ quantum_sigma_z(int target, int width, quantum_reg *reg)
|
||||
}
|
||||
|
||||
/* 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
|
||||
quantum_swaptheleads(int width, quantum_reg *reg)
|
||||
{
|
||||
int i, j;
|
||||
int pat1, pat2;
|
||||
int qec;
|
||||
MAX_UNSIGNED l;
|
||||
|
||||
quantum_qec_get_status(&qec, NULL);
|
||||
|
||||
if(qec)
|
||||
{
|
||||
for(i=0; i<width; i++)
|
||||
{
|
||||
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 */
|
||||
@@ -150,7 +189,7 @@ quantum_swaptheleads(int width, quantum_reg *reg)
|
||||
for(j=0; j<width; j++)
|
||||
pat2 += reg->node[i].state & ((MAX_UNSIGNED) 1 << (width + j));
|
||||
|
||||
/* construct the new base state */
|
||||
/* construct the new basis state */
|
||||
|
||||
l = reg->node[i].state - (pat1 + pat2);
|
||||
l += (pat1 << width);
|
||||
@@ -158,6 +197,7 @@ quantum_swaptheleads(int width, quantum_reg *reg)
|
||||
reg->node[i].state = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Swap WIDTH bits starting at WIDTH and 2*WIDTH+2 controlled by
|
||||
CONTROL */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -449,6 +489,22 @@ quantum_r_z(int target, float gamma, quantum_reg *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 */
|
||||
|
||||
void
|
||||
@@ -485,6 +541,45 @@ quantum_cond_phase(int control, int target, quantum_reg *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
|
||||
current value of the counter is returned. */
|
||||
|
||||
|
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_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_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);
|
||||
|
||||
|
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)
|
||||
max = mem;
|
||||
|
||||
return max;
|
||||
return mem;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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_y(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_hadamard(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_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 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_get_decoherence();
|
||||
extern void quantum_set_decoherence(float lambda);
|
||||
extern void quantum_decohere(quantum_reg *reg);
|
||||
|
||||
extern quantum_reg quantum_matrix2qureg(quantum_matrix *m, int width);
|
||||
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
|
||||
|
37
qureg.c
37
qureg.c
@@ -156,11 +156,44 @@ quantum_qureg2matrix(quantum_reg reg)
|
||||
return m;
|
||||
}
|
||||
|
||||
/* Delete a quantum register. Note that the hash table is still
|
||||
alive. */
|
||||
/* Destroys the entire hash table of a quantum register */
|
||||
|
||||
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
|
||||
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);
|
||||
quantum_memman(-reg->size * sizeof(quantum_reg_node));
|
||||
|
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_new_qureg(MAX_UNSIGNED initval, int width);
|
||||
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_hashpreserve(quantum_reg *reg);
|
||||
|
||||
extern void quantum_print_qureg(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 <stdio.h>
|
||||
#include <math.h>
|
||||
@@ -119,7 +142,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user