diff options
Diffstat (limited to 'gsl-1.9/fft')
62 files changed, 8977 insertions, 0 deletions
diff --git a/gsl-1.9/fft/ChangeLog b/gsl-1.9/fft/ChangeLog new file mode 100644 index 0000000..214c7eb --- /dev/null +++ b/gsl-1.9/fft/ChangeLog @@ -0,0 +1,128 @@ +2006-03-16 Brian Gough <bjg@network-theory.co.uk> + + * changed to gsl_fft_forward and gsl_fft_backward enums throughout + internally instead of forward and backward. + +2005-05-19 Brian Gough <bjg@network-theory.co.uk> + + * Makefile.am (noinst_HEADERS): removed unused real.c + +Tue Jul 24 15:16:50 2001 Brian Gough <bjg@network-theory.co.uk> + + * single precision fft now uses float throughout, rather than + mixing float and double. + +Mon Jul 16 12:38:29 2001 Brian Gough <bjg@network-theory.co.uk> + + * reorganized function names and split work + +Tue May 1 14:35:52 2001 Brian Gough <bjg@network-theory.co.uk> + + * Makefile.am (libgslfft_la_SOURCES): removed spurious headers + from SOURCES line + +2000-10-19 Brian Gough <bjg@inweb.aethos.co.uk> + + * hc_init.c (FUNCTION): scratch space changed to n elements + instead of 2*n (apparently the routine previously allocated too + much space) + +Wed Feb 16 14:43:42 2000 Brian Gough <bjg@network-theory.co.uk> + + * Makefile.am (pkginclude_HEADERS): added missing + pkginclude_HEADERS for float functions. + +Mon Feb 14 15:11:55 2000 Brian Gough <bjg@network-theory.co.uk> + + * made all internal functions static (required a slight + reorganization) + +Fri Aug 6 11:20:25 1999 Brian Gough <bjg@network-theory.co.uk> + + * removed dependence on rand() and RAND_MAX + +Sun Feb 14 17:31:21 1999 Brian Gough <bjg@netsci.freeserve.co.uk> + + * started converting header files to use gsl_complex_packed_array + more consistently + +Mon Dec 14 22:55:00 1998 Brian Gough <bjg@vvv.lanl.gov> + + * real_init.c: fixed a possible malloc(0) bug found by Electric Fence. + +Mon Nov 23 15:47:13 1998 Brian Gough <bjg@vvv.lanl.gov> + + * gsl_fft_complex.h, gsl_fft_complex_float.h: removed data[][] + type arguments from prototypes since this seems to be non-ANSI. + Use **data instead. + +1998-11-09 <bjg@ancho.lanl.gov> + + * compare_source.c: fix up int/unsigned format types to prevent + warnings + +Wed Oct 28 15:07:22 1998 Brian Gough <bjg@vvv.lanl.gov> + + * c.c: added #include <string.h> for memcpy + + * c_float.c: added #include <string.h> for memcpy + +Thu Sep 10 12:05:07 1998 Brian Gough <bjg@vvv.lanl.gov> + + * removed wavetable from function names to make them shorter and + avoid confusion, e.g. gsl_fft_complex_wavetable_alloc -> + gsl_fft_complex_alloc + +Sat Sep 5 22:32:19 1998 Brian Gough <bjg@vvv.lanl.gov> + + * major work done on templatizing everything so that you can do an + fft of a float or a double vector. + +Tue Sep 1 16:44:06 1998 Brian Gough <bjg@vvv.lanl.gov> + + * c_main.c: renamed c.c to c_main.c + +Tue Jul 28 11:30:43 1998 Brian Gough <bjg@vvv.lanl.gov> + + * renamed gsl_fft_signals.h to fft_signals.h (not exported) + + * fft.h: a place to keep some local macros + + * c.c: renamed complex.c to c.c + +Mon Jul 27 12:46:25 1998 Brian Gough <bjg@vvv.lanl.gov> + + * bitreverse.c: removed gsl_ftt_ prefix from non-exported functions + +Wed Jun 10 17:36:01 1998 Brian Gough <bjg@vvv.lanl.gov> + + * test.c: Eliminated the need for getopt + + * test_radix2.c: Eliminated the need for getopt + + * test_trap.c: Eliminated the need for getopt + +Mon Apr 27 18:48:58 1998 Brian Gough <bjg@vvv.lanl.gov> + + * fft_alloc functions now return a pointer to a newly allocated + wavetable struct (or a null pointer if there isn't enough memory) + +Fri Apr 10 15:12:37 1998 Brian Gough <bjg@vvv.lanl.gov> + + * renamed complex_*.c and halfcomplex_*.c to c_*.c and hc_*.c to + avoid linker complaints about long filenames on some platforms + +Sun Mar 29 15:56:34 1998 Brian Gough <bjg@vvv.lanl.gov> + + * To be compatible with other architectures use size_t everywhere + instead of unsigned int + +Sat Mar 21 17:28:26 1998 Brian Gough <bjg@vvv.lanl.gov> + + * factorize.c (gsl_fft_factorize): Stopped returning the sum of + factors in the status variable. The user can compute it if + necessary. + +1998-01-27 Mark Galassi <rosalia@cygnus.com> + + * Makefile.am: fixed a typo: removed trailing \ at the end of this file. diff --git a/gsl-1.9/fft/Makefile.am b/gsl-1.9/fft/Makefile.am new file mode 100644 index 0000000..ad2953f --- /dev/null +++ b/gsl-1.9/fft/Makefile.am @@ -0,0 +1,21 @@ +noinst_LTLIBRARIES = libgslfft.la + +pkginclude_HEADERS = gsl_fft.h gsl_fft_complex.h gsl_fft_halfcomplex.h gsl_fft_real.h gsl_dft_complex.h gsl_dft_complex_float.h gsl_fft_complex_float.h gsl_fft_halfcomplex_float.h gsl_fft_real_float.h + +INCLUDES= -I$(top_builddir) -I$(top_srcdir) + +libgslfft_la_SOURCES = dft.c fft.c + +noinst_HEADERS = c_pass.h hc_pass.h real_pass.h signals.h signals_source.c c_main.c c_init.c c_pass_2.c c_pass_3.c c_pass_4.c c_pass_5.c c_pass_6.c c_pass_7.c c_pass_n.c c_radix2.c bitreverse.c bitreverse.h factorize.c factorize.h hc_init.c hc_pass_2.c hc_pass_3.c hc_pass_4.c hc_pass_5.c hc_pass_n.c hc_radix2.c hc_unpack.c real_init.c real_pass_2.c real_pass_3.c real_pass_4.c real_pass_5.c real_pass_n.c real_radix2.c real_unpack.c compare.h compare_source.c dft_source.c hc_main.c real_main.c test_complex_source.c test_real_source.c test_trap_source.c urand.c complex_internal.h + +TESTS = $(check_PROGRAMS) + +check_PROGRAMS = test + +test_SOURCES = test.c signals.c + +test_LDADD = libgslfft.la ../ieee-utils/libgslieeeutils.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la ../utils/libutils.la + +#errs_LDADD = libgslfft.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la +#benchmark_LDADD = libgslfft.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la + diff --git a/gsl-1.9/fft/Makefile.in b/gsl-1.9/fft/Makefile.in new file mode 100644 index 0000000..ddfcac9 --- /dev/null +++ b/gsl-1.9/fft/Makefile.in @@ -0,0 +1,547 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = test$(EXEEXT) +subdir = fft +DIST_COMMON = $(noinst_HEADERS) $(pkginclude_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog TODO +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libgslfft_la_LIBADD = +am_libgslfft_la_OBJECTS = dft.lo fft.lo +libgslfft_la_OBJECTS = $(am_libgslfft_la_OBJECTS) +am_test_OBJECTS = test.$(OBJEXT) signals.$(OBJEXT) +test_OBJECTS = $(am_test_OBJECTS) +test_DEPENDENCIES = libgslfft.la ../ieee-utils/libgslieeeutils.la \ + ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la \ + ../utils/libutils.la +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libgslfft_la_SOURCES) $(test_SOURCES) +DIST_SOURCES = $(libgslfft_la_SOURCES) $(test_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(pkgincludedir)" +pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GSL_CFLAGS = @GSL_CFLAGS@ +GSL_LIBS = @GSL_LIBS@ +GSL_LT_CBLAS_VERSION = @GSL_LT_CBLAS_VERSION@ +GSL_LT_VERSION = @GSL_LT_VERSION@ +HAVE_AIX_IEEE_INTERFACE = @HAVE_AIX_IEEE_INTERFACE@ +HAVE_DARWIN86_IEEE_INTERFACE = @HAVE_DARWIN86_IEEE_INTERFACE@ +HAVE_DARWIN_IEEE_INTERFACE = @HAVE_DARWIN_IEEE_INTERFACE@ +HAVE_EXTENDED_PRECISION_REGISTERS = @HAVE_EXTENDED_PRECISION_REGISTERS@ +HAVE_FREEBSD_IEEE_INTERFACE = @HAVE_FREEBSD_IEEE_INTERFACE@ +HAVE_GNUM68K_IEEE_INTERFACE = @HAVE_GNUM68K_IEEE_INTERFACE@ +HAVE_GNUPPC_IEEE_INTERFACE = @HAVE_GNUPPC_IEEE_INTERFACE@ +HAVE_GNUSPARC_IEEE_INTERFACE = @HAVE_GNUSPARC_IEEE_INTERFACE@ +HAVE_GNUX86_IEEE_INTERFACE = @HAVE_GNUX86_IEEE_INTERFACE@ +HAVE_HPUX11_IEEE_INTERFACE = @HAVE_HPUX11_IEEE_INTERFACE@ +HAVE_HPUX_IEEE_INTERFACE = @HAVE_HPUX_IEEE_INTERFACE@ +HAVE_IEEE_COMPARISONS = @HAVE_IEEE_COMPARISONS@ +HAVE_IEEE_DENORMALS = @HAVE_IEEE_DENORMALS@ +HAVE_INLINE = @HAVE_INLINE@ +HAVE_IRIX_IEEE_INTERFACE = @HAVE_IRIX_IEEE_INTERFACE@ +HAVE_NETBSD_IEEE_INTERFACE = @HAVE_NETBSD_IEEE_INTERFACE@ +HAVE_OPENBSD_IEEE_INTERFACE = @HAVE_OPENBSD_IEEE_INTERFACE@ +HAVE_OS2EMX_IEEE_INTERFACE = @HAVE_OS2EMX_IEEE_INTERFACE@ +HAVE_PRINTF_LONGDOUBLE = @HAVE_PRINTF_LONGDOUBLE@ +HAVE_SOLARIS_IEEE_INTERFACE = @HAVE_SOLARIS_IEEE_INTERFACE@ +HAVE_SUNOS4_IEEE_INTERFACE = @HAVE_SUNOS4_IEEE_INTERFACE@ +HAVE_TRU64_IEEE_INTERFACE = @HAVE_TRU64_IEEE_INTERFACE@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RELEASED = @RELEASED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +noinst_LTLIBRARIES = libgslfft.la +pkginclude_HEADERS = gsl_fft.h gsl_fft_complex.h gsl_fft_halfcomplex.h gsl_fft_real.h gsl_dft_complex.h gsl_dft_complex_float.h gsl_fft_complex_float.h gsl_fft_halfcomplex_float.h gsl_fft_real_float.h +INCLUDES = -I$(top_builddir) -I$(top_srcdir) +libgslfft_la_SOURCES = dft.c fft.c +noinst_HEADERS = c_pass.h hc_pass.h real_pass.h signals.h signals_source.c c_main.c c_init.c c_pass_2.c c_pass_3.c c_pass_4.c c_pass_5.c c_pass_6.c c_pass_7.c c_pass_n.c c_radix2.c bitreverse.c bitreverse.h factorize.c factorize.h hc_init.c hc_pass_2.c hc_pass_3.c hc_pass_4.c hc_pass_5.c hc_pass_n.c hc_radix2.c hc_unpack.c real_init.c real_pass_2.c real_pass_3.c real_pass_4.c real_pass_5.c real_pass_n.c real_radix2.c real_unpack.c compare.h compare_source.c dft_source.c hc_main.c real_main.c test_complex_source.c test_real_source.c test_trap_source.c urand.c complex_internal.h +TESTS = $(check_PROGRAMS) +test_SOURCES = test.c signals.c +test_LDADD = libgslfft.la ../ieee-utils/libgslieeeutils.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la ../utils/libutils.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps fft/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu --ignore-deps fft/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgslfft.la: $(libgslfft_la_OBJECTS) $(libgslfft_la_DEPENDENCIES) + $(LINK) $(libgslfft_la_LDFLAGS) $(libgslfft_la_OBJECTS) $(libgslfft_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) + @rm -f test$(EXEEXT) + $(LINK) $(test_LDFLAGS) $(test_OBJECTS) $(test_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +uninstall-info-am: +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(mkdir_p) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkgincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + $(pkgincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list='$(TESTS)'; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *" $$tst "*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all tests failed"; \ + else \ + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + skipped="($$skip tests were not run)"; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-libtool distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-pkgincludeHEADERS + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am uninstall-pkgincludeHEADERS + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-exec install-exec-am \ + install-info install-info-am install-man \ + install-pkgincludeHEADERS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-info-am \ + uninstall-pkgincludeHEADERS + + +#errs_LDADD = libgslfft.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la +#benchmark_LDADD = libgslfft.la ../err/libgslerr.la ../test/libgsltest.la ../sys/libgslsys.la +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gsl-1.9/fft/TODO b/gsl-1.9/fft/TODO new file mode 100644 index 0000000..7d65da7 --- /dev/null +++ b/gsl-1.9/fft/TODO @@ -0,0 +1,14 @@ +* Sine and Cosine Transforms from FFTPACK. + +* A simple multidimensional fft. + +* Convolutions. This will need different interfaces corresponding to +the type of underlying FFT (radix-2, mixed-radix, radix-2 real, +mixed-radix real). The convolution function should be fft'ed before +being passed, so that the function can be used in a loop. The main +point of the function being to do the index manipulation for the +multiplication F*G. Theoretically someone might want to convolve real +and complex data together which could be done but would double the +number of interfaces. It would be reasonable to restrict the +convolutions to real-real and complex-complex. + diff --git a/gsl-1.9/fft/bitreverse.c b/gsl-1.9/fft/bitreverse.c new file mode 100644 index 0000000..15e0e8a --- /dev/null +++ b/gsl-1.9/fft/bitreverse.c @@ -0,0 +1,101 @@ +/* fft/bitreverse.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> +#include <gsl/gsl_fft.h> + +#include "complex_internal.h" +#include "bitreverse.h" + +static int +FUNCTION(fft_complex,bitreverse_order) (BASE data[], + const size_t stride, + const size_t n, + size_t logn) +{ + /* This is the Goldrader bit-reversal algorithm */ + + size_t i; + size_t j = 0; + + logn = 0 ; /* not needed for this algorithm */ + + for (i = 0; i < n - 1; i++) + { + size_t k = n / 2 ; + + if (i < j) + { + const BASE tmp_real = REAL(data,stride,i); + const BASE tmp_imag = IMAG(data,stride,i); + REAL(data,stride,i) = REAL(data,stride,j); + IMAG(data,stride,i) = IMAG(data,stride,j); + REAL(data,stride,j) = tmp_real; + IMAG(data,stride,j) = tmp_imag; + } + + while (k <= j) + { + j = j - k ; + k = k / 2 ; + } + + j += k ; + } + + return 0; +} + + +static int +FUNCTION(fft_real,bitreverse_order) (BASE data[], + const size_t stride, + const size_t n, + size_t logn) +{ + /* This is the Goldrader bit-reversal algorithm */ + + size_t i; + size_t j = 0; + + logn = 0 ; /* not needed for this algorithm */ + + for (i = 0; i < n - 1; i++) + { + size_t k = n / 2 ; + + if (i < j) + { + const BASE tmp = VECTOR(data,stride,i); + VECTOR(data,stride,i) = VECTOR(data,stride,j); + VECTOR(data,stride,j) = tmp; + } + + while (k <= j) + { + j = j - k ; + k = k / 2 ; + } + + j += k ; + } + + return 0; +} + diff --git a/gsl-1.9/fft/bitreverse.h b/gsl-1.9/fft/bitreverse.h new file mode 100644 index 0000000..f0afc5f --- /dev/null +++ b/gsl-1.9/fft/bitreverse.h @@ -0,0 +1,33 @@ +/* fft/bitreverse.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +static int FUNCTION(fft_complex,bitreverse_order) (BASE data[], + const size_t stride, + const size_t n, + size_t logn) ; + +static int FUNCTION(fft_real,bitreverse_order) (BASE data[], + const size_t stride, + const size_t n, + size_t logn) ; + + + + diff --git a/gsl-1.9/fft/c_init.c b/gsl-1.9/fft/c_init.c new file mode 100644 index 0000000..89abe95 --- /dev/null +++ b/gsl-1.9/fft/c_init.c @@ -0,0 +1,194 @@ +/* fft/c_init.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +TYPE(gsl_fft_complex_wavetable) * +FUNCTION(gsl_fft_complex_wavetable,alloc) (size_t n) +{ + int status ; + size_t i; + size_t n_factors; + size_t t, product, product_1, q; + double d_theta; + + TYPE(gsl_fft_complex_wavetable) * wavetable ; + + if (n == 0) + { + GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); + } + + wavetable = (TYPE(gsl_fft_complex_wavetable) *) + malloc(sizeof(TYPE(gsl_fft_complex_wavetable))); + + if (wavetable == NULL) + { + GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); + } + + wavetable->trig = (TYPE(gsl_complex) *) malloc (n * sizeof (TYPE(gsl_complex))); + + if (wavetable->trig == NULL) + { + free(wavetable) ; /* error in constructor, prevent memory leak */ + + GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", + GSL_ENOMEM, 0); + } + + wavetable->n = n ; + + status = fft_complex_factorize (n, &n_factors, wavetable->factor); + + if (status) + { + /* exception in constructor, avoid memory leak */ + + free (wavetable->trig); + free (wavetable); + + GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); + }; + + wavetable->nf = n_factors; + + d_theta = -2.0 * M_PI / ((double) n); + + t = 0; + product = 1; + for (i = 0; i < n_factors; i++) + { + size_t j; + const size_t factor = wavetable->factor[i]; + wavetable->twiddle[i] = wavetable->trig + t; + product_1 = product; /* product_1 = p_(i-1) */ + product *= factor; + q = n / product; + + for (j = 1; j < factor; j++) + { + size_t k; + size_t m = 0; + for (k = 1; k <= q; k++) + { + double theta; + m = m + j * product_1; + m = m % n; + theta = d_theta * m; /* d_theta*j*k*p_(i-1) */ + GSL_REAL(wavetable->trig[t]) = cos (theta); + GSL_IMAG(wavetable->trig[t]) = sin (theta); + + t++; + } + } + } + + if (t > n) + { + /* exception in constructor, avoid memory leak */ + + free (wavetable->trig); + free (wavetable); + + GSL_ERROR_VAL ("overflowed trigonometric lookup table", + GSL_ESANITY, 0); + } + + return wavetable; +} + + +TYPE(gsl_fft_complex_workspace) * +FUNCTION(gsl_fft_complex_workspace,alloc) (size_t n) +{ + TYPE(gsl_fft_complex_workspace) * workspace ; + + if (n == 0) + { + GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); + } + + workspace = (TYPE(gsl_fft_complex_workspace) *) + malloc(sizeof(TYPE(gsl_fft_complex_workspace))); + + if (workspace == NULL) + { + GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); + } + + workspace->n = n ; + + workspace->scratch = (BASE *) malloc (2 * n * sizeof (BASE)); + + if (workspace->scratch == NULL) + { + free(workspace) ; /* error in constructor, prevent memory leak */ + + GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0); + } + + return workspace; +} + + +void +FUNCTION(gsl_fft_complex_wavetable,free) (TYPE(gsl_fft_complex_wavetable) * wavetable) +{ + + /* release trigonometric lookup tables */ + + free (wavetable->trig); + wavetable->trig = NULL; + + free (wavetable) ; +} + +void +FUNCTION(gsl_fft_complex_workspace,free) (TYPE(gsl_fft_complex_workspace) * workspace) +{ + /* release scratch space */ + + free (workspace->scratch); + workspace->scratch = NULL; + free (workspace) ; +} + + +int +FUNCTION(gsl_fft_complex,memcpy) (TYPE(gsl_fft_complex_wavetable) * dest, + TYPE(gsl_fft_complex_wavetable) * src) +{ + int i, n, nf ; + + if (dest->n != src->n) + { + GSL_ERROR ("length of src and dest do not match", GSL_EINVAL); + } + + n = dest->n ; + nf = dest->nf ; + + memcpy(dest->trig, src->trig, n * sizeof (double)) ; + + for (i = 0 ; i < nf ; i++) + { + dest->twiddle[i] = dest->trig + (src->twiddle[i] - src->trig) ; + } + + return 0 ; +} diff --git a/gsl-1.9/fft/c_main.c b/gsl-1.9/fft/c_main.c new file mode 100644 index 0000000..2f48fcc --- /dev/null +++ b/gsl-1.9/fft/c_main.c @@ -0,0 +1,223 @@ +/* fft/c_main.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "c_pass.h" + +int +FUNCTION(gsl_fft_complex,forward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const TYPE(gsl_fft_complex_wavetable) * wavetable, + TYPE(gsl_fft_complex_workspace) * work) +{ + gsl_fft_direction sign = gsl_fft_forward; + int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, + wavetable, work, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,backward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const TYPE(gsl_fft_complex_wavetable) * wavetable, + TYPE(gsl_fft_complex_workspace) * work) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, + wavetable, work, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,inverse) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const TYPE(gsl_fft_complex_wavetable) * wavetable, + TYPE(gsl_fft_complex_workspace) * work) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,transform) (data, stride, n, + wavetable, work, sign); + + if (status) + { + return status; + } + + /* normalize inverse fft with 1/n */ + + { + const ATOMIC norm = ONE / (ATOMIC)n; + size_t i; + for (i = 0; i < n; i++) + { + REAL(data,stride,i) *= norm; + IMAG(data,stride,i) *= norm; + } + } + return status; +} + +int +FUNCTION(gsl_fft_complex,transform) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const TYPE(gsl_fft_complex_wavetable) * wavetable, + TYPE(gsl_fft_complex_workspace) * work, + const gsl_fft_direction sign) +{ + const size_t nf = wavetable->nf; + + size_t i; + + size_t q, product = 1; + + TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4, + *twiddle5, *twiddle6; + + size_t state = 0; + + BASE * const scratch = work->scratch; + + BASE * in = data; + size_t istride = stride; + + BASE * out = scratch; + size_t ostride = 1; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + if (n == 1) + { /* FFT of 1 data point is the identity */ + return 0; + } + + if (n != wavetable->n) + { + GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); + } + + if (n != work->n) + { + GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); + } + + for (i = 0; i < nf; i++) + { + const size_t factor = wavetable->factor[i]; + product *= factor; + q = n / product; + + if (state == 0) + { + in = data; + istride = stride; + out = scratch; + ostride = 1; + state = 1; + } + else + { + in = scratch; + istride = 1; + out = data; + ostride = stride; + state = 0; + } + + if (factor == 2) + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_complex,pass_2) (in, istride, out, ostride, sign, + product, n, twiddle1); + } + else if (factor == 3) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + q; + FUNCTION(fft_complex,pass_3) (in, istride, out, ostride, sign, + product, n, twiddle1, twiddle2); + } + else if (factor == 4) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + q; + twiddle3 = twiddle2 + q; + FUNCTION(fft_complex,pass_4) (in, istride, out, ostride, sign, + product, n, twiddle1, twiddle2, + twiddle3); + } + else if (factor == 5) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + q; + twiddle3 = twiddle2 + q; + twiddle4 = twiddle3 + q; + FUNCTION(fft_complex,pass_5) (in, istride, out, ostride, sign, + product, n, twiddle1, twiddle2, + twiddle3, twiddle4); + } + else if (factor == 6) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + q; + twiddle3 = twiddle2 + q; + twiddle4 = twiddle3 + q; + twiddle5 = twiddle4 + q; + FUNCTION(fft_complex,pass_6) (in, istride, out, ostride, sign, + product, n, twiddle1, twiddle2, + twiddle3, twiddle4, twiddle5); + } + else if (factor == 7) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + q; + twiddle3 = twiddle2 + q; + twiddle4 = twiddle3 + q; + twiddle5 = twiddle4 + q; + twiddle6 = twiddle5 + q; + FUNCTION(fft_complex,pass_7) (in, istride, out, ostride, sign, + product, n, twiddle1, twiddle2, + twiddle3, twiddle4, twiddle5, + twiddle6); + } + else + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_complex,pass_n) (in, istride, out, ostride, sign, + factor, product, n, twiddle1); + } + } + + if (state == 1) /* copy results back from scratch to data */ + { + for (i = 0; i < n; i++) + { + REAL(data,stride,i) = REAL(scratch,1,i) ; + IMAG(data,stride,i) = IMAG(scratch,1,i) ; + } + } + + return 0; + +} diff --git a/gsl-1.9/fft/c_pass.h b/gsl-1.9/fft/c_pass.h new file mode 100644 index 0000000..ec89112 --- /dev/null +++ b/gsl-1.9/fft/c_pass.h @@ -0,0 +1,106 @@ +/* fft/c_pass.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); + +static int +FUNCTION(fft_complex,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[]); + +static int +FUNCTION(fft_complex,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]); + +static int +FUNCTION(fft_complex,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]); + +static int +FUNCTION(fft_complex,pass_6) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[], + const TYPE(gsl_complex) twiddle5[]); + +static int +FUNCTION(fft_complex,pass_7) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[], + const TYPE(gsl_complex) twiddle5[], + const TYPE(gsl_complex) twiddle6[]); + + +static int +FUNCTION(fft_complex,pass_n) (BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); + diff --git a/gsl-1.9/fft/c_pass_2.c b/gsl-1.9/fft/c_pass_2.c new file mode 100644 index 0000000..b0dac46 --- /dev/null +++ b/gsl-1.9/fft/c_pass_2.c @@ -0,0 +1,98 @@ +/* fft/c_pass_2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 2; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + const size_t jump = (factor - 1) * product_1; + + for (k = 0; k < q; k++) + { + ATOMIC w_real, w_imag; + + if (k == 0) + { + w_real = 1.0; + w_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w_real = GSL_REAL(twiddle[k - 1]); + w_imag = GSL_IMAG(twiddle[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w_real = GSL_REAL(twiddle[k - 1]); + w_imag = -GSL_IMAG(twiddle[k - 1]); + } + } + + for (k1 = 0; k1 < product_1; k1++) + { + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + + const ATOMIC z1_real = REAL(in,istride,i+m); + const ATOMIC z1_imag = IMAG(in,istride,i+m); + + /* compute x = W(2) z */ + + /* x0 = z0 + z1 */ + const ATOMIC x0_real = z0_real + z1_real; + const ATOMIC x0_imag = z0_imag + z1_imag; + + /* x1 = z0 - z1 */ + const ATOMIC x1_real = z0_real - z1_real; + const ATOMIC x1_imag = z0_imag - z1_imag; + + /* apply twiddle factors */ + + /* out0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* out1 = w * x1 */ + REAL(out,ostride,j+product_1) = w_real * x1_real - w_imag * x1_imag; + IMAG(out,ostride,j+product_1) = w_real * x1_imag + w_imag * x1_real; + + i++; + j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_3.c b/gsl-1.9/fft/c_pass_3.c new file mode 100644 index 0000000..f55fb5c --- /dev/null +++ b/gsl-1.9/fft/c_pass_3.c @@ -0,0 +1,127 @@ +/* fft/c_pass_3.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) * twiddle1, + const TYPE(gsl_complex) * twiddle2) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 3; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + const size_t jump = (factor - 1) * product_1; + + const ATOMIC tau = sqrt (3.0) / 2.0; + + for (k = 0; k < q; k++) + { + ATOMIC w1_real, w1_imag, w2_real, w2_imag; + + if (k == 0) + { + w1_real = 1.0; + w1_imag = 0.0; + w2_real = 1.0; + w2_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = GSL_IMAG(twiddle2[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + } + } + + for (k1 = 0; k1 < product_1; k1++) + { + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + const ATOMIC z1_real = REAL(in,istride,i+m); + const ATOMIC z1_imag = IMAG(in,istride,i+m); + const ATOMIC z2_real = REAL(in,istride,i+2*m); + const ATOMIC z2_imag = IMAG(in,istride,i+2*m); + + /* compute x = W(3) z */ + + /* t1 = z1 + z2 */ + const ATOMIC t1_real = z1_real + z2_real; + const ATOMIC t1_imag = z1_imag + z2_imag; + + /* t2 = z0 - t1/2 */ + const ATOMIC t2_real = z0_real - t1_real / 2.0; + const ATOMIC t2_imag = z0_imag - t1_imag / 2.0; + + /* t3 = (+/-) sin(pi/3)*(z1 - z2) */ + const ATOMIC t3_real = ((int) sign) * tau * (z1_real - z2_real); + const ATOMIC t3_imag = ((int) sign) * tau * (z1_imag - z2_imag); + + /* x0 = z0 + t1 */ + const ATOMIC x0_real = z0_real + t1_real; + const ATOMIC x0_imag = z0_imag + t1_imag; + + /* x1 = t2 + i t3 */ + const ATOMIC x1_real = t2_real - t3_imag; + const ATOMIC x1_imag = t2_imag + t3_real; + + /* x2 = t2 - i t3 */ + const ATOMIC x2_real = t2_real + t3_imag; + const ATOMIC x2_imag = t2_imag - t3_real; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* to1 = w1 * x1 */ + REAL(out,ostride,j+product_1) = w1_real * x1_real - w1_imag * x1_imag; + IMAG(out,ostride,j+product_1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + REAL(out,ostride,j+2*product_1) = w2_real * x2_real - w2_imag * x2_imag; + IMAG(out,ostride,j+2*product_1) = w2_real * x2_imag + w2_imag * x2_real; + + i++; j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_4.c b/gsl-1.9/fft/c_pass_4.c new file mode 100644 index 0000000..8fa3b7f --- /dev/null +++ b/gsl-1.9/fft/c_pass_4.c @@ -0,0 +1,147 @@ +/* fft/c_pass_4.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 4; + const size_t m = n / factor; + const size_t q = n / product; + const size_t p_1 = product / factor; + const size_t jump = (factor - 1) * p_1; + + for (k = 0; k < q; k++) + { + ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag; + + if (k == 0) + { + w1_real = 1.0; + w1_imag = 0.0; + w2_real = 1.0; + w2_imag = 0.0; + w3_real = 1.0; + w3_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = GSL_IMAG(twiddle3[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = -GSL_IMAG(twiddle3[k - 1]); + } + } + + for (k1 = 0; k1 < p_1; k1++) + { + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + const ATOMIC z1_real = REAL(in,istride,i+m); + const ATOMIC z1_imag = IMAG(in,istride,i+m); + const ATOMIC z2_real = REAL(in,istride,i+2*m); + const ATOMIC z2_imag = IMAG(in,istride,i+2*m); + const ATOMIC z3_real = REAL(in,istride,i+3*m); + const ATOMIC z3_imag = IMAG(in,istride,i+3*m); + + /* compute x = W(4) z */ + + /* t1 = z0 + z2 */ + const ATOMIC t1_real = z0_real + z2_real; + const ATOMIC t1_imag = z0_imag + z2_imag; + + /* t2 = z1 + z3 */ + const ATOMIC t2_real = z1_real + z3_real; + const ATOMIC t2_imag = z1_imag + z3_imag; + + /* t3 = z0 - z2 */ + const ATOMIC t3_real = z0_real - z2_real; + const ATOMIC t3_imag = z0_imag - z2_imag; + + /* t4 = (+/-) (z1 - z3) */ + const ATOMIC t4_real = ((int) sign) * (z1_real - z3_real); + const ATOMIC t4_imag = ((int) sign) * (z1_imag - z3_imag); + + /* x0 = t1 + t2 */ + const ATOMIC x0_real = t1_real + t2_real; + const ATOMIC x0_imag = t1_imag + t2_imag; + + /* x1 = t3 + i t4 */ + const ATOMIC x1_real = t3_real - t4_imag; + const ATOMIC x1_imag = t3_imag + t4_real; + + /* x2 = t1 - t2 */ + const ATOMIC x2_real = t1_real - t2_real; + const ATOMIC x2_imag = t1_imag - t2_imag; + + /* x3 = t3 - i t4 */ + const ATOMIC x3_real = t3_real + t4_imag; + const ATOMIC x3_imag = t3_imag - t4_real; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* to1 = w1 * x1 */ + REAL(out, ostride, j + p_1) = w1_real * x1_real - w1_imag * x1_imag; + IMAG(out, ostride, j + p_1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + REAL(out, ostride, j + 2 * p_1) = w2_real * x2_real - w2_imag * x2_imag; + IMAG(out, ostride, j + 2 * p_1) = w2_real * x2_imag + w2_imag * x2_real; + + /* to3 = w3 * x3 */ + REAL(out, ostride, j + 3 * p_1) = w3_real * x3_real - w3_imag * x3_imag; + IMAG(out, ostride, j + 3 * p_1) = w3_real * x3_imag + w3_imag * x3_real; + + i++; + j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_5.c b/gsl-1.9/fft/c_pass_5.c new file mode 100644 index 0000000..d8a9d65 --- /dev/null +++ b/gsl-1.9/fft/c_pass_5.c @@ -0,0 +1,205 @@ +/* fft/c_pass_5.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 5; + const size_t m = n / factor; + const size_t q = n / product; + const size_t p_1 = product / factor; + const size_t jump = (factor - 1) * p_1; + + const ATOMIC sin_2pi_by_5 = sin (2.0 * M_PI / 5.0); + const ATOMIC sin_2pi_by_10 = sin (2.0 * M_PI / 10.0); + + for (k = 0; k < q; k++) + { + + ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, + w4_imag; + + if (k == 0) + { + w1_real = 1.0; + w1_imag = 0.0; + w2_real = 1.0; + w2_imag = 0.0; + w3_real = 1.0; + w3_imag = 0.0; + w4_real = 1.0; + w4_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = GSL_IMAG(twiddle4[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = -GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = -GSL_IMAG(twiddle4[k - 1]); + } + } + + for (k1 = 0; k1 < p_1; k1++) + { + + ATOMIC x0_real, x0_imag, x1_real, x1_imag, x2_real, x2_imag, + x3_real, x3_imag, x4_real, x4_imag; + + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + const ATOMIC z1_real = REAL(in,istride,i + m); + const ATOMIC z1_imag = IMAG(in,istride,i + m); + const ATOMIC z2_real = REAL(in,istride,i + 2*m); + const ATOMIC z2_imag = IMAG(in,istride,i + 2*m); + const ATOMIC z3_real = REAL(in,istride,i + 3*m); + const ATOMIC z3_imag = IMAG(in,istride,i + 3*m); + const ATOMIC z4_real = REAL(in,istride,i + 4*m); + const ATOMIC z4_imag = IMAG(in,istride,i + 4*m); + + /* compute x = W(5) z */ + + /* t1 = z1 + z4 */ + const ATOMIC t1_real = z1_real + z4_real; + const ATOMIC t1_imag = z1_imag + z4_imag; + + /* t2 = z2 + z3 */ + const ATOMIC t2_real = z2_real + z3_real; + const ATOMIC t2_imag = z2_imag + z3_imag; + + /* t3 = z1 - z4 */ + const ATOMIC t3_real = z1_real - z4_real; + const ATOMIC t3_imag = z1_imag - z4_imag; + + /* t4 = z2 - z3 */ + const ATOMIC t4_real = z2_real - z3_real; + const ATOMIC t4_imag = z2_imag - z3_imag; + + /* t5 = t1 + t2 */ + const ATOMIC t5_real = t1_real + t2_real; + const ATOMIC t5_imag = t1_imag + t2_imag; + + /* t6 = (sqrt(5)/4)(t1 - t2) */ + const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); + const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); + + /* t7 = z0 - ((t5)/4) */ + const ATOMIC t7_real = z0_real - t5_real / 4.0; + const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; + + /* t8 = t7 + t6 */ + const ATOMIC t8_real = t7_real + t6_real; + const ATOMIC t8_imag = t7_imag + t6_imag; + + /* t9 = t7 - t6 */ + const ATOMIC t9_real = t7_real - t6_real; + const ATOMIC t9_imag = t7_imag - t6_imag; + + /* t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */ + const ATOMIC t10_real = ((int) sign) * (sin_2pi_by_5 * t3_real + + sin_2pi_by_10 * t4_real); + const ATOMIC t10_imag = ((int) sign) * (sin_2pi_by_5 * t3_imag + + sin_2pi_by_10 * t4_imag); + + /* t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4 */ + const ATOMIC t11_real = ((int) sign) * (sin_2pi_by_10 * t3_real - + sin_2pi_by_5 * t4_real); + const ATOMIC t11_imag = ((int) sign) * (sin_2pi_by_10 * t3_imag - + sin_2pi_by_5 * t4_imag); + + /* x0 = z0 + t5 */ + x0_real = z0_real + t5_real; + x0_imag = z0_imag + t5_imag; + + /* x1 = t8 + i t10 */ + x1_real = t8_real - t10_imag; + x1_imag = t8_imag + t10_real; + + /* x2 = t9 + i t11 */ + x2_real = t9_real - t11_imag; + x2_imag = t9_imag + t11_real; + + /* x3 = t9 - i t11 */ + x3_real = t9_real + t11_imag; + x3_imag = t9_imag - t11_real; + + /* x4 = t8 - i t10 */ + x4_real = t8_real + t10_imag; + x4_imag = t8_imag - t10_real; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* to1 = w1 * x1 */ + REAL(out,ostride,j + p_1) = w1_real * x1_real - w1_imag * x1_imag; + IMAG(out,ostride,j + p_1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + REAL(out,ostride,j + 2*p_1) = w2_real * x2_real - w2_imag * x2_imag; + IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; + + /* to3 = w3 * x3 */ + REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; + IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; + + /* to4 = w4 * x4 */ + REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; + IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; + + i++; + j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_6.c b/gsl-1.9/fft/c_pass_6.c new file mode 100644 index 0000000..02e2128 --- /dev/null +++ b/gsl-1.9/fft/c_pass_6.c @@ -0,0 +1,220 @@ +/* fft/c_pass_6.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_6) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[], + const TYPE(gsl_complex) twiddle5[]) +{ + + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 6; + const size_t m = n / factor; + const size_t q = n / product; + const size_t p_1 = product / factor; + const size_t jump = (factor - 1) * p_1; + + const ATOMIC tau = sqrt (3.0) / 2.0; + + for (k = 0; k < q; k++) + { + ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, + w4_imag, w5_real, w5_imag; + + if (k == 0) + { + w1_real = 1.0; + w1_imag = 0.0; + w2_real = 1.0; + w2_imag = 0.0; + w3_real = 1.0; + w3_imag = 0.0; + w4_real = 1.0; + w4_imag = 0.0; + w5_real = 1.0; + w5_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = GSL_IMAG(twiddle4[k - 1]); + w5_real = GSL_REAL(twiddle5[k - 1]); + w5_imag = GSL_IMAG(twiddle5[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = -GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = -GSL_IMAG(twiddle4[k - 1]); + w5_real = GSL_REAL(twiddle5[k - 1]); + w5_imag = -GSL_IMAG(twiddle5[k - 1]); + } + } + + for (k1 = 0; k1 < p_1; k1++) + { + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + const ATOMIC z1_real = REAL(in,istride,i+m); + const ATOMIC z1_imag = IMAG(in,istride,i+m); + const ATOMIC z2_real = REAL(in,istride,i+2*m); + const ATOMIC z2_imag = IMAG(in,istride,i+2*m); + const ATOMIC z3_real = REAL(in,istride,i+3*m); + const ATOMIC z3_imag = IMAG(in,istride,i+3*m); + const ATOMIC z4_real = REAL(in,istride,i+4*m); + const ATOMIC z4_imag = IMAG(in,istride,i+4*m); + const ATOMIC z5_real = REAL(in,istride,i+5*m); + const ATOMIC z5_imag = IMAG(in,istride,i+5*m); + + /* compute x = W(6) z */ + + /* W(6) is a combination of sums and differences of W(3) acting + on the even and odd elements of z */ + + /* ta1 = z2 + z4 */ + const ATOMIC ta1_real = z2_real + z4_real; + const ATOMIC ta1_imag = z2_imag + z4_imag; + + /* ta2 = z0 - ta1/2 */ + const ATOMIC ta2_real = z0_real - ta1_real / 2; + const ATOMIC ta2_imag = z0_imag - ta1_imag / 2; + + /* ta3 = (+/-) sin(pi/3)*(z2 - z4) */ + const ATOMIC ta3_real = ((int) sign) * tau * (z2_real - z4_real); + const ATOMIC ta3_imag = ((int) sign) * tau * (z2_imag - z4_imag); + + /* a0 = z0 + ta1 */ + const ATOMIC a0_real = z0_real + ta1_real; + const ATOMIC a0_imag = z0_imag + ta1_imag; + + /* a1 = ta2 + i ta3 */ + const ATOMIC a1_real = ta2_real - ta3_imag; + const ATOMIC a1_imag = ta2_imag + ta3_real; + + /* a2 = ta2 - i ta3 */ + const ATOMIC a2_real = ta2_real + ta3_imag; + const ATOMIC a2_imag = ta2_imag - ta3_real; + + /* tb1 = z5 + z1 */ + const ATOMIC tb1_real = z5_real + z1_real; + const ATOMIC tb1_imag = z5_imag + z1_imag; + + /* tb2 = z3 - tb1/2 */ + const ATOMIC tb2_real = z3_real - tb1_real / 2; + const ATOMIC tb2_imag = z3_imag - tb1_imag / 2; + + /* tb3 = (+/-) sin(pi/3)*(z5 - z1) */ + const ATOMIC tb3_real = ((int) sign) * tau * (z5_real - z1_real); + const ATOMIC tb3_imag = ((int) sign) * tau * (z5_imag - z1_imag); + + /* b0 = z3 + tb1 */ + const ATOMIC b0_real = z3_real + tb1_real; + const ATOMIC b0_imag = z3_imag + tb1_imag; + + /* b1 = tb2 + i tb3 */ + const ATOMIC b1_real = tb2_real - tb3_imag; + const ATOMIC b1_imag = tb2_imag + tb3_real; + + /* b2 = tb2 - i tb3 */ + const ATOMIC b2_real = tb2_real + tb3_imag; + const ATOMIC b2_imag = tb2_imag - tb3_real; + + /* x0 = a0 + b0 */ + const ATOMIC x0_real = a0_real + b0_real; + const ATOMIC x0_imag = a0_imag + b0_imag; + + /* x4 = a1 + b1 */ + const ATOMIC x4_real = a1_real + b1_real; + const ATOMIC x4_imag = a1_imag + b1_imag; + + /* x2 = a2 + b2 */ + const ATOMIC x2_real = a2_real + b2_real; + const ATOMIC x2_imag = a2_imag + b2_imag; + + /* x3 = a0 - b0 */ + const ATOMIC x3_real = a0_real - b0_real; + const ATOMIC x3_imag = a0_imag - b0_imag; + + /* x1 = a1 - b1 */ + const ATOMIC x1_real = a1_real - b1_real; + const ATOMIC x1_imag = a1_imag - b1_imag; + + /* x5 = a2 - b2 */ + const ATOMIC x5_real = a2_real - b2_real; + const ATOMIC x5_imag = a2_imag - b2_imag; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* to1 = w1 * x1 */ + REAL(out,ostride,j+p_1) = w1_real * x1_real - w1_imag * x1_imag; + IMAG(out,ostride,j+p_1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + REAL(out,ostride,j+2*p_1) = w2_real * x2_real - w2_imag * x2_imag; + IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; + + /* to3 = w3 * x3 */ + REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; + IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; + + /* to4 = w4 * x4 */ + REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; + IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; + + /* to5 = w5 * x5 */ + REAL(out,ostride,j+5*p_1) = w5_real * x5_real - w5_imag * x5_imag; + IMAG(out,ostride,j+5*p_1) = w5_real * x5_imag + w5_imag * x5_real; + + i++; + j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_7.c b/gsl-1.9/fft/c_pass_7.c new file mode 100644 index 0000000..d996f8a --- /dev/null +++ b/gsl-1.9/fft/c_pass_7.c @@ -0,0 +1,312 @@ +/* fft/c_pass_7.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_7) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[], + const TYPE(gsl_complex) twiddle5[], + const TYPE(gsl_complex) twiddle6[]) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t factor = 7; + const size_t m = n / factor; + const size_t q = n / product; + const size_t p_1 = product / factor; + const size_t jump = (factor - 1) * p_1; + + const ATOMIC c1 = cos(1.0 * 2.0 * M_PI / 7.0) ; + const ATOMIC c2 = cos(2.0 * 2.0 * M_PI / 7.0) ; + const ATOMIC c3 = cos(3.0 * 2.0 * M_PI / 7.0) ; + + const ATOMIC s1 = sin(1.0 * 2.0 * M_PI / 7.0) ; + const ATOMIC s2 = sin(2.0 * 2.0 * M_PI / 7.0) ; + const ATOMIC s3 = sin(3.0 * 2.0 * M_PI / 7.0) ; + + for (k = 0; k < q; k++) + { + ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real, + w4_imag, w5_real, w5_imag, w6_real, w6_imag; + + if (k == 0) + { + w1_real = 1.0; + w1_imag = 0.0; + w2_real = 1.0; + w2_imag = 0.0; + w3_real = 1.0; + w3_imag = 0.0; + w4_real = 1.0; + w4_imag = 0.0; + w5_real = 1.0; + w5_imag = 0.0; + w6_real = 1.0; + w6_imag = 0.0; + } + else + { + if (sign == gsl_fft_forward) + { + /* forward tranform */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = GSL_IMAG(twiddle4[k - 1]); + w5_real = GSL_REAL(twiddle5[k - 1]); + w5_imag = GSL_IMAG(twiddle5[k - 1]); + w6_real = GSL_REAL(twiddle6[k - 1]); + w6_imag = GSL_IMAG(twiddle6[k - 1]); + } + else + { + /* backward tranform: w -> conjugate(w) */ + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = -GSL_IMAG(twiddle3[k - 1]); + w4_real = GSL_REAL(twiddle4[k - 1]); + w4_imag = -GSL_IMAG(twiddle4[k - 1]); + w5_real = GSL_REAL(twiddle5[k - 1]); + w5_imag = -GSL_IMAG(twiddle5[k - 1]); + w6_real = GSL_REAL(twiddle6[k - 1]); + w6_imag = -GSL_IMAG(twiddle6[k - 1]); + } + } + + for (k1 = 0; k1 < p_1; k1++) + { + const ATOMIC z0_real = REAL(in,istride,i); + const ATOMIC z0_imag = IMAG(in,istride,i); + const ATOMIC z1_real = REAL(in,istride,i+m); + const ATOMIC z1_imag = IMAG(in,istride,i+m); + const ATOMIC z2_real = REAL(in,istride,i+2*m); + const ATOMIC z2_imag = IMAG(in,istride,i+2*m); + const ATOMIC z3_real = REAL(in,istride,i+3*m); + const ATOMIC z3_imag = IMAG(in,istride,i+3*m); + const ATOMIC z4_real = REAL(in,istride,i+4*m); + const ATOMIC z4_imag = IMAG(in,istride,i+4*m); + const ATOMIC z5_real = REAL(in,istride,i+5*m); + const ATOMIC z5_imag = IMAG(in,istride,i+5*m); + const ATOMIC z6_real = REAL(in,istride,i+6*m); + const ATOMIC z6_imag = IMAG(in,istride,i+6*m); + + /* compute x = W(7) z */ + + /* t0 = z1 + z6 */ + const ATOMIC t0_real = z1_real + z6_real ; + const ATOMIC t0_imag = z1_imag + z6_imag ; + + /* t1 = z1 - z6 */ + const ATOMIC t1_real = z1_real - z6_real ; + const ATOMIC t1_imag = z1_imag - z6_imag ; + + /* t2 = z2 + z5 */ + const ATOMIC t2_real = z2_real + z5_real ; + const ATOMIC t2_imag = z2_imag + z5_imag ; + + /* t3 = z2 - z5 */ + const ATOMIC t3_real = z2_real - z5_real ; + const ATOMIC t3_imag = z2_imag - z5_imag ; + + /* t4 = z4 + z3 */ + const ATOMIC t4_real = z4_real + z3_real ; + const ATOMIC t4_imag = z4_imag + z3_imag ; + + /* t5 = z4 - z3 */ + const ATOMIC t5_real = z4_real - z3_real ; + const ATOMIC t5_imag = z4_imag - z3_imag ; + + /* t6 = t2 + t0 */ + const ATOMIC t6_real = t2_real + t0_real ; + const ATOMIC t6_imag = t2_imag + t0_imag ; + + /* t7 = t5 + t3 */ + const ATOMIC t7_real = t5_real + t3_real ; + const ATOMIC t7_imag = t5_imag + t3_imag ; + + /* b0 = z0 + t6 + t4 */ + const ATOMIC b0_real = z0_real + t6_real + t4_real ; + const ATOMIC b0_imag = z0_imag + t6_imag + t4_imag ; + + /* b1 = ((cos(2pi/7) + cos(4pi/7) + cos(6pi/7))/3-1) (t6 + t4) */ + const ATOMIC b1_real = (((c1 + c2 + c3)/3.0 - 1.0) * (t6_real + t4_real)); + const ATOMIC b1_imag = (((c1 + c2 + c3)/3.0 - 1.0) * (t6_imag + t4_imag)); + + /* b2 = ((2*cos(2pi/7) - cos(4pi/7) - cos(6pi/7))/3) (t0 - t4) */ + const ATOMIC b2_real = (((2.0 * c1 - c2 - c3)/3.0) * (t0_real - t4_real)); + const ATOMIC b2_imag = (((2.0 * c1 - c2 - c3)/3.0) * (t0_imag - t4_imag)); + + /* b3 = ((cos(2pi/7) - 2*cos(4pi/7) + cos(6pi/7))/3) (t4 - t2) */ + const ATOMIC b3_real = (((c1 - 2.0*c2 + c3)/3.0) * (t4_real - t2_real)); + const ATOMIC b3_imag = (((c1 - 2.0*c2 + c3)/3.0) * (t4_imag - t2_imag)); + + /* b4 = ((cos(2pi/7) + cos(4pi/7) - 2*cos(6pi/7))/3) (t2 - t0) */ + const ATOMIC b4_real = (((c1 + c2 - 2.0 * c3)/3.0) * (t2_real - t0_real)); + const ATOMIC b4_imag = (((c1 + c2 - 2.0 * c3)/3.0) * (t2_imag - t0_imag)); + + /* b5 = sign * ((sin(2pi/7) + sin(4pi/7) - sin(6pi/7))/3) (t7 + t1) */ + const ATOMIC b5_real = (-(int)sign) * ((s1 + s2 - s3)/3.0) * (t7_real + t1_real) ; + const ATOMIC b5_imag = (-(int)sign) * ((s1 + s2 - s3)/3.0) * (t7_imag + t1_imag) ; + + /* b6 = sign * ((2sin(2pi/7) - sin(4pi/7) + sin(6pi/7))/3) (t1 - t5) */ + const ATOMIC b6_real = (-(int)sign) * ((2.0 * s1 - s2 + s3)/3.0) * (t1_real - t5_real) ; + const ATOMIC b6_imag = (-(int)sign) * ((2.0 * s1 - s2 + s3)/3.0) * (t1_imag - t5_imag) ; + + /* b7 = sign * ((sin(2pi/7) - 2sin(4pi/7) - sin(6pi/7))/3) (t5 - t3) */ + const ATOMIC b7_real = (-(int)sign) * ((s1 - 2.0 * s2 - s3)/3.0) * (t5_real - t3_real) ; + const ATOMIC b7_imag = (-(int)sign) * ((s1 - 2.0 * s2 - s3)/3.0) * (t5_imag - t3_imag) ; + + /* b8 = sign * ((sin(2pi/7) + sin(4pi/7) + 2sin(6pi/7))/3) (t3 - t1) */ + const ATOMIC b8_real = (-(int)sign) * ((s1 + s2 + 2.0 * s3)/3.0) * (t3_real - t1_real) ; + const ATOMIC b8_imag = (-(int)sign) * ((s1 + s2 + 2.0 * s3)/3.0) * (t3_imag - t1_imag) ; + + + /* T0 = b0 + b1 */ + const ATOMIC T0_real = b0_real + b1_real ; + const ATOMIC T0_imag = b0_imag + b1_imag ; + + /* T1 = b2 + b3 */ + const ATOMIC T1_real = b2_real + b3_real ; + const ATOMIC T1_imag = b2_imag + b3_imag ; + + /* T2 = b4 - b3 */ + const ATOMIC T2_real = b4_real - b3_real ; + const ATOMIC T2_imag = b4_imag - b3_imag ; + + /* T3 = -b2 - b4 */ + const ATOMIC T3_real = -b2_real - b4_real ; + const ATOMIC T3_imag = -b2_imag - b4_imag ; + + /* T4 = b6 + b7 */ + const ATOMIC T4_real = b6_real + b7_real ; + const ATOMIC T4_imag = b6_imag + b7_imag ; + + /* T5 = b8 - b7 */ + const ATOMIC T5_real = b8_real - b7_real ; + const ATOMIC T5_imag = b8_imag - b7_imag ; + + /* T6 = -b8 - b6 */ + const ATOMIC T6_real = -b8_real - b6_real ; + const ATOMIC T6_imag = -b8_imag - b6_imag ; + + /* T7 = T0 + T1 */ + const ATOMIC T7_real = T0_real + T1_real ; + const ATOMIC T7_imag = T0_imag + T1_imag ; + + /* T8 = T0 + T2 */ + const ATOMIC T8_real = T0_real + T2_real ; + const ATOMIC T8_imag = T0_imag + T2_imag ; + + /* T9 = T0 + T3 */ + const ATOMIC T9_real = T0_real + T3_real ; + const ATOMIC T9_imag = T0_imag + T3_imag ; + + /* T10 = T4 + b5 */ + const ATOMIC T10_real = T4_real + b5_real ; + const ATOMIC T10_imag = T4_imag + b5_imag ; + + /* T11 = T5 + b5 */ + const ATOMIC T11_real = T5_real + b5_real ; + const ATOMIC T11_imag = T5_imag + b5_imag ; + + /* T12 = T6 + b5 */ + const ATOMIC T12_real = T6_real + b5_real ; + const ATOMIC T12_imag = T6_imag + b5_imag ; + + + /* x0 = b0 */ + const ATOMIC x0_real = b0_real ; + const ATOMIC x0_imag = b0_imag ; + + /* x1 = T7 - i T10 */ + const ATOMIC x1_real = T7_real + T10_imag ; + const ATOMIC x1_imag = T7_imag - T10_real ; + + /* x2 = T9 - i T12 */ + const ATOMIC x2_real = T9_real + T12_imag ; + const ATOMIC x2_imag = T9_imag - T12_real ; + + /* x3 = T8 + i T11 */ + const ATOMIC x3_real = T8_real - T11_imag ; + const ATOMIC x3_imag = T8_imag + T11_real ; + + /* x4 = T8 - i T11 */ + const ATOMIC x4_real = T8_real + T11_imag ; + const ATOMIC x4_imag = T8_imag - T11_real ; + + /* x5 = T9 + i T12 */ + const ATOMIC x5_real = T9_real - T12_imag ; + const ATOMIC x5_imag = T9_imag + T12_real ; + + /* x6 = T7 + i T10 */ + const ATOMIC x6_real = T7_real - T10_imag ; + const ATOMIC x6_imag = T7_imag + T10_real ; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + REAL(out,ostride,j) = x0_real; + IMAG(out,ostride,j) = x0_imag; + + /* to1 = w1 * x1 */ + REAL(out,ostride,j+p_1) = w1_real * x1_real - w1_imag * x1_imag; + IMAG(out,ostride,j+p_1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + REAL(out,ostride,j+2*p_1) = w2_real * x2_real - w2_imag * x2_imag; + IMAG(out,ostride,j+2*p_1) = w2_real * x2_imag + w2_imag * x2_real; + + /* to3 = w3 * x3 */ + REAL(out,ostride,j+3*p_1) = w3_real * x3_real - w3_imag * x3_imag; + IMAG(out,ostride,j+3*p_1) = w3_real * x3_imag + w3_imag * x3_real; + + /* to4 = w4 * x4 */ + REAL(out,ostride,j+4*p_1) = w4_real * x4_real - w4_imag * x4_imag; + IMAG(out,ostride,j+4*p_1) = w4_real * x4_imag + w4_imag * x4_real; + + /* to5 = w5 * x5 */ + REAL(out,ostride,j+5*p_1) = w5_real * x5_real - w5_imag * x5_imag; + IMAG(out,ostride,j+5*p_1) = w5_real * x5_imag + w5_imag * x5_real; + + /* to6 = w6 * x6 */ + REAL(out,ostride,j+6*p_1) = w6_real * x6_real - w6_imag * x6_imag; + IMAG(out,ostride,j+6*p_1) = w6_real * x6_imag + w6_imag * x6_real; + + i++; j++; + } + j += jump; + } + return 0; +} diff --git a/gsl-1.9/fft/c_pass_n.c b/gsl-1.9/fft/c_pass_n.c new file mode 100644 index 0000000..a4ec823 --- /dev/null +++ b/gsl-1.9/fft/c_pass_n.c @@ -0,0 +1,204 @@ +/* fft/c_pass_n.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int +FUNCTION(fft_complex,pass_n) (BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const gsl_fft_direction sign, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + size_t i = 0, j = 0; + size_t k, k1; + + const size_t m = n / factor; + const size_t q = n / product; + const size_t p_1 = product / factor; + const size_t jump = (factor - 1) * p_1; + + size_t e, e1; + + for (i = 0; i < m; i++) + { + REAL(out,ostride,i) = REAL(in,istride,i); + IMAG(out,ostride,i) = IMAG(in,istride,i); + } + + for (e = 1; e < (factor - 1) / 2 + 1; e++) + { + for (i = 0; i < m; i++) + { + const size_t idx = i + e * m; + const size_t idxc = i + (factor - e) * m; + REAL(out,ostride,idx) = REAL(in,istride,idx) + REAL(in,istride,idxc); + IMAG(out,ostride,idx) = IMAG(in,istride,idx) + IMAG(in,istride,idxc); + REAL(out,ostride,idxc) = REAL(in,istride,idx) - REAL(in,istride,idxc); + IMAG(out,ostride,idxc) = IMAG(in,istride,idx) - IMAG(in,istride,idxc); + } + } + + /* e = 0 */ + + for (i=0 ; i<m; i++) + { + REAL(in,istride,i) = REAL(out,ostride,i); + IMAG(in,istride,i) = IMAG(out,ostride,i); + } + + for (e1 = 1; e1 < (factor - 1) / 2 + 1; e1++) + { + for (i = 0; i < m; i++) + { + REAL(in,istride,i) += REAL(out,ostride,i + e1*m) ; + IMAG(in,istride,i) += IMAG(out,ostride,i + e1*m) ; + } + } + + for (e = 1; e < (factor-1)/2 + 1; e++) + { + size_t idx = e*q ; + const size_t idx_step = e * q ; + ATOMIC w_real, w_imag ; + + const size_t em = e * m ; + const size_t ecm = (factor - e) * m ; + + for (i = 0; i < m; i++) + { + REAL(in,istride,i+em) = REAL(out,ostride,i) ; + IMAG(in,istride,i+em) = IMAG(out,ostride,i) ; + REAL(in,istride,i+ecm) = REAL(out,ostride,i) ; + IMAG(in,istride,i+ecm) = IMAG(out,ostride,i) ; + } + + for (e1 = 1; e1 < (factor - 1) / 2 + 1; e1++) + { + if (idx == 0) { + w_real = 1 ; + w_imag = 0 ; + } else { + if (sign == gsl_fft_forward) { + w_real = GSL_REAL(twiddle[idx - 1]) ; + w_imag = GSL_IMAG(twiddle[idx - 1]) ; + } else { + w_real = GSL_REAL(twiddle[idx - 1]) ; + w_imag = -GSL_IMAG(twiddle[idx - 1]) ; + } + } + + for (i = 0; i < m; i++) + { + const ATOMIC xp_real = REAL(out,ostride,i + e1 * m); + const ATOMIC xp_imag = IMAG(out,ostride,i + e1 * m); + const ATOMIC xm_real = REAL(out,ostride,i + (factor - e1) *m); + const ATOMIC xm_imag = IMAG(out,ostride,i + (factor - e1) *m); + + const ATOMIC ap = w_real * xp_real ; + const ATOMIC am = w_imag * xm_imag ; + + ATOMIC sum_real = ap - am; + ATOMIC sumc_real = ap + am; + + const ATOMIC bp = w_real * xp_imag ; + const ATOMIC bm = w_imag * xm_real ; + + ATOMIC sum_imag = bp + bm; + ATOMIC sumc_imag = bp - bm; + + REAL(in,istride,i + em) += sum_real; + IMAG(in,istride,i + em) += sum_imag; + REAL(in,istride,i + ecm) += sumc_real; + IMAG(in,istride,i + ecm) += sumc_imag; + } + idx += idx_step ; + idx %= factor * q ; + } + } + + i = 0; + j = 0; + + /* k = 0 */ + for (k1 = 0; k1 < p_1; k1++) + { + REAL(out,ostride,k1) = REAL(in,istride,k1); + IMAG(out,ostride,k1) = IMAG(in,istride,k1); + } + + for (e1 = 1; e1 < factor; e1++) + { + for (k1 = 0; k1 < p_1; k1++) + { + REAL(out,ostride,k1 + e1 * p_1) = REAL(in,istride,k1 + e1 * m) ; + IMAG(out,ostride,k1 + e1 * p_1) = IMAG(in,istride,k1 + e1 * m) ; + } + } + + i = p_1 ; + j = product ; + + for (k = 1; k < q; k++) + { + for (k1 = 0; k1 < p_1; k1++) + { + REAL(out,ostride,j) = REAL(in,istride,i); + IMAG(out,ostride,j) = IMAG(in,istride,i); + i++; + j++; + } + j += jump; + } + + i = p_1 ; + j = product ; + + for (k = 1; k < q; k++) + { + for (k1 = 0; k1 < p_1; k1++) + { + for (e1 = 1; e1 < factor; e1++) + { + ATOMIC x_real = REAL(in, istride,i + e1 * m); + ATOMIC x_imag = IMAG(in, istride,i + e1 * m); + + ATOMIC w_real, w_imag ; + if (sign == gsl_fft_forward) { + w_real = GSL_REAL(twiddle[(e1-1)*q + k-1]) ; + w_imag = GSL_IMAG(twiddle[(e1-1)*q + k-1]) ; + } else { + w_real = GSL_REAL(twiddle[(e1-1)*q + k-1]) ; + w_imag = -GSL_IMAG(twiddle[(e1-1)*q + k-1]) ; + } + + REAL(out,ostride,j + e1 * p_1) = w_real * x_real - w_imag * x_imag; + IMAG(out,ostride,j + e1 * p_1) = w_real * x_imag + w_imag * x_real; + } + i++; + j++; + } + j += jump; + } + + return 0; +} + diff --git a/gsl-1.9/fft/c_radix2.c b/gsl-1.9/fft/c_radix2.c new file mode 100644 index 0000000..f8dcf43 --- /dev/null +++ b/gsl-1.9/fft/c_radix2.c @@ -0,0 +1,316 @@ +/* fft/c_radix2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(gsl_fft_complex,radix2_forward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, const size_t n) +{ + gsl_fft_direction sign = gsl_fft_forward; + int status = FUNCTION(gsl_fft_complex,radix2_transform) (data, stride, n, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,radix2_backward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, const size_t n) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,radix2_transform) (data, stride, n, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,radix2_inverse) (TYPE(gsl_complex_packed_array) data, + const size_t stride, const size_t n) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,radix2_transform) (data, stride, n, sign); + + if (status) + { + return status; + } + + /* normalize inverse fft with 1/n */ + + { + const ATOMIC norm = 1.0 / n; + size_t i; + for (i = 0; i < n; i++) + { + REAL(data,stride,i) *= norm; + IMAG(data,stride,i) *= norm; + } + } + + return status; +} + + + +int +FUNCTION(gsl_fft_complex,radix2_transform) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign) +{ + int result ; + size_t dual; + size_t bit; + size_t logn = 0; + int status; + + if (n == 1) /* identity operation */ + { + return 0 ; + } + + /* make sure that n is a power of 2 */ + + result = fft_binary_logn(n) ; + + if (result == -1) + { + GSL_ERROR ("n is not a power of 2", GSL_EINVAL); + } + else + { + logn = result ; + } + + /* bit reverse the ordering of input data for decimation in time algorithm */ + + status = FUNCTION(fft_complex,bitreverse_order) (data, stride, n, logn) ; + + /* apply fft recursion */ + + dual = 1; + + for (bit = 0; bit < logn; bit++) + { + ATOMIC w_real = 1.0; + ATOMIC w_imag = 0.0; + + const double theta = 2.0 * ((int) sign) * M_PI / (2.0 * (double) dual); + + const ATOMIC s = sin (theta); + const ATOMIC t = sin (theta / 2.0); + const ATOMIC s2 = 2.0 * t * t; + + size_t a, b; + + /* a = 0 */ + + for (b = 0; b < n; b += 2 * dual) + { + const size_t i = b ; + const size_t j = b + dual; + + const ATOMIC z1_real = REAL(data,stride,j) ; + const ATOMIC z1_imag = IMAG(data,stride,j) ; + + const ATOMIC wd_real = z1_real ; + const ATOMIC wd_imag = z1_imag ; + + REAL(data,stride,j) = REAL(data,stride,i) - wd_real; + IMAG(data,stride,j) = IMAG(data,stride,i) - wd_imag; + REAL(data,stride,i) += wd_real; + IMAG(data,stride,i) += wd_imag; + } + + /* a = 1 .. (dual-1) */ + + for (a = 1; a < dual; a++) + { + + /* trignometric recurrence for w-> exp(i theta) w */ + + { + const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; + const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; + w_real = tmp_real; + w_imag = tmp_imag; + } + + for (b = 0; b < n; b += 2 * dual) + { + const size_t i = b + a; + const size_t j = b + a + dual; + + const ATOMIC z1_real = REAL(data,stride,j) ; + const ATOMIC z1_imag = IMAG(data,stride,j) ; + + const ATOMIC wd_real = w_real * z1_real - w_imag * z1_imag; + const ATOMIC wd_imag = w_real * z1_imag + w_imag * z1_real; + + REAL(data,stride,j) = REAL(data,stride,i) - wd_real; + IMAG(data,stride,j) = IMAG(data,stride,i) - wd_imag; + REAL(data,stride,i) += wd_real; + IMAG(data,stride,i) += wd_imag; + } + } + dual *= 2; + } + + return 0; + +} + + +int +FUNCTION(gsl_fft_complex,radix2_dif_forward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n) +{ + gsl_fft_direction sign = gsl_fft_forward; + int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,radix2_dif_backward) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); + return status; +} + +int +FUNCTION(gsl_fft_complex,radix2_dif_inverse) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_fft_complex,radix2_dif_transform) (data, stride, n, sign); + + if (status) + { + return status; + } + + /* normalize inverse fft with 1/n */ + + { + const ATOMIC norm = 1.0 / n; + size_t i; + for (i = 0; i < n; i++) + { + REAL(data,stride,i) *= norm; + IMAG(data,stride,i) *= norm; + } + } + + return status; +} + +int +FUNCTION(gsl_fft_complex,radix2_dif_transform) (TYPE(gsl_complex_packed_array) data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign) +{ + int result ; + size_t dual; + size_t bit; + size_t logn = 0; + int status; + + if (n == 1) /* identity operation */ + { + return 0 ; + } + + /* make sure that n is a power of 2 */ + + result = fft_binary_logn(n) ; + + if (result == -1) + { + GSL_ERROR ("n is not a power of 2", GSL_EINVAL); + } + else + { + logn = result ; + } + + /* apply fft recursion */ + + dual = n / 2; + + for (bit = 0; bit < logn; bit++) + { + ATOMIC w_real = 1.0; + ATOMIC w_imag = 0.0; + + const double theta = 2.0 * ((int) sign) * M_PI / ((double) (2 * dual)); + + const ATOMIC s = sin (theta); + const ATOMIC t = sin (theta / 2.0); + const ATOMIC s2 = 2.0 * t * t; + + size_t a, b; + + for (b = 0; b < dual; b++) + { + for (a = 0; a < n; a+= 2 * dual) + { + const size_t i = b + a; + const size_t j = b + a + dual; + + const ATOMIC t1_real = REAL(data,stride,i) + REAL(data,stride,j); + const ATOMIC t1_imag = IMAG(data,stride,i) + IMAG(data,stride,j); + const ATOMIC t2_real = REAL(data,stride,i) - REAL(data,stride,j); + const ATOMIC t2_imag = IMAG(data,stride,i) - IMAG(data,stride,j); + + REAL(data,stride,i) = t1_real; + IMAG(data,stride,i) = t1_imag; + REAL(data,stride,j) = w_real*t2_real - w_imag * t2_imag; + IMAG(data,stride,j) = w_real*t2_imag + w_imag * t2_real; + } + + /* trignometric recurrence for w-> exp(i theta) w */ + + { + const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; + const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; + w_real = tmp_real; + w_imag = tmp_imag; + } + } + dual /= 2; + } + + /* bit reverse the ordering of output data for decimation in + frequency algorithm */ + + status = FUNCTION(fft_complex,bitreverse_order)(data, stride, n, logn) ; + + return 0; + +} + + + + + + + + diff --git a/gsl-1.9/fft/compare.h b/gsl-1.9/fft/compare.h new file mode 100644 index 0000000..fe37179 --- /dev/null +++ b/gsl-1.9/fft/compare.h @@ -0,0 +1,30 @@ +/* fft/compare.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(compare_complex,results) (const char *name_a, const BASE a[], + const char *name_b, const BASE b[], + size_t stride, size_t n, + const double allowed_ticks); + +int +FUNCTION(compare_real,results) (const char *name_a, const BASE a[], + const char *name_b, const BASE b[], + size_t stride, size_t n, + const double allowed_ticks); diff --git a/gsl-1.9/fft/compare_source.c b/gsl-1.9/fft/compare_source.c new file mode 100644 index 0000000..0f4ad83 --- /dev/null +++ b/gsl-1.9/fft/compare_source.c @@ -0,0 +1,125 @@ +/* fft/compare_source.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "compare.h" + +int +FUNCTION(compare_complex,results) (const char *name_a, const BASE a[], + const char *name_b, const BASE b[], + size_t stride, size_t n, + const double allowed_ticks) +{ + size_t i; + double ticks, max_ticks = 0; + double dr, di; + const char *flag; + + for (i = 0; i < n; i++) + { + dr = b[2*stride*i] - a[2*stride*i]; + di = b[2*stride*i+1] - a[2*stride*i+1]; + ticks = (fabs (dr) + fabs (di)) / BASE_EPSILON; + if (ticks > max_ticks) + { + max_ticks = ticks; + } + } + + if (max_ticks < allowed_ticks) + { + return 0; + } + + printf ("\n%s vs %s : max_ticks = %f\n", name_a, name_b, max_ticks); + + for (i = 0; i < n; i++) + { + dr = b[2*stride*i] - a[2*stride*i]; + di = b[2*stride*i+1] - a[2*stride*i+1]; + ticks = (fabs (dr) + fabs (di)) / BASE_EPSILON; + + if (ticks > 1000) + { + flag = "***"; + } + else + { + flag = ""; + } + + printf ("%15s: %d %.16f %.16f %s\n", name_a, (int)i, + a[2*stride*i], a[2*stride*i+1], flag); + printf ("%15s: %d %.16f %.16f %e %s\n", name_b, (int)i, + b[2*stride*i], b[2*stride*i+1], ticks, flag); + } + + return -1; +} + + +int +FUNCTION(compare_real,results) (const char *name_a, const BASE a[], + const char *name_b, const BASE b[], + size_t stride, size_t n, + const double allowed_ticks) +{ + size_t i; + double ticks, max_ticks = 0; + double dr; + const char *flag; + + for (i = 0; i < n; i++) + { + dr = b[stride*i] - a[stride*i]; + ticks = fabs (dr) / BASE_EPSILON; + if (ticks > max_ticks) + { + max_ticks = ticks; + } + } + + if (max_ticks < allowed_ticks) + { + return 0; + } + + printf ("\n%s vs %s : max_ticks = %f\n", name_a, name_b, max_ticks); + + for (i = 0; i < n; i++) + { + dr = b[stride*i] - a[stride*i]; + ticks = fabs (dr) / BASE_EPSILON; + + if (ticks > 1000) + { + flag = "***"; + } + else + { + flag = ""; + } + + printf ("%15s: %d %.16f %s\n", name_a, (int)i, + a[stride*i], flag); + printf ("%15s: %d %.16f %e %s\n", name_b, (int)i, + b[stride*i], ticks, flag); + } + + return -1; +} diff --git a/gsl-1.9/fft/complex_internal.h b/gsl-1.9/fft/complex_internal.h new file mode 100644 index 0000000..1c9c366 --- /dev/null +++ b/gsl-1.9/fft/complex_internal.h @@ -0,0 +1,14 @@ +/* Handling of packed complex types... not meant for client consumption. + */ +#ifndef COMPLEX_INTERNAL_H_ +#define COMPLEX_INTERNAL_H_ + +#define VECTOR(a,stride,i) ((a)[(stride)*(i)]) +#define REAL(a,stride,i) ((a)[2*(stride)*(i)]) +#define IMAG(a,stride,i) ((a)[2*(stride)*(i)+1]) + +#define REAL0(a) ((a)[0]) +#define IMAG0(a) ((a)[1]) + + +#endif /* !COMPLEX_INTERNAL_H_ */ diff --git a/gsl-1.9/fft/dft.c b/gsl-1.9/fft/dft.c new file mode 100644 index 0000000..26d32a5 --- /dev/null +++ b/gsl-1.9/fft/dft.c @@ -0,0 +1,25 @@ +#include <config.h> +#include <stddef.h> +#include <stdlib.h> +#include <math.h> + +#include <gsl/gsl_errno.h> +#include <gsl/gsl_complex.h> + +#include <gsl/gsl_dft_complex.h> +#include <gsl/gsl_dft_complex_float.h> + +#include "complex_internal.h" + +#define BASE_DOUBLE +#include "templates_on.h" +#include "dft_source.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "dft_source.c" +#include "templates_off.h" +#undef BASE_FLOAT + diff --git a/gsl-1.9/fft/dft_source.c b/gsl-1.9/fft/dft_source.c new file mode 100644 index 0000000..2f2c349 --- /dev/null +++ b/gsl-1.9/fft/dft_source.c @@ -0,0 +1,104 @@ +/* fft/dft_source.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(gsl_dft_complex,forward) (const BASE data[], + const size_t stride, const size_t n, + BASE result[]) +{ + gsl_fft_direction sign = gsl_fft_forward; + int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); + return status; +} + +int +FUNCTION(gsl_dft_complex,backward) (const BASE data[], + const size_t stride, const size_t n, + BASE result[]) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); + return status; +} + + +int +FUNCTION(gsl_dft_complex,inverse) (const BASE data[], + const size_t stride, const size_t n, + BASE result[]) +{ + gsl_fft_direction sign = gsl_fft_backward; + int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign); + + /* normalize inverse fft with 1/n */ + + { + const ATOMIC norm = ONE / (ATOMIC)n; + size_t i; + for (i = 0; i < n; i++) + { + REAL(result,stride,i) *= norm; + IMAG(result,stride,i) *= norm; + } + } + return status; +} + +int +FUNCTION(gsl_dft_complex,transform) (const BASE data[], + const size_t stride, const size_t n, + BASE result[], + const gsl_fft_direction sign) +{ + + size_t i, j, exponent; + + const double d_theta = 2.0 * ((int) sign) * M_PI / (double) n; + + /* FIXME: check that input length == output length and give error */ + + for (i = 0; i < n; i++) + { + ATOMIC sum_real = 0; + ATOMIC sum_imag = 0; + + exponent = 0; + + for (j = 0; j < n; j++) + { + double theta = d_theta * (double) exponent; + /* sum = exp(i theta) * data[j] */ + + ATOMIC w_real = (ATOMIC) cos (theta); + ATOMIC w_imag = (ATOMIC) sin (theta); + + ATOMIC data_real = REAL(data,stride,j); + ATOMIC data_imag = IMAG(data,stride,j); + + sum_real += w_real * data_real - w_imag * data_imag; + sum_imag += w_real * data_imag + w_imag * data_real; + + exponent = (exponent + i) % n; + } + REAL(result,stride,i) = sum_real; + IMAG(result,stride,i) = sum_imag; + } + + return 0; +} diff --git a/gsl-1.9/fft/factorize.c b/gsl-1.9/fft/factorize.c new file mode 100644 index 0000000..2379fad --- /dev/null +++ b/gsl-1.9/fft/factorize.c @@ -0,0 +1,176 @@ +/* fft/factorize.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> +#include <gsl/gsl_errno.h> +#include <gsl/gsl_fft_complex.h> + +#include "factorize.h" + +static int +fft_complex_factorize (const size_t n, + size_t *nf, + size_t factors[]) +{ + const size_t complex_subtransforms[] = + {7, 6, 5, 4, 3, 2, 0}; + + /* other factors can be added here if their transform modules are + implemented. The end of the list is marked by 0. */ + + int status = fft_factorize (n, complex_subtransforms, nf, factors); + return status; +} + +static int +fft_halfcomplex_factorize (const size_t n, + size_t *nf, + size_t factors[]) +{ + const size_t halfcomplex_subtransforms[] = + {5, 4, 3, 2, 0}; + + int status = fft_factorize (n, halfcomplex_subtransforms, nf, factors); + return status; +} + +static int +fft_real_factorize (const size_t n, + size_t *nf, + size_t factors[]) +{ + const size_t real_subtransforms[] = + {5, 4, 3, 2, 0}; + + int status = fft_factorize (n, real_subtransforms, nf, factors); + return status; +} + + +static int +fft_factorize (const size_t n, + const size_t implemented_subtransforms[], + size_t *n_factors, + size_t factors[]) + +{ + size_t nf = 0; + size_t ntest = n; + size_t factor; + size_t i = 0; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + if (n == 1) + { + factors[0] = 1; + *n_factors = 1; + return 0; + } + + /* deal with the implemented factors first */ + + while (implemented_subtransforms[i] && ntest != 1) + { + factor = implemented_subtransforms[i]; + while ((ntest % factor) == 0) + { + ntest = ntest / factor; + factors[nf] = factor; + nf++; + } + i++; + } + + /* deal with any other even prime factors (there is only one) */ + + factor = 2; + + while ((ntest % factor) == 0 && (ntest != 1)) + { + ntest = ntest / factor; + factors[nf] = factor; + nf++; + } + + /* deal with any other odd prime factors */ + + factor = 3; + + while (ntest != 1) + { + while ((ntest % factor) != 0) + { + factor += 2; + } + ntest = ntest / factor; + factors[nf] = factor; + nf++; + } + + /* check that the factorization is correct */ + { + size_t product = 1; + + for (i = 0; i < nf; i++) + { + product *= factors[i]; + } + + if (product != n) + { + GSL_ERROR ("factorization failed", GSL_ESANITY); + } + } + + *n_factors = nf; + + return 0; +} + + +static int +fft_binary_logn (const size_t n) +{ + size_t ntest ; + size_t binary_logn = 0 ; + size_t k = 1; + + while (k < n) + { + k *= 2; + binary_logn++; + } + + ntest = (1 << binary_logn) ; + + if (n != ntest ) + { + return -1 ; /* n is not a power of 2 */ + } + + return binary_logn; +} + + + + diff --git a/gsl-1.9/fft/factorize.h b/gsl-1.9/fft/factorize.h new file mode 100644 index 0000000..af57a51 --- /dev/null +++ b/gsl-1.9/fft/factorize.h @@ -0,0 +1,29 @@ +/* fft/factorize.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static int fft_complex_factorize (const size_t n, size_t *nf, size_t factors[]); + +static int fft_halfcomplex_factorize (const size_t n, size_t *nf, size_t factors[]); + +static int fft_real_factorize (const size_t n, size_t *nf, size_t factors[]); + +static int fft_factorize (const size_t n, const size_t implemented_subtransforms[], size_t *n_factors, size_t factors[]); + +static int fft_binary_logn (const size_t n) ; + diff --git a/gsl-1.9/fft/fft.c b/gsl-1.9/fft/fft.c new file mode 100644 index 0000000..9aa0da7 --- /dev/null +++ b/gsl-1.9/fft/fft.c @@ -0,0 +1,117 @@ +#include <config.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <gsl/gsl_errno.h> +#include <gsl/gsl_complex.h> + +#include <gsl/gsl_fft_complex.h> +#include <gsl/gsl_fft_complex_float.h> + +#define BASE_DOUBLE +#include "templates_on.h" +#include "bitreverse.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "bitreverse.c" +#include "templates_off.h" +#undef BASE_FLOAT + +#include "factorize.c" + +#define BASE_DOUBLE +#include "templates_on.h" +#include "c_init.c" +#include "c_main.c" +#include "c_pass_2.c" +#include "c_pass_3.c" +#include "c_pass_4.c" +#include "c_pass_5.c" +#include "c_pass_6.c" +#include "c_pass_7.c" +#include "c_pass_n.c" +#include "c_radix2.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "c_init.c" +#include "c_main.c" +#include "c_pass_2.c" +#include "c_pass_3.c" +#include "c_pass_4.c" +#include "c_pass_5.c" +#include "c_pass_6.c" +#include "c_pass_7.c" +#include "c_pass_n.c" +#include "c_radix2.c" +#include "templates_off.h" +#undef BASE_FLOAT + +#include <gsl/gsl_fft_halfcomplex.h> +#include <gsl/gsl_fft_halfcomplex_float.h> + +#define BASE_DOUBLE +#include "templates_on.h" +#include "hc_init.c" +#include "hc_main.c" +#include "hc_pass_2.c" +#include "hc_pass_3.c" +#include "hc_pass_4.c" +#include "hc_pass_5.c" +#include "hc_pass_n.c" +#include "hc_radix2.c" +#include "hc_unpack.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "hc_init.c" +#include "hc_main.c" +#include "hc_pass_2.c" +#include "hc_pass_3.c" +#include "hc_pass_4.c" +#include "hc_pass_5.c" +#include "hc_pass_n.c" +#include "hc_radix2.c" +#include "hc_unpack.c" +#include "templates_off.h" +#undef BASE_FLOAT + +#include <gsl/gsl_fft_real.h> +#include <gsl/gsl_fft_real_float.h> + +#define BASE_DOUBLE +#include "templates_on.h" +#include "real_init.c" +#include "real_main.c" +#include "real_pass_2.c" +#include "real_pass_3.c" +#include "real_pass_4.c" +#include "real_pass_5.c" +#include "real_pass_n.c" +#include "real_radix2.c" +#include "real_unpack.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "real_init.c" +#include "real_main.c" +#include "real_pass_2.c" +#include "real_pass_3.c" +#include "real_pass_4.c" +#include "real_pass_5.c" +#include "real_pass_n.c" +#include "real_radix2.c" +#include "real_unpack.c" +#include "templates_off.h" +#undef BASE_FLOAT diff --git a/gsl-1.9/fft/gsl_dft_complex.h b/gsl-1.9/fft/gsl_dft_complex.h new file mode 100644 index 0000000..6337e60 --- /dev/null +++ b/gsl-1.9/fft/gsl_dft_complex.h @@ -0,0 +1,55 @@ +/* fft/gsl_dft_complex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DFT_COMPLEX_H__ +#define __GSL_DFT_COMPLEX_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_dft_complex_forward (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_backward (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_inverse (const double data[], const size_t stride, const size_t n, + double result[]); + +int gsl_dft_complex_transform (const double data[], const size_t stride, const size_t n, + double result[], const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_DFT_COMPLEX_H__ */ diff --git a/gsl-1.9/fft/gsl_dft_complex_float.h b/gsl-1.9/fft/gsl_dft_complex_float.h new file mode 100644 index 0000000..9acf9af --- /dev/null +++ b/gsl-1.9/fft/gsl_dft_complex_float.h @@ -0,0 +1,55 @@ +/* fft/gsl_dft_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_DFT_COMPLEX_FLOAT_H__ +#define __GSL_DFT_COMPLEX_FLOAT_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_dft_complex_float_forward (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_backward (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_inverse (const float data[], const size_t stride, const size_t n, + float result[]); + +int gsl_dft_complex_float_transform (const float data[], const size_t stride, const size_t n, + float result[], const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_DFT_COMPLEX_FLOAT_H__ */ diff --git a/gsl-1.9/fft/gsl_fft.h b/gsl-1.9/fft/gsl_fft.h new file mode 100644 index 0000000..d98971f --- /dev/null +++ b/gsl-1.9/fft/gsl_fft.h @@ -0,0 +1,60 @@ +/* fft/gsl_fft.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_H__ +#define __GSL_FFT_H__ + +#include <gsl/gsl_complex.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +#ifndef GSL_DISABLE_DEPRECATED +typedef enum + { + forward = -1, backward = +1, + gsl_fft_forward = -1, gsl_fft_backward = +1 + } +gsl_fft_direction; +#else +typedef enum + { + gsl_fft_forward = -1, gsl_fft_backward = +1 + } +gsl_fft_direction; +#endif + +/* this gives the sign in the formula + + h(f) = \sum x(t) exp(+/- 2 pi i f t) + + where - is the forward transform direction and + the inverse direction */ + +__END_DECLS + +#endif /* __GSL_FFT_H__ */ diff --git a/gsl-1.9/fft/gsl_fft_complex.h b/gsl-1.9/fft/gsl_fft_complex.h new file mode 100644 index 0000000..dd3d968 --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_complex.h @@ -0,0 +1,136 @@ +/* fft/gsl_fft_complex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_COMPLEX_H__ +#define __GSL_FFT_COMPLEX_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Power of 2 routines */ + + +int gsl_fft_complex_radix2_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_transform (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +int gsl_fft_complex_radix2_dif_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_radix2_dif_transform (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +/* Mixed Radix general-N routines */ + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_complex_wavetable; + +typedef struct +{ + size_t n; + double *scratch; +} +gsl_fft_complex_workspace; + + +gsl_fft_complex_wavetable *gsl_fft_complex_wavetable_alloc (size_t n); + +void gsl_fft_complex_wavetable_free (gsl_fft_complex_wavetable * wavetable); + +gsl_fft_complex_workspace *gsl_fft_complex_workspace_alloc (size_t n); + +void gsl_fft_complex_workspace_free (gsl_fft_complex_workspace * workspace); + +int gsl_fft_complex_memcpy (gsl_fft_complex_wavetable * dest, + gsl_fft_complex_wavetable * src); + + +int gsl_fft_complex_forward (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_backward (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_inverse (gsl_complex_packed_array data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work); + +int gsl_fft_complex_transform (gsl_complex_packed_array data, + const size_t stride, const size_t n, + const gsl_fft_complex_wavetable * wavetable, + gsl_fft_complex_workspace * work, + const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_FFT_COMPLEX_H__ */ diff --git a/gsl-1.9/fft/gsl_fft_complex_float.h b/gsl-1.9/fft/gsl_fft_complex_float.h new file mode 100644 index 0000000..6216a02 --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_complex_float.h @@ -0,0 +1,139 @@ +/* fft/gsl_fft_complex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_COMPLEX_FLOAT_H__ +#define __GSL_FFT_COMPLEX_FLOAT_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +/* Power of 2 routines */ + + +int gsl_fft_complex_float_radix2_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_transform (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +int gsl_fft_complex_float_radix2_dif_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n); + +int gsl_fft_complex_float_radix2_dif_transform (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_direction sign); + +/* Mixed Radix general-N routines */ + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_complex_wavetable_float; + +typedef struct +{ + size_t n; + float *scratch; +} +gsl_fft_complex_workspace_float; + + +gsl_fft_complex_wavetable_float *gsl_fft_complex_wavetable_float_alloc (size_t n); + +void gsl_fft_complex_wavetable_float_free (gsl_fft_complex_wavetable_float * wavetable); + +gsl_fft_complex_workspace_float *gsl_fft_complex_workspace_float_alloc (size_t n); + +void gsl_fft_complex_workspace_float_free (gsl_fft_complex_workspace_float * workspace); + + +int gsl_fft_complex_float_memcpy (gsl_fft_complex_wavetable_float * dest, + gsl_fft_complex_wavetable_float * src); + + +int gsl_fft_complex_float_forward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_backward (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_inverse (gsl_complex_packed_array_float data, + const size_t stride, + const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work); + +int gsl_fft_complex_float_transform (gsl_complex_packed_array_float data, + const size_t stride, const size_t n, + const gsl_fft_complex_wavetable_float * wavetable, + gsl_fft_complex_workspace_float * work, + const gsl_fft_direction sign); + +__END_DECLS + +#endif /* __GSL_FFT_COMPLEX_FLOAT_H__ */ + + diff --git a/gsl-1.9/fft/gsl_fft_halfcomplex.h b/gsl-1.9/fft/gsl_fft_halfcomplex.h new file mode 100644 index 0000000..c7ed2da --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_halfcomplex.h @@ -0,0 +1,86 @@ +/* fft/gsl_fft_halfcomplex.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_HALFCOMPLEX_H__ +#define __GSL_FFT_HALFCOMPLEX_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> +#include <gsl/gsl_fft_real.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_halfcomplex_radix2_backward (double data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_radix2_inverse (double data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_radix2_transform (double data[], const size_t stride, const size_t n); + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_halfcomplex_wavetable; + +gsl_fft_halfcomplex_wavetable * gsl_fft_halfcomplex_wavetable_alloc (size_t n); + +void +gsl_fft_halfcomplex_wavetable_free (gsl_fft_halfcomplex_wavetable * wavetable); + + +int gsl_fft_halfcomplex_backward (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int gsl_fft_halfcomplex_inverse (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int gsl_fft_halfcomplex_transform (double data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable * wavetable, + gsl_fft_real_workspace * work); + +int +gsl_fft_halfcomplex_unpack (const double halfcomplex_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +int +gsl_fft_halfcomplex_radix2_unpack (const double halfcomplex_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_HALFCOMPLEX_H__ */ diff --git a/gsl-1.9/fft/gsl_fft_halfcomplex_float.h b/gsl-1.9/fft/gsl_fft_halfcomplex_float.h new file mode 100644 index 0000000..4666850 --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_halfcomplex_float.h @@ -0,0 +1,86 @@ +/* fft/gsl_fft_halfcomplex_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_HALFCOMPLEX_FLOAT_H__ +#define __GSL_FFT_HALFCOMPLEX_FLOAT_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> +#include <gsl/gsl_fft_real_float.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_halfcomplex_float_radix2_backward (float data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_float_radix2_inverse (float data[], const size_t stride, const size_t n); +int gsl_fft_halfcomplex_float_radix2_transform (float data[], const size_t stride, const size_t n); + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_halfcomplex_wavetable_float; + + +gsl_fft_halfcomplex_wavetable_float * gsl_fft_halfcomplex_wavetable_float_alloc (size_t n); + +void +gsl_fft_halfcomplex_wavetable_float_free (gsl_fft_halfcomplex_wavetable_float * wavetable); + +int gsl_fft_halfcomplex_float_backward (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int gsl_fft_halfcomplex_float_inverse (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int gsl_fft_halfcomplex_float_transform (float data[], const size_t stride, const size_t n, + const gsl_fft_halfcomplex_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + +int +gsl_fft_halfcomplex_float_unpack (const float halfcomplex_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +int +gsl_fft_halfcomplex_float_radix2_unpack (const float halfcomplex_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_HALFCOMPLEX_FLOAT_H__ */ diff --git a/gsl-1.9/fft/gsl_fft_real.h b/gsl-1.9/fft/gsl_fft_real.h new file mode 100644 index 0000000..5af69e8 --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_real.h @@ -0,0 +1,80 @@ +/* fft/gsl_fft_real.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_REAL_H__ +#define __GSL_FFT_REAL_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_real_radix2_transform (double data[], const size_t stride, const size_t n) ; + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex *twiddle[64]; + gsl_complex *trig; + } +gsl_fft_real_wavetable; + +typedef struct + { + size_t n; + double *scratch; + } +gsl_fft_real_workspace; + +gsl_fft_real_wavetable * gsl_fft_real_wavetable_alloc (size_t n); + +void gsl_fft_real_wavetable_free (gsl_fft_real_wavetable * wavetable); + +gsl_fft_real_workspace * gsl_fft_real_workspace_alloc (size_t n); + +void gsl_fft_real_workspace_free (gsl_fft_real_workspace * workspace); + + +int gsl_fft_real_transform (double data[], const size_t stride, const size_t n, + const gsl_fft_real_wavetable * wavetable, + gsl_fft_real_workspace * work); + + +int gsl_fft_real_unpack (const double real_coefficient[], + double complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_REAL_H__ */ diff --git a/gsl-1.9/fft/gsl_fft_real_float.h b/gsl-1.9/fft/gsl_fft_real_float.h new file mode 100644 index 0000000..2c219d7 --- /dev/null +++ b/gsl-1.9/fft/gsl_fft_real_float.h @@ -0,0 +1,79 @@ +/* fft/gsl_fft_real_float.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __GSL_FFT_REAL_FLOAT_H__ +#define __GSL_FFT_REAL_FLOAT_H__ + +#include <stddef.h> + +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft.h> + +#undef __BEGIN_DECLS +#undef __END_DECLS +#ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +#else +# define __BEGIN_DECLS /* empty */ +# define __END_DECLS /* empty */ +#endif + +__BEGIN_DECLS + +int gsl_fft_real_float_radix2_transform (float data[], const size_t stride, const size_t n) ; + +typedef struct + { + size_t n; + size_t nf; + size_t factor[64]; + gsl_complex_float *twiddle[64]; + gsl_complex_float *trig; + } +gsl_fft_real_wavetable_float; + +typedef struct + { + size_t n; + float *scratch; + } +gsl_fft_real_workspace_float; + +gsl_fft_real_wavetable_float * gsl_fft_real_wavetable_float_alloc (size_t n); + +void gsl_fft_real_wavetable_float_free (gsl_fft_real_wavetable_float * wavetable); + +gsl_fft_real_workspace_float * gsl_fft_real_workspace_float_alloc (size_t n); + +void gsl_fft_real_workspace_float_free (gsl_fft_real_workspace_float * workspace); + +int gsl_fft_real_float_transform (float data[], const size_t stride, const size_t n, + const gsl_fft_real_wavetable_float * wavetable, + gsl_fft_real_workspace_float * work); + + +int gsl_fft_real_float_unpack (const float real_float_coefficient[], + float complex_coefficient[], + const size_t stride, const size_t n); + +__END_DECLS + +#endif /* __GSL_FFT_REAL_FLOAT_H__ */ diff --git a/gsl-1.9/fft/hc_init.c b/gsl-1.9/fft/hc_init.c new file mode 100644 index 0000000..e4b59c0 --- /dev/null +++ b/gsl-1.9/fft/hc_init.c @@ -0,0 +1,128 @@ +/* fft/hc_init.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +TYPE(gsl_fft_halfcomplex_wavetable) * +FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (size_t n) +{ + int status; + size_t i; + size_t n_factors; + size_t t, product, product_1, q; + double d_theta; + + TYPE(gsl_fft_halfcomplex_wavetable) * wavetable ; + + if (n == 0) + { + GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); + } + + wavetable = (TYPE(gsl_fft_halfcomplex_wavetable) *) + malloc(sizeof(TYPE(gsl_fft_halfcomplex_wavetable))); + + if (wavetable == NULL) + { + GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); + } + + wavetable->trig = (TYPE(gsl_complex) *) malloc (n * sizeof (TYPE(gsl_complex))); + + if (wavetable->trig == NULL) + { + /* error in constructor, prevent memory leak */ + + free(wavetable) ; + + GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", + GSL_ENOMEM, 0); + } + + wavetable->n = n ; + + status = fft_halfcomplex_factorize (n, &n_factors, wavetable->factor); + + if (status) + { + /* error in constructor, prevent memory leak */ + + free(wavetable->trig) ; + free(wavetable) ; + + GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); + } + + wavetable->nf = n_factors; + + d_theta = 2.0 * M_PI / ((double) n); + + t = 0; + product = 1; + for (i = 0; i < n_factors; i++) + { + size_t j; + const size_t factor = wavetable->factor[i]; + wavetable->twiddle[i] = wavetable->trig + t; + product_1 = product; /* product_1 = p_(i-1) */ + product *= factor; + q = n / product; + + for (j = 1; j < factor; j++) + { + size_t k; + size_t m = 0; + for (k = 1; k < (q + 1) / 2; k++) + { + double theta; + m = m + j * product_1; + m = m % n; + theta = d_theta * m; /* d_theta*j*k*product_1 */ + GSL_REAL(wavetable->trig[t]) = cos (theta); + GSL_IMAG(wavetable->trig[t]) = sin (theta); + + t++; + } + } + } + + if (t > (n / 2)) + { + /* error in constructor, prevent memory leak */ + + free(wavetable->trig) ; + free(wavetable) ; + + GSL_ERROR_VAL ("overflowed trigonometric lookup table", GSL_ESANITY, 0); + } + + return wavetable; +} + + +void +FUNCTION(gsl_fft_halfcomplex_wavetable,free) (TYPE(gsl_fft_halfcomplex_wavetable) * wavetable) +{ + + /* release trigonometric lookup tables */ + + free (wavetable->trig); + wavetable->trig = NULL; + + free (wavetable); +} + diff --git a/gsl-1.9/fft/hc_main.c b/gsl-1.9/fft/hc_main.c new file mode 100644 index 0000000..591acd4 --- /dev/null +++ b/gsl-1.9/fft/hc_main.c @@ -0,0 +1,188 @@ +/* fft/hc_main.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <math.h> + +#include <gsl/gsl_errno.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft_halfcomplex.h> + +#include "hc_pass.h" + +int +FUNCTION(gsl_fft_halfcomplex,backward) (BASE data[], const size_t stride, + const size_t n, + const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, + TYPE(gsl_fft_real_workspace) * work) +{ + int status = FUNCTION(gsl_fft_halfcomplex,transform) (data, stride, n, wavetable, work) ; + return status ; +} + +int +FUNCTION(gsl_fft_halfcomplex,inverse) (BASE data[], const size_t stride, + const size_t n, + const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, + TYPE(gsl_fft_real_workspace) * work) +{ + int status = FUNCTION(gsl_fft_halfcomplex,transform) (data, stride, n, wavetable, work); + + if (status) + { + return status; + } + + /* normalize inverse fft with 1/n */ + + { + const double norm = 1.0 / n; + size_t i; + for (i = 0; i < n; i++) + { + data[stride*i] *= norm; + } + } + return status; +} + +int +FUNCTION(gsl_fft_halfcomplex,transform) (BASE data[], const size_t stride, const size_t n, + const TYPE(gsl_fft_halfcomplex_wavetable) * wavetable, + TYPE(gsl_fft_real_workspace) * work) +{ + BASE * const scratch = work->scratch; + + BASE * in; + BASE * out; + size_t istride, ostride ; + + + size_t factor, product, q; + size_t i; + size_t nf; + int state; + int product_1; + int tskip; + TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + if (n == 1) + { /* FFT of one data point is the identity */ + return 0; + } + + if (n != wavetable->n) + { + GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); + } + + if (n != work->n) + { + GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); + } + + nf = wavetable->nf; + product = 1; + state = 0; + + for (i = 0; i < nf; i++) + { + factor = wavetable->factor[i]; + product_1 = product; + product *= factor; + q = n / product; + + tskip = (q + 1) / 2 - 1; + + if (state == 0) + { + in = data; + istride = stride; + out = scratch; + ostride = 1; + state = 1; + } + else + { + in = scratch; + istride = 1; + out = data; + ostride = stride; + state = 0; + } + + if (factor == 2) + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_halfcomplex,pass_2) (in, istride, out, ostride, + product, n, twiddle1); + } + else if (factor == 3) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + FUNCTION(fft_halfcomplex,pass_3) (in, istride, out, ostride, + product, n, twiddle1, twiddle2); + } + else if (factor == 4) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + twiddle3 = twiddle2 + tskip; + FUNCTION(fft_halfcomplex,pass_4) (in, istride, out, ostride, + product, n, twiddle1, twiddle2, + twiddle3); + } + else if (factor == 5) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + twiddle3 = twiddle2 + tskip; + twiddle4 = twiddle3 + tskip; + FUNCTION(fft_halfcomplex,pass_5) (in, istride, out, ostride, + product, n, twiddle1, twiddle2, + twiddle3, twiddle4); + } + else + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_halfcomplex,pass_n) (in, istride, out, ostride, + factor, product, n, twiddle1); + } + } + + if (state == 1) /* copy results back from scratch to data */ + { + for (i = 0; i < n; i++) + { + data[stride*i] = scratch[i] ; + } + } + + return 0; + +} + + diff --git a/gsl-1.9/fft/hc_pass.h b/gsl-1.9/fft/hc_pass.h new file mode 100644 index 0000000..dd8f3d9 --- /dev/null +++ b/gsl-1.9/fft/hc_pass.h @@ -0,0 +1,76 @@ +/* fft/hc_pass.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "complex_internal.h" + +static void +FUNCTION(fft_halfcomplex,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); + +static void +FUNCTION(fft_halfcomplex,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[]); + +static void +FUNCTION(fft_halfcomplex,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]); + +static void +FUNCTION(fft_halfcomplex,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]); + +static void +FUNCTION(fft_halfcomplex,pass_n) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); + + + + diff --git a/gsl-1.9/fft/hc_pass_2.c b/gsl-1.9/fft/hc_pass_2.c new file mode 100644 index 0000000..2cb448e --- /dev/null +++ b/gsl-1.9/fft/hc_pass_2.c @@ -0,0 +1,106 @@ +/* fft/hc_pass_2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_halfcomplex,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + size_t i, j, k, k1, jump; + size_t factor, q, m, product_1; + i = 0; + j = 0; + + factor = 2; + m = n / factor; + q = n / product; + product_1 = product / factor; + jump = (factor - 1) * q; + + for (k1 = 0; k1 < product_1; k1++) + { + const ATOMIC r0 = VECTOR(in,istride,2 * k1 * q); + const ATOMIC r1 = VECTOR(in,istride,2 * k1 * q + 2 * q - 1); + + const ATOMIC s0 = r0 + r1; + const ATOMIC s1 = r0 - r1; + + VECTOR(out,ostride,q * k1) = s0; + VECTOR(out,ostride,q * k1 + m) = s1; + } + + if (q == 1) + return; + + for (k = 1; k < (q + 1) / 2; k++) + { + const ATOMIC w_real = GSL_REAL(twiddle[k - 1]); + const ATOMIC w_imag = GSL_IMAG(twiddle[k - 1]); + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 2 * k1 * q + 2 * k - 1; + const size_t from1 = 2 * k1 * q - 2 * k + 2 * q - 1; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + /* compute x = W(2) z */ + + /* x0 = z0 + z1 */ + const ATOMIC x0_real = z0_real + z1_real; + const ATOMIC x0_imag = z0_imag - z1_imag; + + /* x1 = z0 - z1 */ + const ATOMIC x1_real = z0_real - z1_real; + const ATOMIC x1_imag = z0_imag + z1_imag; + + const size_t to0 = k1 * q + 2 * k - 1; + const size_t to1 = to0 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + VECTOR(out,ostride,to1) = w_real * x1_real - w_imag * x1_imag; + VECTOR(out,ostride,to1 + 1) = w_imag * x1_real + w_real * x1_imag; + + } + } + + if (q % 2 == 1) + return; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 2 * k1 * q + q - 1; + const size_t to0 = k1 * q + q - 1; + const size_t to1 = to0 + m; + + VECTOR(out,ostride,to0) = 2 * VECTOR(in,istride,from0); + VECTOR(out,ostride,to1) = -2 * VECTOR(in,istride,from0 + 1); + } + return; +} diff --git a/gsl-1.9/fft/hc_pass_3.c b/gsl-1.9/fft/hc_pass_3.c new file mode 100644 index 0000000..1edd5b0 --- /dev/null +++ b/gsl-1.9/fft/hc_pass_3.c @@ -0,0 +1,162 @@ +/* fft/hc_pass_3.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_halfcomplex,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[]) +{ + size_t i, j, k, k1, jump; + size_t factor, q, m, product_1; + + ATOMIC tau = sqrt (3.0) / 2.0; + + i = 0; + j = 0; + + factor = 3; + m = n / factor; + q = n / product; + product_1 = product / factor; + jump = (factor - 1) * q; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 3 * k1 * q; + const size_t from1 = from0 + 2 * q - 1; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC t1_real = 2 * z1_real; + const ATOMIC t2_real = z0_real - z1_real; + const ATOMIC t3_imag = 2 * tau * z1_imag; + + const size_t to0 = q * k1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + + VECTOR(out,ostride,to0) = z0_real + t1_real; + VECTOR(out,ostride,to1) = t2_real - t3_imag; + VECTOR(out,ostride,to2) = t2_real + t3_imag; + + } + + if (q == 1) + return; + + for (k = 1; k < (q + 1) / 2; k++) + { + const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); + const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); + const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); + const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 3 * k1 * q + 2 * k - 1; + const size_t from1 = from0 + 2 * q; + const size_t from2 = 3 * k1 * q - 2 * k + 2 * q - 1; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z2_imag = -VECTOR(in,istride,from2 + 1); + + /* compute x = W(3) z */ + + /* t1 = z1 + z2 */ + const ATOMIC t1_real = z1_real + z2_real; + const ATOMIC t1_imag = z1_imag + z2_imag; + + /* t2 = z0 - t1/2 */ + const ATOMIC t2_real = z0_real - t1_real / 2.0; + const ATOMIC t2_imag = z0_imag - t1_imag / 2.0; + + /* t3 = sin(pi/3)*(z1 - z2) */ + const ATOMIC t3_real = tau * (z1_real - z2_real); + const ATOMIC t3_imag = tau * (z1_imag - z2_imag); + + /* x0 = z0 + t1 */ + const ATOMIC x0_real = z0_real + t1_real; + const ATOMIC x0_imag = z0_imag + t1_imag; + + /* x1 = t2 + i t3 */ + const ATOMIC x1_real = t2_real - t3_imag; + const ATOMIC x1_imag = t2_imag + t3_real; + + /* x2 = t2 - i t3 */ + const ATOMIC x2_real = t2_real + t3_imag; + const ATOMIC x2_imag = t2_imag - t3_real; + + const size_t to0 = k1 * q + 2 * k - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; + VECTOR(out,ostride,to1 + 1) = w1_imag * x1_real + w1_real * x1_imag; + + VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; + VECTOR(out,ostride,to2 + 1) = w2_imag * x2_real + w2_real * x2_imag; + + } + } + + if (q % 2 == 1) + return; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 3 * k1 * q + q - 1; + const size_t from1 = from0 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + const ATOMIC z1_real = VECTOR(in,istride,from1); + + const ATOMIC t1_real = z0_real - z1_real; + const ATOMIC t2_real = 2 * tau * z0_imag; + + const ATOMIC x0_real = 2 * z0_real + z1_real; + const ATOMIC x1_real = t1_real - t2_real; + const ATOMIC x2_real = -t1_real - t2_real; + + const size_t to0 = k1 * q + q - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to2) = x2_real; + } + return; +} diff --git a/gsl-1.9/fft/hc_pass_4.c b/gsl-1.9/fft/hc_pass_4.c new file mode 100644 index 0000000..9f2caeb --- /dev/null +++ b/gsl-1.9/fft/hc_pass_4.c @@ -0,0 +1,189 @@ +/* fft/hc_pass_4.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_halfcomplex,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]) +{ + size_t i, j, k, k1, jump; + size_t factor, q, m, product_1; + + i = 0; + j = 0; + + factor = 4; + m = n / factor; + q = n / product; + product_1 = product / factor; + jump = (factor - 1) * q; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 4 * k1 * q; + const size_t from1 = from0 + 2 * q - 1; + const size_t from2 = from1 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + + const ATOMIC t1_real = z0_real + z2_real; + const ATOMIC t2_real = 2 * z1_real; + const ATOMIC t3_real = z0_real - z2_real; + const ATOMIC t4_imag = 2 * z1_imag; + + const size_t to0 = q * k1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + + VECTOR(out,ostride,to0) = t1_real + t2_real; + VECTOR(out,ostride,to1) = t3_real - t4_imag; + VECTOR(out,ostride,to2) = t1_real - t2_real; + VECTOR(out,ostride,to3) = t3_real + t4_imag; + } + + if (q == 1) + return; + + for (k = 1; k < (q + 1) / 2; k++) + { + const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); + const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); + const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); + const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); + const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); + const ATOMIC w3_imag = GSL_IMAG(twiddle3[k - 1]); + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 4 * k1 * q + 2 * k - 1; + const size_t from1 = from0 + 2 * q; + const size_t from2 = 4 * k1 * q - 2 * k + 2 * q - 1; + const size_t from3 = from2 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC z2_real = VECTOR(in,istride,from3); + const ATOMIC z2_imag = -VECTOR(in,istride,from3 + 1); + + const ATOMIC z3_real = VECTOR(in,istride,from2); + const ATOMIC z3_imag = -VECTOR(in,istride,from2 + 1); + + /* compute x = W(4) z */ + + /* t1 = z0 + z2 */ + const ATOMIC t1_real = z0_real + z2_real; + const ATOMIC t1_imag = z0_imag + z2_imag; + + /* t2 = z1 + z3 */ + const ATOMIC t2_real = z1_real + z3_real; + const ATOMIC t2_imag = z1_imag + z3_imag; + + /* t3 = z0 - z2 */ + const ATOMIC t3_real = z0_real - z2_real; + const ATOMIC t3_imag = z0_imag - z2_imag; + + /* t4 = (z1 - z3) */ + const ATOMIC t4_real = (z1_real - z3_real); + const ATOMIC t4_imag = (z1_imag - z3_imag); + + /* x0 = t1 + t2 */ + const ATOMIC x0_real = t1_real + t2_real; + const ATOMIC x0_imag = t1_imag + t2_imag; + + /* x1 = t3 + i t4 */ + const ATOMIC x1_real = t3_real - t4_imag; + const ATOMIC x1_imag = t3_imag + t4_real; + + /* x2 = t1 - t2 */ + const ATOMIC x2_real = t1_real - t2_real; + const ATOMIC x2_imag = t1_imag - t2_imag; + + /* x3 = t3 - i t4 */ + const ATOMIC x3_real = t3_real + t4_imag; + const ATOMIC x3_imag = t3_imag - t4_real; + + const size_t to0 = k1 * q + 2 * k - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; + VECTOR(out,ostride,to1 + 1) = w1_imag * x1_real + w1_real * x1_imag; + + VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; + VECTOR(out,ostride,to2 + 1) = w2_imag * x2_real + w2_real * x2_imag; + + /* to3 = w3 * x3 */ + VECTOR(out,ostride,to3) = w3_real * x3_real - w3_imag * x3_imag; + VECTOR(out,ostride,to3 + 1) = w3_real * x3_imag + w3_imag * x3_real; + + } + } + + if (q % 2 == 1) + return; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 4 * k1 * q + q - 1; + const size_t from1 = from0 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC t1_real = sqrt (2.0) * (z0_imag + z1_imag); + const ATOMIC t2_real = sqrt (2.0) * (z0_real - z1_real); + + const ATOMIC x0_real = 2 * (z0_real + z1_real); + const ATOMIC x1_real = t2_real - t1_real; + const ATOMIC x2_real = 2 * (z1_imag - z0_imag); + const ATOMIC x3_real = -(t2_real + t1_real); + + const size_t to0 = k1 * q + q - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to3) = x3_real; + } + return; +} diff --git a/gsl-1.9/fft/hc_pass_5.c b/gsl-1.9/fft/hc_pass_5.c new file mode 100644 index 0000000..6074eb5 --- /dev/null +++ b/gsl-1.9/fft/hc_pass_5.c @@ -0,0 +1,264 @@ +/* fft/hc_pass_5.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_halfcomplex,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]) +{ + + size_t i, j, k, k1, jump; + size_t factor, q, m, product_1; + + const ATOMIC sina = sin (2.0 * M_PI / 5.0); + const ATOMIC sinb = sin (2.0 * M_PI / 10.0); + + i = 0; + j = 0; + + factor = 5; + m = n / factor; + q = n / product; + product_1 = product / factor; + jump = (factor - 1) * q; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 5 * k1 * q; + const size_t from1 = from0 + 2 * q - 1; + const size_t from2 = from1 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z2_imag = VECTOR(in,istride,from2 + 1); + + const ATOMIC t1_real = 2 * (z1_real + z2_real); + const ATOMIC t2_real = 2 * (sqrt (5.0) / 4.0) * (z1_real - z2_real); + const ATOMIC t3_real = z0_real - t1_real / 4.0; + const ATOMIC t4_real = t2_real + t3_real; + const ATOMIC t5_real = -t2_real + t3_real; + const ATOMIC t6_imag = 2 * (sina * z1_imag + sinb * z2_imag); + const ATOMIC t7_imag = 2 * (sinb * z1_imag - sina * z2_imag); + + const ATOMIC x0_real = z0_real + t1_real; + const ATOMIC x1_real = t4_real - t6_imag; + const ATOMIC x2_real = t5_real - t7_imag; + const ATOMIC x3_real = t5_real + t7_imag; + const ATOMIC x4_real = t4_real + t6_imag; + + const size_t to0 = q * k1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + const size_t to4 = to3 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to3) = x3_real; + VECTOR(out,ostride,to4) = x4_real; + } + + if (q == 1) + return; + + for (k = 1; k < (q + 1) / 2; k++) + { + const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); + const ATOMIC w1_imag = GSL_IMAG(twiddle1[k - 1]); + const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); + const ATOMIC w2_imag = GSL_IMAG(twiddle2[k - 1]); + const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); + const ATOMIC w3_imag = GSL_IMAG(twiddle3[k - 1]); + const ATOMIC w4_real = GSL_REAL(twiddle4[k - 1]); + const ATOMIC w4_imag = GSL_IMAG(twiddle4[k - 1]); + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 5 * k1 * q + 2 * k - 1; + const size_t from1 = from0 + 2 * q; + const size_t from2 = from1 + 2 * q; + const size_t from3 = 5 * k1 * q - 2 * k + 2 * q - 1; + const size_t from4 = from3 + 2 * q; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z2_imag = VECTOR(in,istride,from2 + 1); + + const ATOMIC z3_real = VECTOR(in,istride,from4); + const ATOMIC z3_imag = -VECTOR(in,istride,from4 + 1); + + const ATOMIC z4_real = VECTOR(in,istride,from3); + const ATOMIC z4_imag = -VECTOR(in,istride,from3 + 1); + + /* compute x = W(5) z */ + + /* t1 = z1 + z4 */ + const ATOMIC t1_real = z1_real + z4_real; + const ATOMIC t1_imag = z1_imag + z4_imag; + + /* t2 = z2 + z3 */ + const ATOMIC t2_real = z2_real + z3_real; + const ATOMIC t2_imag = z2_imag + z3_imag; + + /* t3 = z1 - z4 */ + const ATOMIC t3_real = z1_real - z4_real; + const ATOMIC t3_imag = z1_imag - z4_imag; + + /* t4 = z2 - z3 */ + const ATOMIC t4_real = z2_real - z3_real; + const ATOMIC t4_imag = z2_imag - z3_imag; + + /* t5 = t1 + t2 */ + const ATOMIC t5_real = t1_real + t2_real; + const ATOMIC t5_imag = t1_imag + t2_imag; + + /* t6 = (sqrt(5)/4)(t1 - t2) */ + const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); + const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); + + /* t7 = z0 - ((t5)/4) */ + const ATOMIC t7_real = z0_real - t5_real / 4.0; + const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; + + /* t8 = t7 + t6 */ + const ATOMIC t8_real = t7_real + t6_real; + const ATOMIC t8_imag = t7_imag + t6_imag; + + /* t9 = t7 - t6 */ + const ATOMIC t9_real = t7_real - t6_real; + const ATOMIC t9_imag = t7_imag - t6_imag; + + /* t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */ + const ATOMIC t10_real = sina * t3_real + sinb * t4_real; + const ATOMIC t10_imag = sina * t3_imag + sinb * t4_imag; + + /* t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4 */ + const ATOMIC t11_real = sinb * t3_real - sina * t4_real; + const ATOMIC t11_imag = sinb * t3_imag - sina * t4_imag; + + /* x0 = z0 + t5 */ + const ATOMIC x0_real = z0_real + t5_real; + const ATOMIC x0_imag = z0_imag + t5_imag; + + /* x1 = t8 + i t10 */ + const ATOMIC x1_real = t8_real - t10_imag; + const ATOMIC x1_imag = t8_imag + t10_real; + + /* x2 = t9 + i t11 */ + const ATOMIC x2_real = t9_real - t11_imag; + const ATOMIC x2_imag = t9_imag + t11_real; + + /* x3 = t9 - i t11 */ + const ATOMIC x3_real = t9_real + t11_imag; + const ATOMIC x3_imag = t9_imag - t11_real; + + /* x4 = t8 - i t10 */ + const ATOMIC x4_real = t8_real + t10_imag; + const ATOMIC x4_imag = t8_imag - t10_real; + + const size_t to0 = k1 * q + 2 * k - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + const size_t to4 = to3 + m; + + /* apply twiddle factors */ + + /* to0 = 1 * x0 */ + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + /* to1 = w1 * x1 */ + VECTOR(out,ostride,to1) = w1_real * x1_real - w1_imag * x1_imag; + VECTOR(out,ostride,to1 + 1) = w1_real * x1_imag + w1_imag * x1_real; + + /* to2 = w2 * x2 */ + VECTOR(out,ostride,to2) = w2_real * x2_real - w2_imag * x2_imag; + VECTOR(out,ostride,to2 + 1) = w2_real * x2_imag + w2_imag * x2_real; + + /* to3 = w3 * x3 */ + VECTOR(out,ostride,to3) = w3_real * x3_real - w3_imag * x3_imag; + VECTOR(out,ostride,to3 + 1) = w3_real * x3_imag + w3_imag * x3_real; + + /* to4 = w4 * x4 */ + VECTOR(out,ostride,to4) = w4_real * x4_real - w4_imag * x4_imag; + VECTOR(out,ostride,to4 + 1) = w4_real * x4_imag + w4_imag * x4_real; + } + } + + if (q % 2 == 1) + return; + + for (k1 = 0; k1 < product_1; k1++) + { + const size_t from0 = 5 * k1 * q + q - 1; + const size_t from1 = from0 + 2 * q; + const size_t from2 = from1 + 2 * q; + + const ATOMIC z0_real = 2 * VECTOR(in,istride,from0); + const ATOMIC z0_imag = 2 * VECTOR(in,istride,from0 + 1); + + const ATOMIC z1_real = 2 * VECTOR(in,istride,from1); + const ATOMIC z1_imag = 2 * VECTOR(in,istride,from1 + 1); + + const ATOMIC z2_real = VECTOR(in,istride,from2); + + const ATOMIC t1_real = z0_real + z1_real; + const ATOMIC t2_real = (t1_real / 4.0) - z2_real; + const ATOMIC t3_real = (sqrt (5.0) / 4.0) * (z0_real - z1_real); + const ATOMIC t4_real = sinb * z0_imag + sina * z1_imag; + const ATOMIC t5_real = sina * z0_imag - sinb * z1_imag; + const ATOMIC t6_real = t3_real + t2_real; + const ATOMIC t7_real = t3_real - t2_real; + + const ATOMIC x0_real = t1_real + z2_real; + const ATOMIC x1_real = t6_real - t4_real; + const ATOMIC x2_real = t7_real - t5_real; + const ATOMIC x3_real = -t7_real - t5_real; + const ATOMIC x4_real = -t6_real - t4_real; + + const size_t to0 = k1 * q + q - 1; + const size_t to1 = to0 + m; + const size_t to2 = to1 + m; + const size_t to3 = to2 + m; + const size_t to4 = to3 + m; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to3) = x3_real; + VECTOR(out,ostride,to4) = x4_real; + } + return; +} diff --git a/gsl-1.9/fft/hc_pass_n.c b/gsl-1.9/fft/hc_pass_n.c new file mode 100644 index 0000000..0572744 --- /dev/null +++ b/gsl-1.9/fft/hc_pass_n.c @@ -0,0 +1,257 @@ +/* fft/hc_pass_n.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_halfcomplex,pass_n) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + + size_t k, k1; + + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + size_t e1, e2; + + const double d_theta = 2.0 * M_PI / ((double) factor); + const ATOMIC cos_d_theta = cos (d_theta); + const ATOMIC sin_d_theta = sin (d_theta); + + for (k1 = 0; k1 < product_1; k1++) + { + /* compute z = W(factor) x, for x halfcomplex */ + + ATOMIC dw_real = 1.0, dw_imag = 0.0; + + for (e1 = 0; e1 < factor; e1++) + { + ATOMIC sum_real = 0.0; + ATOMIC w_real = 1.0, w_imag = 0.0; + + if (e1 > 0) + { + ATOMIC tmp_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; + ATOMIC tmp_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = tmp_real; + dw_imag = tmp_imag; + } + + for (e2 = 0; e2 <= factor - e2; e2++) + { + ATOMIC z_real, z_imag; + + if (e2 > 0) + { + ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + if (e2 == 0) + { + size_t from_idx = factor * k1 * q; + z_real = VECTOR(in,istride,from_idx); + z_imag = 0.0; + sum_real += w_real * z_real - w_imag * z_imag; + } + else if (e2 == factor - e2) + { + size_t from_idx = factor * q * k1 + 2 * e2 * q - 1; + z_real = VECTOR(in,istride,from_idx); + z_imag = 0.0; + sum_real += w_real * z_real; + } + else + { + size_t from_idx = factor * q * k1 + 2 * e2 * q - 1; + z_real = VECTOR(in,istride,from_idx); + z_imag = VECTOR(in,istride,from_idx + 1); + sum_real += 2 * (w_real * z_real - w_imag * z_imag); + } + + } + + { + const size_t to_idx = q * k1 + e1 * m; + VECTOR(out,ostride,to_idx) = sum_real; + } + } + } + + if (q == 1) + return; + + for (k = 1; k < (q + 1) / 2; k++) + { + for (k1 = 0; k1 < product_1; k1++) + { + + ATOMIC dw_real = 1.0, dw_imag = 0.0; + + for (e1 = 0; e1 < factor; e1++) + { + ATOMIC z_real, z_imag; + ATOMIC sum_real = 0.0; + ATOMIC sum_imag = 0.0; + ATOMIC w_real = 1.0, w_imag = 0.0; + + if (e1 > 0) + { + ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; + ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = t_real; + dw_imag = t_imag; + } + + for (e2 = 0; e2 < factor; e2++) + { + + if (e2 > 0) + { + ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + if (e2 < factor - e2) + { + const size_t from0 = factor * k1 * q + 2 * k + 2 * e2 * q - 1; + z_real = VECTOR(in,istride,from0); + z_imag = VECTOR(in,istride,from0 + 1); + } + else + { + const size_t from0 = factor * k1 * q - 2 * k + 2 * (factor - e2) * q - 1; + z_real = VECTOR(in,istride,from0); + z_imag = -VECTOR(in,istride,from0 + 1); + } + + sum_real += w_real * z_real - w_imag * z_imag; + sum_imag += w_real * z_imag + w_imag * z_real; + } + + if (k == 0 || e1 == 0) + { + w_real = 1.0; + w_imag = 0.0; + } + else + { + size_t tskip = (q + 1) / 2 - 1; + w_real = GSL_REAL(twiddle[k - 1 + tskip * (e1 - 1)]); + w_imag = GSL_IMAG(twiddle[k - 1 + tskip * (e1 - 1)]); + } + + { + const size_t to0 = k1 * q + 2 * k + e1 * m - 1; + VECTOR(out,ostride,to0) = w_real * sum_real - w_imag * sum_imag; + VECTOR(out,ostride,to0 + 1) = w_real * sum_imag + w_imag * sum_real; + } + + } + } + } + + + if (q % 2 == 1) + return; + + { + double tw_arg = M_PI / ((double) factor); + ATOMIC cos_tw_arg = cos (tw_arg); + ATOMIC sin_tw_arg = sin (tw_arg); + + for (k1 = 0; k1 < product_1; k1++) + { + + ATOMIC dw_real = 1.0, dw_imag = 0.0; + ATOMIC tw_real = 1.0, tw_imag = 0.0; + + for (e1 = 0; e1 < factor; e1++) + { + ATOMIC w_real, w_imag, z_real, z_imag; + + ATOMIC sum_real = 0.0; + + if (e1 > 0) + { + ATOMIC tmp_real = tw_real * cos_tw_arg - tw_imag * sin_tw_arg; + ATOMIC tmp_imag = tw_real * sin_tw_arg + tw_imag * cos_tw_arg; + tw_real = tmp_real; + tw_imag = tmp_imag; + } + + w_real = tw_real; + w_imag = tw_imag; + + if (e1 > 0) + { + ATOMIC t_real = dw_real * cos_d_theta - dw_imag * sin_d_theta; + ATOMIC t_imag = dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = t_real; + dw_imag = t_imag; + } + + for (e2 = 0; e2 <= factor - e2 - 1; e2++) + { + + if (e2 > 0) + { + ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + + if (e2 == factor - e2 - 1) + { + const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1; + z_real = VECTOR(in,istride,from0); + z_imag = 0.0; + sum_real += w_real * z_real - w_imag * z_imag; + } + else + { + const size_t from0 = factor * k1 * q + q + 2 * e2 * q - 1; + z_real = VECTOR(in,istride,from0); + z_imag = VECTOR(in,istride,from0 + 1); + sum_real += 2 * (w_real * z_real - w_imag * z_imag); + } + + } + + { + const size_t to0 = k1 * q + q + e1 * m - 1; + VECTOR(out,ostride,to0) = sum_real; + } + } + } + } + return; +} diff --git a/gsl-1.9/fft/hc_radix2.c b/gsl-1.9/fft/hc_radix2.c new file mode 100644 index 0000000..bc0d540 --- /dev/null +++ b/gsl-1.9/fft/hc_radix2.c @@ -0,0 +1,173 @@ +/* fft/hc_radix2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(gsl_fft_halfcomplex,radix2_backward) (BASE data[], + const size_t stride, + const size_t n) +{ + int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n) ; + return status ; +} + +int +FUNCTION(gsl_fft_halfcomplex,radix2_inverse) (BASE data[], + const size_t stride, + const size_t n) +{ + int status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (data, stride, n); + + if (status) + { + return status; + } + + /* normalize inverse fft with 1/n */ + + { + const ATOMIC norm = 1.0 / n; + size_t i; + for (i = 0; i < n; i++) + { + data[stride*i] *= norm; + } + } + return status; +} + +int +FUNCTION(gsl_fft_halfcomplex,radix2_transform) (BASE data[], + const size_t stride, + const size_t n) +{ + int result ; + size_t p, p_1, q; + size_t i; + size_t logn = 0; + int status; + + if (n == 1) /* identity operation */ + { + return 0 ; + } + + /* make sure that n is a power of 2 */ + + result = fft_binary_logn(n) ; + + if (result == -1) + { + GSL_ERROR ("n is not a power of 2", GSL_EINVAL); + } + else + { + logn = result ; + } + + /* apply fft recursion */ + + p = n; q = 1 ; p_1 = n/2 ; + + for (i = 1; i <= logn; i++) + { + size_t a, b; + + /* a = 0 */ + + for (b = 0; b < q; b++) + { + const ATOMIC z0 = VECTOR(data,stride,b*p); + const ATOMIC z1 = VECTOR(data,stride,b*p + p_1); + + const ATOMIC t0_real = z0 + z1 ; + const ATOMIC t1_real = z0 - z1 ; + + VECTOR(data,stride,b*p) = t0_real; + VECTOR(data,stride,b*p + p_1) = t1_real ; + } + + /* a = 1 ... p_{i-1}/2 - 1 */ + + { + ATOMIC w_real = 1.0; + ATOMIC w_imag = 0.0; + + const ATOMIC theta = 2.0 * M_PI / p; + + const ATOMIC s = sin (theta); + const ATOMIC t = sin (theta / 2.0); + const ATOMIC s2 = 2.0 * t * t; + + for (a = 1; a < (p_1)/2; a++) + { + /* trignometric recurrence for w-> exp(i theta) w */ + + { + const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; + const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; + w_real = tmp_real; + w_imag = tmp_imag; + } + + for (b = 0; b < q; b++) + { + ATOMIC z0_real = VECTOR(data,stride,b*p + a) ; + ATOMIC z0_imag = VECTOR(data,stride,b*p + p - a) ; + ATOMIC z1_real = VECTOR(data,stride,b*p + p_1 - a) ; + ATOMIC z1_imag = -VECTOR(data,stride,b*p + p_1 + a) ; + + /* t0 = z0 + z1 */ + + ATOMIC t0_real = z0_real + z1_real; + ATOMIC t0_imag = z0_imag + z1_imag; + + /* t1 = (z0 - z1) */ + + ATOMIC t1_real = z0_real - z1_real; + ATOMIC t1_imag = z0_imag - z1_imag; + + VECTOR(data,stride,b*p + a) = t0_real ; + VECTOR(data,stride,b*p + p_1 - a) = t0_imag ; + + VECTOR(data,stride,b*p + p_1 + a) = (w_real * t1_real - w_imag * t1_imag) ; + VECTOR(data,stride,b*p + p - a) = (w_real * t1_imag + w_imag * t1_real) ; + } + } + } + + if (p_1 > 1) { + for (b = 0; b < q; b++) { + VECTOR(data,stride,b*p + p_1/2) *= 2 ; + VECTOR(data,stride,b*p + p_1 + p_1/2) *= -2 ; + } + } + + p_1 = p_1 / 2 ; + p = p / 2 ; + q = q * 2 ; + } + + /* bit reverse the ordering of output data for decimation in + frequency algorithm */ + + status = FUNCTION(fft_real,bitreverse_order)(data, stride, n, logn) ; + + return 0; + +} diff --git a/gsl-1.9/fft/hc_unpack.c b/gsl-1.9/fft/hc_unpack.c new file mode 100644 index 0000000..00e37d6 --- /dev/null +++ b/gsl-1.9/fft/hc_unpack.c @@ -0,0 +1,90 @@ +/* fft/hc_unpack.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(gsl_fft_halfcomplex,unpack) (const BASE halfcomplex_coefficient[], + BASE complex_coefficient[], + const size_t stride, const size_t n) +{ + size_t i; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + REAL(complex_coefficient,stride,0) = halfcomplex_coefficient[0]; + IMAG(complex_coefficient,stride,0) = 0.0; + + for (i = 1; i < n - i; i++) + { + const ATOMIC hc_real = halfcomplex_coefficient[(2 * i - 1) * stride]; + const ATOMIC hc_imag = halfcomplex_coefficient[2 * i * stride]; + + REAL(complex_coefficient,stride,i) = hc_real; + IMAG(complex_coefficient,stride,i) = hc_imag; + REAL(complex_coefficient,stride,n - i) = hc_real; + IMAG(complex_coefficient,stride,n - i) = -hc_imag; + } + + if (i == n - i) + { + REAL(complex_coefficient,stride,i) = halfcomplex_coefficient[(n - 1) * stride]; + IMAG(complex_coefficient,stride,i) = 0.0; + } + + return 0; +} + + +int +FUNCTION(gsl_fft_halfcomplex,radix2_unpack) (const BASE halfcomplex_coefficient[], + BASE complex_coefficient[], + const size_t stride, const size_t n) +{ + size_t i; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + REAL(complex_coefficient,stride,0) = halfcomplex_coefficient[0]; + IMAG(complex_coefficient,stride,0) = 0.0; + + for (i = 1; i < n - i; i++) + { + const ATOMIC hc_real = halfcomplex_coefficient[i * stride]; + const ATOMIC hc_imag = halfcomplex_coefficient[(n - i) * stride]; + + REAL(complex_coefficient,stride,i) = hc_real; + IMAG(complex_coefficient,stride,i) = hc_imag; + REAL(complex_coefficient,stride,n - i) = hc_real; + IMAG(complex_coefficient,stride,n - i) = -hc_imag; + } + + if (i == n - i) + { + REAL(complex_coefficient,stride,i) = halfcomplex_coefficient[i * stride]; + IMAG(complex_coefficient,stride,i) = 0.0; + } + + return 0; +} + diff --git a/gsl-1.9/fft/real_init.c b/gsl-1.9/fft/real_init.c new file mode 100644 index 0000000..75d89e8 --- /dev/null +++ b/gsl-1.9/fft/real_init.c @@ -0,0 +1,183 @@ +/* fft/real_init.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +TYPE(gsl_fft_real_wavetable) * +FUNCTION(gsl_fft_real_wavetable,alloc) (size_t n) +{ + int status; + size_t i; + size_t n_factors; + size_t t, product, product_1, q; + double d_theta; + + TYPE(gsl_fft_real_wavetable) * wavetable; + + if (n == 0) + { + GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); + } + + wavetable = (TYPE(gsl_fft_real_wavetable) *) + malloc(sizeof(TYPE(gsl_fft_real_wavetable))); + + if (wavetable == NULL) + { + GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); + } + + if (n == 1) + { + wavetable->trig = 0; + } + else + { + wavetable->trig = (TYPE(gsl_complex) *) + malloc ((n / 2) * sizeof (TYPE(gsl_complex))); + + if (wavetable->trig == NULL) + { + /* error in constructor, prevent memory leak */ + + free(wavetable) ; + + GSL_ERROR_VAL ("failed to allocate trigonometric lookup table", + GSL_ENOMEM, 0); + } + } + + wavetable->n = n; + + status = fft_real_factorize (n, &n_factors, wavetable->factor); + + if (status) + { + /* error in constructor, prevent memory leak */ + + free(wavetable->trig); + free(wavetable) ; + + GSL_ERROR_VAL ("factorization failed", GSL_EFACTOR, 0); + } + + wavetable->nf = n_factors; + + d_theta = 2.0 * M_PI / ((double) n); + + t = 0; + product = 1; + for (i = 0; i < wavetable->nf; i++) + { + size_t j; + const size_t factor = wavetable->factor[i]; + wavetable->twiddle[i] = wavetable->trig + t; + product_1 = product; /* product_1 = p_(i-1) */ + product *= factor; + q = n / product; + + for (j = 1; j < factor; j++) + { + size_t k; + size_t m = 0; + for (k = 1; k < (product_1 + 1) / 2; k++) + { + double theta; + m = m + j * q; + m = m % n; + theta = d_theta * m; /* d_theta*j*k*q */ + GSL_REAL(wavetable->trig[t]) = cos (theta); + GSL_IMAG(wavetable->trig[t]) = sin (theta); + + t++; + } + } + } + + if (t > (n / 2)) + { + /* error in constructor, prevent memory leak */ + + free(wavetable->trig); + free(wavetable) ; + + GSL_ERROR_VAL ("overflowed trigonometric lookup table", + GSL_ESANITY, 0); + } + + return wavetable; +} + +TYPE(gsl_fft_real_workspace) * +FUNCTION(gsl_fft_real_workspace,alloc) (size_t n) +{ + TYPE(gsl_fft_real_workspace) * workspace; + + if (n == 0) + { + GSL_ERROR_VAL ("length n must be positive integer", GSL_EDOM, 0); + } + + workspace = (TYPE(gsl_fft_real_workspace) *) + malloc(sizeof(TYPE(gsl_fft_real_workspace))); + + if (workspace == NULL) + { + GSL_ERROR_VAL ("failed to allocate struct", GSL_ENOMEM, 0); + } + + workspace->n = n; + + workspace->scratch = (BASE *) malloc (n * sizeof (BASE)); + + if (workspace->scratch == NULL) + { + /* error in constructor, prevent memory leak */ + + free(workspace) ; + + GSL_ERROR_VAL ("failed to allocate scratch space", GSL_ENOMEM, 0); + } + + return workspace; +} + + + +void +FUNCTION(gsl_fft_real_wavetable,free) (TYPE(gsl_fft_real_wavetable) * wavetable) +{ + + /* release trigonometric lookup tables */ + + free (wavetable->trig); + wavetable->trig = NULL; + + free (wavetable) ; +} + +void +FUNCTION(gsl_fft_real_workspace,free) (TYPE(gsl_fft_real_workspace) * workspace) +{ + + /* release scratch space */ + + free (workspace->scratch); + workspace->scratch = NULL; + + free (workspace) ; +} diff --git a/gsl-1.9/fft/real_main.c b/gsl-1.9/fft/real_main.c new file mode 100644 index 0000000..47919a9 --- /dev/null +++ b/gsl-1.9/fft/real_main.c @@ -0,0 +1,145 @@ +/* fft/real_main.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <math.h> + +#include <gsl/gsl_errno.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_fft_real.h> + +#include "real_pass.h" + +int +FUNCTION(gsl_fft_real,transform) (BASE data[], const size_t stride, const size_t n, + const TYPE(gsl_fft_real_wavetable) * wavetable, + TYPE(gsl_fft_real_workspace) * work) +{ + const size_t nf = wavetable->nf; + + size_t i; + + size_t q, product = 1; + size_t tskip; + size_t product_1; + + BASE *const scratch = work->scratch; + TYPE(gsl_complex) *twiddle1, *twiddle2, *twiddle3, *twiddle4; + + size_t state = 0; + BASE *in = data; + size_t istride = stride ; + BASE *out = scratch; + size_t ostride = 1 ; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + if (n == 1) + { /* FFT of one data point is the identity */ + return 0; + } + + if (n != wavetable->n) + { + GSL_ERROR ("wavetable does not match length of data", GSL_EINVAL); + } + + if (n != work->n) + { + GSL_ERROR ("workspace does not match length of data", GSL_EINVAL); + } + + for (i = 0; i < nf; i++) + { + const size_t factor = wavetable->factor[i]; + product_1 = product; + product *= factor; + q = n / product; + + tskip = (product_1 + 1) / 2 - 1; + + if (state == 0) + { + in = data; + istride = stride; + out = scratch; + ostride = 1; + state = 1; + } + else + { + in = scratch; + istride = 1; + out = data; + ostride = stride; + state = 0; + } + + if (factor == 2) + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_real,pass_2) (in, istride, out, ostride, product, n, twiddle1); + } + else if (factor == 3) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + FUNCTION(fft_real,pass_3) (in, istride, out, ostride, product, n, twiddle1, + twiddle2); + } + else if (factor == 4) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + twiddle3 = twiddle2 + tskip; + FUNCTION(fft_real,pass_4) (in, istride, out, ostride, product, n, twiddle1, + twiddle2, twiddle3); + } + else if (factor == 5) + { + twiddle1 = wavetable->twiddle[i]; + twiddle2 = twiddle1 + tskip; + twiddle3 = twiddle2 + tskip; + twiddle4 = twiddle3 + tskip; + FUNCTION(fft_real,pass_5) (in, istride, out, ostride, product, n, twiddle1, + twiddle2, twiddle3, twiddle4); + } + else + { + twiddle1 = wavetable->twiddle[i]; + FUNCTION(fft_real,pass_n) (in, istride, out, ostride, factor, product, n, + twiddle1); + } + } + + if (state == 1) /* copy results back from scratch to data */ + { + for (i = 0; i < n; i++) + { + data[stride*i] = scratch[i] ; + } + } + + return 0; + +} diff --git a/gsl-1.9/fft/real_pass.h b/gsl-1.9/fft/real_pass.h new file mode 100644 index 0000000..af795f7 --- /dev/null +++ b/gsl-1.9/fft/real_pass.h @@ -0,0 +1,65 @@ +/* fft/real_pass.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void FUNCTION(fft_real,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); + +static void FUNCTION(fft_real,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[]); + +static void FUNCTION(fft_real,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]); + +static void FUNCTION(fft_real,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]); + +static void FUNCTION(fft_real,pass_n) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]); diff --git a/gsl-1.9/fft/real_pass_2.c b/gsl-1.9/fft/real_pass_2.c new file mode 100644 index 0000000..b1f5184 --- /dev/null +++ b/gsl-1.9/fft/real_pass_2.c @@ -0,0 +1,116 @@ +/* fft/real_pass_2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_real,pass_2) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + size_t k, k1; + + const size_t factor = 2; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1; + const size_t from1 = from0 + m; + + const ATOMIC r0 = VECTOR(in,istride,from0); + const ATOMIC r1 = VECTOR(in,istride,from1); + + const ATOMIC s0 = r0 + r1; + const ATOMIC s1 = r0 - r1; + + const size_t to0 = product * k1; + const size_t to1 = to0 + product - 1; + + VECTOR(out,ostride,to0) = s0; + VECTOR(out,ostride,to1) = s1; + } + + if (product_1 == 1) + return; + + for (k = 1; k < (product_1 + 1) / 2; k++) + { + + /* forward real transform: w -> conjugate(w) */ + const ATOMIC w_real = GSL_REAL(twiddle[k - 1]); + const ATOMIC w_imag = -GSL_IMAG(twiddle[k - 1]); + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + 2 * k - 1; + const size_t from1 = from0 + m; + + const ATOMIC f0_real = VECTOR(in,istride,from0); + const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); + + const ATOMIC f1_real = VECTOR(in,istride,from1); + const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); + + const ATOMIC z0_real = f0_real; + const ATOMIC z0_imag = f0_imag; + + const ATOMIC z1_real = w_real * f1_real - w_imag * f1_imag; + const ATOMIC z1_imag = w_real * f1_imag + w_imag * f1_real; + + /* compute x = W(2) z */ + + /* x0 = z0 + z1 */ + const ATOMIC x0_real = z0_real + z1_real; + const ATOMIC x0_imag = z0_imag + z1_imag; + + /* x1 = z0 - z1 */ + const ATOMIC x1_real = z0_real - z1_real; + const ATOMIC x1_imag = z0_imag - z1_imag; + + const size_t to0 = k1 * product + 2 * k - 1; + const size_t to1 = k1 * product + product - 2 * k - 1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + /* stored in conjugate location */ + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = -x1_imag; + } + } + + if (product_1 % 2 == 1) + return; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + product_1 - 1; + const size_t from1 = from0 + m; + const size_t to0 = k1 * product + product_1 - 1; + + VECTOR(out,ostride,to0) = VECTOR(in,istride,from0); + VECTOR(out,ostride,to0 + 1) = -VECTOR(in,istride,from1); + } + return; +} diff --git a/gsl-1.9/fft/real_pass_3.c b/gsl-1.9/fft/real_pass_3.c new file mode 100644 index 0000000..561a156 --- /dev/null +++ b/gsl-1.9/fft/real_pass_3.c @@ -0,0 +1,166 @@ +/* fft/real_pass_3.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_real,pass_3) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[]) +{ + size_t k, k1; + + const size_t factor = 3; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + const ATOMIC tau = sqrt (3.0) / 2.0; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + + const ATOMIC t1 = z1_real + z2_real; + + const ATOMIC x0_real = z0_real + t1; + const ATOMIC x1_real = z0_real - t1 / 2.0; + const ATOMIC x1_imag = -tau * (z1_real - z2_real); + + const size_t to0 = product * k1; + const size_t to1 = to0 + 2 * product_1 - 1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + } + + if (product_1 == 1) + return; + + for (k = 1; k < (product_1 + 1) / 2; k++) + { + const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); + const ATOMIC w1_imag = -GSL_IMAG(twiddle1[k - 1]); + const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); + const ATOMIC w2_imag = -GSL_IMAG(twiddle2[k - 1]); + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + 2 * k - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + + const ATOMIC f0_real = VECTOR(in,istride,from0); + const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); + const ATOMIC f1_real = VECTOR(in,istride,from1); + const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); + const ATOMIC f2_real = VECTOR(in,istride,from2); + const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); + + const ATOMIC z0_real = f0_real; + const ATOMIC z0_imag = f0_imag; + const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; + const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; + const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; + const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; + + /* compute x = W(3) z */ + + /* t1 = z1 + z2 */ + const ATOMIC t1_real = z1_real + z2_real; + const ATOMIC t1_imag = z1_imag + z2_imag; + + /* t2 = z0 - t1/2 */ + const ATOMIC t2_real = z0_real - t1_real / 2; + const ATOMIC t2_imag = z0_imag - t1_imag / 2; + + /* t3 = (+/-) sin(pi/3)*(z1 - z2) */ + const ATOMIC t3_real = -tau * (z1_real - z2_real); + const ATOMIC t3_imag = -tau * (z1_imag - z2_imag); + + /* x0 = z0 + t1 */ + const ATOMIC x0_real = z0_real + t1_real; + const ATOMIC x0_imag = z0_imag + t1_imag; + + /* x1 = t2 + i t3 */ + const ATOMIC x1_real = t2_real - t3_imag; + const ATOMIC x1_imag = t2_imag + t3_real; + + /* x2 = t2 - i t3 */ + const ATOMIC x2_real = t2_real + t3_imag; + const ATOMIC x2_imag = t2_imag - t3_real; + + /* apply twiddle factors */ + + const size_t to0 = k1 * product + 2 * k - 1; + const size_t to1 = to0 + 2 * product_1; + const size_t to2 = 2 * product_1 - 2 * k + k1 * product - 1; + + /* to0 = 1 * x0 */ + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + /* to1 = 1 * x1 */ + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + + /* to2 = 1 * x2 */ + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to2 + 1) = -x2_imag; + } + } + + if (product_1 % 2 == 1) + return; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + product_1 - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + + const ATOMIC t1 = z1_real - z2_real; + const ATOMIC x0_real = z0_real + t1 / 2.0; + const ATOMIC x0_imag = -tau * (z1_real + z2_real); + const ATOMIC x1_real = z0_real - t1; + + const size_t to0 = k1 * product + product_1 - 1; + const size_t to1 = to0 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + VECTOR(out,ostride,to1) = x1_real; + } + + return; +} diff --git a/gsl-1.9/fft/real_pass_4.c b/gsl-1.9/fft/real_pass_4.c new file mode 100644 index 0000000..576791b --- /dev/null +++ b/gsl-1.9/fft/real_pass_4.c @@ -0,0 +1,203 @@ +/* fft/real_pass_4.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_real,pass_4) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[]) +{ + size_t k, k1; + + const size_t factor = 4; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z3_real = VECTOR(in,istride,from3); + + /* compute x = W(4) z */ + + /* t1 = z0 + z2 */ + const ATOMIC t1_real = z0_real + z2_real; + + /* t2 = z1 + z3 */ + const ATOMIC t2_real = z1_real + z3_real; + + /* t3 = z0 - z2 */ + const ATOMIC t3_real = z0_real - z2_real; + + /* t4 = - (z1 - z3) */ + const ATOMIC t4_real = -(z1_real - z3_real); + + /* x0 = t1 + t2 */ + const ATOMIC x0_real = t1_real + t2_real; + + /* x1 = t3 + i t4 */ + const ATOMIC x1_real = t3_real; + const ATOMIC x1_imag = t4_real; + + /* x2 = t1 - t2 */ + const ATOMIC x2_real = t1_real - t2_real; + + const size_t to0 = product * k1; + const size_t to1 = to0 + 2 * product_1 - 1; + const size_t to2 = to1 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + VECTOR(out,ostride,to2) = x2_real; + } + + if (product_1 == 1) + return; + + for (k = 1; k < (product_1 + 1) / 2; k++) + { + ATOMIC w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag; + w1_real = GSL_REAL(twiddle1[k - 1]); + w1_imag = -GSL_IMAG(twiddle1[k - 1]); + w2_real = GSL_REAL(twiddle2[k - 1]); + w2_imag = -GSL_IMAG(twiddle2[k - 1]); + w3_real = GSL_REAL(twiddle3[k - 1]); + w3_imag = -GSL_IMAG(twiddle3[k - 1]); + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + 2 * k - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + + const ATOMIC f0_real = VECTOR(in,istride,from0); + const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); + const ATOMIC f1_real = VECTOR(in,istride,from1); + const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); + const ATOMIC f2_real = VECTOR(in,istride,from2); + const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); + const ATOMIC f3_real = VECTOR(in,istride,from3); + const ATOMIC f3_imag = VECTOR(in,istride,from3 + 1); + + const ATOMIC z0_real = f0_real; + const ATOMIC z0_imag = f0_imag; + const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; + const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; + const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; + const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; + const ATOMIC z3_real = w3_real * f3_real - w3_imag * f3_imag; + const ATOMIC z3_imag = w3_real * f3_imag + w3_imag * f3_real; + + /* compute x = W(4) z */ + + /* t1 = z0 + z2 */ + const ATOMIC t1_real = z0_real + z2_real; + const ATOMIC t1_imag = z0_imag + z2_imag; + + /* t2 = z1 + z3 */ + const ATOMIC t2_real = z1_real + z3_real; + const ATOMIC t2_imag = z1_imag + z3_imag; + + /* t3 = z0 - z2 */ + const ATOMIC t3_real = z0_real - z2_real; + const ATOMIC t3_imag = z0_imag - z2_imag; + + /* t4 = - (z1 - z3) */ + const ATOMIC t4_real = -(z1_real - z3_real); + const ATOMIC t4_imag = -(z1_imag - z3_imag); + + /* x0 = t1 + t2 */ + const ATOMIC x0_real = t1_real + t2_real; + const ATOMIC x0_imag = t1_imag + t2_imag; + + /* x1 = t3 + i t4 */ + const ATOMIC x1_real = t3_real - t4_imag; + const ATOMIC x1_imag = t3_imag + t4_real; + + /* x2 = t1 - t2 */ + const ATOMIC x2_real = t1_real - t2_real; + const ATOMIC x2_imag = t1_imag - t2_imag; + + /* x3 = t3 - i t4 */ + const ATOMIC x3_real = t3_real + t4_imag; + const ATOMIC x3_imag = t3_imag - t4_real; + + const size_t to0 = k1 * product + 2 * k - 1; + const size_t to1 = to0 + 2 * product_1; + const size_t to2 = 2 * product_1 - 2 * k + k1 * product - 1; + const size_t to3 = to2 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + + VECTOR(out,ostride,to3) = x2_real; + VECTOR(out,ostride,to3 + 1) = -x2_imag; + + VECTOR(out,ostride,to2) = x3_real; + VECTOR(out,ostride,to2 + 1) = -x3_imag; + } + } + + if (product_1 % 2 == 1) + return; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + product_1 - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + + const ATOMIC x0 = VECTOR(in,istride,from0); + const ATOMIC x1 = VECTOR(in,istride,from1); + const ATOMIC x2 = VECTOR(in,istride,from2); + const ATOMIC x3 = VECTOR(in,istride,from3); + + const ATOMIC t1 = (1.0 / sqrt (2.0)) * (x1 - x3); + const ATOMIC t2 = (1.0 / sqrt (2.0)) * (x1 + x3); + + const size_t to0 = k1 * product + 2 * k - 1; + const size_t to1 = to0 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0 + t1; + VECTOR(out,ostride,to0 + 1) = -x2 - t2; + + VECTOR(out,ostride,to1) = x0 - t1; + VECTOR(out,ostride,to1 + 1) = x2 - t2; + } + return; +} diff --git a/gsl-1.9/fft/real_pass_5.c b/gsl-1.9/fft/real_pass_5.c new file mode 100644 index 0000000..3b3b4a7 --- /dev/null +++ b/gsl-1.9/fft/real_pass_5.c @@ -0,0 +1,283 @@ +/* fft/real_pass_5.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_real,pass_5) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle1[], + const TYPE(gsl_complex) twiddle2[], + const TYPE(gsl_complex) twiddle3[], + const TYPE(gsl_complex) twiddle4[]) +{ + size_t k, k1; + + const size_t factor = 5; + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + const ATOMIC sina = sin (2.0 * M_PI / 5.0); + const ATOMIC sinb = sin (2.0 * M_PI / 10.0); + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + const size_t from4 = from3 + m; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z3_real = VECTOR(in,istride,from3); + const ATOMIC z4_real = VECTOR(in,istride,from4); + + /* t1 = z1 + z4 */ + const ATOMIC t1_real = z1_real + z4_real; + + /* t2 = z2 + z3 */ + const ATOMIC t2_real = z2_real + z3_real; + + /* t3 = z1 - z4 */ + const ATOMIC t3_real = z1_real - z4_real; + + /* t4 = z2 - z3 */ + const ATOMIC t4_real = z2_real - z3_real; + + /* t5 = t1 + t2 */ + const ATOMIC t5_real = t1_real + t2_real; + + /* t6 = (sqrt(5)/4)(t1 - t2) */ + const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); + + /* t7 = z0 - ((t5)/4) */ + const ATOMIC t7_real = z0_real - t5_real / 4.0; + + /* t8 = t7 + t6 */ + const ATOMIC t8_real = t7_real + t6_real; + + /* t9 = t7 - t6 */ + const ATOMIC t9_real = t7_real - t6_real; + + /* t10 = -(sin(2 pi/5) t3 + sin(2 pi/10) t4 ) */ + const ATOMIC t10_real = -sina * t3_real - sinb * t4_real; + + /* t11 = -(sin(2 pi/10) t3 - sin(2 pi/5) t4) */ + const ATOMIC t11_real = -sinb * t3_real + sina * t4_real; + + /* x0 = z0 + t5 */ + const ATOMIC x0_real = z0_real + t5_real; + + /* x1 = t8 + i t10 */ + const ATOMIC x1_real = t8_real; + const ATOMIC x1_imag = t10_real; + + /* x2 = t9 + i t11 */ + const ATOMIC x2_real = t9_real; + const ATOMIC x2_imag = t11_real; + + const size_t to0 = product * k1; + const size_t to1 = to0 + 2 * product_1 - 1; + const size_t to2 = to1 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to2 + 1) = x2_imag; + } + + if (product_1 == 1) + return; + + for (k = 1; k < (product_1 + 1) / 2; k++) + { + const ATOMIC w1_real = GSL_REAL(twiddle1[k - 1]); + const ATOMIC w1_imag = -GSL_IMAG(twiddle1[k - 1]); + const ATOMIC w2_real = GSL_REAL(twiddle2[k - 1]); + const ATOMIC w2_imag = -GSL_IMAG(twiddle2[k - 1]); + const ATOMIC w3_real = GSL_REAL(twiddle3[k - 1]); + const ATOMIC w3_imag = -GSL_IMAG(twiddle3[k - 1]); + const ATOMIC w4_real = GSL_REAL(twiddle4[k - 1]); + const ATOMIC w4_imag = -GSL_IMAG(twiddle4[k - 1]); + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + 2 * k - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + const size_t from4 = from3 + m; + + const ATOMIC f0_real = VECTOR(in,istride,from0); + const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); + const ATOMIC f1_real = VECTOR(in,istride,from1); + const ATOMIC f1_imag = VECTOR(in,istride,from1 + 1); + const ATOMIC f2_real = VECTOR(in,istride,from2); + const ATOMIC f2_imag = VECTOR(in,istride,from2 + 1); + const ATOMIC f3_real = VECTOR(in,istride,from3); + const ATOMIC f3_imag = VECTOR(in,istride,from3 + 1); + const ATOMIC f4_real = VECTOR(in,istride,from4); + const ATOMIC f4_imag = VECTOR(in,istride,from4 + 1); + + const ATOMIC z0_real = f0_real; + const ATOMIC z0_imag = f0_imag; + const ATOMIC z1_real = w1_real * f1_real - w1_imag * f1_imag; + const ATOMIC z1_imag = w1_real * f1_imag + w1_imag * f1_real; + const ATOMIC z2_real = w2_real * f2_real - w2_imag * f2_imag; + const ATOMIC z2_imag = w2_real * f2_imag + w2_imag * f2_real; + const ATOMIC z3_real = w3_real * f3_real - w3_imag * f3_imag; + const ATOMIC z3_imag = w3_real * f3_imag + w3_imag * f3_real; + const ATOMIC z4_real = w4_real * f4_real - w4_imag * f4_imag; + const ATOMIC z4_imag = w4_real * f4_imag + w4_imag * f4_real; + + /* compute x = W(5) z */ + + /* t1 = z1 + z4 */ + const ATOMIC t1_real = z1_real + z4_real; + const ATOMIC t1_imag = z1_imag + z4_imag; + + /* t2 = z2 + z3 */ + const ATOMIC t2_real = z2_real + z3_real; + const ATOMIC t2_imag = z2_imag + z3_imag; + + /* t3 = z1 - z4 */ + const ATOMIC t3_real = z1_real - z4_real; + const ATOMIC t3_imag = z1_imag - z4_imag; + + /* t4 = z2 - z3 */ + const ATOMIC t4_real = z2_real - z3_real; + const ATOMIC t4_imag = z2_imag - z3_imag; + + /* t5 = t1 + t2 */ + const ATOMIC t5_real = t1_real + t2_real; + const ATOMIC t5_imag = t1_imag + t2_imag; + + /* t6 = (sqrt(5)/4)(t1 - t2) */ + const ATOMIC t6_real = (sqrt (5.0) / 4.0) * (t1_real - t2_real); + const ATOMIC t6_imag = (sqrt (5.0) / 4.0) * (t1_imag - t2_imag); + + /* t7 = z0 - ((t5)/4) */ + const ATOMIC t7_real = z0_real - t5_real / 4.0; + const ATOMIC t7_imag = z0_imag - t5_imag / 4.0; + + /* t8 = t7 + t6 */ + const ATOMIC t8_real = t7_real + t6_real; + const ATOMIC t8_imag = t7_imag + t6_imag; + + /* t9 = t7 - t6 */ + const ATOMIC t9_real = t7_real - t6_real; + const ATOMIC t9_imag = t7_imag - t6_imag; + + /* t10 = - (sin(2 pi/5) t3 + sin(2 pi/10) t4) */ + const ATOMIC t10_real = -sina * t3_real - sinb * t4_real; + const ATOMIC t10_imag = -sina * t3_imag - sinb * t4_imag; + + /* t11 = -(sin(2 pi/10) t3 - sin(2 pi/5) t4) */ + const ATOMIC t11_real = -sinb * t3_real + sina * t4_real; + const ATOMIC t11_imag = -sinb * t3_imag + sina * t4_imag; + + /* x0 = z0 + t5 */ + const ATOMIC x0_real = z0_real + t5_real; + const ATOMIC x0_imag = z0_imag + t5_imag; + + /* x1 = t8 + i t10 */ + const ATOMIC x1_real = t8_real - t10_imag; + const ATOMIC x1_imag = t8_imag + t10_real; + + /* x2 = t9 + i t11 */ + const ATOMIC x2_real = t9_real - t11_imag; + const ATOMIC x2_imag = t9_imag + t11_real; + + /* x3 = t9 - i t11 */ + const ATOMIC x3_real = t9_real + t11_imag; + const ATOMIC x3_imag = t9_imag - t11_real; + + /* x4 = t8 - i t10 */ + const ATOMIC x4_real = t8_real + t10_imag; + const ATOMIC x4_imag = t8_imag - t10_real; + + const size_t to0 = k1 * product + 2 * k - 1; + const size_t to1 = to0 + 2 * product_1; + const size_t to2 = to1 + 2 * product_1; + const size_t to3 = 2 * product_1 - 2 * k + k1 * product - 1; + const size_t to4 = to3 + 2 * product_1; + + VECTOR(out,ostride,to0) = x0_real; + VECTOR(out,ostride,to0 + 1) = x0_imag; + + VECTOR(out,ostride,to1) = x1_real; + VECTOR(out,ostride,to1 + 1) = x1_imag; + + VECTOR(out,ostride,to2) = x2_real; + VECTOR(out,ostride,to2 + 1) = x2_imag; + + VECTOR(out,ostride,to3) = x4_real; + VECTOR(out,ostride,to3 + 1) = -x4_imag; + + VECTOR(out,ostride,to4) = x3_real; + VECTOR(out,ostride,to4 + 1) = -x3_imag; + } + } + + if (product_1 % 2 == 1) + return; + + for (k1 = 0; k1 < q; k1++) + { + const size_t from0 = k1 * product_1 + product_1 - 1; + const size_t from1 = from0 + m; + const size_t from2 = from1 + m; + const size_t from3 = from2 + m; + const size_t from4 = from3 + m; + + const ATOMIC z0_real = VECTOR(in,istride,from0); + const ATOMIC z1_real = VECTOR(in,istride,from1); + const ATOMIC z2_real = VECTOR(in,istride,from2); + const ATOMIC z3_real = VECTOR(in,istride,from3); + const ATOMIC z4_real = VECTOR(in,istride,from4); + + const ATOMIC t1 = z1_real - z4_real; + const ATOMIC t2 = z1_real + z4_real; + const ATOMIC t3 = z2_real - z3_real; + const ATOMIC t4 = z2_real + z3_real; + const ATOMIC t5 = t1 - t3; + const ATOMIC t6 = z0_real + t5 / 4.0; + const ATOMIC t7 = (sqrt (5.0) / 4.0) * (t1 + t3); + + const size_t to0 = k1 * product + product_1 - 1; + const size_t to1 = to0 + 2 * product_1; + const size_t to2 = to1 + 2 * product_1; + + VECTOR(out,ostride,to0) = t6 + t7; + VECTOR(out,ostride,to0 + 1) = -sinb * t2 - sina * t4; + + VECTOR(out,ostride,to1) = t6 - t7; + VECTOR(out,ostride,to1 + 1) = -sina * t2 + sinb * t4; + + VECTOR(out,ostride,to2) = z0_real - t5; + } + + return; +} diff --git a/gsl-1.9/fft/real_pass_n.c b/gsl-1.9/fft/real_pass_n.c new file mode 100644 index 0000000..984728c --- /dev/null +++ b/gsl-1.9/fft/real_pass_n.c @@ -0,0 +1,264 @@ +/* fft/real_pass_n.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +static void +FUNCTION(fft_real,pass_n) (const BASE in[], + const size_t istride, + BASE out[], + const size_t ostride, + const size_t factor, + const size_t product, + const size_t n, + const TYPE(gsl_complex) twiddle[]) +{ + size_t k, k1; + + const size_t m = n / factor; + const size_t q = n / product; + const size_t product_1 = product / factor; + + size_t e1, e2; + + const double d_theta = 2.0 * M_PI / ((double) factor); + const ATOMIC cos_d_theta = cos (d_theta); + const ATOMIC sin_d_theta = sin (d_theta); + + for (k1 = 0; k1 < q; k1++) + { + /* compute x = W(factor) z, for z real */ + + ATOMIC dw_real = 1.0, dw_imag = 0.0; + + for (e1 = 0; e1 <= factor - e1; e1++) + { + ATOMIC sum_real = 0.0; + ATOMIC sum_imag = 0.0; + + ATOMIC w_real = 1.0, w_imag = 0.0; + + if (e1 > 0) + { + ATOMIC tmp_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; + ATOMIC tmp_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = tmp_real; + dw_imag = tmp_imag; + } + + for (e2 = 0; e2 < factor; e2++) + { + ATOMIC z_real = VECTOR(in,istride,k1 * product_1 + e2 * m); + + if (e2 > 0) + { + ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + sum_real += w_real * z_real; + sum_imag += w_imag * z_real; + + } + if (e1 == 0) + { + const size_t to0 = product * k1; + VECTOR(out,ostride,to0) = sum_real; + } + else if (e1 < factor - e1) + { + const size_t to0 = k1 * product + 2 * e1 * product_1 - 1; + VECTOR(out,ostride,to0) = sum_real; + VECTOR(out,ostride,to0 + 1) = sum_imag; + } + else if (e1 == factor - e1) + { + const size_t to0 = k1 * product + 2 * e1 * product_1 - 1; + VECTOR(out,ostride,to0) = sum_real; + } + + } + } + + if (product_1 == 1) + return; + + for (k = 1; k < (product_1 + 1) / 2; k++) + { + for (k1 = 0; k1 < q; k1++) + { + + ATOMIC dw_real = 1.0, dw_imag = 0.0; + + for (e1 = 0; e1 < factor; e1++) + { + ATOMIC sum_real = 0.0, sum_imag = 0.0; + + ATOMIC w_real = 1.0, w_imag = 0.0; + + if (e1 > 0) + { + const ATOMIC tmp_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; + const ATOMIC tmp_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = tmp_real; + dw_imag = tmp_imag; + } + + for (e2 = 0; e2 < factor; e2++) + { + + int tskip = (product_1 + 1) / 2 - 1; + const size_t from0 = k1 * product_1 + 2 * k + e2 * m - 1; + ATOMIC tw_real, tw_imag; + ATOMIC z_real, z_imag; + + if (e2 == 0) + { + tw_real = 1.0; + tw_imag = 0.0; + } + else + { + const size_t t_index = (k - 1) + (e2 - 1) * tskip; + tw_real = GSL_REAL(twiddle[t_index]); + tw_imag = -GSL_IMAG(twiddle[t_index]); + } + + { + const ATOMIC f0_real = VECTOR(in,istride,from0); + const ATOMIC f0_imag = VECTOR(in,istride,from0 + 1); + + z_real = tw_real * f0_real - tw_imag * f0_imag; + z_imag = tw_real * f0_imag + tw_imag * f0_real; + } + + if (e2 > 0) + { + const ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + const ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + sum_real += w_real * z_real - w_imag * z_imag; + sum_imag += w_real * z_imag + w_imag * z_real; + } + + if (e1 < factor - e1) + { + const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; + VECTOR(out,ostride,to0) = sum_real; + VECTOR(out,ostride,to0 + 1) = sum_imag; + } + else + { + const size_t to0 = k1 * product - 1 + 2 * (factor - e1) * product_1 - 2 * k; + VECTOR(out,ostride,to0) = sum_real; + VECTOR(out,ostride,to0 + 1) = -sum_imag; + } + + } + } + } + + + if (product_1 % 2 == 1) + return; + + { + double tw_arg = M_PI / ((double) factor); + ATOMIC cos_tw_arg = cos (tw_arg); + ATOMIC sin_tw_arg = -sin (tw_arg); + + for (k1 = 0; k1 < q; k1++) + { + ATOMIC dw_real = 1.0, dw_imag = 0.0; + + for (e1 = 0; e1 < factor; e1++) + { + ATOMIC z_real, z_imag; + + ATOMIC sum_real = 0.0; + ATOMIC sum_imag = 0.0; + + ATOMIC w_real = 1.0, w_imag = 0.0; + ATOMIC tw_real = 1.0, tw_imag = 0.0; + + if (e1 > 0) + { + ATOMIC t_real = dw_real * cos_d_theta + dw_imag * sin_d_theta; + ATOMIC t_imag = -dw_real * sin_d_theta + dw_imag * cos_d_theta; + dw_real = t_real; + dw_imag = t_imag; + } + + for (e2 = 0; e2 < factor; e2++) + { + + if (e2 > 0) + { + ATOMIC tmp_real = tw_real * cos_tw_arg - tw_imag * sin_tw_arg; + ATOMIC tmp_imag = tw_real * sin_tw_arg + tw_imag * cos_tw_arg; + tw_real = tmp_real; + tw_imag = tmp_imag; + } + + if (e2 > 0) + { + ATOMIC tmp_real = dw_real * w_real - dw_imag * w_imag; + ATOMIC tmp_imag = dw_real * w_imag + dw_imag * w_real; + w_real = tmp_real; + w_imag = tmp_imag; + } + + + { + const size_t from0 = k1 * product_1 + 2 * k + e2 * m - 1; + const ATOMIC f0_real = VECTOR(in,istride,from0); + z_real = tw_real * f0_real; + z_imag = tw_imag * f0_real; + } + + sum_real += w_real * z_real - w_imag * z_imag; + sum_imag += w_real * z_imag + w_imag * z_real; + } + + if (e1 + 1 < factor - e1) + { + const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; + VECTOR(out,ostride,to0) = sum_real; + VECTOR(out,ostride,to0 + 1) = sum_imag; + } + else if (e1 + 1 == factor - e1) + { + const size_t to0 = k1 * product - 1 + 2 * e1 * product_1 + 2 * k; + VECTOR(out,ostride,to0) = sum_real; + } + else + { + const size_t to0 = k1 * product - 1 + 2 * (factor - e1) * product_1 - 2 * k; + VECTOR(out,ostride,to0) = sum_real; + VECTOR(out,ostride,to0 + 1) = -sum_imag; + } + + } + } + } + return; +} diff --git a/gsl-1.9/fft/real_radix2.c b/gsl-1.9/fft/real_radix2.c new file mode 100644 index 0000000..ad5d827 --- /dev/null +++ b/gsl-1.9/fft/real_radix2.c @@ -0,0 +1,134 @@ +/* fft/real_radix2.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int +FUNCTION(gsl_fft_real,radix2_transform) (BASE data[], const size_t stride, const size_t n) +{ + int result ; + size_t p, p_1, q; + size_t i; + size_t logn = 0; + int status; + + if (n == 1) /* identity operation */ + { + return 0 ; + } + + /* make sure that n is a power of 2 */ + + result = fft_binary_logn(n) ; + + if (result == -1) + { + GSL_ERROR ("n is not a power of 2", GSL_EINVAL); + } + else + { + logn = result ; + } + + /* bit reverse the ordering of input data for decimation in time algorithm */ + + status = FUNCTION(fft_real,bitreverse_order)(data, stride, n, logn) ; + + /* apply fft recursion */ + + p = 1; q = n ; + + for (i = 1; i <= logn; i++) + { + size_t a, b; + + p_1 = p ; + p = 2 * p ; + q = q / 2 ; + + /* a = 0 */ + + for (b = 0; b < q; b++) + { + ATOMIC t0_real = VECTOR(data,stride,b*p) + VECTOR(data,stride,b*p + p_1) ; + ATOMIC t1_real = VECTOR(data,stride,b*p) - VECTOR(data,stride,b*p + p_1) ; + + VECTOR(data,stride,b*p) = t0_real ; + VECTOR(data,stride,b*p + p_1) = t1_real ; + } + + /* a = 1 ... p_{i-1}/2 - 1 */ + + { + ATOMIC w_real = 1.0; + ATOMIC w_imag = 0.0; + + const double theta = - 2.0 * M_PI / p; + + const ATOMIC s = sin (theta); + const ATOMIC t = sin (theta / 2.0); + const ATOMIC s2 = 2.0 * t * t; + + for (a = 1; a < (p_1)/2; a++) + { + /* trignometric recurrence for w-> exp(i theta) w */ + + { + const ATOMIC tmp_real = w_real - s * w_imag - s2 * w_real; + const ATOMIC tmp_imag = w_imag + s * w_real - s2 * w_imag; + w_real = tmp_real; + w_imag = tmp_imag; + } + + for (b = 0; b < q; b++) + { + ATOMIC z0_real = VECTOR(data,stride,b*p + a) ; + ATOMIC z0_imag = VECTOR(data,stride,b*p + p_1 - a) ; + ATOMIC z1_real = VECTOR(data,stride,b*p + p_1 + a) ; + ATOMIC z1_imag = VECTOR(data,stride,b*p + p - a) ; + + /* t0 = z0 + w * z1 */ + + ATOMIC t0_real = z0_real + w_real * z1_real - w_imag * z1_imag; + ATOMIC t0_imag = z0_imag + w_real * z1_imag + w_imag * z1_real; + + /* t1 = z0 - w * z1 */ + + ATOMIC t1_real = z0_real - w_real * z1_real + w_imag * z1_imag; + ATOMIC t1_imag = z0_imag - w_real * z1_imag - w_imag * z1_real; + + VECTOR(data,stride,b*p + a) = t0_real ; + VECTOR(data,stride,b*p + p - a) = t0_imag ; + + VECTOR(data,stride,b*p + p_1 - a) = t1_real ; + VECTOR(data,stride,b*p + p_1 + a) = -t1_imag ; + } + } + } + + if (p_1 > 1) + { + for (b = 0; b < q; b++) + { + /* a = p_{i-1}/2 */ + + VECTOR(data,stride,b*p + p - p_1/2) *= -1 ; + } + } + } + return 0; +} diff --git a/gsl-1.9/fft/real_unpack.c b/gsl-1.9/fft/real_unpack.c new file mode 100644 index 0000000..f8da6f9 --- /dev/null +++ b/gsl-1.9/fft/real_unpack.c @@ -0,0 +1,42 @@ +/* fft/real_unpack.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "complex_internal.h" + +int +FUNCTION(gsl_fft_real,unpack) (const BASE real_coefficient[], + BASE complex_coefficient[], + const size_t stride, const size_t n) +{ + size_t i; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + for (i = 0; i < n; i++) + { + REAL(complex_coefficient,stride,i) = real_coefficient[i * stride]; + IMAG(complex_coefficient,stride,i) = 0.0; + } + + return 0; + +} diff --git a/gsl-1.9/fft/signals.c b/gsl-1.9/fft/signals.c new file mode 100644 index 0000000..9869abe --- /dev/null +++ b/gsl-1.9/fft/signals.c @@ -0,0 +1,26 @@ +#include <config.h> +#include <math.h> +#include <stdlib.h> +#include <gsl/gsl_math.h> +#include <gsl/gsl_complex.h> +#include <gsl/gsl_errno.h> + +#include <gsl/gsl_dft_complex.h> +#include <gsl/gsl_dft_complex_float.h> + +#include "complex_internal.h" + +#include "urand.c" + +#define BASE_DOUBLE +#include "templates_on.h" +#include "signals_source.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "signals_source.c" +#include "templates_off.h" +#undef BASE_FLOAT + diff --git a/gsl-1.9/fft/signals.h b/gsl-1.9/fft/signals.h new file mode 100644 index 0000000..9f7da2c --- /dev/null +++ b/gsl-1.9/fft/signals.h @@ -0,0 +1,64 @@ +/* fft/signals.h + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +int FUNCTION(fft_signal,complex_pulse) (const size_t k, + const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]); + +int FUNCTION(fft_signal,complex_constant) (const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]); + +int FUNCTION(fft_signal,complex_exp) (const int k, + const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]); + + +int FUNCTION(fft_signal,complex_exppair) (const int k1, + const int k2, + const size_t n, + const size_t stride, + const BASE z1_real, + const BASE z1_imag, + const BASE z2_real, + const BASE z2_imag, + BASE data[], + BASE fft[]); + +int FUNCTION(fft_signal,complex_noise) (const size_t n, + const size_t stride, + BASE data[], + BASE fft[]); + +int FUNCTION(fft_signal,real_noise) (const size_t n, + const size_t stride, + BASE data[], + BASE fft[]); + diff --git a/gsl-1.9/fft/signals_source.c b/gsl-1.9/fft/signals_source.c new file mode 100644 index 0000000..eff3ec7 --- /dev/null +++ b/gsl-1.9/fft/signals_source.c @@ -0,0 +1,288 @@ +/* fft/signals_source.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "signals.h" + +int +FUNCTION(fft_signal,complex_pulse) (const size_t k, + const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]) +{ + size_t j; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + /* gsl_complex pulse at position k, data[j] = z * delta_{jk} */ + + for (j = 0; j < n; j++) + { + REAL(data,stride,j) = 0.0; + IMAG(data,stride,j) = 0.0; + } + + REAL(data,stride,k % n) = z_real; + IMAG(data,stride,k % n) = z_imag; + + /* fourier transform, fft[j] = z * exp(-2 pi i j k / n) */ + + for (j = 0; j < n; j++) + { + const double arg = -2 * M_PI * ((double) ((j * k) % n)) / ((double) n); + const BASE w_real = (BASE)cos (arg); + const BASE w_imag = (BASE)sin (arg); + REAL(fft,stride,j) = w_real * z_real - w_imag * z_imag; + IMAG(fft,stride,j) = w_real * z_imag + w_imag * z_real; + } + + return 0; + +} + + +int +FUNCTION(fft_signal,complex_constant) (const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]) +{ + size_t j; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + /* constant, data[j] = z */ + + for (j = 0; j < n; j++) + { + REAL(data,stride,j) = z_real; + IMAG(data,stride,j) = z_imag; + } + + /* fourier transform, fft[j] = n z delta_{j0} */ + + for (j = 0; j < n; j++) + { + REAL(fft,stride,j) = 0.0; + IMAG(fft,stride,j) = 0.0; + } + + REAL(fft,stride,0) = ((BASE) n) * z_real; + IMAG(fft,stride,0) = ((BASE) n) * z_imag; + + return 0; + +} + + +int +FUNCTION(fft_signal,complex_exp) (const int k, + const size_t n, + const size_t stride, + const BASE z_real, + const BASE z_imag, + BASE data[], + BASE fft[]) +{ + size_t j; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + /* exponential, data[j] = z * exp(2 pi i j k) */ + + for (j = 0; j < n; j++) + { + const double arg = 2 * M_PI * ((double) ((j * k) % n)) / ((double) n); + const BASE w_real = (BASE)cos (arg); + const BASE w_imag = (BASE)sin (arg); + REAL(data,stride,j) = w_real * z_real - w_imag * z_imag; + IMAG(data,stride,j) = w_real * z_imag + w_imag * z_real; + } + + /* fourier transform, fft[j] = z * delta{(j - k),0} */ + + for (j = 0; j < n; j++) + { + REAL(fft,stride,j) = 0.0; + IMAG(fft,stride,j) = 0.0; + } + + { + int freq; + + if (k <= 0) + { + freq = (n-k) % n ; + } + else + { + freq = (k % n); + }; + + REAL(fft,stride,freq) = ((BASE) n) * z_real; + IMAG(fft,stride,freq) = ((BASE) n) * z_imag; + } + + return 0; + +} + + +int +FUNCTION(fft_signal,complex_exppair) (const int k1, + const int k2, + const size_t n, + const size_t stride, + const BASE z1_real, + const BASE z1_imag, + const BASE z2_real, + const BASE z2_imag, + BASE data[], + BASE fft[]) +{ + size_t j; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + /* exponential, data[j] = z1 * exp(2 pi i j k1) + z2 * exp(2 pi i j k2) */ + + for (j = 0; j < n; j++) + { + const double arg1 = 2 * M_PI * ((double) ((j * k1) % n)) / ((double) n); + const BASE w1_real = (BASE)cos (arg1); + const BASE w1_imag = (BASE)sin (arg1); + const double arg2 = 2 * M_PI * ((double) ((j * k2) % n)) / ((double) n); + const BASE w2_real = (BASE)cos (arg2); + const BASE w2_imag = (BASE)sin (arg2); + REAL(data,stride,j) = w1_real * z1_real - w1_imag * z1_imag; + IMAG(data,stride,j) = w1_real * z1_imag + w1_imag * z1_real; + REAL(data,stride,j) += w2_real * z2_real - w2_imag * z2_imag; + IMAG(data,stride,j) += w2_real * z2_imag + w2_imag * z2_real; + } + + /* fourier transform, fft[j] = z1 * delta{(j - k1),0} + z2 * + delta{(j - k2,0)} */ + + for (j = 0; j < n; j++) + { + REAL(fft,stride,j) = 0.0; + IMAG(fft,stride,j) = 0.0; + } + + { + int freq1, freq2; + + if (k1 <= 0) + { + freq1 = (n - k1) % n; + } + else + { + freq1 = (k1 % n); + }; + + if (k2 <= 0) + { + freq2 = (n - k2) % n; + } + else + { + freq2 = (k2 % n); + }; + + REAL(fft,stride,freq1) += ((BASE) n) * z1_real; + IMAG(fft,stride,freq1) += ((BASE) n) * z1_imag; + REAL(fft,stride,freq2) += ((BASE) n) * z2_real; + IMAG(fft,stride,freq2) += ((BASE) n) * z2_imag; + } + + return 0; + +} + + +int +FUNCTION(fft_signal,complex_noise) (const size_t n, + const size_t stride, + BASE data[], + BASE fft[]) +{ + size_t i; + int status; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + for (i = 0; i < n; i++) + { + REAL(data,stride,i) = (BASE)urand(); + IMAG(data,stride,i) = (BASE)urand(); + } + + /* compute the dft */ + status = FUNCTION(gsl_dft_complex,forward) (data, stride, n, fft); + + return status; +} + + +int +FUNCTION(fft_signal,real_noise) (const size_t n, + const size_t stride, + BASE data[], + BASE fft[]) +{ + size_t i; + int status; + + if (n == 0) + { + GSL_ERROR ("length n must be positive integer", GSL_EDOM); + } + + for (i = 0; i < n; i++) + { + REAL(data,stride,i) = (BASE)urand(); + IMAG(data,stride,i) = 0.0; + } + + /* compute the dft */ + status = FUNCTION(gsl_dft_complex,forward) (data, stride, n, fft); + + return status; +} + diff --git a/gsl-1.9/fft/test.c b/gsl-1.9/fft/test.c new file mode 100644 index 0000000..779a056 --- /dev/null +++ b/gsl-1.9/fft/test.c @@ -0,0 +1,126 @@ +/* fft/test.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <config.h> +#include <string.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <float.h> + +#include <gsl/gsl_complex.h> +#include <gsl/gsl_errno.h> +#include <gsl/gsl_dft_complex.h> +#include <gsl/gsl_fft_complex.h> +#include <gsl/gsl_fft_complex_float.h> +#include <gsl/gsl_fft_real.h> +#include <gsl/gsl_fft_real_float.h> +#include <gsl/gsl_fft_halfcomplex.h> +#include <gsl/gsl_fft_halfcomplex_float.h> +#include <gsl/gsl_ieee_utils.h> +#include <gsl/gsl_test.h> + +void my_error_handler (const char *reason, const char *file, + int line, int err); + +#include "complex_internal.h" + +/* Usage: test [n] + Exercise the fft routines for length n. By default n runs from 1 to 100. + The exit status indicates success or failure. */ + +#define BASE_DOUBLE +#include "templates_on.h" +#include "compare_source.c" +#include "bitreverse.c" +#include "test_complex_source.c" +#include "test_real_source.c" +#include "test_trap_source.c" +#include "templates_off.h" +#undef BASE_DOUBLE + +#define BASE_FLOAT +#include "templates_on.h" +#include "compare_source.c" +#include "bitreverse.c" +#include "test_complex_source.c" +#include "test_real_source.c" +#include "test_trap_source.c" +#include "templates_off.h" +#undef BASE_FLOAT + +int +main (int argc, char *argv[]) +{ + size_t i; + size_t start = 1, end = 99; + size_t stride ; + size_t n = 0; + + gsl_ieee_env_setup (); + + if (argc == 2) + n = strtol (argv[1], NULL, 0); + + if (n) + { + start = n ; + end = n ; + } + + + for (i = 1 ; i <= end ; i *= 2) + { + if (i >= start) + { + for (stride = 1 ; stride < 4 ; stride++) + { + test_complex_bitreverse_order (stride, i) ; + test_complex_radix2 (stride, i) ; + test_real_bitreverse_order (stride, i) ; + test_real_radix2 (stride, i) ; + } + } + } + + for (i = start ; i <= end ; i++) + { + for (stride = 1 ; stride < 4 ; stride++) + { + test_complex_func (stride, i) ; + test_complex_float_func (stride, i) ; + test_real_func (stride, i) ; + test_real_float_func (stride, i) ; + } + } + + gsl_set_error_handler (&my_error_handler); + test_trap () ; + test_float_trap () ; + + exit (gsl_test_summary ()); +} + + +void +my_error_handler (const char *reason, const char *file, int line, int err) +{ + if (0) printf ("(caught [%s:%d: %s (%d)])\n", file, line, reason, err) ; +} diff --git a/gsl-1.9/fft/test_complex_source.c b/gsl-1.9/fft/test_complex_source.c new file mode 100644 index 0000000..a4c0d27 --- /dev/null +++ b/gsl-1.9/fft/test_complex_source.c @@ -0,0 +1,448 @@ +/* fft/test_complex.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "bitreverse.h" +#include "signals.h" +#include "compare.h" + +void FUNCTION(test_complex,func) (size_t stride, size_t n); +int FUNCTION(test,offset) (const BASE data[], size_t stride, + size_t n, size_t offset); +void FUNCTION(test_complex,bitreverse_order) (size_t stride, size_t n) ; +void FUNCTION(test_complex,radix2) (size_t stride, size_t n); + +int FUNCTION(test,offset) (const BASE data[], size_t stride, + size_t n, size_t offset) +{ + int status = 0 ; + size_t i, j, k = 0 ; + + for (i = 0; i < n; i++) + { + k += 2 ; + + for (j = 1; j < stride; j++) + { + status |= data[k] != k + offset ; + k++ ; + status |= data[k] != k + offset ; + k++ ; + } + } + return status ; +} + + +void FUNCTION(test_complex,func) (size_t stride, size_t n) +{ + size_t i ; + int status ; + + TYPE(gsl_fft_complex_wavetable) * cw ; + TYPE(gsl_fft_complex_workspace) * cwork ; + + BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + + for (i = 0 ; i < 2 * n * stride ; i++) + { + complex_data[i] = (BASE)i ; + complex_tmp[i] = (BASE)(i + 1000.0) ; + fft_complex_data[i] = (BASE)(i + 2000.0) ; + fft_complex_tmp[i] = (BASE)(i + 3000.0) ; + } + + gsl_set_error_handler (NULL); /* abort on any errors */ + + /* Test allocation */ + + { + cw = FUNCTION(gsl_fft_complex_wavetable,alloc) (n); + gsl_test (cw == 0, NAME(gsl_fft_complex_wavetable) + "_alloc, n = %d, stride = %d", n, stride); + } + + { + cwork = FUNCTION(gsl_fft_complex_workspace,alloc) (n); + gsl_test (cwork == 0, NAME(gsl_fft_complex_workspace) + "_alloc, n = %d", n); + } + + + /* Test mixed radix fft with noise */ + + { + FUNCTION(fft_signal,complex_noise) (n, stride, complex_data, fft_complex_data); + for (i = 0 ; i < n ; i++) + { + REAL(complex_tmp,stride,i) = REAL(complex_data,stride,i) ; + IMAG(complex_tmp,stride,i) = IMAG(complex_data,stride,i) ; + } + + FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork); + + for (i = 0 ; i < n ; i++) + { + REAL(fft_complex_tmp,stride,i) = REAL(complex_data,stride,i) ; + IMAG(fft_complex_tmp,stride,i) = IMAG(complex_data,stride,i) ; + } + + status = FUNCTION(compare_complex,results) ("dft", fft_complex_data, + "fft of noise", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_forward with signal_noise, n = %d, stride = %d", n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (complex_data, stride, n, 0) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_forward avoids unstrided data, n = %d, stride = %d", + n, stride); + } + } + + /* Test the inverse fft */ + + { + status = FUNCTION(gsl_fft_complex,inverse) (complex_data, stride, n, cw, cwork); + status = FUNCTION(compare_complex,results) ("orig", complex_tmp, + "fft inverse", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_inverse with signal_noise, n = %d, stride = %d", n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (complex_data, stride, n, 0) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_inverse other data untouched, n = %d, stride = %d", + n, stride); + } + + } + + /* Test the backward fft */ + + { + status = FUNCTION(gsl_fft_complex,backward) (fft_complex_tmp, stride, n, cw, cwork); + + for (i = 0; i < n; i++) + { + REAL(complex_tmp,stride,i) *= n; + IMAG(complex_tmp,stride,i) *= n; + } + status = FUNCTION(compare_complex,results) ("orig", + complex_tmp, + "fft backward", + fft_complex_tmp, + stride, n, 1e6); + + gsl_test (status, NAME(gsl_fft_complex) + "_backward with signal_noise, n = %d, stride = %d", n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (fft_complex_tmp, stride, n, 3000) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_backward avoids unstrided data, n = %d, stride = %d", + n, stride); + } + + } + + /* Test a pulse signal */ + + { + FUNCTION(fft_signal,complex_pulse) (1, n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork); + status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data, + "fft of pulse", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_forward with signal_pulse, n = %d, stride = %d", n, stride); + + } + + + /* Test a constant signal */ + + { + FUNCTION(fft_signal,complex_constant) (n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork); + status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data, + "fft of constant", + complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_forward with signal_constant, n = %d, stride = %d", n, stride); + } + + /* Test an exponential (cos/sin) signal */ + + { + status = 0; + for (i = 0; i < n; i++) + { + FUNCTION(fft_signal,complex_exp) ((int)i, n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,forward) (complex_data, stride, n, cw, cwork); + status |= FUNCTION(compare_complex,results) ("analytic", + fft_complex_data, + "fft of exp", + complex_data, + stride, n, 1e6); + } + gsl_test (status, NAME(gsl_fft_complex) + "_forward with signal_exp, n = %d, stride = %d", n, stride); + } + + FUNCTION(gsl_fft_complex_wavetable,free) (cw); + FUNCTION(gsl_fft_complex_workspace,free) (cwork); + + free (complex_data); + free (complex_tmp); + free (fft_complex_data); + free (fft_complex_tmp); +} + + +void +FUNCTION(test_complex,bitreverse_order) (size_t stride, size_t n) +{ + int status ; + size_t logn, i ; + + BASE * tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * reversed_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + + for (i = 0; i < 2 * stride * n; i++) + { + data[i] = (BASE)i ; + } + + memcpy (tmp, data, 2 * n * stride * sizeof(BASE)) ; + + logn = 0 ; while (n > (1U<<logn)) {logn++ ; } ; + + /* do a naive bit reversal as a baseline for testing the other routines */ + + for (i = 0; i < n; i++) + { + size_t i_tmp = i ; + size_t j = 0 ; + size_t bit ; + + for (bit = 0; bit < logn; bit++) + { + j <<= 1; /* reverse shift i into j */ + j |= i_tmp & 1; + i_tmp >>= 1; + } + + reversed_data[2*j*stride] = data[2*i*stride] ; + reversed_data[2*j*stride+1] = data[2*i*stride+1] ; + } + + FUNCTION(fft_complex,bitreverse_order) (data, stride, n, logn); + + status = FUNCTION(compare_complex,results) ("naive bit reverse", + reversed_data, + "fft_complex_bitreverse_order", + data, + stride, n, 1e6); + + gsl_test (status, "fft_complex_bitreverse_order, n = %d", n); + + free (reversed_data) ; + free (data) ; + free (tmp) ; +} + +void FUNCTION(test_complex,radix2) (size_t stride, size_t n) +{ + size_t i ; + int status ; + + BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + + for (i = 0 ; i < 2 * n * stride ; i++) + { + complex_data[i] = (BASE)i ; + complex_tmp[i] = (BASE)(i + 1000.0) ; + fft_complex_data[i] = (BASE)(i + 2000.0) ; + fft_complex_tmp[i] = (BASE)(i + 3000.0) ; + } + + gsl_set_error_handler (NULL); /* abort on any errors */ + + /* Test radix-2 fft with noise */ + + { + FUNCTION(fft_signal,complex_noise) (n, stride, complex_data, + fft_complex_data); + for (i = 0 ; i < n ; i++) + { + REAL(complex_tmp,stride,i) = REAL(complex_data,stride,i) ; + IMAG(complex_tmp,stride,i) = IMAG(complex_data,stride,i) ; + } + + FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n); + + for (i = 0 ; i < n ; i++) + { + REAL(fft_complex_tmp,stride,i) = REAL(complex_data,stride,i) ; + IMAG(fft_complex_tmp,stride,i) = IMAG(complex_data,stride,i) ; + } + + status = FUNCTION(compare_complex,results) ("dft", fft_complex_data, + "fft of noise", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_forward with signal_noise, n = %d, stride = %d", + n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (complex_data, stride, n, 0) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_forward avoids unstrided data, n = %d, stride = %d", + n, stride); + } + } + + /* Test the inverse fft */ + + { + status = FUNCTION(gsl_fft_complex,radix2_inverse) (complex_data, stride, n); + status = FUNCTION(compare_complex,results) ("orig", complex_tmp, + "fft inverse", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_inverse with signal_noise, n = %d, stride = %d", n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (complex_data, stride, n, 0) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_inverse other data untouched, n = %d, stride = %d", + n, stride); + } + + } + + /* Test the backward fft */ + + { + status = FUNCTION(gsl_fft_complex,radix2_backward) (fft_complex_tmp, stride, n); + + for (i = 0; i < n; i++) + { + REAL(complex_tmp,stride,i) *= n; + IMAG(complex_tmp,stride,i) *= n; + } + status = FUNCTION(compare_complex,results) ("orig", + complex_tmp, + "fft backward", + fft_complex_tmp, + stride, n, 1e6); + + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_backward with signal_noise, n = %d, stride = %d", n, stride); + + if (stride > 1) + { + status = FUNCTION(test, offset) (fft_complex_tmp, stride, n, 3000) ; + + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_backward avoids unstrided data, n = %d, stride = %d", + n, stride); + } + + } + + /* Test a pulse signal */ + + { + FUNCTION(fft_signal,complex_pulse) (1, n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n); + status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data, + "fft of pulse", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_forward with signal_pulse, n = %d, stride = %d", n, stride); + + } + + + /* Test a constant signal */ + + { + FUNCTION(fft_signal,complex_constant) (n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n); + status = FUNCTION(compare_complex,results) ("analytic", fft_complex_data, + "fft of constant", + complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_forward with signal_constant, n = %d, stride = %d", + n, stride); + } + + /* Test an exponential (cos/sin) signal */ + + { + status = 0; + for (i = 0; i < n; i++) + { + FUNCTION(fft_signal,complex_exp) ((int)i, n, stride, 1.0, 0.0, complex_data, + fft_complex_data); + FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, stride, n); + status |= FUNCTION(compare_complex,results) ("analytic", + fft_complex_data, + "fft of exp", + complex_data, + stride, n, 1e6); + } + gsl_test (status, NAME(gsl_fft_complex) + "_radix2_forward with signal_exp, n = %d, stride = %d", n, stride); + } + + + free (complex_data); + free (complex_tmp); + free (fft_complex_data); + free (fft_complex_tmp); +} + diff --git a/gsl-1.9/fft/test_real_source.c b/gsl-1.9/fft/test_real_source.c new file mode 100644 index 0000000..1605a78 --- /dev/null +++ b/gsl-1.9/fft/test_real_source.c @@ -0,0 +1,235 @@ +/* fft/test_real.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "bitreverse.h" +#include "signals.h" +#include "compare.h" + +void FUNCTION(test_real,func) (size_t stride, size_t n); +void FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n); +void FUNCTION(test_real,radix2) (size_t stride, size_t n); + +void FUNCTION(test_real,func) (size_t stride, size_t n) +{ + size_t i ; + int status ; + + TYPE(gsl_fft_real_wavetable) * rw ; + TYPE(gsl_fft_halfcomplex_wavetable) * hcw ; + TYPE(gsl_fft_real_workspace) * rwork ; + + BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE)); + BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + + for (i = 0 ; i < n * stride ; i++) + { + real_data[i] = (BASE)i ; + } + + for (i = 0 ; i < 2 * n * stride ; i++) + { + complex_data[i] = (BASE)(i + 1000.0) ; + complex_tmp[i] = (BASE)(i + 2000.0) ; + fft_complex_data[i] = (BASE)(i + 3000.0) ; + } + + gsl_set_error_handler (NULL); /* abort on any errors */ + + /* mixed radix real fft */ + + rw = FUNCTION(gsl_fft_real_wavetable,alloc) (n); + gsl_test (rw == 0, NAME(gsl_fft_real_wavetable) + "_alloc, n = %d, stride = %d", n, stride); + + rwork = FUNCTION(gsl_fft_real_workspace,alloc) (n); + gsl_test (rwork == 0, NAME(gsl_fft_real_workspace) + "_alloc, n = %d", n); + + FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data); + memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE)); + + for (i = 0; i < n; i++) + { + real_data[i*stride] = REAL(complex_data,stride,i); + } + + FUNCTION(gsl_fft_real,transform) (real_data, stride, n, rw, rwork); + FUNCTION(gsl_fft_halfcomplex,unpack) (real_data, complex_data, stride, n); + + status = FUNCTION(compare_complex,results) ("dft", fft_complex_data, + "fft of noise", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_real) + " with signal_real_noise, n = %d, stride = %d", n, stride); + + /* compute the inverse fft */ + + hcw = FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (n); + gsl_test (hcw == 0, NAME(gsl_fft_halfcomplex_wavetable) + "_alloc, n = %d, stride = %d", n, stride); + + status = FUNCTION(gsl_fft_halfcomplex,transform) (real_data, stride, n, hcw, rwork); + + for (i = 0; i < n; i++) + { + real_data[i*stride] /= n; + } + + FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n); + + status = FUNCTION(compare_complex,results) ("orig", complex_tmp, + "fft inverse", complex_data, + stride, n, 1e6); + + gsl_test (status, NAME(gsl_fft_halfcomplex) + " with data from signal_noise, n = %d, stride = %d", n, stride); + + FUNCTION(gsl_fft_real_workspace,free) (rwork); + FUNCTION(gsl_fft_real_wavetable,free) (rw); + FUNCTION(gsl_fft_halfcomplex_wavetable,free) (hcw); + + free(real_data) ; + free(complex_data) ; + free(complex_tmp) ; + free(fft_complex_data) ; +} + + +void +FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n) +{ + int status ; + size_t logn, i ; + + BASE * tmp = (BASE *) malloc (n * stride * sizeof (BASE)); + BASE * data = (BASE *) malloc (n * stride * sizeof (BASE)); + BASE * reversed_data = (BASE *) malloc (n * stride * sizeof (BASE)); + + for (i = 0; i < stride * n; i++) + { + data[i] = (BASE)i ; + } + + memcpy (tmp, data, n * stride * sizeof(BASE)) ; + + logn = 0 ; while (n > (1U <<logn)) {logn++;} ; + + /* do a naive bit reversal as a baseline for testing the other routines */ + + for (i = 0; i < n; i++) + { + size_t i_tmp = i ; + size_t j = 0 ; + size_t bit ; + + for (bit = 0; bit < logn; bit++) + { + j <<= 1; /* reverse shift i into j */ + j |= i_tmp & 1; + i_tmp >>= 1; + } + + reversed_data[j*stride] = data[i*stride] ; + } + + FUNCTION(fft_real,bitreverse_order) (data, stride, n, logn); + + status = FUNCTION(compare_real,results) ("naive bit reverse", + reversed_data, + "fft_complex_bitreverse_order", + data, + stride, n, 1e6); + + gsl_test (status, NAME(fft_real) "_bitreverse_order, n = %d", n); + + free (reversed_data) ; + free (data) ; + free (tmp) ; +} + + +void FUNCTION(test_real,radix2) (size_t stride, size_t n) +{ + size_t i ; + int status ; + + BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE)); + BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE)); + + for (i = 0 ; i < n * stride ; i++) + { + real_data[i] = (BASE)i ; + } + + for (i = 0 ; i < 2 * n * stride ; i++) + { + complex_data[i] = (BASE)(i + 1000.0) ; + complex_tmp[i] = (BASE)(i + 2000.0) ; + fft_complex_data[i] = (BASE)(i + 3000.0) ; + } + + gsl_set_error_handler (NULL); /* abort on any errors */ + + /* radix-2 real fft */ + + FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data); + memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE)); + + for (i = 0; i < n; i++) + { + real_data[i*stride] = REAL(complex_data,stride,i); + } + + FUNCTION(gsl_fft_real,radix2_transform) (real_data, stride, n); + FUNCTION(gsl_fft_halfcomplex,radix2_unpack) (real_data, complex_data, stride, n); + + status = FUNCTION(compare_complex,results) ("dft", fft_complex_data, + "fft of noise", complex_data, + stride, n, 1e6); + gsl_test (status, NAME(gsl_fft_real) + "_radix2 with signal_real_noise, n = %d, stride = %d", n, stride); + + /* compute the inverse fft */ + + status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (real_data, stride, n); + + for (i = 0; i < n; i++) + { + real_data[i*stride] /= n; + } + + FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n); + + status = FUNCTION(compare_complex,results) ("orig", complex_tmp, + "fft inverse", complex_data, + stride, n, 1e6); + + gsl_test (status, NAME(gsl_fft_halfcomplex) + "_radix2 with data from signal_noise, n = %d, stride = %d", n, stride); + + + free(real_data) ; + free(complex_data) ; + free(complex_tmp) ; + free(fft_complex_data) ; +} diff --git a/gsl-1.9/fft/test_trap_source.c b/gsl-1.9/fft/test_trap_source.c new file mode 100644 index 0000000..379ac7a --- /dev/null +++ b/gsl-1.9/fft/test_trap_source.c @@ -0,0 +1,138 @@ +/* fft/test_trap.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +void FUNCTION(test,trap) (void); + +void +FUNCTION(test,trap) (void) +{ + int status ; + + BASE real_x ; + BASE complex_x ; + + BASE * real_data = &real_x ; + BASE * complex_data = &complex_x ; + + TYPE(gsl_fft_complex_wavetable) * cw; + TYPE(gsl_fft_real_wavetable) * rw; + TYPE(gsl_fft_halfcomplex_wavetable) * hcw; + + TYPE(gsl_fft_complex_workspace) * cwork; + TYPE(gsl_fft_real_workspace) * rwork; + + /* n = 0 in alloc */ + + cw = FUNCTION(gsl_fft_complex_wavetable,alloc) (0); + gsl_test (cw != 0, "trap for n = 0 in " NAME(gsl_fft_complex_wavetable) "_alloc"); + + rw = FUNCTION(gsl_fft_real_wavetable,alloc) (0); + gsl_test (rw != 0, "trap for n = 0 in " NAME(gsl_fft_real_wavetable) "_alloc" ); + + hcw = FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (0); + gsl_test (hcw != 0, "trap for n = 0 in " NAME(gsl_fft_halfcomplex_wavetable) "_alloc"); + + cwork = FUNCTION(gsl_fft_complex_workspace,alloc) (0); + gsl_test (cw != 0, "trap for n = 0 in " NAME(gsl_fft_complex_workspace) "_alloc"); + + rwork = FUNCTION(gsl_fft_real_workspace,alloc) (0); + gsl_test (rw != 0, "trap for n = 0 in " NAME(gsl_fft_real_workspace) "_alloc" ); + + cw = FUNCTION(gsl_fft_complex_wavetable,alloc) (10); + hcw = FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (10); + rw = FUNCTION(gsl_fft_real_wavetable,alloc) (10); + + cwork = FUNCTION(gsl_fft_complex_workspace,alloc) (10); + rwork = FUNCTION(gsl_fft_real_workspace,alloc) (10); + + /* n = 0 in fft forward */ + + status = FUNCTION(gsl_fft_complex,forward) (complex_data, 1, 0, cw, cwork); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_forward"); + + status = FUNCTION(gsl_fft_real,transform) (real_data, 1, 0, rw, rwork); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_real) "_transform"); + + status = FUNCTION(gsl_fft_halfcomplex,transform) (real_data, 1, 0, hcw, rwork); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_halfcomplex) "_transform"); + + status = FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, 1, 0); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_radix2_forward"); + + /* n = 0 in fft backward */ + + status = FUNCTION(gsl_fft_complex,backward) (complex_data, 1, 0, cw, cwork); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_backward"); + + status = FUNCTION(gsl_fft_complex,radix2_backward) (complex_data, 1, 0); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_radix2_backward"); + + /* n = 0 in fft inverse */ + + status = FUNCTION(gsl_fft_complex,inverse) (complex_data, 1, 0, cw, cwork); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_inverse"); + + status = FUNCTION(gsl_fft_complex,radix2_inverse) (complex_data, 1, 0); + gsl_test (!status, "trap for n = 0 in " NAME(gsl_fft_complex) "_radix2_inverse"); + + /* n != 2^k in power of 2 routines */ + + status = FUNCTION(gsl_fft_complex,radix2_forward) (complex_data, 1, 17); + gsl_test (!status, "trap for n != 2^k in " NAME(gsl_fft_complex) "_radix2_forward"); + + status = FUNCTION(gsl_fft_complex,radix2_backward) (complex_data, 1, 17); + gsl_test (!status, "trap for n != 2^k in " NAME(gsl_fft_complex) "_radix2_backward"); + + status = FUNCTION(gsl_fft_complex,radix2_inverse) (complex_data, 1, 17); + gsl_test (!status, "trap for n != 2^k in " NAME(gsl_fft_complex) "_radix2_inverse"); + + /* n != wavetable.n in mixed radix routines */ + + cw->n = 3; + status = FUNCTION(gsl_fft_complex,forward) (complex_data, 1, 4, cw, cwork); + gsl_test (!status, "trap for n != nw in " NAME(gsl_fft_complex) "_forward"); + + cw->n = 3; + status = FUNCTION(gsl_fft_complex,backward) (complex_data, 1, 4, cw, cwork); + gsl_test (!status, "trap for n != nw in " NAME(gsl_fft_complex) "_backward"); + + cw->n = 3; + status = FUNCTION(gsl_fft_complex,inverse) (complex_data, 1, 4, cw, cwork); + gsl_test (!status, "trap for n != nw in " NAME(gsl_fft_complex) "_inverse"); + + rw->n = 3; + status = FUNCTION(gsl_fft_real,transform) (real_data, 1, 4, rw, rwork); + gsl_test (!status, "trap for n != nw in " NAME(gsl_fft_real) "_transform"); + + hcw->n = 3; + status = FUNCTION(gsl_fft_halfcomplex,transform) (real_data, 1, 4, hcw, rwork); + gsl_test (!status, "trap for n != nw in " NAME(gsl_fft_halfcomplex) "_transform"); + + FUNCTION (gsl_fft_halfcomplex_wavetable,free) (hcw) ; + FUNCTION (gsl_fft_real_wavetable,free) (rw) ; + FUNCTION (gsl_fft_complex_wavetable,free) (cw) ; + + FUNCTION (gsl_fft_real_workspace,free) (rwork) ; + FUNCTION (gsl_fft_complex_workspace,free) (cwork) ; + +} + + + + diff --git a/gsl-1.9/fft/urand.c b/gsl-1.9/fft/urand.c new file mode 100644 index 0000000..3a0fccf --- /dev/null +++ b/gsl-1.9/fft/urand.c @@ -0,0 +1,26 @@ +/* fft/urand.c + * + * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +double urand (void); + +double urand (void) { + static unsigned long int x = 1; + x = (1103515245 * x + 12345) & 0x7fffffffUL ; + return x / 2147483648.0 ; +} |