updated libquantum 0.2.1 source files

This commit is contained in:
libquantum
2016-10-27 04:14:06 +09:00
parent dc03271227
commit ce2bb44638
22 changed files with 473 additions and 346 deletions

12
CHANGES
View File

@@ -1,3 +1,15 @@
libquantum 0.2.1:
- Completed GNU/Hurd and FreeBSD ports
- Added unbounded toffoli gate
- Changed hashing method to linear probing (breaks backward
compatibility)
- Optimized quantum_gate1 and gates using quantum_cexp
- Added a bit measurement function that does not remove the
measured bit
- Corrected qft, added qft_inv and adjusted shor
- Corrected the implementation of the Walsh-Hadamard transform
- Supplied version information
libquantum 0.2.0: libquantum 0.2.0:
- Added Quantum Error Correction - Added Quantum Error Correction
- Included an Implementation of Grover's algorithm - Included an Implementation of Grover's algorithm

View File

@@ -1,4 +1,4 @@
libquantum 0.2.0 installation guide libquantum 0.2.1 installation guide
----------------------------------- -----------------------------------
Contents: Contents:
@@ -13,7 +13,7 @@ Contents:
--------------- ---------------
libquantum needs a C compiler with complex number support (C99 libquantum needs a C compiler with complex number support (C99
prefered). A recent gcc (>=2.9.5) will do the job. Furthermore, the prefered). A recent gcc (>=2.95) will do the job. Furthermore, the
host must support 64-bit integers, even if it is not a 64-bit machine. host must support 64-bit integers, even if it is not a 64-bit machine.
If you encounter any difficulties while building, installing or using If you encounter any difficulties while building, installing or using
@@ -27,7 +27,7 @@ libquantum@enyo.de.
As libquantum was created using autoconf and libtool, this step should As libquantum was created using autoconf and libtool, this step should
not be a major problem. Simply extract the tarball to a directory: not be a major problem. Simply extract the tarball to a directory:
tar xzvf libquantum-0.1.0.tar.gz tar xzvf libquantum-0.2.1.tar.gz
Next, run the configure script: Next, run the configure script:

View File

@@ -26,44 +26,44 @@ SHELL=/bin/sh
# Target directory prefix # Target directory prefix
PREFIX=@prefix@ PREFIX=@prefix@
EPREFIX=${PREFIX}
# Other directories # Other directories
LIBDIR=${PREFIX}/lib LIBDIR=${EPREFIX}/lib
INCLUDEDIR=${PREFIX}/include INCLUDEDIR=${PREFIX}/include
top_builddir=. top_builddir=.
# Release information # Version information
MAJOR=0 VERSION=@PACKAGE_VERSION@
MINOR=2
RELEASE=0
# Tools needed to build libquantum # Tools needed to build libquantum
CC=@CC@ -O2 -g -pg CC=@CC@
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 2:0:2 LDFLAGS=-rpath $(LIBDIR) -version-info 3:0:0
# 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 qec.lo Makefile qureg.lo decoherence.lo oaddn.lo omuln.lo expn.lo qec.lo version.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 qec.lo -lm qureg.lo decoherence.lo qec.lo version.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
measure.lo: measure.c measure.h matrix.h qureg.h config.h Makefile measure.lo: measure.c measure.h matrix.h qureg.h complex.h config.h Makefile
$(LIBTOOL) $(CC) $(CFLAGS) -c measure.c $(LIBTOOL) $(CC) $(CFLAGS) -c measure.c
matrix.lo: matrix.c matrix.h complex.h Makefile matrix.lo: matrix.c matrix.h complex.h Makefile
@@ -94,14 +94,11 @@ decoherence.lo: decoherence.c decoherence.h measure.h gates.h qureg.h\
complex.h config.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 qec.lo: qec.c qec.h gates.h qureg.h decoherence.h measure.h config.h Makefile
$(LIBTOOL) $(CC) $(CFLAGS) -c qec.c $(LIBTOOL) $(CC) $(CFLAGS) -c qec.c
# Bring this savage back home version.lo: version.c version.h config.h Makefile
$(LIBTOOL) $(CC) $(CFLAGS) -c version.c
install: libquantum.la
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
$(INSTALL) -m 0644 quantum.h $(INCLUDEDIR)
# Build demos of Shor's and Grover's algorithms # Build demos of Shor's and Grover's algorithms
@@ -114,6 +111,12 @@ grover: libquantum.la grover.c Makefile
$(LIBTOOL) $(CC) $(CFLAGS) -o grover grover.c -I./ -lquantum -static\ $(LIBTOOL) $(CC) $(CFLAGS) -o grover grover.c -I./ -lquantum -static\
-lm -lm
# Bring this savage back home
install: libquantum.la
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
$(INSTALL) -m 0644 quantum.h $(INCLUDEDIR)
# Make everything neat and tidy # Make everything neat and tidy
clean: clean:
@@ -127,10 +130,9 @@ distclean:
dist: dist:
-rm quantum.h config.h -rm quantum.h config.h
mkdir libquantum-$(MAJOR).$(MINOR).$(RELEASE) mkdir libquantum-$(VERSION)
cp *.c *.h quantum.h.in Makefile.in config.h.in configure configure.in\ 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\ COPYING install-sh ltmain.sh config.sub config.guess README INSTALL\
CHANGES libquantum-$(MAJOR).$(MINOR).$(RELEASE) CHANGES libquantum-$(VERSION)
tar czf libquantum-$(MAJOR).$(MINOR).$(RELEASE).tar.gz\ tar czf libquantum-$(VERSION).tar.gz libquantum-$(VERSION)/
libquantum-$(MAJOR).$(MINOR).$(RELEASE)/ rm -rf libquantum-$(VERSION)
rm -rf libquantum-$(MAJOR).$(MINOR).$(RELEASE)

2
README
View File

@@ -1,4 +1,4 @@
libquantum 0.2.0 README file libquantum 0.2.1 README file
---------------------------- ----------------------------
libquantum is a C library for quantum computing. It provides quantum libquantum is a C library for quantum computing. It provides quantum

View File

@@ -26,24 +26,6 @@
#include "complex.h" #include "complex.h"
#include "config.h" #include "config.h"
/* Return the real part of a complex number */
float
quantum_real(COMPLEX_FLOAT a)
{
float *p = (float *) &a;
return p[0];
}
/* Return the imaginary part of a complex number */
float
quantum_imag(COMPLEX_FLOAT a)
{
float *p = (float *) &a;
return p[1];
}
/* Return the complex conjugate of a complex number */ /* Return the complex conjugate of a complex number */
COMPLEX_FLOAT COMPLEX_FLOAT
@@ -62,7 +44,7 @@ quantum_conj(COMPLEX_FLOAT a)
float float
quantum_prob(COMPLEX_FLOAT a) quantum_prob(COMPLEX_FLOAT a)
{ {
return (float) (a * quantum_conj(a)); return quantum_prob_inline(a);
} }
/* Calculate e^(i * phi) */ /* Calculate e^(i * phi) */

View File

@@ -27,11 +27,40 @@
#include "config.h" #include "config.h"
extern float quantum_real(COMPLEX_FLOAT a);
extern float quantum_imag(COMPLEX_FLOAT a);
extern COMPLEX_FLOAT quantum_conj(COMPLEX_FLOAT a); extern COMPLEX_FLOAT quantum_conj(COMPLEX_FLOAT a);
extern float quantum_prob (COMPLEX_FLOAT a); extern float quantum_prob (COMPLEX_FLOAT a);
extern COMPLEX_FLOAT quantum_cexp(float phi); extern COMPLEX_FLOAT quantum_cexp(float phi);
/* Return the real part of a complex number */
static inline float
quantum_real(COMPLEX_FLOAT a)
{
float *p = (float *) &a;
return p[0];
}
/* Return the imaginary part of a complex number */
static inline float
quantum_imag(COMPLEX_FLOAT a)
{
float *p = (float *) &a;
return p[1];
}
/* Calculate the square of a complex number (i.e. the probability) */
static inline float
quantum_prob_inline(COMPLEX_FLOAT a)
{
float r, i;
r = quantum_real(a);
i = quantum_imag(a);
return r * r + i * i;
}
#endif #endif

48
configure vendored
View File

@@ -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.2.0. # Generated by GNU Autoconf 2.57 for libquantum 0.2.1.
# #
# 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.2.0' PACKAGE_VERSION='0.2.1'
PACKAGE_STRING='libquantum 0.2.0' PACKAGE_STRING='libquantum 0.2.1'
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.2.0 to adapt to many kinds of systems. \`configure' configures libquantum 0.2.1 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.2.0:";; short | recursive ) echo "Configuration of libquantum 0.2.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1010,6 +1010,7 @@ Optional Features:
--enable-static=PKGS build static libraries default=yes --enable-static=PKGS build static libraries default=yes
--enable-fast-install=PKGS optimize for fast installation default=yes --enable-fast-install=PKGS optimize for fast installation default=yes
--disable-libtool-lock avoid locking (might break parallel builds) --disable-libtool-lock avoid locking (might break parallel builds)
--enable-profiling compile with profiling support
Optional Packages: Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1092,7 +1093,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.2.0 libquantum configure 0.2.1
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 +1108,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.2.0, which was It was created by libquantum $as_me 0.2.1, which was
generated by GNU Autoconf 2.57. Invocation command line was generated by GNU Autoconf 2.57. Invocation command line was
$ $0 $@ $ $0 $@
@@ -2225,12 +2226,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
for ac_declaration in \ for ac_declaration in \
''\ ''\
'#include <stdlib.h>' \
'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \ 'extern "C" void exit (int) throw ();' \
'extern "C" void exit (int);' \ 'extern "C" void exit (int);' \
'void exit (int);' 'void exit (int);' \
'#include <stdlib.h>'
do do
cat >conftest.$ac_ext <<_ACEOF cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure" #line $LINENO "configure"
@@ -4130,7 +4131,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
case $host in case $host in
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 4133 "configure"' > conftest.$ac_ext echo '#line 4134 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@@ -4673,7 +4674,7 @@ chmod -w .
save_CFLAGS="$CFLAGS" save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
compiler_c_o=no compiler_c_o=no
if { (eval echo configure:4676: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then if { (eval echo configure:4677: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings # So say no if there are warnings
if test -s out/conftest.err; then if test -s out/conftest.err; then
@@ -6556,7 +6557,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6559 "configure" #line 6560 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -6654,7 +6655,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 6657 "configure" #line 6658 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -7391,7 +7392,6 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
# Checks for libraries. # Checks for libraries.
# FIXME: Replace `main' with a function in `-lm':
echo "$as_me:$LINENO: checking for sqrt in -lm" >&5 echo "$as_me:$LINENO: checking for sqrt in -lm" >&5
echo $ECHO_N "checking for sqrt in -lm... $ECHO_C" >&6 echo $ECHO_N "checking for sqrt in -lm... $ECHO_C" >&6
@@ -8255,9 +8255,24 @@ fi
echo "$as_me:$LINENO: result: $I" >&5 echo "$as_me:$LINENO: result: $I" >&5
echo "${ECHO_T}$I" >&6 echo "${ECHO_T}$I" >&6
# Substitute fields in quantum.h.in
# Profiling check
# Check whether --enable-profiling or --disable-profiling was given.
if test "${enable_profiling+set}" = set; then
enableval="$enable_profiling"
CFLAGS="$CFLAGS -pg"
fi;
# Enable -Wall for gcc
if test $CC = "gcc"
then
CFLAGS="$CFLAGS -Wall"
fi
# Write the output files
ac_config_files="$ac_config_files Makefile quantum.h" ac_config_files="$ac_config_files Makefile quantum.h"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
@@ -8620,7 +8635,7 @@ _ASBOX
} >&5 } >&5
cat >&5 <<_CSEOF cat >&5 <<_CSEOF
This file was extended by libquantum $as_me 0.2.0, which was This file was extended by libquantum $as_me 0.2.1, 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 +8695,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
libquantum config.status 0.2.0 libquantum config.status 0.2.1
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,3 +9373,4 @@ 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

View File

@@ -1,5 +1,5 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_INIT([libquantum], [0.2.0], [libquantum@enyo.de]) AC_INIT([libquantum], [0.2.1], [libquantum@enyo.de])
AC_CONFIG_SRCDIR([classic.c]) AC_CONFIG_SRCDIR([classic.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
@@ -12,7 +12,6 @@ AC_PROG_INSTALL
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
# Checks for libraries. # Checks for libraries.
# FIXME: Replace `main' with a function in `-lm':
AC_CHECK_LIB([m], [sqrt]) AC_CHECK_LIB([m], [sqrt])
# Checks for header files. # Checks for header files.
@@ -72,8 +71,22 @@ then
fi fi
AC_MSG_RESULT($I) AC_MSG_RESULT($I)
# Substitute fields in quantum.h.in
AC_SUBST(MU_TYPE) AC_SUBST(MU_TYPE)
AC_SUBST(CF_TYPE) AC_SUBST(CF_TYPE)
# Profiling check
AC_ARG_ENABLE(profiling,
[ --enable-profiling compile with profiling support],
[CFLAGS="$CFLAGS -pg"],
[])
# Enable -Wall for gcc
if test $CC = "gcc"
then
CFLAGS="$CFLAGS -Wall"
fi
# Write the output files
AC_CONFIG_FILES([Makefile quantum.h]) AC_CONFIG_FILES([Makefile quantum.h])
AC_OUTPUT AC_OUTPUT

194
gates.c
View File

@@ -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
@@ -24,6 +24,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <stdarg.h>
#include "matrix.h" #include "matrix.h"
#include "defs.h" #include "defs.h"
@@ -48,7 +49,7 @@ quantum_cnot(int control, int target, quantum_reg *reg)
{ {
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
/* Flip the target bit of a base state if the control bit is set */ /* Flip the target bit of a basis 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);
@@ -73,7 +74,7 @@ quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
{ {
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
/* Flip the target bit of a base state if both control bits are /* Flip the target bit of a basis state if both control bits are
set */ set */
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << control1))
@@ -88,6 +89,53 @@ quantum_toffoli(int control1, int control2, int target, quantum_reg *reg)
} }
} }
/* Apply an unbounded toffoli gate. This gate is not considered
elementary and is not available on all physical realizations of a
quantum computer. Be sure to pass the function the correct number of
controlling qubits. The target is given in the last argument. */
void
quantum_unbounded_toffoli(int controlling, quantum_reg *reg, ...)
{
va_list bits;
int target;
int *controls;
int i, j;
controls = malloc(controlling * sizeof(int));
if(!controls)
{
printf("Error allocating %i-element int array!\n", controlling);
exit(1);
}
quantum_memman(controlling * sizeof(int));
va_start(bits, reg);
for(i=0; i<controlling; i++)
controls[i] = va_arg(bits, int);
target = va_arg(bits, int);
va_end(bits);
for(i=0; i<reg->size; i++)
{
for(j=0; (j < controlling) &&
(reg->node[i].state & (MAX_UNSIGNED) 1 << controls[j]); j++);
if(j == controlling) /* all control bits are set */
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
}
free(controls);
quantum_memman(-controlling * sizeof(int));
quantum_decohere(reg);
}
/* Apply a sigma_x (or not) gate */ /* Apply a sigma_x (or not) gate */
void void
@@ -104,7 +152,7 @@ quantum_sigma_x(int target, quantum_reg *reg)
{ {
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
/* Flip the target bit of each base state */ /* Flip the target bit of each basis state */
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target); reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
} }
@@ -121,7 +169,7 @@ quantum_sigma_y(int target, quantum_reg *reg)
for(i=0; i<reg->size;i++) for(i=0; i<reg->size;i++)
{ {
/* Flip the target bit of each base state and multiply with /* Flip the target bit of each basis state and multiply with
+/- i */ +/- i */
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target); reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
@@ -221,12 +269,12 @@ quantum_swaptheleads_omuln_controlled(int control, int width, quantum_reg *reg)
void void
quantum_gate1(int target, quantum_matrix m, quantum_reg *reg) quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
{ {
int i, j, k; int i, j, k, iset;
int addsize=0, decsize=0; int addsize=0, decsize=0;
COMPLEX_FLOAT t, tnot=0; COMPLEX_FLOAT t, tnot=0;
float limit;
char *done; char *done;
quantum_reg out; // quantum_reg_hash *p;
quantum_reg_hash *p;
if((m.cols != 2) || (m.rows != 2)) if((m.cols != 2) || (m.rows != 2))
{ {
@@ -238,19 +286,20 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
for(i=0; i<(1 << reg->hashw); i++) for(i=0; i<(1 << reg->hashw); i++)
{ {
while(reg->hash[i]) /* while(reg->hash[i])
{ {
p = reg->hash[i]->next; p = reg->hash[i]->next;
free(reg->hash[i]); free(reg->hash[i]);
quantum_memman(-sizeof(quantum_reg_hash)); quantum_memman(-sizeof(quantum_reg_hash));
reg->hash[i] = p; reg->hash[i] = p;
} }*/
reg->hash[i] = 0;
} }
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
quantum_add_hash(reg->node[i].state, i, reg); quantum_add_hash(reg->node[i].state, i, reg);
/* calculate the number of base states to be added */ /* calculate the number of basis states to be added */
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
@@ -267,7 +316,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
} }
} }
/* allocate memory for the new base states */ /* allocate memory for the new basis states */
reg->node = realloc(reg->node, reg->node = realloc(reg->node,
(reg->size + addsize) * sizeof(quantum_reg_node)); (reg->size + addsize) * sizeof(quantum_reg_node));
@@ -295,12 +344,18 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
k = reg->size; k = reg->size;
limit = (1.0 / ((MAX_UNSIGNED) 1 << reg->width)) / 1000000;
/* perform the actual matrix multiplication */ /* perform the actual matrix multiplication */
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
if(!done[i]) if(!done[i])
{ {
/* determine if the target of the basis state is set */
iset = reg->node[i].state & ((MAX_UNSIGNED) 1 << target);
tnot = 0; tnot = 0;
j = quantum_get_state(reg->node[i].state j = quantum_get_state(reg->node[i].state
^ ((MAX_UNSIGNED) 1<<target), *reg); ^ ((MAX_UNSIGNED) 1<<target), *reg);
@@ -309,7 +364,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
if(j >= 0) if(j >= 0)
tnot = reg->node[j].amplitude; tnot = reg->node[j].amplitude;
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(iset)
reg->node[i].amplitude = m.t[2] * tnot + m.t[3] * t; reg->node[i].amplitude = m.t[2] * tnot + m.t[3] * t;
else else
@@ -317,7 +372,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
if(j >= 0) if(j >= 0)
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(iset)
reg->node[j].amplitude = m.t[0] * tnot + m.t[1] * t; reg->node[j].amplitude = m.t[0] * tnot + m.t[1] * t;
else else
@@ -325,20 +380,18 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
} }
else /* new base state will be created */ else /* new basis state will be created */
{ {
if((m.t[1] == 0) if((m.t[1] == 0) && (iset))
&& (reg->node[i].state & ((MAX_UNSIGNED) 1 << target)))
break; break;
if((m.t[2] == 0) if((m.t[2] == 0) && !(iset))
&& !(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)))
break; break;
reg->node[k].state = reg->node[i].state reg->node[k].state = reg->node[i].state
^ ((MAX_UNSIGNED) 1 << target); ^ ((MAX_UNSIGNED) 1 << target);
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(iset)
reg->node[k].amplitude = m.t[1] * t; reg->node[k].amplitude = m.t[1] * t;
else else
@@ -350,14 +403,6 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
if(j >= 0) if(j >= 0)
done[j] = 1; done[j] = 1;
if(!reg->node[i].amplitude)
decsize++;
if(j >= 0)
{
if(!reg->node[j].amplitude)
decsize++;
}
} }
} }
@@ -366,34 +411,33 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
free(done); free(done);
quantum_memman(-reg->size * sizeof(char)); quantum_memman(-reg->size * sizeof(char));
/* remove base states with zero amplitude */ /* remove basis states with extremely small amplitude */
for(i=0, j=0; i<reg->size; i++)
{
if(quantum_prob_inline(reg->node[i].amplitude) < limit)
{
j++;
decsize++;
}
else if(j)
{
reg->node[i-j].state = reg->node[i].state;
reg->node[i-j].amplitude = reg->node[i].amplitude;
}
}
if(decsize) if(decsize)
{ {
out.width = reg->width; reg->size -= decsize;
out.size = reg->size - decsize; reg->node = realloc(reg->node, reg->size * sizeof(quantum_reg_node));
out.node = calloc(out.size, sizeof(quantum_reg_node)); if(!reg->node)
if(!out.node)
{ {
printf("Not enough memory for %i-sized qubit!\n", out.size); printf("Not enough memory for %i-sized qubit!\n",
reg->size + addsize);
exit(1); exit(1);
} }
quantum_memman(out.size * sizeof(quantum_reg_node));
out.hashw = reg->hashw;
out.hash = reg->hash;
for(i=0, j=0; i<reg->size; i++)
{
if(reg->node[i].amplitude)
{
out.node[j].state = reg->node[i].state;
out.node[j].amplitude = reg->node[i].amplitude;
j++;
}
}
quantum_delete_qureg_hashpreserve(reg);
*reg = out;
} }
quantum_decohere(reg); quantum_decohere(reg);
@@ -417,21 +461,15 @@ quantum_hadamard(int target, quantum_reg *reg)
} }
/* Apply a walsh-hadamard gate */ /* Apply a walsh-hadamard transform */
void void
quantum_walsh(int target, quantum_reg *reg) quantum_walsh(int width, quantum_reg *reg)
{ {
quantum_matrix m; int i;
m = quantum_new_matrix(2, 2); for(i=0; i<width; i++)
quantum_hadamard(i, reg);
m.t[0] = IMAGINARY*sqrt(1.0/2); m.t[1] = IMAGINARY*sqrt(1.0/2);
m.t[2] = IMAGINARY*sqrt(1.0/2); m.t[3] = -IMAGINARY*sqrt(1.0/2);
quantum_gate1(target, m, reg);
quantum_delete_matrix(&m);
} }
@@ -477,13 +515,16 @@ void
quantum_r_z(int target, float gamma, quantum_reg *reg) quantum_r_z(int target, float gamma, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(gamma/2);
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
reg->node[i].amplitude *= quantum_cexp(gamma/2); reg->node[i].amplitude *= z;
else else
reg->node[i].amplitude *= quantum_cexp(-gamma/2); reg->node[i].amplitude /= z;
} }
quantum_decohere(reg); quantum_decohere(reg);
@@ -495,10 +536,13 @@ void
quantum_phase_scale(int target, float gamma, quantum_reg *reg) quantum_phase_scale(int target, float gamma, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(gamma);
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
reg->node[i].amplitude *= quantum_cexp(gamma); reg->node[i].amplitude *= z;
} }
quantum_decohere(reg); quantum_decohere(reg);
@@ -511,11 +555,14 @@ void
quantum_phase_kick(int target, float gamma, quantum_reg *reg) quantum_phase_kick(int target, float gamma, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(gamma);
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
reg->node[i].amplitude *= quantum_cexp(gamma); reg->node[i].amplitude *= z;
} }
quantum_decohere(reg); quantum_decohere(reg);
@@ -527,14 +574,16 @@ void
quantum_cond_phase(int control, int target, quantum_reg *reg) quantum_cond_phase(int control, int target, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(pi / ((MAX_UNSIGNED) 1 << (control - target)));
for(i=0; i<reg->size; 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 << control))
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
reg->node[i].amplitude reg->node[i].amplitude *= z;
*= quantum_cexp(pi / ((MAX_UNSIGNED) 1 << (control - target)));
} }
} }
@@ -546,14 +595,16 @@ void
quantum_cond_phase_inv(int control, int target, quantum_reg *reg) quantum_cond_phase_inv(int control, int target, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(-pi / ((MAX_UNSIGNED) 1 << (control - target)));
for(i=0; i<reg->size; 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 << control))
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
reg->node[i].amplitude reg->node[i].amplitude *= z;
*= quantum_cexp(-pi / ((MAX_UNSIGNED) 1 << (control - target)));
} }
} }
@@ -566,13 +617,16 @@ void
quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg) quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg)
{ {
int i; int i;
COMPLEX_FLOAT z;
z = quantum_cexp(gamma);
for(i=0; i<reg->size; 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 << control))
{ {
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)) if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
reg->node[i].amplitude *= quantum_cexp(gamma); reg->node[i].amplitude *= z;
} }
} }
quantum_decohere(reg); quantum_decohere(reg);

View File

@@ -31,6 +31,8 @@
extern void quantum_cnot(int control, int target, quantum_reg *reg); extern void quantum_cnot(int control, int target, quantum_reg *reg);
extern void quantum_toffoli(int control1, int control2, int target, extern void quantum_toffoli(int control1, int control2, int target,
quantum_reg *reg); quantum_reg *reg);
extern void quantum_unbounded_toffoli(int controlling, quantum_reg *reg, ...);
extern void quantum_sigma_x(int target, quantum_reg *reg); extern void quantum_sigma_x(int target, quantum_reg *reg);
extern void quantum_sigma_y(int target, quantum_reg *reg); extern void quantum_sigma_y(int target, quantum_reg *reg);
extern void quantum_sigma_z(int target, quantum_reg *reg); extern void quantum_sigma_z(int target, quantum_reg *reg);
@@ -46,7 +48,7 @@ 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_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 width, quantum_reg *reg);
extern void quantum_phase_scale(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);

View File

@@ -120,14 +120,6 @@ void grover(int target, quantum_reg *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) int main(int argc, char **argv)
{ {
quantum_reg reg; quantum_reg reg;

102
measure.c
View File

@@ -59,8 +59,8 @@ quantum_measure(quantum_reg reg)
given base state - r, return the base state as the given base state - r, return the base state as the
result. Otherwise, continue with the next base state. */ result. Otherwise, continue with the next base state. */
r -= quantum_prob(reg.node[i].amplitude); r -= quantum_prob_inline(reg.node[i].amplitude);
if(quantum_prob(reg.node[i].amplitude) >= r) if(quantum_prob_inline(reg.node[i].amplitude) >= r)
return reg.node[i].state; return reg.node[i].state;
} }
@@ -86,14 +86,14 @@ quantum_bmeasure(int pos, quantum_reg *reg)
MAX_UNSIGNED lpat=0, rpat=0, pos2; MAX_UNSIGNED lpat=0, rpat=0, pos2;
quantum_reg out; quantum_reg out;
pos2 = 1 << pos; pos2 = (MAX_UNSIGNED) 1 << pos;
/* Sum up the probability for 0 being the result */ /* Sum up the probability for 0 being the result */
for(i=0; i<reg->size; i++) for(i=0; i<reg->size; i++)
{ {
if(!(reg->node[i].state & pos2)) if(!(reg->node[i].state & pos2))
pa += quantum_prob(reg->node[i].amplitude); pa += quantum_prob_inline(reg->node[i].amplitude);
} }
/* Compare the probability for 0 with a random number and determine /* Compare the probability for 0 with a random number and determine
@@ -115,7 +115,7 @@ quantum_bmeasure(int pos, quantum_reg *reg)
reg->node[i].amplitude = 0; reg->node[i].amplitude = 0;
else else
{ {
d += quantum_prob(reg->node[i].amplitude); d += quantum_prob_inline(reg->node[i].amplitude);
size++; size++;
} }
} }
@@ -125,7 +125,7 @@ quantum_bmeasure(int pos, quantum_reg *reg)
reg->node[i].amplitude = 0; reg->node[i].amplitude = 0;
else else
{ {
d += quantum_prob(reg->node[i].amplitude); d += quantum_prob_inline(reg->node[i].amplitude);
size++; size++;
} }
} }
@@ -173,3 +173,93 @@ quantum_bmeasure(int pos, quantum_reg *reg)
*reg = out; *reg = out;
return result; return result;
} }
/* Measure a single bit, but do not remove it from the quantum
register */
int
quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg)
{
int i, j;
int size=0, result=0;
double d=0, pa=0, r;
MAX_UNSIGNED pos2;
quantum_reg out;
pos2 = (MAX_UNSIGNED) 1 << pos;
/* Sum up the probability for 0 being the result */
for(i=0; i<reg->size; i++)
{
if(!(reg->node[i].state & pos2))
pa += quantum_prob_inline(reg->node[i].amplitude);
}
/* Compare the probability for 0 with a random number and determine
the result of the measurement */
r = quantum_frand();
if (r > pa)
result = 1;
/* Eradicate all amplitudes of base states which have been ruled out
by the measurement and get the absolute of the new register */
for(i=0;i<reg->size;i++)
{
if(reg->node[i].state & pos2)
{
if(!result)
reg->node[i].amplitude = 0;
else
{
d += quantum_prob_inline(reg->node[i].amplitude);
size++;
}
}
else
{
if(result)
reg->node[i].amplitude = 0;
else
{
d += quantum_prob_inline(reg->node[i].amplitude);
size++;
}
}
}
/* Build the new quantum register */
out.size = size;
out.node = calloc(size, sizeof(quantum_reg_node));
if(!out.node)
{
printf("Not enough memory for %i-sized qubit!\n", size);
exit(1);
}
quantum_memman(size * sizeof(quantum_reg_node));
out.hashw = reg->hashw;
out.hash = reg->hash;
out.width = reg->width;
/* Determine the numbers of the new base states and norm the quantum
register */
for(i=0, j=0; i<reg->size; i++)
{
if(reg->node[i].amplitude)
{
out.node[j].state = reg->node[i].state;
out.node[j].amplitude = reg->node[i].amplitude * 1 / (float) sqrt(d);
j++;
}
}
quantum_delete_qureg_hashpreserve(reg);
*reg = out;
return result;
}

View File

@@ -33,5 +33,6 @@ extern double quantum_frand();
extern MAX_UNSIGNED quantum_measure(quantum_reg reg); extern MAX_UNSIGNED quantum_measure(quantum_reg reg);
extern int quantum_bmeasure(int pos, quantum_reg *reg); extern int quantum_bmeasure(int pos, quantum_reg *reg);
extern int quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg);
#endif #endif

1
qec.c
View File

@@ -27,6 +27,7 @@
#include "gates.h" #include "gates.h"
#include "config.h" #include "config.h"
#include "decoherence.h" #include "decoherence.h"
#include "measure.h"
/* Type of the QEC. Currently implemented versions are: /* Type of the QEC. Currently implemented versions are:

22
qft.c
View File

@@ -40,10 +40,20 @@ void quantum_qft(int width, quantum_reg *reg)
quantum_hadamard(i, reg); quantum_hadamard(i, reg);
} }
for(i=0; i<width/2; i++) }
{
quantum_cnot(i, width-i-1, reg);
quantum_cnot(width-i-1, i, reg); void quantum_qft_inv(int width, quantum_reg *reg)
quantum_cnot(i, width-i-1, reg); {
} int i, j;
for(i=0; i<width; i++)
{
quantum_hadamard(i, reg);
for(j=i+1; j<width; j++)
quantum_cond_phase_inv(j, i, reg);
}
} }

4
qft.h
View File

@@ -1,4 +1,4 @@
/* qft.c: Declarations for qft.c /* qft.h: Declarations for qft.c
Copyright 2003 Bjoern Butscher, Hendrik Weimer Copyright 2003 Bjoern Butscher, Hendrik Weimer
@@ -27,4 +27,6 @@
extern void quantum_qft(int width, quantum_reg *reg); extern void quantum_qft(int width, quantum_reg *reg);
extern void quantum_qft_inv(int width, quantum_reg *reg);
#endif #endif

View File

@@ -46,16 +46,6 @@ struct quantum_reg_node_struct
typedef struct quantum_reg_node_struct quantum_reg_node; typedef struct quantum_reg_node_struct quantum_reg_node;
/* One element of the hash table */
struct quantum_reg_hash_struct
{
int i;
struct quantum_reg_hash_struct *next;
};
typedef struct quantum_reg_hash_struct quantum_reg_hash;
/* The quantum register */ /* The quantum register */
struct quantum_reg_struct struct quantum_reg_struct
@@ -64,7 +54,7 @@ struct quantum_reg_struct
int size; /* number of non-zero vectors */ int size; /* number of non-zero vectors */
int hashw; /* width of the hash array */ int hashw; /* width of the hash array */
quantum_reg_node *node; quantum_reg_node *node;
quantum_reg_hash **hash; int *hash;
}; };
typedef struct quantum_reg_struct quantum_reg; typedef struct quantum_reg_struct quantum_reg;
@@ -77,6 +67,7 @@ extern void quantum_addscratch(int bits, quantum_reg *reg);
extern void quantum_cnot(int control, int target, quantum_reg *reg); extern void quantum_cnot(int control, int target, quantum_reg *reg);
extern void quantum_toffoli(int control1, int control2, int target, extern void quantum_toffoli(int control1, int control2, int target,
quantum_reg *reg); quantum_reg *reg);
extern void quantum_unbounded_toffoli(int controlling, quantum_reg *reg, ...);
extern void quantum_sigma_x(int target, quantum_reg *reg); extern void quantum_sigma_x(int target, quantum_reg *reg);
extern void quantum_sigma_y(int target, quantum_reg *reg); extern void quantum_sigma_y(int target, quantum_reg *reg);
extern void quantum_sigma_z(int target, quantum_reg *reg); extern void quantum_sigma_z(int target, quantum_reg *reg);
@@ -87,7 +78,7 @@ 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_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 width, 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_inv(int control, int target, quantum_reg *reg);
extern void quantum_cond_phase_kick(int control, int target, float gamma, extern void quantum_cond_phase_kick(int control, int target, float gamma,
@@ -95,12 +86,14 @@ extern void quantum_cond_phase_kick(int control, int target, float gamma,
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);
extern void quantum_qft_inv(int width, quantum_reg *reg);
extern void quantum_exp_mod_n(int N, int x, int width_input, int width, extern void quantum_exp_mod_n(int N, int x, int width_input, int width,
quantum_reg *reg); quantum_reg *reg);
extern MAX_UNSIGNED quantum_measure(quantum_reg reg); extern MAX_UNSIGNED quantum_measure(quantum_reg reg);
extern int quantum_bmeasure(int pos, quantum_reg *reg); extern int quantum_bmeasure(int pos, quantum_reg *reg);
extern int quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg);
extern quantum_matrix quantum_new_matrix(int cols, int rows); extern quantum_matrix quantum_new_matrix(int cols, int rows);
extern void quantum_delete_matrix(quantum_matrix *m); extern void quantum_delete_matrix(quantum_matrix *m);
@@ -123,4 +116,6 @@ extern quantum_matrix quantum_qureg2matrix(quantum_reg reg);
extern void quantum_qec_encode(int type, int width, 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); extern void quantum_qec_decode(int type, int width, quantum_reg *reg);
extern const char * quantum_get_version();
#endif #endif

145
qureg.c
View File

@@ -69,13 +69,13 @@ quantum_matrix2qureg(quantum_matrix *m, int width)
/* Allocate the hash table */ /* Allocate the hash table */
reg.hash = calloc(1 << reg.hashw, sizeof(quantum_reg_hash *)); reg.hash = calloc(1 << reg.hashw, sizeof(int));
if(!reg.hash) if(!reg.hash)
{ {
printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw); printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw);
exit(1); exit(1);
} }
quantum_memman((1 << reg.hashw) * sizeof(quantum_reg_hash *)); quantum_memman((1 << reg.hashw) * sizeof(int));
/* Copy the nonzero amplitudes of the vector into the quantum /* Copy the nonzero amplitudes of the vector into the quantum
register */ register */
@@ -120,13 +120,13 @@ quantum_new_qureg(MAX_UNSIGNED initval, int width)
/* Allocate the hash table */ /* Allocate the hash table */
reg.hash = calloc(1 << reg.hashw, sizeof(quantum_reg_hash *)); reg.hash = calloc(1 << reg.hashw, sizeof(int));
if(!reg.hash) if(!reg.hash)
{ {
printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw); printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw);
exit(1); exit(1);
} }
quantum_memman((1 << reg.hashw) * sizeof(quantum_reg_hash *)); quantum_memman((1 << reg.hashw) * sizeof(int));
/* Initialize the quantum register */ /* Initialize the quantum register */
@@ -161,22 +161,8 @@ quantum_qureg2matrix(quantum_reg reg)
void void
quantum_destroy_hash(quantum_reg *reg) 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); free(reg->hash);
quantum_memman(-(1 << reg->hashw) * sizeof(quantum_reg_hash *)); quantum_memman(-(1 << reg->hashw) * sizeof(int));
} }
/* Delete a quantum register */ /* Delete a quantum register */
@@ -205,12 +191,16 @@ quantum_delete_qureg_hashpreserve(quantum_reg *reg)
void void
quantum_print_qureg(quantum_reg reg) quantum_print_qureg(quantum_reg reg)
{ {
int i; int i,j;
for(i=0; i<reg.size; i++) for(i=0; i<reg.size; i++)
{ {
printf("%f %+fi|%lli>\n", quantum_real(reg.node[i].amplitude), printf("%f %+fi|%lli> (%e) (|", quantum_real(reg.node[i].amplitude),
quantum_imag(reg.node[i].amplitude), reg.node[i].state); quantum_imag(reg.node[i].amplitude), reg.node[i].state,
quantum_prob_inline(reg.node[i].amplitude));
for(j=reg.width-1;j>=0;j--)
printf("%i", ((((MAX_UNSIGNED) 1 << j) & reg.node[i].state) > 0));
printf(">)\n");
} }
printf("\n"); printf("\n");
@@ -249,122 +239,19 @@ quantum_addscratch(int bits, quantum_reg *reg)
} }
} }
/* Add an element to the hash table */
void
quantum_add_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg)
{
int i;
quantum_reg_hash *p;
i = quantum_hash64(a, reg->hashw);
p = calloc(1, sizeof(quantum_reg_hash));
if(!p)
{
printf("Not enough memory for hash element!\n");
exit(1);
}
quantum_memman(sizeof(quantum_reg_hash));
p->i = pos;
p->next = reg->hash[i];
reg->hash[i] = p;
}
/* Remove an element from the hash table */
void
delete_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg)
{
int i;
quantum_reg_hash *p, *q=0;
i = quantum_hash64(a, reg->hashw);
p = reg->hash[i];
while(p->i != pos)
{
q = p;
p = p->next;
}
if(q)
{
q->next = p->next;
free(p);
}
else
{
if(p)
{
reg->hash[i] = p->next;
free(p);
}
else
{
reg->hash[i] = 0;
free(reg->hash[i]);
}
}
}
/* Print the hash table to stdout and test if the hash table is /* Print the hash table to stdout and test if the hash table is
corrupted */ corrupted */
void void
print_hash(quantum_reg reg) quantum_print_hash(quantum_reg reg)
{ {
int i; int i;
quantum_reg_hash *p;
char *done;
done = calloc(reg.size, sizeof(char));
if(!done)
{
printf("Not enough memory for %i bytes array!\n",
(reg.size)*sizeof(char));
exit(1);
}
for(i=0; i < (1 << reg.hashw); i++) for(i=0; i < (1 << reg.hashw); i++)
{ {
printf("%i: ", i); if(i)
printf("%i: %i %llu\n", i, reg.hash[i]-1,
if(reg.hash[i]) reg.node[reg.hash[i]-1].state);
{
p = reg.hash[i];
while(p->next)
{
printf("%llu ", reg.node[p->i].state);
if(quantum_hash64(reg.node[p->i].state, reg.hashw) != i)
printf(" Corrupted hash table!\n... ");
done[p->i] = 1;
p = p->next;
}
printf("%llu", reg.node[p->i].state);
if(quantum_hash64(reg.node[p->i].state, reg.hashw) != i)
printf(" Corrupted hash table!");
done[p->i] = 1;
}
printf("\n");
} }
/* Test if there are elements in the quantum register which are not
in the hash table */
for(i=0; i<reg.size; i++)
{
if(!done[i])
printf("Corrupted hash table: %llu is detached!\n", reg.node[i].state);
}
free(done);
} }

64
qureg.h
View File

@@ -40,16 +40,6 @@ struct quantum_reg_node_struct
typedef struct quantum_reg_node_struct quantum_reg_node; typedef struct quantum_reg_node_struct quantum_reg_node;
/* One element of the hash table */
struct quantum_reg_hash_struct
{
int i;
struct quantum_reg_hash_struct *next;
};
typedef struct quantum_reg_hash_struct quantum_reg_hash;
/* The quantum register */ /* The quantum register */
struct quantum_reg_struct struct quantum_reg_struct
@@ -58,7 +48,7 @@ struct quantum_reg_struct
int size; /* number of non-zero vectors */ int size; /* number of non-zero vectors */
int hashw; /* width of the hash array */ int hashw; /* width of the hash array */
quantum_reg_node *node; quantum_reg_node *node;
quantum_reg_hash **hash; int *hash;
}; };
typedef struct quantum_reg_struct quantum_reg; typedef struct quantum_reg_struct quantum_reg;
@@ -75,8 +65,6 @@ extern void quantum_print_expn(quantum_reg reg);
extern void quantum_addscratch(int bits, quantum_reg *reg); extern void quantum_addscratch(int bits, quantum_reg *reg);
extern void quantum_add_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg);
extern void quantum_delete_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg);
extern void quantum_print_hash(quantum_reg reg); extern void quantum_print_hash(quantum_reg reg);
/* Our 64-bit multiplicative hash function */ /* Our 64-bit multiplicative hash function */
@@ -100,56 +88,40 @@ static inline int
quantum_get_state(MAX_UNSIGNED a, quantum_reg reg) quantum_get_state(MAX_UNSIGNED a, quantum_reg reg)
{ {
int i; int i;
quantum_reg_hash *p;
i = quantum_hash64(a, reg.hashw); i = quantum_hash64(a, reg.hashw);
if(reg.hash[i]) while(reg.hash[i])
{ {
p = reg.hash[i]; if(reg.node[reg.hash[i]-1].state == a)
return reg.hash[i]-1;
do i++;
{ if(i == (1 << reg.hashw))
if(reg.node[p->i].state == a) i = 0;
return p->i;
if(p->next)
p = p->next;
} while(p->next);
if(reg.node[p->i].state == a)
return p->i;
} }
return -1; return -1;
} }
/* Update an element of the hash table */ /* Add an element to the hash table */
static inline void static inline void
quantum_change_hash(MAX_UNSIGNED a, int oldpos, MAX_UNSIGNED b, int pos, quantum_add_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg)
quantum_reg *reg)
{ {
int i, j; int i;
quantum_reg_hash *p, *q=0;
i = quantum_hash64(a, reg->hashw); i = quantum_hash64(a, reg->hashw);
p = reg->hash[i]; while(reg->hash[i])
q = reg->hash[i]; {
j = p->i; i++;
if(i == (1 << reg->hashw))
i = 0;
}
while(p->i != oldpos) reg->hash[i] = pos+1;
p = p->next;
p->i = j;
reg->hash[i] = q->next;
i = quantum_hash64(b, reg->hashw);
q->next = reg->hash[i];
reg->hash[i] = q;
q->i = pos;
} }
#endif #endif

7
shor.c
View File

@@ -81,6 +81,13 @@ int main(int argc, char **argv) {
quantum_qft(width, &qr); quantum_qft(width, &qr);
for(i=0; i<width/2; i++)
{
quantum_cnot(i, width-i-1, &qr);
quantum_cnot(width-i-1, i, &qr);
quantum_cnot(i, width-i-1, &qr);
}
// quantum_print_qureg(qr); // quantum_print_qureg(qr);
c=quantum_measure(qr); c=quantum_measure(qr);

30
version.c Normal file
View File

@@ -0,0 +1,30 @@
/* version.c: libquantum version information
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 "config.h"
const char *
quantum_get_version()
{
return PACKAGE_VERSION;
}

30
version.h Normal file
View File

@@ -0,0 +1,30 @@
/* version.h: Declarations for version.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 __VERSION_H
#define __VERSION_H
extern const char * quantum_get_version();
#endif