mirror of
https://github.com/libquantum/libquantum.git
synced 2025-10-03 08:42:01 +00:00
updated libquantum 0.2.1 source files
This commit is contained in:
12
CHANGES
12
CHANGES
@@ -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:
|
||||
- Added Quantum Error Correction
|
||||
- Included an Implementation of Grover's algorithm
|
||||
|
6
INSTALL
6
INSTALL
@@ -1,4 +1,4 @@
|
||||
libquantum 0.2.0 installation guide
|
||||
libquantum 0.2.1 installation guide
|
||||
-----------------------------------
|
||||
|
||||
Contents:
|
||||
@@ -13,7 +13,7 @@ Contents:
|
||||
---------------
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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:
|
||||
|
||||
|
44
Makefile.in
44
Makefile.in
@@ -26,44 +26,44 @@ SHELL=/bin/sh
|
||||
# Target directory prefix
|
||||
|
||||
PREFIX=@prefix@
|
||||
EPREFIX=${PREFIX}
|
||||
|
||||
# Other directories
|
||||
|
||||
LIBDIR=${PREFIX}/lib
|
||||
LIBDIR=${EPREFIX}/lib
|
||||
INCLUDEDIR=${PREFIX}/include
|
||||
top_builddir=.
|
||||
|
||||
# Release information
|
||||
# Version information
|
||||
|
||||
MAJOR=0
|
||||
MINOR=2
|
||||
RELEASE=0
|
||||
VERSION=@PACKAGE_VERSION@
|
||||
|
||||
# Tools needed to build libquantum
|
||||
|
||||
CC=@CC@ -O2 -g -pg
|
||||
CC=@CC@
|
||||
INSTALL=@INSTALL@
|
||||
LIBTOOL=@LIBTOOL@
|
||||
|
||||
# Flags passed to C compiler
|
||||
|
||||
CFLAGS=@CFLAGS@
|
||||
LDFLAGS=-rpath $(LIBDIR) -version-info 2:0:2
|
||||
LDFLAGS=-rpath $(LIBDIR) -version-info 3:0:0
|
||||
|
||||
# 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 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\
|
||||
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
|
||||
$(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
|
||||
|
||||
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
|
||||
$(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
|
||||
|
||||
# Bring this savage back home
|
||||
|
||||
install: libquantum.la
|
||||
$(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR)
|
||||
$(INSTALL) -m 0644 quantum.h $(INCLUDEDIR)
|
||||
version.lo: version.c version.h config.h Makefile
|
||||
$(LIBTOOL) $(CC) $(CFLAGS) -c version.c
|
||||
|
||||
# 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\
|
||||
-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
|
||||
|
||||
clean:
|
||||
@@ -127,10 +130,9 @@ distclean:
|
||||
|
||||
dist:
|
||||
-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\
|
||||
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)
|
||||
CHANGES libquantum-$(VERSION)
|
||||
tar czf libquantum-$(VERSION).tar.gz libquantum-$(VERSION)/
|
||||
rm -rf libquantum-$(VERSION)
|
||||
|
2
README
2
README
@@ -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
|
||||
|
20
complex.c
20
complex.c
@@ -26,24 +26,6 @@
|
||||
#include "complex.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 */
|
||||
|
||||
COMPLEX_FLOAT
|
||||
@@ -62,7 +44,7 @@ quantum_conj(COMPLEX_FLOAT a)
|
||||
float
|
||||
quantum_prob(COMPLEX_FLOAT a)
|
||||
{
|
||||
return (float) (a * quantum_conj(a));
|
||||
return quantum_prob_inline(a);
|
||||
}
|
||||
|
||||
/* Calculate e^(i * phi) */
|
||||
|
33
complex.h
33
complex.h
@@ -27,11 +27,40 @@
|
||||
|
||||
#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 float quantum_prob (COMPLEX_FLOAT a);
|
||||
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
|
||||
|
48
configure
vendored
48
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.2.0.
|
||||
# Generated by GNU Autoconf 2.57 for libquantum 0.2.1.
|
||||
#
|
||||
# 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.2.0'
|
||||
PACKAGE_STRING='libquantum 0.2.0'
|
||||
PACKAGE_VERSION='0.2.1'
|
||||
PACKAGE_STRING='libquantum 0.2.1'
|
||||
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.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]...
|
||||
|
||||
@@ -999,7 +999,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of libquantum 0.2.0:";;
|
||||
short | recursive ) echo "Configuration of libquantum 0.2.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1010,6 +1010,7 @@ Optional Features:
|
||||
--enable-static=PKGS build static libraries default=yes
|
||||
--enable-fast-install=PKGS optimize for fast installation default=yes
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--enable-profiling compile with profiling support
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@@ -1092,7 +1093,7 @@ fi
|
||||
test -n "$ac_init_help" && exit 0
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
libquantum configure 0.2.0
|
||||
libquantum configure 0.2.1
|
||||
generated by GNU Autoconf 2.57
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
$ $0 $@
|
||||
@@ -2225,12 +2226,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(exit $ac_status); }; }; then
|
||||
for ac_declaration in \
|
||||
''\
|
||||
'#include <stdlib.h>' \
|
||||
'extern "C" void std::exit (int) throw (); using std::exit;' \
|
||||
'extern "C" void std::exit (int); using std::exit;' \
|
||||
'extern "C" void exit (int) throw ();' \
|
||||
'extern "C" void exit (int);' \
|
||||
'void exit (int);'
|
||||
'void exit (int);' \
|
||||
'#include <stdlib.h>'
|
||||
do
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
#line $LINENO "configure"
|
||||
@@ -4130,7 +4131,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
|
||||
case $host in
|
||||
*-*-irix6*)
|
||||
# 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
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -4673,7 +4674,7 @@ chmod -w .
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
|
||||
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
|
||||
# So say no if there are warnings
|
||||
if test -s out/conftest.err; then
|
||||
@@ -6556,7 +6557,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 6559 "configure"
|
||||
#line 6560 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -6654,7 +6655,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 6657 "configure"
|
||||
#line 6658 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -7391,7 +7392,6 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
|
||||
|
||||
|
||||
# Checks for libraries.
|
||||
# FIXME: Replace `main' with a function in `-lm':
|
||||
|
||||
echo "$as_me:$LINENO: checking for sqrt in -lm" >&5
|
||||
echo $ECHO_N "checking for sqrt in -lm... $ECHO_C" >&6
|
||||
@@ -8255,9 +8255,24 @@ fi
|
||||
echo "$as_me:$LINENO: result: $I" >&5
|
||||
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"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
@@ -8620,7 +8635,7 @@ _ASBOX
|
||||
} >&5
|
||||
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
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -8680,7 +8695,7 @@ _ACEOF
|
||||
|
||||
cat >>$CONFIG_STATUS <<_ACEOF
|
||||
ac_cs_version="\\
|
||||
libquantum config.status 0.2.0
|
||||
libquantum config.status 0.2.1
|
||||
configured by $0, generated by GNU Autoconf 2.57,
|
||||
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.
|
||||
$ac_cs_success || { (exit 1); exit 1; }
|
||||
fi
|
||||
|
||||
|
17
configure.in
17
configure.in
@@ -1,5 +1,5 @@
|
||||
# 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_HEADER([config.h])
|
||||
|
||||
@@ -12,7 +12,6 @@ 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.
|
||||
@@ -72,8 +71,22 @@ then
|
||||
fi
|
||||
AC_MSG_RESULT($I)
|
||||
|
||||
# Substitute fields in quantum.h.in
|
||||
AC_SUBST(MU_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_OUTPUT
|
194
gates.c
194
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
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "matrix.h"
|
||||
#include "defs.h"
|
||||
@@ -48,7 +49,7 @@ quantum_cnot(int control, int target, quantum_reg *reg)
|
||||
{
|
||||
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)))
|
||||
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++)
|
||||
{
|
||||
/* 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 */
|
||||
|
||||
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 */
|
||||
|
||||
void
|
||||
@@ -104,7 +152,7 @@ quantum_sigma_x(int target, quantum_reg *reg)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -121,7 +169,7 @@ quantum_sigma_y(int target, quantum_reg *reg)
|
||||
|
||||
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 */
|
||||
|
||||
reg->node[i].state ^= ((MAX_UNSIGNED) 1 << target);
|
||||
@@ -221,12 +269,12 @@ quantum_swaptheleads_omuln_controlled(int control, int width, quantum_reg *reg)
|
||||
void
|
||||
quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
||||
{
|
||||
int i, j, k;
|
||||
int i, j, k, iset;
|
||||
int addsize=0, decsize=0;
|
||||
COMPLEX_FLOAT t, tnot=0;
|
||||
float limit;
|
||||
char *done;
|
||||
quantum_reg out;
|
||||
quantum_reg_hash *p;
|
||||
// quantum_reg_hash *p;
|
||||
|
||||
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++)
|
||||
{
|
||||
while(reg->hash[i])
|
||||
/* while(reg->hash[i])
|
||||
{
|
||||
p = reg->hash[i]->next;
|
||||
free(reg->hash[i]);
|
||||
quantum_memman(-sizeof(quantum_reg_hash));
|
||||
reg->hash[i] = p;
|
||||
}
|
||||
}*/
|
||||
reg->hash[i] = 0;
|
||||
}
|
||||
|
||||
for(i=0; i<reg->size; i++)
|
||||
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++)
|
||||
{
|
||||
@@ -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->size + addsize) * sizeof(quantum_reg_node));
|
||||
@@ -295,12 +344,18 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
||||
|
||||
k = reg->size;
|
||||
|
||||
limit = (1.0 / ((MAX_UNSIGNED) 1 << reg->width)) / 1000000;
|
||||
|
||||
/* perform the actual matrix multiplication */
|
||||
|
||||
for(i=0; i<reg->size; 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;
|
||||
j = quantum_get_state(reg->node[i].state
|
||||
^ ((MAX_UNSIGNED) 1<<target), *reg);
|
||||
@@ -309,7 +364,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
||||
if(j >= 0)
|
||||
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;
|
||||
|
||||
else
|
||||
@@ -317,7 +372,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
&& (reg->node[i].state & ((MAX_UNSIGNED) 1 << target)))
|
||||
if((m.t[1] == 0) && (iset))
|
||||
break;
|
||||
if((m.t[2] == 0)
|
||||
&& !(reg->node[i].state & ((MAX_UNSIGNED) 1 << target)))
|
||||
if((m.t[2] == 0) && !(iset))
|
||||
break;
|
||||
|
||||
reg->node[k].state = reg->node[i].state
|
||||
^ ((MAX_UNSIGNED) 1 << target);
|
||||
|
||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
|
||||
if(iset)
|
||||
reg->node[k].amplitude = m.t[1] * t;
|
||||
|
||||
else
|
||||
@@ -350,14 +403,6 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg)
|
||||
if(j >= 0)
|
||||
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);
|
||||
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)
|
||||
{
|
||||
out.width = reg->width;
|
||||
out.size = reg->size - decsize;
|
||||
out.node = calloc(out.size, sizeof(quantum_reg_node));
|
||||
if(!out.node)
|
||||
reg->size -= decsize;
|
||||
reg->node = realloc(reg->node, reg->size * sizeof(quantum_reg_node));
|
||||
if(!reg->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);
|
||||
}
|
||||
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);
|
||||
@@ -417,21 +461,15 @@ quantum_hadamard(int target, quantum_reg *reg)
|
||||
|
||||
}
|
||||
|
||||
/* Apply a walsh-hadamard gate */
|
||||
/* Apply a walsh-hadamard transform */
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
for(i=0; i<width; i++)
|
||||
quantum_hadamard(i, reg);
|
||||
|
||||
}
|
||||
|
||||
@@ -477,13 +515,16 @@ void
|
||||
quantum_r_z(int target, float gamma, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(gamma/2);
|
||||
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
|
||||
reg->node[i].amplitude *= quantum_cexp(gamma/2);
|
||||
reg->node[i].amplitude *= z;
|
||||
else
|
||||
reg->node[i].amplitude *= quantum_cexp(-gamma/2);
|
||||
reg->node[i].amplitude /= z;
|
||||
}
|
||||
|
||||
quantum_decohere(reg);
|
||||
@@ -495,10 +536,13 @@ void
|
||||
quantum_phase_scale(int target, float gamma, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(gamma);
|
||||
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
reg->node[i].amplitude *= quantum_cexp(gamma);
|
||||
reg->node[i].amplitude *= z;
|
||||
}
|
||||
|
||||
quantum_decohere(reg);
|
||||
@@ -511,11 +555,14 @@ void
|
||||
quantum_phase_kick(int target, float gamma, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(gamma);
|
||||
|
||||
for(i=0; i<reg->size; i++)
|
||||
{
|
||||
if(reg->node[i].state & ((MAX_UNSIGNED) 1 << target))
|
||||
reg->node[i].amplitude *= quantum_cexp(gamma);
|
||||
reg->node[i].amplitude *= z;
|
||||
}
|
||||
|
||||
quantum_decohere(reg);
|
||||
@@ -527,14 +574,16 @@ void
|
||||
quantum_cond_phase(int control, int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(pi / ((MAX_UNSIGNED) 1 << (control - target)));
|
||||
|
||||
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)));
|
||||
reg->node[i].amplitude *= z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,14 +595,16 @@ void
|
||||
quantum_cond_phase_inv(int control, int target, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(-pi / ((MAX_UNSIGNED) 1 << (control - target)));
|
||||
|
||||
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)));
|
||||
reg->node[i].amplitude *= z;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,13 +617,16 @@ void
|
||||
quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg)
|
||||
{
|
||||
int i;
|
||||
COMPLEX_FLOAT z;
|
||||
|
||||
z = quantum_cexp(gamma);
|
||||
|
||||
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);
|
||||
reg->node[i].amplitude *= z;
|
||||
}
|
||||
}
|
||||
quantum_decohere(reg);
|
||||
|
4
gates.h
4
gates.h
@@ -31,6 +31,8 @@
|
||||
extern void quantum_cnot(int control, int target, quantum_reg *reg);
|
||||
extern void quantum_toffoli(int control1, int control2, int target,
|
||||
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_y(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_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_kick(int target, float gamma, quantum_reg *reg);
|
||||
|
8
grover.c
8
grover.c
@@ -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)
|
||||
{
|
||||
quantum_reg reg;
|
||||
|
102
measure.c
102
measure.c
@@ -59,8 +59,8 @@ quantum_measure(quantum_reg reg)
|
||||
given base state - r, return the base state as the
|
||||
result. Otherwise, continue with the next base state. */
|
||||
|
||||
r -= quantum_prob(reg.node[i].amplitude);
|
||||
if(quantum_prob(reg.node[i].amplitude) >= r)
|
||||
r -= quantum_prob_inline(reg.node[i].amplitude);
|
||||
if(quantum_prob_inline(reg.node[i].amplitude) >= r)
|
||||
return reg.node[i].state;
|
||||
}
|
||||
|
||||
@@ -86,14 +86,14 @@ quantum_bmeasure(int pos, quantum_reg *reg)
|
||||
MAX_UNSIGNED lpat=0, rpat=0, pos2;
|
||||
quantum_reg out;
|
||||
|
||||
pos2 = 1 << pos;
|
||||
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(reg->node[i].amplitude);
|
||||
pa += quantum_prob_inline(reg->node[i].amplitude);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
else
|
||||
{
|
||||
d += quantum_prob(reg->node[i].amplitude);
|
||||
d += quantum_prob_inline(reg->node[i].amplitude);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ quantum_bmeasure(int pos, quantum_reg *reg)
|
||||
reg->node[i].amplitude = 0;
|
||||
else
|
||||
{
|
||||
d += quantum_prob(reg->node[i].amplitude);
|
||||
d += quantum_prob_inline(reg->node[i].amplitude);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
@@ -173,3 +173,93 @@ quantum_bmeasure(int pos, quantum_reg *reg)
|
||||
*reg = out;
|
||||
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;
|
||||
}
|
||||
|
@@ -33,5 +33,6 @@ extern double quantum_frand();
|
||||
|
||||
extern MAX_UNSIGNED quantum_measure(quantum_reg reg);
|
||||
extern int quantum_bmeasure(int pos, quantum_reg *reg);
|
||||
extern int quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg);
|
||||
|
||||
#endif
|
||||
|
1
qec.c
1
qec.c
@@ -27,6 +27,7 @@
|
||||
#include "gates.h"
|
||||
#include "config.h"
|
||||
#include "decoherence.h"
|
||||
#include "measure.h"
|
||||
|
||||
/* Type of the QEC. Currently implemented versions are:
|
||||
|
||||
|
22
qft.c
22
qft.c
@@ -40,10 +40,20 @@ void quantum_qft(int width, quantum_reg *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);
|
||||
quantum_cnot(i, width-i-1, reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void quantum_qft_inv(int width, quantum_reg *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
4
qft.h
@@ -1,4 +1,4 @@
|
||||
/* qft.c: Declarations for qft.c
|
||||
/* qft.h: Declarations for qft.c
|
||||
|
||||
Copyright 2003 Bjoern Butscher, Hendrik Weimer
|
||||
|
||||
@@ -27,4 +27,6 @@
|
||||
|
||||
extern void quantum_qft(int width, quantum_reg *reg);
|
||||
|
||||
extern void quantum_qft_inv(int width, quantum_reg *reg);
|
||||
|
||||
#endif
|
||||
|
19
quantum.h.in
19
quantum.h.in
@@ -46,16 +46,6 @@ struct quantum_reg_node_struct
|
||||
|
||||
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 */
|
||||
|
||||
struct quantum_reg_struct
|
||||
@@ -64,7 +54,7 @@ struct quantum_reg_struct
|
||||
int size; /* number of non-zero vectors */
|
||||
int hashw; /* width of the hash array */
|
||||
quantum_reg_node *node;
|
||||
quantum_reg_hash **hash;
|
||||
int *hash;
|
||||
};
|
||||
|
||||
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_toffoli(int control1, int control2, int target,
|
||||
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_y(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_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_walsh(int width, 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,
|
||||
@@ -95,12 +86,14 @@ extern void quantum_cond_phase_kick(int control, int target, float gamma,
|
||||
extern int quantum_gate_counter(int inc);
|
||||
|
||||
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,
|
||||
quantum_reg *reg);
|
||||
|
||||
extern MAX_UNSIGNED quantum_measure(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 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_decode(int type, int width, quantum_reg *reg);
|
||||
|
||||
extern const char * quantum_get_version();
|
||||
|
||||
#endif
|
||||
|
145
qureg.c
145
qureg.c
@@ -69,13 +69,13 @@ quantum_matrix2qureg(quantum_matrix *m, int width)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw);
|
||||
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
|
||||
register */
|
||||
@@ -120,13 +120,13 @@ quantum_new_qureg(MAX_UNSIGNED initval, int width)
|
||||
|
||||
/* 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)
|
||||
{
|
||||
printf("Not enough memory for %i-sized hash!\n", 1 << reg.hashw);
|
||||
exit(1);
|
||||
}
|
||||
quantum_memman((1 << reg.hashw) * sizeof(quantum_reg_hash *));
|
||||
quantum_memman((1 << reg.hashw) * sizeof(int));
|
||||
|
||||
/* Initialize the quantum register */
|
||||
|
||||
@@ -161,22 +161,8 @@ quantum_qureg2matrix(quantum_reg reg)
|
||||
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 *));
|
||||
quantum_memman(-(1 << reg->hashw) * sizeof(int));
|
||||
}
|
||||
|
||||
/* Delete a quantum register */
|
||||
@@ -205,12 +191,16 @@ quantum_delete_qureg_hashpreserve(quantum_reg *reg)
|
||||
void
|
||||
quantum_print_qureg(quantum_reg reg)
|
||||
{
|
||||
int i;
|
||||
int i,j;
|
||||
|
||||
for(i=0; i<reg.size; i++)
|
||||
{
|
||||
printf("%f %+fi|%lli>\n", quantum_real(reg.node[i].amplitude),
|
||||
quantum_imag(reg.node[i].amplitude), reg.node[i].state);
|
||||
printf("%f %+fi|%lli> (%e) (|", quantum_real(reg.node[i].amplitude),
|
||||
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");
|
||||
@@ -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
|
||||
corrupted */
|
||||
|
||||
void
|
||||
print_hash(quantum_reg reg)
|
||||
quantum_print_hash(quantum_reg reg)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
printf("%i: ", i);
|
||||
|
||||
if(reg.hash[i])
|
||||
{
|
||||
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");
|
||||
if(i)
|
||||
printf("%i: %i %llu\n", i, reg.hash[i]-1,
|
||||
reg.node[reg.hash[i]-1].state);
|
||||
}
|
||||
|
||||
/* 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
64
qureg.h
@@ -40,16 +40,6 @@ struct quantum_reg_node_struct
|
||||
|
||||
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 */
|
||||
|
||||
struct quantum_reg_struct
|
||||
@@ -58,7 +48,7 @@ struct quantum_reg_struct
|
||||
int size; /* number of non-zero vectors */
|
||||
int hashw; /* width of the hash array */
|
||||
quantum_reg_node *node;
|
||||
quantum_reg_hash **hash;
|
||||
int *hash;
|
||||
};
|
||||
|
||||
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_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);
|
||||
|
||||
/* Our 64-bit multiplicative hash function */
|
||||
@@ -100,56 +88,40 @@ static inline int
|
||||
quantum_get_state(MAX_UNSIGNED a, quantum_reg reg)
|
||||
{
|
||||
int i;
|
||||
quantum_reg_hash *p;
|
||||
|
||||
i = quantum_hash64(a, reg.hashw);
|
||||
|
||||
if(reg.hash[i])
|
||||
while(reg.hash[i])
|
||||
{
|
||||
p = reg.hash[i];
|
||||
|
||||
do
|
||||
{
|
||||
if(reg.node[p->i].state == a)
|
||||
return p->i;
|
||||
if(p->next)
|
||||
p = p->next;
|
||||
} while(p->next);
|
||||
|
||||
if(reg.node[p->i].state == a)
|
||||
return p->i;
|
||||
if(reg.node[reg.hash[i]-1].state == a)
|
||||
return reg.hash[i]-1;
|
||||
i++;
|
||||
if(i == (1 << reg.hashw))
|
||||
i = 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
/* Update an element of the hash table */
|
||||
/* Add an element to the hash table */
|
||||
|
||||
static inline void
|
||||
quantum_change_hash(MAX_UNSIGNED a, int oldpos, MAX_UNSIGNED b, int pos,
|
||||
quantum_reg *reg)
|
||||
quantum_add_hash(MAX_UNSIGNED a, int pos, quantum_reg *reg)
|
||||
{
|
||||
int i, j;
|
||||
quantum_reg_hash *p, *q=0;
|
||||
int i;
|
||||
|
||||
i = quantum_hash64(a, reg->hashw);
|
||||
|
||||
p = reg->hash[i];
|
||||
q = reg->hash[i];
|
||||
j = p->i;
|
||||
while(reg->hash[i])
|
||||
{
|
||||
i++;
|
||||
if(i == (1 << reg->hashw))
|
||||
i = 0;
|
||||
}
|
||||
|
||||
while(p->i != oldpos)
|
||||
p = p->next;
|
||||
reg->hash[i] = pos+1;
|
||||
|
||||
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
|
||||
|
||||
|
7
shor.c
7
shor.c
@@ -81,6 +81,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
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);
|
||||
|
||||
c=quantum_measure(qr);
|
||||
|
30
version.c
Normal file
30
version.c
Normal 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
30
version.h
Normal 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
|
Reference in New Issue
Block a user