From 8f37efac2491d92b33a1b067beae1d397cc1b8c0 Mon Sep 17 00:00:00 2001 From: libquantum Date: Thu, 27 Oct 2016 04:16:13 +0900 Subject: [PATCH] updated libquantum 0.2.2 source files --- CHANGES | 6 + INSTALL | 34 +++- Makefile.in | 39 ++++- README | 4 +- config.h.in | 2 + configure | 97 +++++++---- configure.in | 41 +++-- decoherence.c | 2 +- gates.c | 61 +++++-- grover.c | 3 + measure.c | 10 ++ objcode.c | 448 ++++++++++++++++++++++++++++++++++++++++++++++++++ objcode.h | 67 ++++++++ quantum.h.in | 5 + quobdump.c | 54 ++++++ quobprint.c | 157 ++++++++++++++++++ qureg.c | 72 +++++++- shor.c | 16 +- types.h.in | 40 +++++ 19 files changed, 1069 insertions(+), 89 deletions(-) create mode 100644 objcode.c create mode 100644 objcode.h create mode 100644 quobdump.c create mode 100644 quobprint.c create mode 100644 types.h.in diff --git a/CHANGES b/CHANGES index 68d0d35..891091c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +libquantum 0.2.2: + - Added quantum object code interface + - Additional configure options for better portability + - Added Kronecker product function + - Some minor fixes + libquantum 0.2.1: - Completed GNU/Hurd and FreeBSD ports - Added unbounded toffoli gate diff --git a/INSTALL b/INSTALL index 63407b9..8176e13 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,4 @@ -libquantum 0.2.1 installation guide +libquantum 0.2.2 installation guide ----------------------------------- Contents: @@ -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.2.1.tar.gz + tar xzvf libquantum-0.2.2.tar.gz Next, run the configure script: @@ -55,6 +55,29 @@ means 2^10 = 1024 elements): ./grover 42 10 +To see which quantum operations a program or an algorithm actually +performs, the concept of quantum object code (quobcode) has been +developed. Two helper tools can be built by typing + + make quobtools + +This will create two programs, quobdump and quobprint. quobdump can +generate the object code directly from a program, which does not need +to be recompiled. It requires as arguements the file to which the +object code shall be written and the name of the program for which the +quobcode shall be created (plus the arguments for this program). For +example: + + ./quobdump output_file ./shor 15 + +Quobcode files are binary data files. quobprint can be used to view +these files and takes the quobcode file as the only argument: + + ./quobprint output_file + +Each line of output contains the number of the operation, the type of +operation and its arguments. + 2. Installation of the library ------------------------------ @@ -69,6 +92,11 @@ not in the standard search path for libraries. Take a look at the output of the last command to get some advice on how to deal with this. +To install the quobcode tools on your system type + + make quobtools_install + + 3. Writing your own programs ---------------------------- @@ -77,4 +105,4 @@ You can use libquantum as any other C library. Just #include with the linker flag -lquantum. For a detailed guide on programming with libquantum take a look at -http://www.enyo.de/libquantum. \ No newline at end of file +http://www.enyo.de/libquantum/. \ No newline at end of file diff --git a/Makefile.in b/Makefile.in index 33ebc4b..4ebaa38 100644 --- a/Makefile.in +++ b/Makefile.in @@ -32,6 +32,7 @@ EPREFIX=${PREFIX} LIBDIR=${EPREFIX}/lib INCLUDEDIR=${PREFIX}/include +BINDIR=${PREFIX}/bin top_builddir=. # Version information @@ -47,21 +48,24 @@ LIBTOOL=@LIBTOOL@ # Flags passed to C compiler CFLAGS=@CFLAGS@ -LDFLAGS=-rpath $(LIBDIR) -version-info 3:0:0 +LDFLAGS=-rpath $(LIBDIR) -version-info 4:0:1 # Dependencies all: libquantum.la +Makefile: Makefile.in configure.in config.h.in types.h.in quantum.h.in + ./configure + 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 version.lo\ - Makefile + objcode.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 version.lo -lm + qureg.lo decoherence.lo qec.lo version.lo objcode.lo -lm 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 complex.h config.h Makefile $(LIBTOOL) $(CC) $(CFLAGS) -c measure.c @@ -100,6 +104,10 @@ qec.lo: qec.c qec.h gates.h qureg.h decoherence.h measure.h config.h Makefile version.lo: version.c version.h config.h Makefile $(LIBTOOL) $(CC) $(CFLAGS) -c version.c +objcode.lo: objcode.c objcode.h matrix.h gates.h qureg.h measure.h config.h\ + Makefile + $(LIBTOOL) $(CC) $(CFLAGS) -c objcode.c + # Build demos of Shor's and Grover's algorithms demos: shor grover @@ -111,17 +119,31 @@ grover: libquantum.la grover.c Makefile $(LIBTOOL) $(CC) $(CFLAGS) -o grover grover.c -I./ -lquantum -static\ -lm +# Quantum object code tools + +quobtools: quobprint quobdump + +quobprint: libquantum.la quobprint.c objcode.h Makefile + $(LIBTOOL) $(CC) $(CFLAGS) -o quobprint quobprint.c -lquantum + +quobdump: libquantum.la quobdump.c objcode.h Makefile + $(LIBTOOL) $(CC) $(CFLAGS) -o quobdump quobdump.c -lquantum + # Bring this savage back home install: libquantum.la $(LIBTOOL) $(INSTALL) -m 0644 libquantum.la $(LIBDIR) $(INSTALL) -m 0644 quantum.h $(INCLUDEDIR) +quobtools_install: quobtools + $(LIBTOOL) $(INSTALL) -m 0755 quobprint $(BINDIR) + $(LIBTOOL) $(INSTALL) -m 0755 quobdump $(BINDIR) + # Make everything neat and tidy clean: -rm -rf .libs - -rm shor libquantum.la *.lo *.o + -rm shor grover libquantum.la *.lo *.o distclean: -rm -rf .libs @@ -129,10 +151,9 @@ distclean: libquantum.la dist: - -rm quantum.h config.h + -rm quantum.h config.h types.h 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-$(VERSION) + cp *.c *.h *.in configure COPYING install-sh ltmain.sh config.sub\ + config.guess README INSTALL CHANGES libquantum-$(VERSION) tar czf libquantum-$(VERSION).tar.gz libquantum-$(VERSION)/ rm -rf libquantum-$(VERSION) diff --git a/README b/README index d6bc8a0..e90e2ef 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -libquantum 0.2.1 README file +libquantum 0.2.2 README file ---------------------------- libquantum is a C library for quantum computing. It provides quantum @@ -18,4 +18,4 @@ Send inquiries, comments, bug reports, suggestions, patches, etc. to: libquantum@enyo.de See also the libquantum website: -http://www.enyo.de/libquantum +http://www.enyo.de/libquantum/ diff --git a/config.h.in b/config.h.in index 9ffbcc3..64efa6f 100644 --- a/config.h.in +++ b/config.h.in @@ -66,3 +66,5 @@ /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ #undef inline + +#include "types.h" diff --git a/configure b/configure index e65aa1a..0d67e55 100755 --- a/configure +++ b/configure @@ -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.1. +# Generated by GNU Autoconf 2.57 for libquantum 0.2.2. # # Report bugs to . # @@ -427,8 +427,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='libquantum' PACKAGE_TARNAME='libquantum' -PACKAGE_VERSION='0.2.1' -PACKAGE_STRING='libquantum 0.2.1' +PACKAGE_VERSION='0.2.2' +PACKAGE_STRING='libquantum 0.2.2' PACKAGE_BUGREPORT='libquantum@enyo.de' ac_unique_file="classic.c" @@ -469,7 +469,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP EGREP LIBTOOL MU_TYPE CF_TYPE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA build build_cpu build_vendor build_os host host_cpu host_vendor host_os LN_S ECHO RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP CPP EGREP LIBTOOL MU_TYPE CF_TYPE I LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -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.1 to adapt to many kinds of systems. +\`configure' configures libquantum 0.2.2 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.1:";; + short | recursive ) echo "Configuration of libquantum 0.2.2:";; esac cat <<\_ACEOF @@ -1017,6 +1017,9 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld default=no --with-pic try to use only PIC/non-PIC objects default=use both + --with-max-unsigned-type=ARG integer type for quantum registers + --with-complex-type=ARG type for complex numbers + --with-imaginary=ARG name of the imaginary unit Some influential environment variables: CC C compiler command @@ -1093,7 +1096,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -libquantum configure 0.2.1 +libquantum configure 0.2.2 generated by GNU Autoconf 2.57 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 @@ -1108,7 +1111,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.1, which was +It was created by libquantum $as_me 0.2.2, which was generated by GNU Autoconf 2.57. Invocation command line was $ $0 $@ @@ -1285,7 +1288,7 @@ _ASBOX echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 - rm -f core core.* *.core && + rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 @@ -2225,13 +2228,12 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - ''\ + '' \ '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);' \ - '#include ' + 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" @@ -2240,8 +2242,8 @@ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include $ac_declaration +#include int main () { @@ -3592,7 +3594,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi @@ -4131,7 +4133,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4134 "configure"' > conftest.$ac_ext + echo '#line 4136 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4674,7 +4676,7 @@ chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" compiler_c_o=no -if { (eval echo configure:4677: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then +if { (eval echo configure:4679: \"$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 @@ -6557,7 +6559,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi @@ -7824,8 +7826,14 @@ esac # Check for 64-bit integer -MU_TYPE="none" -echo "$as_me:$LINENO: checking for uint_64t" >&5 + +# Check whether --with-max-unsigned-type or --without-max-unsigned-type was given. +if test "${with_max_unsigned_type+set}" = set; then + withval="$with_max_unsigned_type" + MU_TYPE=$withval +else + MU_TYPE="none" + echo "$as_me:$LINENO: checking for uint_64t" >&5 echo $ECHO_N "checking for uint_64t... $ECHO_C" >&6 if test "${ac_cv_type_uint_64t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -7880,6 +7888,7 @@ _ACEOF MU_TYPE="uint_64t" fi +fi; if test "$MU_TYPE" = "none" then echo "$as_me:$LINENO: checking for u_int_64t" >&5 @@ -8005,8 +8014,15 @@ echo "$as_me: error: No 64-bit integer type!" >&2;} fi # Check for complex number type -CF_TYPE="none" -echo "$as_me:$LINENO: checking for float _Complex" >&5 + +# Check whether --with-complex-type or --without-complex-type was given. +if test "${with_complex_type+set}" = set; then + withval="$with_complex_type" + CF_TYPE=$withval + +else + CF_TYPE="none" + echo "$as_me:$LINENO: checking for float _Complex" >&5 echo $ECHO_N "checking for float _Complex... $ECHO_C" >&6 if test "${ac_cv_type_float__Complex+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 @@ -8058,9 +8074,10 @@ if test $ac_cv_type_float__Complex = yes; then #define COMPLEX_FLOAT float _Complex _ACEOF - CF_TYPE="float _Complex" + CF_TYPE="float _Complex" fi +fi; if test "$CF_TYPE" = "none" then echo "$as_me:$LINENO: checking for __complex__ float" >&5 @@ -8130,15 +8147,21 @@ fi # Check for the imaginary unit echo "$as_me:$LINENO: checking for the imaginary unit" >&5 echo $ECHO_N "checking for the imaginary unit... $ECHO_C" >&6 -I="none" -cat >conftest.$ac_ext <<_ACEOF + +# Check whether --with-imaginary or --without-imaginary was given. +if test "${with_imaginary+set}" = set; then + withval="$with_imaginary" + I=$withval +else + I="none" + cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -COMPLEX_FLOAT z; +$CF_TYPE z; int main () { @@ -8170,14 +8193,14 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext -cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -COMPLEX_FLOAT z; +$CF_TYPE z; int main () { @@ -8208,14 +8231,14 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext -cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -COMPLEX_FLOAT z; +$CF_TYPE z; int main () { @@ -8246,6 +8269,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext +fi; if test $I = "none" then { { echo "$as_me:$LINENO: error: No imaginary unit!" >&5 @@ -8255,7 +8279,8 @@ fi echo "$as_me:$LINENO: result: $I" >&5 echo "${ECHO_T}$I" >&6 -# Substitute fields in quantum.h.in +# Substitute fields in quantum.h.in and types.h + @@ -8273,7 +8298,7 @@ then fi # Write the output files - ac_config_files="$ac_config_files Makefile quantum.h" + ac_config_files="$ac_config_files Makefile quantum.h types.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -8635,7 +8660,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by libquantum $as_me 0.2.1, which was +This file was extended by libquantum $as_me 0.2.2, which was generated by GNU Autoconf 2.57. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8695,7 +8720,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -libquantum config.status 0.2.1 +libquantum config.status 0.2.2 configured by $0, generated by GNU Autoconf 2.57, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -8801,6 +8826,7 @@ do # Handling of arguments. "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "quantum.h" ) CONFIG_FILES="$CONFIG_FILES quantum.h" ;; + "types.h" ) CONFIG_FILES="$CONFIG_FILES types.h" ;; "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} @@ -8915,6 +8941,7 @@ s,@EGREP@,$EGREP,;t t s,@LIBTOOL@,$LIBTOOL,;t t s,@MU_TYPE@,$MU_TYPE,;t t s,@CF_TYPE@,$CF_TYPE,;t t +s,@I@,$I,;t t s,@LIBOBJS@,$LIBOBJS,;t t s,@LTLIBOBJS@,$LTLIBOBJS,;t t CEOF diff --git a/configure.in b/configure.in index ede0d90..0f85738 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ # Process this file with autoconf to produce a configure script. -AC_INIT([libquantum], [0.2.1], [libquantum@enyo.de]) +AC_INIT([libquantum], [0.2.2], [libquantum@enyo.de]) AC_CONFIG_SRCDIR([classic.c]) AC_CONFIG_HEADER([config.h]) @@ -22,9 +22,11 @@ AC_CHECK_HEADERS([fcntl.h stdlib.h unistd.h]) AC_C_INLINE # Check for 64-bit integer -MU_TYPE="none" -AC_CHECK_TYPE([uint_64t], [AC_DEFINE([MAX_UNSIGNED], [uint_64t]) - MU_TYPE="uint_64t"]) +AC_ARG_WITH([max-unsigned-type], + [ --with-max-unsigned-type=ARG integer type for quantum registers], + [MU_TYPE=$withval], [MU_TYPE="none" + AC_CHECK_TYPE([uint_64t], [AC_DEFINE([MAX_UNSIGNED], [uint_64t]) + MU_TYPE="uint_64t"])]) if test "$MU_TYPE" = "none" then AC_CHECK_TYPE([u_int_64t], [AC_DEFINE([MAX_UNSIGNED], [u_int_64t]) @@ -42,9 +44,13 @@ then fi # Check for complex number type -CF_TYPE="none" -AC_CHECK_TYPE([float _Complex], [AC_DEFINE([COMPLEX_FLOAT], [float _Complex]) - CF_TYPE="float _Complex"]) +AC_ARG_WITH([complex-type], + [ --with-complex-type=ARG type for complex numbers], + [CF_TYPE=$withval +], [CF_TYPE="none" + AC_CHECK_TYPE([float _Complex], [AC_DEFINE([COMPLEX_FLOAT], + [float _Complex]) + CF_TYPE="float _Complex"])]) if test "$CF_TYPE" = "none" then AC_CHECK_TYPE([__complex__ float], [AC_DEFINE([COMPLEX_FLOAT], @@ -58,22 +64,25 @@ fi # Check for the imaginary unit AC_MSG_CHECKING([for the imaginary unit]) -I="none" -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=I;])], - [AC_DEFINE([IMAGINARY], [I], [Imaginary unit]) I="I"]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=_Complex_I;])], - [AC_DEFINE([IMAGINARY], [_Complex_I]) I="_Complex_I"]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([COMPLEX_FLOAT z;], [z=1i;])], - [AC_DEFINE([IMAGINARY], [1i]) I="1i"]) +AC_ARG_WITH([imaginary], + [ --with-imaginary=ARG name of the imaginary unit], + [I=$withval], [I="none" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$CF_TYPE z;], [z=I;])], + [AC_DEFINE([IMAGINARY], [I], [Imaginary unit]) I="I"]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$CF_TYPE z;], [z=_Complex_I;])], + [AC_DEFINE([IMAGINARY], [_Complex_I]) I="_Complex_I"]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$CF_TYPE z;], [z=1i;])], + [AC_DEFINE([IMAGINARY], [1i]) I="1i"])]) if test $I = "none" then AC_MSG_ERROR([No imaginary unit!]) fi AC_MSG_RESULT($I) -# Substitute fields in quantum.h.in +# Substitute fields in quantum.h.in and types.h AC_SUBST(MU_TYPE) AC_SUBST(CF_TYPE) +AC_SUBST(I) # Profiling check AC_ARG_ENABLE(profiling, @@ -88,5 +97,5 @@ then fi # Write the output files -AC_CONFIG_FILES([Makefile quantum.h]) +AC_CONFIG_FILES([Makefile quantum.h types.h]) AC_OUTPUT diff --git a/decoherence.c b/decoherence.c index 3d60dda..b57295c 100644 --- a/decoherence.c +++ b/decoherence.c @@ -125,7 +125,7 @@ quantum_decohere(quantum_reg *reg) } free(nrands); - quantum_memman(reg->width * sizeof(float)); + quantum_memman(-reg->width * sizeof(float)); } } diff --git a/gates.c b/gates.c index 5e917cd..122473e 100644 --- a/gates.c +++ b/gates.c @@ -32,6 +32,7 @@ #include "qureg.h" #include "decoherence.h" #include "qec.h" +#include "objcode.h" /* Apply a controlled-not gate */ @@ -47,6 +48,9 @@ quantum_cnot(int control, int target, quantum_reg *reg) quantum_cnot_ft(control, target, reg); else { + if(quantum_objcode_put(CNOT, control, target)) + return; + for(i=0; isize; i++) { /* Flip the target bit of a basis state if the control bit is set */ @@ -72,6 +76,9 @@ quantum_toffoli(int control1, int control2, int target, quantum_reg *reg) quantum_toffoli_ft(control1, control2, target, reg); else { + if(quantum_objcode_put(TOFFOLI, control1, control2, target)) + return; + for(i=0; isize; i++) { /* Flip the target bit of a basis state if both control bits are @@ -150,6 +157,9 @@ quantum_sigma_x(int target, quantum_reg *reg) quantum_sigma_x_ft(target, reg); else { + if(quantum_objcode_put(SIGMA_X, target)) + return; + for(i=0; isize; i++) { /* Flip the target bit of each basis state */ @@ -166,6 +176,9 @@ void quantum_sigma_y(int target, quantum_reg *reg) { int i; + + if(quantum_objcode_put(SIGMA_Y, target)) + return; for(i=0; isize;i++) { @@ -190,6 +203,9 @@ quantum_sigma_z(int target, quantum_reg *reg) { int i; + if(quantum_objcode_put(SIGMA_Z, target)) + return; + for(i=0; isize; i++) { /* Multiply with -1 if the target bit is set */ @@ -226,6 +242,10 @@ quantum_swaptheleads(int width, quantum_reg *reg) { for(i=0; isize; i++) { + + if(quantum_objcode_put(SWAPLEADS, width)) + return; + /* calculate left bit pattern */ pat1 = reg->node[i].state % ((MAX_UNSIGNED) 1 << width); @@ -274,7 +294,6 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg) COMPLEX_FLOAT t, tnot=0; float limit; char *done; - // quantum_reg_hash *p; if((m.cols != 2) || (m.rows != 2)) { @@ -285,16 +304,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg) /* Build hash table */ 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; - }*/ - reg->hash[i] = 0; - } + reg->hash[i] = 0; for(i=0; isize; i++) quantum_add_hash(reg->node[i].state, i, reg); @@ -438,6 +448,7 @@ quantum_gate1(int target, quantum_matrix m, quantum_reg *reg) reg->size + addsize); exit(1); } + quantum_memman(-decsize * sizeof(quantum_reg_node)); } quantum_decohere(reg); @@ -449,7 +460,10 @@ void quantum_hadamard(int target, quantum_reg *reg) { quantum_matrix m; - + + if(quantum_objcode_put(HADAMARD, target)) + return; + m = quantum_new_matrix(2, 2); m.t[0] = sqrt(1.0/2); m.t[1] = sqrt(1.0/2); @@ -479,6 +493,9 @@ void quantum_r_x(int target, float gamma, quantum_reg *reg) { quantum_matrix m; + + if(quantum_objcode_put(ROT_X, target, (double) gamma)) + return; m = quantum_new_matrix(2, 2); @@ -498,6 +515,9 @@ quantum_r_y(int target, float gamma, quantum_reg *reg) { quantum_matrix m; + if(quantum_objcode_put(ROT_Y, target, (double) gamma)) + return; + m = quantum_new_matrix(2, 2); m.t[0] = cos(gamma / 2); m.t[1] = -sin(gamma / 2); @@ -517,6 +537,9 @@ quantum_r_z(int target, float gamma, quantum_reg *reg) int i; COMPLEX_FLOAT z; + if(quantum_objcode_put(ROT_Z, target, (double) gamma)) + return; + z = quantum_cexp(gamma/2); for(i=0; isize; i++) @@ -538,6 +561,9 @@ quantum_phase_scale(int target, float gamma, quantum_reg *reg) int i; COMPLEX_FLOAT z; + if(quantum_objcode_put(PHASE_SCALE, target, (double) gamma)) + return; + z = quantum_cexp(gamma); for(i=0; isize; i++) @@ -557,6 +583,9 @@ quantum_phase_kick(int target, float gamma, quantum_reg *reg) int i; COMPLEX_FLOAT z; + if(quantum_objcode_put(PHASE_KICK, target, (double) gamma)) + return; + z = quantum_cexp(gamma); for(i=0; isize; i++) @@ -576,6 +605,9 @@ quantum_cond_phase(int control, int target, quantum_reg *reg) int i; COMPLEX_FLOAT z; + if(quantum_objcode_put(COND_PHASE, control, target)) + return; + z = quantum_cexp(pi / ((MAX_UNSIGNED) 1 << (control - target))); for(i=0; isize; i++) @@ -612,13 +644,15 @@ quantum_cond_phase_inv(int control, int target, quantum_reg *reg) } - void quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg) { int i; COMPLEX_FLOAT z; + if(quantum_objcode_put(COND_PHASE, control, target, (double) gamma)) + return; + z = quantum_cexp(gamma); for(i=0; isize; i++) @@ -633,7 +667,6 @@ quantum_cond_phase_kick(int control, int target, float gamma, quantum_reg *reg) } - /* Increase the gate counter by INC steps or reset it if INC < 0. The current value of the counter is returned. */ diff --git a/grover.c b/grover.c index f5f3ca0..7e2d9e8 100644 --- a/grover.c +++ b/grover.c @@ -25,6 +25,7 @@ #include #include #include +#include #define pi 3.141592654 @@ -125,6 +126,8 @@ int main(int argc, char **argv) quantum_reg reg; int i, N, width=0; + srandom(time(0)); + if(argc==1) { printf("Usage: grover [number] [[qubits]]\n\n"); diff --git a/measure.c b/measure.c index 289454f..cfe7224 100644 --- a/measure.c +++ b/measure.c @@ -32,6 +32,7 @@ #include "qureg.h" #include "complex.h" #include "config.h" +#include "objcode.h" /* Generate a uniformly distributed random number between 0 and 1 */ @@ -49,6 +50,9 @@ quantum_measure(quantum_reg reg) double r; int i; + if(quantum_objcode_put(MEASURE)) + return 0; + /* Get a random number between 0 and 1 */ r = quantum_frand(); @@ -86,6 +90,9 @@ quantum_bmeasure(int pos, quantum_reg *reg) MAX_UNSIGNED lpat=0, rpat=0, pos2; quantum_reg out; + if(quantum_objcode_put(BMEASURE, pos)) + return 0; + pos2 = (MAX_UNSIGNED) 1 << pos; /* Sum up the probability for 0 being the result */ @@ -186,6 +193,9 @@ quantum_bmeasure_bitpreserve(int pos, quantum_reg *reg) MAX_UNSIGNED pos2; quantum_reg out; + if(quantum_objcode_put(BMEASURE_P, pos)) + return 0; + pos2 = (MAX_UNSIGNED) 1 << pos; /* Sum up the probability for 0 being the result */ diff --git a/objcode.c b/objcode.c new file mode 100644 index 0000000..adbc1eb --- /dev/null +++ b/objcode.c @@ -0,0 +1,448 @@ +/* objcode.c: Quantum object code functions + + 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 +#include +#include +#include + +#include "objcode.h" +#include "config.h" +#include "matrix.h" +#include "qureg.h" +#include "gates.h" +#include "measure.h" + +/* status of the objcode functionality (0 = disabled) */ + +int opstatus = 0; + +/* Generated OBJCODE data */ + +unsigned char *objcode = 0; + +/* Current POSITION of the last instruction in the OBJCODE array */ + +unsigned long position = 0; + +/* Number of ALLOCATED pages */ + +unsigned long allocated = 0; + +/* file to write the object code to, if not given */ + +char *globalfile; + +/* Convert a big integer to a byte array */ + +void +quantum_mu2char(MAX_UNSIGNED mu, unsigned char *buf) +{ + int i, size; + + size = sizeof(MAX_UNSIGNED); + + for(i=0; i=0 ; i--) + mu += buf[i] * ((MAX_UNSIGNED) 1 << (8 * (size - i - 1))); + + return mu; +} + +int quantum_char2int(unsigned char *buf) +{ + int i, size; + int j = 0; + + size = sizeof(int); + + for(i=size-1; i>=0 ; i--) + j += buf[i] * (1 << (8 * (size - i - 1))); + + return j; +} + +double quantum_char2double(unsigned char *buf) +{ + double *d = (double *) buf; + + return *d; +} + + +/* Start object code recording */ + +void +quantum_objcode_start() +{ + opstatus = 1; + allocated = 1; + objcode = malloc(OBJCODE_PAGE * sizeof(char)); + if(!objcode) + { + printf("Error allocating memory for objcode data!\n"); + exit(1); + } + quantum_memman(OBJCODE_PAGE * sizeof(char)); +} + +/* Stop object code recording */ + +void +quantum_objcode_stop() +{ + opstatus = 0; + free(objcode); + objcode = 0; + quantum_memman(- allocated * OBJCODE_PAGE * sizeof(char)); + allocated = 0; +} + +/* Store an operation with its arguments in the object code data */ + +int +quantum_objcode_put(unsigned char operation, ...) +{ + int i, size; + va_list args; + unsigned char buf[80]; + double d; + MAX_UNSIGNED mu; + + if(!opstatus) + return 0; + + va_start(args, operation); + + buf[0] = operation; + + switch(operation) + { + case INIT: + mu = va_arg(args, MAX_UNSIGNED); + quantum_mu2char(mu, &buf[1]); + size = sizeof(MAX_UNSIGNED) + 1; + break; + case CNOT: + case COND_PHASE: + i = va_arg(args, int); + quantum_int2char(i, &buf[1]); + i = va_arg(args, int); + quantum_int2char(i, &buf[sizeof(int)+1]); + size = 2 * sizeof(int) + 1; + break; + case TOFFOLI: + i = va_arg(args, int); + quantum_int2char(i, &buf[1]); + i = va_arg(args, int); + quantum_int2char(i, &buf[sizeof(int)+1]); + i = va_arg(args, int); + quantum_int2char(i, &buf[2*sizeof(int)+1]); + size = 3 * sizeof(int) + 1; + break; + case SIGMA_X: + case SIGMA_Y: + case SIGMA_Z: + case HADAMARD: + case BMEASURE: + case BMEASURE_P: + case SWAPLEADS: + i = va_arg(args, int); + quantum_int2char(i, &buf[1]); + size = sizeof(int) + 1; + break; + case ROT_X: + case ROT_Y: + case ROT_Z: + case PHASE_KICK: + case PHASE_SCALE: + i = va_arg(args, int); + d = va_arg(args, double); + quantum_int2char(i, &buf[1]); + quantum_double2char(d, &buf[sizeof(int)+1]); + size = sizeof(int) + sizeof(double) + 1; + break; + case CPHASE_KICK: + i = va_arg(args, int); + quantum_int2char(i, &buf[1]); + i = va_arg(args, int); + quantum_int2char(i, &buf[sizeof(int)+1]); + d = va_arg(args, double); + quantum_double2char(d, &buf[2*sizeof(int)+1]); + size = 2 * sizeof(int) + sizeof(double) + 1; + break; + case MEASURE: + case NOP: + size = 1; + break; + default: + printf("Unknown opcode 0x(%X)!\n", operation); + exit(1); + } + + if((position+size) / OBJCODE_PAGE > position / OBJCODE_PAGE) + { + allocated++; + objcode = realloc(objcode, allocated * OBJCODE_PAGE); + if(!objcode) + { + printf("Error reallocating memory for objcode data!\n"); + exit(1); + } + quantum_memman(OBJCODE_PAGE * sizeof(char)); + } + + for(i=0; i +#include +#include +#include + +#include "objcode.h" + +int main(int argc, char **argv) +{ + char *envstr; + extern char **environ; + + if(argc < 3) + { + printf("Usage: quopdump [file] [program] [[args]]\n\n"); + return 1; + } + + envstr = malloc(strlen(argv[1]) + 20); + + snprintf(envstr, strlen(argv[1]) + 19, "QUOBFILE=%s", argv[1]); + + putenv(envstr); + + execve(argv[2], &argv[2], environ); + + fprintf(stderr, "Unable to execute %s: ", argv[2]); + perror(NULL); + + return 1; +} diff --git a/quobprint.c b/quobprint.c new file mode 100644 index 0000000..5fa2881 --- /dev/null +++ b/quobprint.c @@ -0,0 +1,157 @@ +/* quobprint.c: Examine quantum object code file + + 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 +#include +#include + +#include "objcode.h" +#include "types.h" + +int main(int argc, char **argv) +{ + int i, j, k, l; + FILE *fhd; + unsigned char operation; + unsigned char buf[OBJBUF_SIZE]; + char output[OBJBUF_SIZE]; + char opname[256][25]; + MAX_UNSIGNED mu; + double d; + + strncpy(opname[INIT], "init", 24); + strncpy(opname[CNOT], "cnot", 24); + strncpy(opname[TOFFOLI], "toffoli", 24); + strncpy(opname[SIGMA_X], "sigma_x", 24); + strncpy(opname[SIGMA_Y], "sigma_y", 24); + strncpy(opname[SIGMA_Z], "sigma_z", 24); + strncpy(opname[HADAMARD], "hadamard", 24); + strncpy(opname[ROT_X], "rotate_x", 24); + strncpy(opname[ROT_Y], "rotate_y", 24); + strncpy(opname[ROT_Z], "rotate_z", 24); + strncpy(opname[PHASE_KICK], "phase_kick", 24); + strncpy(opname[PHASE_SCALE], "phase_scale", 24); + strncpy(opname[COND_PHASE], "cond_phase", 24); + strncpy(opname[CPHASE_KICK], "cond_phase_kick", 24); + strncpy(opname[MEASURE], "measure", 24); + strncpy(opname[BMEASURE], "bmeasure", 24); + strncpy(opname[BMEASURE_P], "bmeasure_preserve", 24); + strncpy(opname[SWAPLEADS], "swaptheleads", 24); + strncpy(opname[NOP], "nop", 24); + if(argc != 2) + { + printf("Usage: quobprint [file]\n\n"); + return 1; + } + + fhd = fopen(argv[1], "r"); + + if(!fhd) + { + fprintf(stderr, "Could not open %s: ", argv[1]); + perror(0); + return 1; + } + + for(i=0; !feof(fhd); i++) + { + for(j=0; j=0;j--) - printf("%i", ((((MAX_UNSIGNED) 1 << j) & reg.node[i].state) > 0)); + { + if(j % 4 == 3) + printf(" "); + printf("%i", ((((MAX_UNSIGNED) 1 << j) & reg.node[i].state) > 0)); + } + printf(">)\n"); } @@ -255,3 +273,53 @@ quantum_print_hash(quantum_reg reg) } } + +/* Compute the Kronecker product of two quantum registers */ + +quantum_reg +quantum_kronecker(quantum_reg *reg1, quantum_reg *reg2) +{ + int i,j; + quantum_reg reg; + + reg.width = reg1->width+reg2->width; + reg.size = reg1->size*reg2->size; + reg.hashw = reg1->size*reg2->size + 2; + + + /* allocate memory for the new basis states */ + + reg.node = calloc(reg.size, sizeof(quantum_reg_node)); + if(!reg.node) + { + printf("Not enough memory for %i-sized qubit!\n", reg.size); + exit(1); + } + quantum_memman((reg.size)*sizeof(quantum_reg_node)); + + + /* Allocate the hash table */ + + 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(int)); + + for(i=0; isize; i++) + for(j=0; jsize; j++) + { + /* printf("processing |%lli> x |%lli>\n", reg1->node[i].state, + reg2->node[j].state); + printf("%lli\n", (reg1->node[i].state) << reg2->width); */ + + reg.node[i*reg2->size+j].state = ((reg1->node[i].state) << reg2->width) + | reg2->node[j].state; + reg.node[i*reg2->size+j].amplitude = + reg1->node[i].amplitude * reg2->node[j].amplitude; + } + + return reg; +} diff --git a/shor.c b/shor.c index fc0ba0c..9ff1369 100644 --- a/shor.c +++ b/shor.c @@ -33,13 +33,13 @@ int main(int argc, char **argv) { quantum_reg qr; int i; int width, swidth; - int x; + int x = 0; int N; int c,q,a,b, factor; srandom(time(0)); - if(argc==1) + if(argc == 1) { printf("Usage: shor [number]\n\n"); return 3; @@ -58,10 +58,14 @@ int main(int argc, char **argv) { printf("N = %i, %i qubits required\n", N, width+3*swidth+2); - do + if(argc >= 3) + { + x = atoi(argv[2]); + } + while((quantum_gcd(N, x) > 1) || (x < 2)) { x = random() % N; - } while((quantum_gcd(N, x) > 1) || (x < 2)); + } printf("Random seed: %i\n", x); @@ -88,8 +92,6 @@ int main(int argc, char **argv) { quantum_cnot(i, width-i-1, &qr); } - // quantum_print_qureg(qr); - c=quantum_measure(qr); if(c==-1) @@ -149,7 +151,7 @@ int main(int argc, char **argv) { quantum_delete_qureg(&qr); - // printf("Memory leak: %i bytes\n", (int) quantum_memman(0)); + /* printf("Memory leak: %i bytes\n", (int) quantum_memman(0)); */ return 0; } diff --git a/types.h.in b/types.h.in new file mode 100644 index 0000000..9f1c755 --- /dev/null +++ b/types.h.in @@ -0,0 +1,40 @@ +/* types.h: Data types for libquantum + + 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 __TYPES_H + +#define __TYPES_H + +#ifndef COMPLEX_FLOAT + #define COMPLEX_FLOAT @CF_TYPE@ +#endif + +#ifndef MAX_UNSIGNED + #define MAX_UNSIGNED @MU_TYPE@ +#endif + +#ifndef IMAGINARY + #define IMAGINARY @I@ +#endif + +#endif