This commit is contained in:
2025-07-12 12:17:44 +03:00
parent c759f60ff7
commit 792e1b937a
3507 changed files with 492613 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
BFNNCONV_SRC = bfnnconv.pl m-ascii.pl m-html.pl m-info.pl m-lout.pl m-post.pl
FAQ = fftw-faq.ascii fftw-faq.html
EXTRA_DIST = fftw-faq.bfnn $(FAQ) $(BFNNCONV_SRC) html.refs
html.refs2: html.refs
cp -f ${srcdir}/html.refs html.refs2
fftw-faq.ascii: fftw-faq.html
# generates both fftw-faq.html and fftw-faq.ascii
fftw-faq.html: $(BFNNCONV_SRC) fftw-faq.bfnn html.refs2
@echo converting...
perl -I${srcdir} ${srcdir}/bfnnconv.pl < ${srcdir}/fftw-faq.bfnn
@echo converting again...
perl -I${srcdir} ${srcdir}/bfnnconv.pl < ${srcdir}/fftw-faq.bfnn
rm -f fftw-faq.ascii
mv stdin.ascii fftw-faq.ascii
rm -rf fftw-faq.html
mv -f stdin.html fftw-faq.html
faq: $(FAQ)
clean-local:
rm -f *~ core a.out *.lout *.ps *.info *.ascii *.xrefdb *.post
rm -rf *.html html.refs2

View File

@@ -0,0 +1,506 @@
# Makefile.in generated by automake 1.16.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 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@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
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@
subdir = doc/FAQ
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/acx_mpi.m4 \
$(top_srcdir)/m4/acx_pthread.m4 \
$(top_srcdir)/m4/ax_cc_maxopt.m4 \
$(top_srcdir)/m4/ax_check_compiler_flags.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_gcc_aligns_stack.m4 \
$(top_srcdir)/m4/ax_gcc_version.m4 \
$(top_srcdir)/m4/ax_openmp.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
ALTIVEC_CFLAGS = @ALTIVEC_CFLAGS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AVX2_CFLAGS = @AVX2_CFLAGS@
AVX512_CFLAGS = @AVX512_CFLAGS@
AVX_128_FMA_CFLAGS = @AVX_128_FMA_CFLAGS@
AVX_CFLAGS = @AVX_CFLAGS@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CHECK_PL_OPTS = @CHECK_PL_OPTS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
C_FFTW_R2R_KIND = @C_FFTW_R2R_KIND@
C_MPI_FINT = @C_MPI_FINT@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FGREP = @FGREP@
FLIBS = @FLIBS@
GREP = @GREP@
INDENT = @INDENT@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KCVI_CFLAGS = @KCVI_CFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBQUADMATH = @LIBQUADMATH@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPILIBS = @MPILIBS@
MPIRUN = @MPIRUN@
NEON_CFLAGS = @NEON_CFLAGS@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OCAMLBUILD = @OCAMLBUILD@
OPENMP_CFLAGS = @OPENMP_CFLAGS@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
POW_LIB = @POW_LIB@
PRECISION = @PRECISION@
PREC_SUFFIX = @PREC_SUFFIX@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHARED_VERSION_INFO = @SHARED_VERSION_INFO@
SHELL = @SHELL@
SSE2_CFLAGS = @SSE2_CFLAGS@
STACK_ALIGN_CFLAGS = @STACK_ALIGN_CFLAGS@
STRIP = @STRIP@
THREADLIBS = @THREADLIBS@
VERSION = @VERSION@
VSX_CFLAGS = @VSX_CFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_F77 = @ac_ct_F77@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
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@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
BFNNCONV_SRC = bfnnconv.pl m-ascii.pl m-html.pl m-info.pl m-lout.pl m-post.pl
FAQ = fftw-faq.ascii fftw-faq.html
EXTRA_DIST = fftw-faq.bfnn $(FAQ) $(BFNNCONV_SRC) html.refs
all: all-am
.SUFFIXES:
$(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 ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/FAQ/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu doc/FAQ/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__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
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
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$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
check: check-am
all-am: Makefile
installdirs:
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:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
clean-local cscopelist-am ctags-am distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
.PRECIOUS: Makefile
html.refs2: html.refs
cp -f ${srcdir}/html.refs html.refs2
fftw-faq.ascii: fftw-faq.html
# generates both fftw-faq.html and fftw-faq.ascii
fftw-faq.html: $(BFNNCONV_SRC) fftw-faq.bfnn html.refs2
@echo converting...
perl -I${srcdir} ${srcdir}/bfnnconv.pl < ${srcdir}/fftw-faq.bfnn
@echo converting again...
perl -I${srcdir} ${srcdir}/bfnnconv.pl < ${srcdir}/fftw-faq.bfnn
rm -f fftw-faq.ascii
mv stdin.ascii fftw-faq.ascii
rm -rf fftw-faq.html
mv -f stdin.html fftw-faq.html
faq: $(FAQ)
clean-local:
rm -f *~ core a.out *.lout *.ps *.info *.ascii *.xrefdb *.post
rm -rf *.html html.refs2
# 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:

298
fftw-3.3.10/doc/FAQ/bfnnconv.pl Executable file
View File

@@ -0,0 +1,298 @@
#!/usr/bin/perl --
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
@outputs=('ascii','info','html');
while ($ARGV[0] =~ m/^\-/) {
$_= shift(@ARGV);
if (m/^-only/) {
@outputs= (shift(@ARGV));
} else {
warn "unknown option `$_' ignored";
}
}
$prefix= $ARGV[0];
$prefix= 'stdin' unless length($prefix);
$prefix =~ s/\.bfnn$//;
if (open(O,"$prefix.xrefdb")) {
@xrefdb= <O>;
close(O);
} else {
warn "no $prefix.xrefdb ($!)";
}
$section= -1;
for $thisxr (@xrefdb) {
$_= $thisxr;
chop;
if (m/^Q (\w+) ((\d+)\.(\d+)) (.*)$/) {
$qrefn{$1}= $2;
$qreft{$1}= $5;
$qn2ref{$3,$4}= $1;
$maxsection= $3;
$maxquestion[$3]= $4;
} elsif (m/^S (\d+) /) {
$maxsection= $1;
$sn2title{$1}=$';
}
}
open(U,">$prefix.xrefdb-new");
for $x (@outputs) { require("m-$x.pl"); }
&call('init');
while (<>) {
chop;
next if m/^\\comment\b/;
if (!m/\S/) {
&call('endpara');
next;
}
if (s/^\\section +//) {
$line= $_;
$section++; $question=0;
print U "S $section $line\n";
$|=1; print "S$section",' 'x10,"\r"; $|=0;
&call('endpara');
&call('startmajorheading',"$section",
"Section $section",
$section<$maxsection ? "Section ".($section+1) : '',
$section>1 ? 'Section '.($section-1) : 'Top');
&text($line);
&call('endmajorheading');
if ($section) {
&call('endpara');
&call('startindex');
for $thisxr (@xrefdb) {
$_= $thisxr;
chop;
if (m/^Q (\w+) (\d+)\.(\d+) (.*)$/) {
$ref= $1; $num1= $2; $num2= $3; $text= $4;
next unless $num1 == $section;
&call('startindexitem',$ref,"Q$num1.$num2","Question $num1.$num2");
&text($text);
&call('endindexitem');
}
}
&call('endindex');
}
} elsif (s/^\\question \d{2}[a-z]{3}((:\w+)?) +//) {
$line= $_;
$question++;
$qrefstring= $1;
$qrefstring= "q_${section}_$question" unless $qrefstring =~ s/^://;
print U "Q $qrefstring $section.$question $line\n";
$|=1; print "Q$section.$question",' 'x10,"\r"; $|=0;
&call('endpara');
&call('startminorheading',$qrefstring,
"Question $section.$question",
$question < $maxquestion[$section] ? "Question $section.".($question+1) :
$section < $maxsection ? "Question ".($section+1).".1" : '',
$question > 1 ? "Question $section.".($question-1) :
$section > 1 ? "Question ".($section-1).'.'.($maxquestion[$section-1]) :
'Top',
"Section $section");
&text("Question $section.$question. $line");
&call('endminorheading');
} elsif (s/^\\only +//) {
@saveoutputs= @outputs;
@outputs=();
for $x (split(/\s+/,$_)) {
push(@outputs,$x) if grep($x eq $_, @saveoutputs);
}
} elsif (s/^\\endonly$//) {
@outputs= @saveoutputs;
} elsif (s/^\\copyto +//) {
$fh= $';
while(<>) {
last if m/^\\endcopy$/;
while (s/^([^\`]*)\`//) {
print $fh $1;
m/([^\\])\`/ || warn "`$_'";
$_= $';
$cmd= $`.$1;
$it= `$cmd`; chop $it;
print $fh $it;
}
print $fh $_;
}
} elsif (m/\\index$/) {
&call('startindex');
for $thisxr (@xrefdb) {
$_= $thisxr;
chop;
if (m/^Q (\w+) (\d+\.\d+) (.*)$/) {
$ref= $1; $num= $2; $text= $3;
&call('startindexitem',$ref,"Q$num","Question $num");
&text($text);
&call('endindexitem');
} elsif (m/^S (\d+) (.*)$/) {
$num= $1; $text= $2;
next unless $num;
&call('startindexmainitem',"s_$num",
"Section $num.","Section $num");
&text($text);
&call('endindexitem');
} else {
warn $_;
}
}
&call('endindex');
} elsif (m/^\\call-(\w+) +(\w+)\s*(.*)$/) {
$fn= $1.'_'.$2;
eval { &$fn($3); };
warn $@ if length($@);
} elsif (m/^\\call +(\w+)\s*(.*)$/) {
eval { &call($1,$2); };
warn $@ if length($@);
} elsif (s/^\\set +(\w+)\s*//) {
$svalue= $'; $svari= $1;
eval("\$user_$svari=\$svalue"); $@ && warn "setting $svalue failed: $@\n";
} elsif (m/^\\verbatim$/) {
&call('startverbatim');
while (<>) {
chop;
last if m/^\\endverbatim$/;
&call('verbatim',$_);
}
&call('endverbatim');
} else {
s/\.$/\. /;
&text($_." ");
}
}
print ' 'x25,"\r";
&call('finish');
rename("$prefix.xrefdb-new","$prefix.xrefdb") || warn "rename xrefdb: $!";
exit 0;
sub text {
local($in,$rhs,$word,$refn,$reft,$fn,$style);
$in= "$holdover$_[0]";
$holdover= '';
while ($in =~ m/\\/) {
#print STDERR ">$`##$'\n";
$rhs=$';
&call('text',$`);
$_= $rhs;
if (m/^\w+ $/) {
$holdover= "\\$&";
$in= '';
} elsif (s/^fn\s+([^\s\\]*\w)//) {
$in= $_;
$word= $1;
&call('courier');
&call('text',$word);
&call('endcourier');
} elsif (s/^tab\s+(\d+)\s+//) {
$in= $_; &call('tab',$1);
} elsif (s/^nl\s+//) {
$in= $_; &call('newline');
} elsif (s/^qref\s+(\w+)//) {
$refn= $qrefn{$1};
$reft= $qreft{$1};
if (!length($refn)) {
warn "unknown question `$1'";
}
$in= "$`\\pageref:$1:$refn:$reft\\endpageref.$_";
} elsif (s/^pageref:(\w+):([^:\n]+)://) {
$in= $_;
&call('pageref',$1,$2);
} elsif (s/^endpageref\.//) {
$in= $_; &call('endpageref');
} elsif (s/^(\w+)\{//) {
$in= $_; $fn= $1;
eval { &call("$fn"); };
if (length($@)) { warn $@; $fn= 'x'; }
push(@styles,$fn);
} elsif (s/^\}//) {
$in= $_;
$fn= pop(@styles);
if ($fn ne 'x') { &call("end$fn"); }
} elsif (s/^\\//) {
$in= $_;
&call('text',"\\");
} elsif (s,^(\w+)\s+([-A-Za-z0-9.\@:/]*\w),,) {
#print STDERR "**$&**$_\n";
$in= $_;
$style=$1; $word= $2;
&call($style);
&call('text',$word);
&call("end$style");
} else {
warn "unknown control `\\$_'";
$in= $_;
}
}
&call('text',$in);
}
sub call {
local ($fnbase, @callargs) = @_;
local ($coutput);
for $coutput (@outputs) {
if ($fnbase eq 'text' && eval("\@${coutput}_cmds")) {
#print STDERR "special handling text (@callargs) for $coutput\n";
$evstrg= "\$${coutput}_args[\$#${coutput}_args].=\"\@callargs\"";
eval($evstrg);
length($@) && warn "call adding for $coutput (($evstrg)): $@";
} else {
$fntc= $coutput.'_'.$fnbase;
&$fntc(@callargs);
}
}
}
sub recurse {
local (@outputs) = $coutput;
local ($holdover);
&text($_[0]);
}
sub arg {
#print STDERR "arg($_[0]) from $coutput\n";
$cmd= $_[0];
eval("push(\@${coutput}_cmds,\$cmd); push(\@${coutput}_args,'')");
length($@) && warn "arg setting up for $coutput: $@";
}
sub endarg {
#print STDERR "endarg($_[0]) from $coutput\n";
$evstrg= "\$${coutput}_cmd= \$cmd= pop(\@${coutput}_cmds); ".
"\$${coutput}_arg= \$arg= pop(\@${coutput}_args); ";
eval($evstrg);
length($@) && warn "endarg extracting for $coutput (($evstrg)): $@";
#print STDERR ">call $coutput $cmd $arg< (($evstrg))\n";
$evstrg= "&${coutput}_do_${cmd}(\$arg)";
eval($evstrg);
length($@) && warn "endarg running ${coutput}_do_${cmd} (($evstrg)): $@";
}

View File

@@ -0,0 +1,842 @@
FFTW FREQUENTLY ASKED QUESTIONS WITH ANSWERS
14 Sep 2021
Matteo Frigo
Steven G. Johnson
<fftw@fftw.org>
This is the list of Frequently Asked Questions about FFTW, a collection of
fast C routines for computing the Discrete Fourier Transform in one or
more dimensions.
===============================================================================
Index
Section 1. Introduction and General Information
Q1.1 What is FFTW?
Q1.2 How do I obtain FFTW?
Q1.3 Is FFTW free software?
Q1.4 What is this about non-free licenses?
Q1.5 In the West? I thought MIT was in the East?
Section 2. Installing FFTW
Q2.1 Which systems does FFTW run on?
Q2.2 Does FFTW run on Windows?
Q2.3 My compiler has trouble with FFTW.
Q2.4 FFTW does not compile on Solaris, complaining about const.
Q2.5 What's the difference between --enable-3dnow and --enable-k7?
Q2.6 What's the difference between the fma and the non-fma versions?
Q2.7 Which language is FFTW written in?
Q2.8 Can I call FFTW from Fortran?
Q2.9 Can I call FFTW from C++?
Q2.10 Why isn't FFTW written in Fortran/C++?
Q2.11 How do I compile FFTW to run in single precision?
Q2.12 --enable-k7 does not work on x86-64
Section 3. Using FFTW
Q3.1 Why not support the FFTW 2 interface in FFTW 3?
Q3.2 Why do FFTW 3 plans encapsulate the input/output arrays and not ju
Q3.3 FFTW seems really slow.
Q3.4 FFTW slows down after repeated calls.
Q3.5 An FFTW routine is crashing when I call it.
Q3.6 My Fortran program crashes when calling FFTW.
Q3.7 FFTW gives results different from my old FFT.
Q3.8 FFTW gives different results between runs
Q3.9 Can I save FFTW's plans?
Q3.10 Why does your inverse transform return a scaled result?
Q3.11 How can I make FFTW put the origin (zero frequency) at the center
Q3.12 How do I FFT an image/audio file in *foobar* format?
Q3.13 My program does not link (on Unix).
Q3.14 I included your header, but linking still fails.
Q3.15 My program crashes, complaining about stack space.
Q3.16 FFTW seems to have a memory leak.
Q3.17 The output of FFTW's transform is all zeros.
Q3.18 How do I call FFTW from the Microsoft language du jour?
Q3.19 Can I compute only a subset of the DFT outputs?
Q3.20 Can I use FFTW's routines for in-place and out-of-place matrix tra
Section 4. Internals of FFTW
Q4.1 How does FFTW work?
Q4.2 Why is FFTW so fast?
Section 5. Known bugs
Q5.1 FFTW 1.1 crashes in rfftwnd on Linux.
Q5.2 The MPI transforms in FFTW 1.2 give incorrect results/leak memory.
Q5.3 The test programs in FFTW 1.2.1 fail when I change FFTW to use sin
Q5.4 The test program in FFTW 1.2.1 fails for n > 46340.
Q5.5 The threaded code fails on Linux Redhat 5.0
Q5.6 FFTW 2.0's rfftwnd fails for rank > 1 transforms with a final dime
Q5.7 FFTW 2.0's complex transforms give the wrong results with prime fa
Q5.8 FFTW 2.1.1's MPI test programs crash with MPICH.
Q5.9 FFTW 2.1.2's multi-threaded transforms don't work on AIX.
Q5.10 FFTW 2.1.2's complex transforms give incorrect results for large p
Q5.11 FFTW 2.1.3's multi-threaded transforms don't give any speedup on S
Q5.12 FFTW 2.1.3 crashes on AIX.
===============================================================================
Section 1. Introduction and General Information
Q1.1 What is FFTW?
Q1.2 How do I obtain FFTW?
Q1.3 Is FFTW free software?
Q1.4 What is this about non-free licenses?
Q1.5 In the West? I thought MIT was in the East?
-------------------------------------------------------------------------------
Question 1.1. What is FFTW?
FFTW is a free collection of fast C routines for computing the Discrete
Fourier Transform in one or more dimensions. It includes complex, real,
symmetric, and parallel transforms, and can handle arbitrary array sizes
efficiently. FFTW is typically faster than other publically-available FFT
implementations, and is even competitive with vendor-tuned libraries.
(See our web page for extensive benchmarks.) To achieve this performance,
FFTW uses novel code-generation and runtime self-optimization techniques
(along with many other tricks).
-------------------------------------------------------------------------------
Question 1.2. How do I obtain FFTW?
FFTW can be found at the FFTW web page. You can also retrieve it from
ftp.fftw.org in /pub/fftw.
-------------------------------------------------------------------------------
Question 1.3. Is FFTW free software?
Starting with version 1.3, FFTW is Free Software in the technical sense
defined by the Free Software Foundation (see Categories of Free and
Non-Free Software), and is distributed under the terms of the GNU General
Public License. Previous versions of FFTW were distributed without fee
for noncommercial use, but were not technically ``free.''
Non-free licenses for FFTW are also available that permit different terms
of use than the GPL.
-------------------------------------------------------------------------------
Question 1.4. What is this about non-free licenses?
The non-free licenses are for companies that wish to use FFTW in their
products but are unwilling to release their software under the GPL (which
would require them to release source code and allow free redistribution).
Such users can purchase an unlimited-use license from MIT. Contact us for
more details.
We could instead have released FFTW under the LGPL, or even disallowed
non-Free usage. Suffice it to say, however, that MIT owns the copyright
to FFTW and they only let us GPL it because we convinced them that it
would neither affect their licensing revenue nor irritate existing
licensees.
-------------------------------------------------------------------------------
Question 1.5. In the West? I thought MIT was in the East?
Not to an Italian. You could say that we're a Spaghetti Western (with
apologies to Sergio Leone).
===============================================================================
Section 2. Installing FFTW
Q2.1 Which systems does FFTW run on?
Q2.2 Does FFTW run on Windows?
Q2.3 My compiler has trouble with FFTW.
Q2.4 FFTW does not compile on Solaris, complaining about const.
Q2.5 What's the difference between --enable-3dnow and --enable-k7?
Q2.6 What's the difference between the fma and the non-fma versions?
Q2.7 Which language is FFTW written in?
Q2.8 Can I call FFTW from Fortran?
Q2.9 Can I call FFTW from C++?
Q2.10 Why isn't FFTW written in Fortran/C++?
Q2.11 How do I compile FFTW to run in single precision?
Q2.12 --enable-k7 does not work on x86-64
-------------------------------------------------------------------------------
Question 2.1. Which systems does FFTW run on?
FFTW is written in ANSI C, and should work on any system with a decent C
compiler. (See also Q2.2 `Does FFTW run on Windows?', Q2.3 `My compiler
has trouble with FFTW.'.) FFTW can also take advantage of certain
hardware-specific features, such as cycle counters and SIMD instructions,
but this is optional.
-------------------------------------------------------------------------------
Question 2.2. Does FFTW run on Windows?
Yes, many people have reported successfully using FFTW on Windows with
various compilers. FFTW was not developed on Windows, but the source code
is essentially straight ANSI C. See also the FFTW Windows installation
notes, Q2.3 `My compiler has trouble with FFTW.', and Q3.18 `How do I call
FFTW from the Microsoft language du jour?'.
-------------------------------------------------------------------------------
Question 2.3. My compiler has trouble with FFTW.
Complain fiercely to the vendor of the compiler.
We have successfully used gcc 3.2.x on x86 and PPC, a recent Compaq C
compiler for Alpha, version 6 of IBM's xlc compiler for AIX, Intel's icc
versions 5-7, and Sun WorkShop cc version 6.
FFTW is likely to push compilers to their limits, however, and several
compiler bugs have been exposed by FFTW. A partial list follows.
gcc 2.95.x for Solaris/SPARC produces incorrect code for the test program
(workaround: recompile the libbench2 directory with -O2).
NetBSD/macppc 1.6 comes with a gcc version that also miscompiles the test
program. (Please report a workaround if you know one.)
gcc 3.2.3 for ARM reportedly crashes during compilation. This bug is
reportedly fixed in later versions of gcc.
Versions 8.0 and 8.1 of Intel's icc falsely claim to be gcc, so you should
specify CC="icc -no-gcc"; this is automatic in FFTW 3.1. icc-8.0.066
reportely produces incorrect code for FFTW 2.1.5, but is fixed in version
8.1. icc-7.1 compiler build 20030402Z appears to produce incorrect
dependencies, causing the compilation to fail. icc-7.1 build 20030307Z
appears to work fine. (Use icc -V to check which build you have.) As of
2003/04/18, build 20030402Z appears not to be available any longer on
Intel's website, whereas the older build 20030307Z is available.
ranlib of GNU binutils 2.9.1 on Irix has been observed to corrupt the FFTW
libraries, causing a link failure when FFTW is compiled. Since ranlib is
completely superfluous on Irix, we suggest deleting it from your system
and replacing it with a symbolic link to /bin/echo.
If support for SIMD instructions is enabled in FFTW, further compiler
problems may appear:
gcc 3.4.[0123] for x86 produces incorrect SSE2 code for FFTW when -O2 (the
best choice for FFTW) is used, causing FFTW to crash (make check crashes).
This bug is fixed in gcc 3.4.4. On x86_64 (amd64/em64t), gcc 3.4.4
reportedly still has a similar problem, but this is fixed as of gcc 3.4.6.
gcc-3.2 for x86 produces incorrect SIMD code if -O3 is used. The same
compiler produces incorrect SIMD code if no optimization is used, too.
When using gcc-3.2, it is a good idea not to change the default CFLAGS
selected by the configure script.
Some 3.0.x and 3.1.x versions of gcc on x86 may crash. gcc so-called 2.96
shipping with RedHat 7.3 crashes when compiling SIMD code. In both cases,
please upgrade to gcc-3.2 or later.
Intel's icc 6.0 misaligns SSE constants, but FFTW has a workaround. icc
8.x fails to compile FFTW 3.0.x because it falsely claims to be gcc; we
believe this to be a bug in icc, but FFTW 3.1 has a workaround.
Visual C++ 2003 reportedly produces incorrect code for SSE/SSE2 when
compiling FFTW. This bug was reportedly fixed in VC++ 2005;
alternatively, you could switch to the Intel compiler. VC++ 6.0 also
reportedly produces incorrect code for the file reodft11e-r2hc-odd.c
unless optimizations are disabled for that file.
gcc 2.95 on MacOS X miscompiles AltiVec code (fixed in later versions).
gcc 3.2.x miscompiles AltiVec permutations, but FFTW has a workaround.
gcc 4.0.1 on MacOS for Intel crashes when compiling FFTW; a workaround is
to compile one file without optimization: cd kernel; make CFLAGS=" "
trig.lo.
gcc 4.1.1 reportedly crashes when compiling FFTW for MIPS; the workaround
is to compile the file it crashes on (t2_64.c) with a lower optimization
level.
gcc versions 4.1.2 to 4.2.0 for x86 reportedly miscompile FFTW 3.1's test
program, causing make check to crash (gcc bug #26528). The bug was
reportedly fixed in gcc version 4.2.1 and later. A workaround is to
compile libbench2/verify-lib.c without optimization.
-------------------------------------------------------------------------------
Question 2.4. FFTW does not compile on Solaris, complaining about const.
We know that at least on Solaris 2.5.x with Sun's compilers 4.2 you might
get error messages from make such as
"./fftw.h", line 88: warning: const is a keyword in ANSI C
This is the case when the configure script reports that const does not
work:
checking for working const... (cached) no
You should be aware that Solaris comes with two compilers, namely,
/opt/SUNWspro/SC4.2/bin/cc and /usr/ucb/cc. The latter compiler is
non-ANSI. Indeed, it is a perverse shell script that calls the real
compiler in non-ANSI mode. In order to compile FFTW, change your path so
that the right cc is used.
To know whether your compiler is the right one, type cc -V. If the
compiler prints ``ucbcc'', as in
ucbcc: WorkShop Compilers 4.2 30 Oct 1996 C 4.2
then the compiler is wrong. The right message is something like
cc: WorkShop Compilers 4.2 30 Oct 1996 C 4.2
-------------------------------------------------------------------------------
Question 2.5. What's the difference between --enable-3dnow and --enable-k7?
--enable-k7 enables 3DNow! instructions on K7 processors (AMD Athlon and
its variants). K7 support is provided by assembly routines generated by a
special purpose compiler. As of fftw-3.2, --enable-k7 is no longer
supported.
--enable-3dnow enables generic 3DNow! support using gcc builtin functions.
This works on earlier AMD processors, but it is not as fast as our special
assembly routines. As of fftw-3.1, --enable-3dnow is no longer supported.
-------------------------------------------------------------------------------
Question 2.6. What's the difference between the fma and the non-fma versions?
The fma version tries to exploit the fused multiply-add instructions
implemented in many processors such as PowerPC, ia-64, and MIPS. The two
FFTW packages are otherwise identical. In FFTW 3.1, the fma and non-fma
versions were merged together into a single package, and the configure
script attempts to automatically guess which version to use.
The FFTW 3.1 configure script enables fma by default on PowerPC, Itanium,
and PA-RISC, and disables it otherwise. You can force one or the other by
using the --enable-fma or --disable-fma flag for configure.
Definitely use fma if you have a PowerPC-based system with gcc (or IBM
xlc). This includes all GNU/Linux systems for PowerPC and the older
PowerPC-based MacOS systems. Also use it on PA-RISC and Itanium with the
HP/UX compiler.
Definitely do not use the fma version if you have an ia-32 processor
(Intel, AMD, MacOS on Intel, etcetera).
For other architectures/compilers, the situation is not so clear. For
example, ia-64 has the fma instruction, but gcc-3.2 appears not to exploit
it correctly. Other compilers may do the right thing, but we have not
tried them. Please send us your feedback so that we can update this FAQ
entry.
-------------------------------------------------------------------------------
Question 2.7. Which language is FFTW written in?
FFTW is written in ANSI C. Most of the code, however, was automatically
generated by a program called genfft, written in the Objective Caml
dialect of ML. You do not need to know ML or to have an Objective Caml
compiler in order to use FFTW.
genfft is provided with the FFTW sources, which means that you can play
with the code generator if you want. In this case, you need a working
Objective Caml system. Objective Caml is available from the Caml web
page.
-------------------------------------------------------------------------------
Question 2.8. Can I call FFTW from Fortran?
Yes, FFTW (versions 1.3 and higher) contains a Fortran-callable interface,
documented in the FFTW manual.
By default, FFTW configures its Fortran interface to work with the first
compiler it finds, e.g. g77. To configure for a different, incompatible
Fortran compiler foobar, use ./configure F77=foobar when installing FFTW.
(In the case of g77, however, FFTW 3.x also includes an extra set of
Fortran-callable routines with one less underscore at the end of
identifiers, which should cover most other Fortran compilers on Linux at
least.)
-------------------------------------------------------------------------------
Question 2.9. Can I call FFTW from C++?
Most definitely. FFTW should compile and/or link under any C++ compiler.
Moreover, it is likely that the C++ <complex> template class is
bit-compatible with FFTW's complex-number format (see the FFTW manual for
more details).
-------------------------------------------------------------------------------
Question 2.10. Why isn't FFTW written in Fortran/C++?
Because we don't like those languages, and neither approaches the
portability of C.
-------------------------------------------------------------------------------
Question 2.11. How do I compile FFTW to run in single precision?
On a Unix system: configure --enable-float. On a non-Unix system: edit
config.h to #define the symbol FFTW_SINGLE (for FFTW 3.x). In both cases,
you must then recompile FFTW. In FFTW 3, all FFTW identifiers will then
begin with fftwf_ instead of fftw_.
-------------------------------------------------------------------------------
Question 2.12. --enable-k7 does not work on x86-64
Support for --enable-k7 was discontinued in fftw-3.2.
The fftw-3.1 release supports --enable-k7. This option only works on
32-bit x86 machines that implement 3DNow!, including the AMD Athlon and
the AMD Opteron in 32-bit mode. --enable-k7 does not work on AMD Opteron
in 64-bit mode. Use --enable-sse for x86-64 machines.
FFTW supports 3DNow! by means of assembly code generated by a
special-purpose compiler. It is hard to produce assembly code that works
in both 32-bit and 64-bit mode.
===============================================================================
Section 3. Using FFTW
Q3.1 Why not support the FFTW 2 interface in FFTW 3?
Q3.2 Why do FFTW 3 plans encapsulate the input/output arrays and not ju
Q3.3 FFTW seems really slow.
Q3.4 FFTW slows down after repeated calls.
Q3.5 An FFTW routine is crashing when I call it.
Q3.6 My Fortran program crashes when calling FFTW.
Q3.7 FFTW gives results different from my old FFT.
Q3.8 FFTW gives different results between runs
Q3.9 Can I save FFTW's plans?
Q3.10 Why does your inverse transform return a scaled result?
Q3.11 How can I make FFTW put the origin (zero frequency) at the center
Q3.12 How do I FFT an image/audio file in *foobar* format?
Q3.13 My program does not link (on Unix).
Q3.14 I included your header, but linking still fails.
Q3.15 My program crashes, complaining about stack space.
Q3.16 FFTW seems to have a memory leak.
Q3.17 The output of FFTW's transform is all zeros.
Q3.18 How do I call FFTW from the Microsoft language du jour?
Q3.19 Can I compute only a subset of the DFT outputs?
Q3.20 Can I use FFTW's routines for in-place and out-of-place matrix tra
-------------------------------------------------------------------------------
Question 3.1. Why not support the FFTW 2 interface in FFTW 3?
FFTW 3 has semantics incompatible with earlier versions: its plans can
only be used for a given stride, multiplicity, and other characteristics
of the input and output arrays; these stronger semantics are necessary for
performance reasons. Thus, it is impossible to efficiently emulate the
older interface (whose plans can be used for any transform of the same
size). We believe that it should be possible to upgrade most programs
without any difficulty, however.
-------------------------------------------------------------------------------
Question 3.2. Why do FFTW 3 plans encapsulate the input/output arrays and not just the algorithm?
There are several reasons:
* It was important for performance reasons that the plan be specific to
array characteristics like the stride (and alignment, for SIMD), and
requiring that the user maintain these invariants is error prone.
* In most high-performance applications, as far as we can tell, you are
usually transforming the same array over and over, so FFTW's semantics
should not be a burden.
* If you need to transform another array of the same size, creating a new
plan once the first exists is a cheap operation.
* If you need to transform many arrays of the same size at once, you
should really use the plan_many routines in FFTW's "advanced" interface.
* If the abovementioned array characteristics are the same, you are
willing to pay close attention to the documentation, and you really need
to, we provide a "new-array execution" interface to apply a plan to a
new array.
-------------------------------------------------------------------------------
Question 3.3. FFTW seems really slow.
You are probably recreating the plan before every transform, rather than
creating it once and reusing it for all transforms of the same size. FFTW
is designed to be used in the following way:
* First, you create a plan. This will take several seconds.
* Then, you reuse the plan many times to perform FFTs. These are fast.
If you don't need to compute many transforms and the time for the planner
is significant, you have two options. First, you can use the
FFTW_ESTIMATE option in the planner, which uses heuristics instead of
runtime measurements and produces a good plan in a short time. Second,
you can use the wisdom feature to precompute the plan; see Q3.9 `Can I
save FFTW's plans?'
-------------------------------------------------------------------------------
Question 3.4. FFTW slows down after repeated calls.
Probably, NaNs or similar are creeping into your data, and the slowdown is
due to the resulting floating-point exceptions. For example, be aware
that repeatedly FFTing the same array is a diverging process (because FFTW
computes the unnormalized transform).
-------------------------------------------------------------------------------
Question 3.5. An FFTW routine is crashing when I call it.
Did the FFTW test programs pass (make check, or cd tests; make bigcheck if
you want to be paranoid)? If so, you almost certainly have a bug in your
own code. For example, you could be passing invalid arguments (such as
wrongly-sized arrays) to FFTW, or you could simply have memory corruption
elsewhere in your program that causes random crashes later on. Please
don't complain to us unless you can come up with a minimal self-contained
program (preferably under 30 lines) that illustrates the problem.
-------------------------------------------------------------------------------
Question 3.6. My Fortran program crashes when calling FFTW.
As described in the manual, on 64-bit machines you must store the plans in
variables large enough to hold a pointer, for example integer*8. We
recommend using integer*8 on 32-bit machines as well, to simplify porting.
-------------------------------------------------------------------------------
Question 3.7. FFTW gives results different from my old FFT.
People follow many different conventions for the DFT, and you should be
sure to know the ones that we use (described in the FFTW manual). In
particular, you should be aware that the FFTW_FORWARD/FFTW_BACKWARD
directions correspond to signs of -1/+1 in the exponent of the DFT
definition. (*Numerical Recipes* uses the opposite convention.)
You should also know that we compute an unnormalized transform. In
contrast, Matlab is an example of program that computes a normalized
transform. See Q3.10 `Why does your inverse transform return a scaled
result?'.
Finally, note that floating-point arithmetic is not exact, so different
FFT algorithms will give slightly different results (on the order of the
numerical accuracy; typically a fractional difference of 1e-15 or so in
double precision).
-------------------------------------------------------------------------------
Question 3.8. FFTW gives different results between runs
If you use FFTW_MEASURE or FFTW_PATIENT mode, then the algorithm FFTW
employs is not deterministic: it depends on runtime performance
measurements. This will cause the results to vary slightly from run to
run. However, the differences should be slight, on the order of the
floating-point precision, and therefore should have no practical impact on
most applications.
If you use saved plans (wisdom) or FFTW_ESTIMATE mode, however, then the
algorithm is deterministic and the results should be identical between
runs.
-------------------------------------------------------------------------------
Question 3.9. Can I save FFTW's plans?
Yes. Starting with version 1.2, FFTW provides the wisdom mechanism for
saving plans; see the FFTW manual.
-------------------------------------------------------------------------------
Question 3.10. Why does your inverse transform return a scaled result?
Computing the forward transform followed by the backward transform (or
vice versa) yields the original array scaled by the size of the array.
(For multi-dimensional transforms, the size of the array is the product of
the dimensions.) We could, instead, have chosen a normalization that
would have returned the unscaled array. Or, to accomodate the many
conventions in this matter, the transform routines could have accepted a
"scale factor" parameter. We did not do this, however, for two reasons.
First, we didn't want to sacrifice performance in the common case where
the scale factor is 1. Second, in real applications the FFT is followed or
preceded by some computation on the data, into which the scale factor can
typically be absorbed at little or no cost.
-------------------------------------------------------------------------------
Question 3.11. How can I make FFTW put the origin (zero frequency) at the center of its output?
For human viewing of a spectrum, it is often convenient to put the origin
in frequency space at the center of the output array, rather than in the
zero-th element (the default in FFTW). If all of the dimensions of your
array are even, you can accomplish this by simply multiplying each element
of the input array by (-1)^(i + j + ...), where i, j, etcetera are the
indices of the element. (This trick is a general property of the DFT, and
is not specific to FFTW.)
-------------------------------------------------------------------------------
Question 3.12. How do I FFT an image/audio file in *foobar* format?
FFTW performs an FFT on an array of floating-point values. You can
certainly use it to compute the transform of an image or audio stream, but
you are responsible for figuring out your data format and converting it to
the form FFTW requires.
-------------------------------------------------------------------------------
Question 3.13. My program does not link (on Unix).
The libraries must be listed in the correct order (-lfftw3 -lm for FFTW
3.x) and *after* your program sources/objects. (The general rule is that
if *A* uses *B*, then *A* must be listed before *B* in the link command.).
-------------------------------------------------------------------------------
Question 3.14. I included your header, but linking still fails.
You're a C++ programmer, aren't you? You have to compile the FFTW library
and link it into your program, not just #include <fftw3.h>. (Yes, this is
really a FAQ.)
-------------------------------------------------------------------------------
Question 3.15. My program crashes, complaining about stack space.
You cannot declare large arrays with automatic storage (e.g. via
fftw_complex array[N]); you should use fftw_malloc (or equivalent) to
allocate the arrays you want to transform if they are larger than a few
hundred elements.
-------------------------------------------------------------------------------
Question 3.16. FFTW seems to have a memory leak.
After you create a plan, FFTW caches the information required to quickly
recreate the plan. (See Q3.9 `Can I save FFTW's plans?') It also
maintains a small amount of other persistent memory. You can deallocate
all of FFTW's internally allocated memory, if you wish, by calling
fftw_cleanup(), as documented in the manual.
-------------------------------------------------------------------------------
Question 3.17. The output of FFTW's transform is all zeros.
You should initialize your input array *after* creating the plan, unless
you use FFTW_ESTIMATE: planning with FFTW_MEASURE or FFTW_PATIENT
overwrites the input/output arrays, as described in the manual.
-------------------------------------------------------------------------------
Question 3.18. How do I call FFTW from the Microsoft language du jour?
Please *do not* ask us Windows-specific questions. We do not use Windows.
We know nothing about Visual Basic, Visual C++, or .NET. Please find the
appropriate Usenet discussion group and ask your question there. See also
Q2.2 `Does FFTW run on Windows?'.
-------------------------------------------------------------------------------
Question 3.19. Can I compute only a subset of the DFT outputs?
In general, no, an FFT intrinsically computes all outputs from all inputs.
In principle, there is something called a *pruned FFT* that can do what
you want, but to compute K outputs out of N the complexity is in general
O(N log K) instead of O(N log N), thus saving only a small additive factor
in the log. (The same argument holds if you instead have only K nonzero
inputs.)
There are some specific cases in which you can get the O(N log K)
performance benefits easily, however, by combining a few ordinary FFTs.
In particular, the case where you want the first K outputs, where K
divides N, can be handled by performing N/K transforms of size K and then
summing the outputs multiplied by appropriate phase factors. For more
details, see pruned FFTs with FFTW.
There are also some algorithms that compute pruned transforms
*approximately*, but they are beyond the scope of this FAQ.
-------------------------------------------------------------------------------
Question 3.20. Can I use FFTW's routines for in-place and out-of-place matrix transposition?
You can use the FFTW guru interface to create a rank-0 transform of vector
rank 2 where the vector strides are transposed. (A rank-0 transform is
equivalent to a 1D transform of size 1, which. just copies the input into
the output.) Specifying the same location for the input and output makes
the transpose in-place.
For double-valued data stored in row-major format, plan creation looks
like this:
fftw_plan plan_transpose(int rows, int cols, double *in, double *out)
{
const unsigned flags = FFTW_ESTIMATE; /* other flags are possible */
fftw_iodim howmany_dims[2];
howmany_dims[0].n = rows;
howmany_dims[0].is = cols;
howmany_dims[0].os = 1;
howmany_dims[1].n = cols;
howmany_dims[1].is = 1;
howmany_dims[1].os = rows;
return fftw_plan_guru_r2r(/*rank=*/ 0, /*dims=*/ NULL,
/*howmany_rank=*/ 2, howmany_dims,
in, out, /*kind=*/ NULL, flags);
}
(This entry was written by Rhys Ulerich.)
===============================================================================
Section 4. Internals of FFTW
Q4.1 How does FFTW work?
Q4.2 Why is FFTW so fast?
-------------------------------------------------------------------------------
Question 4.1. How does FFTW work?
The innovation (if it can be so called) in FFTW consists in having a
variety of composable *solvers*, representing different FFT algorithms and
implementation strategies, whose combination into a particular *plan* for
a given size can be determined at runtime according to the characteristics
of your machine/compiler. This peculiar software architecture allows FFTW
to adapt itself to almost any machine.
For more details (albeit somewhat outdated), see the paper "FFTW: An
Adaptive Software Architecture for the FFT", by M. Frigo and S. G.
Johnson, *Proc. ICASSP* 3, 1381 (1998), also available at the FFTW web
page.
-------------------------------------------------------------------------------
Question 4.2. Why is FFTW so fast?
This is a complex question, and there is no simple answer. In fact, the
authors do not fully know the answer, either. In addition to many small
performance hacks throughout FFTW, there are three general reasons for
FFTW's speed.
* FFTW uses a variety of FFT algorithms and implementation styles that
can be arbitrarily composed to adapt itself to a machine. See Q4.1 `How
does FFTW work?'.
* FFTW uses a code generator to produce highly-optimized routines for
computing small transforms.
* FFTW uses explicit divide-and-conquer to take advantage of the memory
hierarchy.
For more details (albeit somewhat outdated), see the paper "FFTW: An
Adaptive Software Architecture for the FFT", by M. Frigo and S. G.
Johnson, *Proc. ICASSP* 3, 1381 (1998), available along with other
references at the FFTW web page.
===============================================================================
Section 5. Known bugs
Q5.1 FFTW 1.1 crashes in rfftwnd on Linux.
Q5.2 The MPI transforms in FFTW 1.2 give incorrect results/leak memory.
Q5.3 The test programs in FFTW 1.2.1 fail when I change FFTW to use sin
Q5.4 The test program in FFTW 1.2.1 fails for n > 46340.
Q5.5 The threaded code fails on Linux Redhat 5.0
Q5.6 FFTW 2.0's rfftwnd fails for rank > 1 transforms with a final dime
Q5.7 FFTW 2.0's complex transforms give the wrong results with prime fa
Q5.8 FFTW 2.1.1's MPI test programs crash with MPICH.
Q5.9 FFTW 2.1.2's multi-threaded transforms don't work on AIX.
Q5.10 FFTW 2.1.2's complex transforms give incorrect results for large p
Q5.11 FFTW 2.1.3's multi-threaded transforms don't give any speedup on S
Q5.12 FFTW 2.1.3 crashes on AIX.
-------------------------------------------------------------------------------
Question 5.1. FFTW 1.1 crashes in rfftwnd on Linux.
This bug was fixed in FFTW 1.2. There was a bug in rfftwnd causing an
incorrect amount of memory to be allocated. The bug showed up in Linux
with libc-5.3.12 (and nowhere else that we know of).
-------------------------------------------------------------------------------
Question 5.2. The MPI transforms in FFTW 1.2 give incorrect results/leak memory.
These bugs were corrected in FFTW 1.2.1. The MPI transforms (really, just
the transpose routines) in FFTW 1.2 had bugs that could cause errors in
some situations.
-------------------------------------------------------------------------------
Question 5.3. The test programs in FFTW 1.2.1 fail when I change FFTW to use single precision.
This bug was fixed in FFTW 1.3. (Older versions of FFTW did work in
single precision, but the test programs didn't--the error tolerances in
the tests were set for double precision.)
-------------------------------------------------------------------------------
Question 5.4. The test program in FFTW 1.2.1 fails for n > 46340.
This bug was fixed in FFTW 1.3. FFTW 1.2.1 produced the right answer, but
the test program was wrong. For large n, n*n in the naive transform that
we used for comparison overflows 32 bit integer precision, breaking the
test.
-------------------------------------------------------------------------------
Question 5.5. The threaded code fails on Linux Redhat 5.0
We had problems with glibc-2.0.5. The code should work with glibc-2.0.7.
-------------------------------------------------------------------------------
Question 5.6. FFTW 2.0's rfftwnd fails for rank > 1 transforms with a final dimension >= 65536.
This bug was fixed in FFTW 2.0.1. (There was a 32-bit integer overflow
due to a poorly-parenthesized expression.)
-------------------------------------------------------------------------------
Question 5.7. FFTW 2.0's complex transforms give the wrong results with prime factors 17 to 97.
There was a bug in the complex transforms that could cause incorrect
results under (hopefully rare) circumstances for lengths with
intermediate-size prime factors (17-97). This bug was fixed in FFTW
2.1.1.
-------------------------------------------------------------------------------
Question 5.8. FFTW 2.1.1's MPI test programs crash with MPICH.
This bug was fixed in FFTW 2.1.2. The 2.1/2.1.1 MPI test programs crashed
when using the MPICH implementation of MPI with the ch_p4 device (TCP/IP);
the transforms themselves worked fine.
-------------------------------------------------------------------------------
Question 5.9. FFTW 2.1.2's multi-threaded transforms don't work on AIX.
This bug was fixed in FFTW 2.1.3. The multi-threaded transforms in
previous versions didn't work with AIX's pthreads implementation, which
idiosyncratically creates threads in detached (non-joinable) mode by
default.
-------------------------------------------------------------------------------
Question 5.10. FFTW 2.1.2's complex transforms give incorrect results for large prime sizes.
This bug was fixed in FFTW 2.1.3. FFTW's complex-transform algorithm for
prime sizes (in versions 2.0 to 2.1.2) had an integer overflow problem
that caused incorrect results for many primes greater than 32768 (on
32-bit machines). (Sizes without large prime factors are not affected.)
-------------------------------------------------------------------------------
Question 5.11. FFTW 2.1.3's multi-threaded transforms don't give any speedup on Solaris.
This bug was fixed in FFTW 2.1.4. (By default, Solaris creates threads
that do not parallelize over multiple processors, so one has to request
the proper behavior specifically.)
-------------------------------------------------------------------------------
Question 5.12. FFTW 2.1.3 crashes on AIX.
The FFTW 2.1.3 configure script picked incorrect compiler flags for the
xlc compiler on newer IBM processors. This is fixed in FFTW 2.1.4.

View File

@@ -0,0 +1,708 @@
\comment This is the source for the FFTW FAQ list, in
\comment the Bizarre Format With No Name. It is turned into Lout
\comment input, HTML, plain ASCII and an Info document by a Perl script.
\comment
\comment The format and scripts come from the Linux FAQ, by
\comment Ian Jackson.
\set brieftitle FFTW FAQ
\set author <A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
\set authormail fftw@fftw.org
\set title FFTW Frequently Asked Questions with Answers
\set copyholder Matteo Frigo and Massachusetts Institute of Technology
\call-html startup html.refs2
\copyto ASCII
FFTW FREQUENTLY ASKED QUESTIONS WITH ANSWERS
`date '+%d %h %Y'`
Matteo Frigo
Steven G. Johnson
<fftw@fftw.org>
\endcopy
\copyto INFO
INFO-DIR-SECTION Development
START-INFO-DIR-ENTRY
* FFTW FAQ: (fftw-faq). FFTW Frequently Asked Questions with Answers.
END-INFO-DIR-ENTRY

File: $prefix.info, Node: Top, Next: Question 1.1, Up: (dir)
FFTW FREQUENTLY ASKED QUESTIONS WITH ANSWERS
`date '+%d %h %Y'`
Matteo Frigo
Steven G. Johnson
<fftw@fftw.org>
\endcopy
This is the list of Frequently Asked Questions about FFTW, a
collection of fast C routines for computing the Discrete Fourier
Transform in one or more dimensions.
\section Index
\index
\comment ######################################################################
\section Introduction and General Information
\question 26aug:whatisfftw What is FFTW?
FFTW is a free collection of fast C routines for computing the
Discrete Fourier Transform in one or more dimensions. It includes
complex, real, symmetric, and parallel transforms, and can handle
arbitrary array sizes efficiently. FFTW is typically faster than
other publically-available FFT implementations, and is even
competitive with vendor-tuned libraries. (See our web page for
extensive benchmarks.) To achieve this performance, FFTW uses novel
code-generation and runtime self-optimization techniques (along with
many other tricks).
\question 26aug:whereisfftw How do I obtain FFTW?
FFTW can be found at \docref{the FFTW web page\}. You can also
retrieve it from \ftpon ftp.fftw.org in \ftpin /pub/fftw.
\question 26aug:isfftwfree Is FFTW free software?
Starting with version 1.3, FFTW is Free Software in the technical
sense defined by the Free Software Foundation (see \docref{Categories
of Free and Non-Free Software\}), and is distributed under the terms
of the GNU General Public License. Previous versions of FFTW were
distributed without fee for noncommercial use, but were not
technically ``free.''
Non-free licenses for FFTW are also available that permit different
terms of use than the GPL.
\question 10apr:nonfree What is this about non-free licenses?
The non-free licenses are for companies that wish to use FFTW in their
products but are unwilling to release their software under the GPL
(which would require them to release source code and allow free
redistribution). Such users can purchase an unlimited-use license
from MIT. Contact us for more details.
We could instead have released FFTW under the LGPL, or even disallowed
non-Free usage. Suffice it to say, however, that MIT owns the
copyright to FFTW and they only let us GPL it because we convinced
them that it would neither affect their licensing revenue nor irritate
existing licensees.
\question 24oct:west In the West? I thought MIT was in the East?
Not to an Italian. You could say that we're a Spaghetti Western
(with apologies to Sergio Leone).
\comment ######################################################################
\section Installing FFTW
\question 26aug:systems Which systems does FFTW run on?
FFTW is written in ANSI C, and should work on any system with a decent
C compiler. (See also \qref runOnWindows, \qref compilerCrashes.)
FFTW can also take advantage of certain hardware-specific features,
such as cycle counters and SIMD instructions, but this is optional.
\question 26aug:runOnWindows Does FFTW run on Windows?
Yes, many people have reported successfully using FFTW on Windows with
various compilers. FFTW was not developed on Windows, but the source
code is essentially straight ANSI C. See also the \docref{FFTW
Windows installation notes\}, \qref compilerCrashes, and \qref
vbetalia.
\question 26aug:compilerCrashes My compiler has trouble with FFTW.
Complain fiercely to the vendor of the compiler.
We have successfully used \courier{gcc\} 3.2.x on x86 and PPC, a
recent Compaq C compiler for Alpha, version 6 of IBM's \courier{xlc\}
compiler for AIX, Intel's \courier{icc\} versions 5-7, and Sun
WorkShop \courier{cc\} version 6.
FFTW is likely to push compilers to their limits, however, and several
compiler bugs have been exposed by FFTW. A partial list follows.
\courier{gcc\} 2.95.x for Solaris/SPARC produces incorrect code for
the test program (workaround: recompile the \courier{libbench2\}
directory with \courier{-O2\}).
NetBSD/macppc 1.6 comes with a \courier{gcc\} version that also
miscompiles the test program. (Please report a workaround if you know
one.)
\courier{gcc\} 3.2.3 for ARM reportedly crashes during compilation.
This bug is reportedly fixed in later versions of \courier{gcc\}.
Versions 8.0 and 8.1 of Intel's \courier{icc\} falsely claim to be
\courier{gcc\}, so you should specify \courier{CC="icc -no-gcc"\};
this is automatic in FFTW 3.1. \courier{icc-8.0.066\} reportely
produces incorrect code for FFTW 2.1.5, but is fixed in version 8.1.
\courier{icc-7.1\} compiler build 20030402Z appears to produce
incorrect dependencies, causing the compilation to fail.
\courier{icc-7.1\} build 20030307Z appears to work fine. (Use
\courier{icc -V\} to check which build you have.) As of 2003/04/18,
build 20030402Z appears not to be available any longer on Intel's
website, whereas the older build 20030307Z is available.
\courier{ranlib\} of GNU \courier{binutils\} 2.9.1 on Irix has been
observed to corrupt the FFTW libraries, causing a link failure when
FFTW is compiled. Since \courier{ranlib\} is completely superfluous
on Irix, we suggest deleting it from your system and replacing it with
a symbolic link to \courier{/bin/echo\}.
If support for SIMD instructions is enabled in FFTW, further compiler
problems may appear:
\courier{gcc\} 3.4.[0123] for x86 produces incorrect SSE2 code for
FFTW when \courier{-O2\} (the best choice for FFTW) is used, causing
FFTW to crash (\courier{make check\} crashes). This bug is fixed in
\courier{gcc\} 3.4.4. On x86_64 (amd64/em64t), \courier{gcc\} 3.4.4
reportedly still has a similar problem, but this is fixed as of
\courier{gcc\} 3.4.6.
\courier{gcc-3.2\} for x86 produces incorrect SIMD code if
\courier{-O3\} is used. The same compiler produces incorrect SIMD
code if no optimization is used, too. When using \courier{gcc-3.2\},
it is a good idea not to change the default \courier{CFLAGS\} selected
by the \courier{configure\} script.
Some 3.0.x and 3.1.x versions of \courier{gcc\} on \courier{x86\} may
crash. \courier{gcc\} so-called 2.96 shipping with RedHat 7.3 crashes
when compiling SIMD code. In both cases, please upgrade to
\courier{gcc-3.2\} or later.
Intel's \courier{icc\} 6.0 misaligns SSE constants, but FFTW has a
workaround. \courier{icc\} 8.x fails to compile FFTW 3.0.x because it
falsely claims to be \courier{gcc\}; we believe this to be a bug in
\courier{icc\}, but FFTW 3.1 has a workaround.
Visual C++ 2003 reportedly produces incorrect code for SSE/SSE2 when
compiling FFTW. This bug was reportedly fixed in VC++ 2005;
alternatively, you could switch to the Intel compiler. VC++ 6.0 also
reportedly produces incorrect code for the file
\courier{reodft11e-r2hc-odd.c\} unless optimizations are disabled for
that file.
\courier{gcc\} 2.95 on MacOS X miscompiles AltiVec code (fixed in
later versions). \courier{gcc\} 3.2.x miscompiles AltiVec
permutations, but FFTW has a workaround. \courier{gcc\} 4.0.1 on
MacOS for Intel crashes when compiling FFTW; a workaround is to
compile one file without optimization: \courier{cd kernel; make
CFLAGS=" " trig.lo\}.
\courier{gcc\} 4.1.1 reportedly crashes when compiling FFTW for MIPS;
the workaround is to compile the file it crashes on
(\courier{t2_64.c\}) with a lower optimization level.
\courier{gcc\} versions 4.1.2 to 4.2.0 for x86 reportedly miscompile
FFTW 3.1's test program, causing \courier{make check\} to crash
(\courier{gcc\} bug #26528). The bug was reportedly fixed in
\courier{gcc\} version 4.2.1 and later. A workaround is to compile
\courier{libbench2/verify-lib.c\} without optimization.
\question 26aug:solarisSucks FFTW does not compile on Solaris, complaining about \courier{const\}.
We know that at least on Solaris 2.5.x with Sun's compilers 4.2 you
might get error messages from \courier{make\} such as
\courier{"./fftw.h", line 88: warning: const is a keyword in ANSI C\}
This is the case when the \courier{configure\} script reports that
\courier{const\} does not work:
\courier{checking for working const... (cached) no\}
You should be aware that Solaris comes with two compilers, namely,
\courier{/opt/SUNWspro/SC4.2/bin/cc\} and \courier{/usr/ucb/cc\}. The
latter compiler is non-ANSI. Indeed, it is a perverse shell script
that calls the real compiler in non-ANSI mode. In order
to compile FFTW, change your path so that the right \courier{cc\}
is used.
To know whether your compiler is the right one, type
\courier{cc -V\}. If the compiler prints ``\courier{ucbcc\}'',
as in
\courier{ucbcc: WorkShop Compilers 4.2 30 Oct 1996 C 4.2\}
then the compiler is wrong. The right message is something like
\courier{cc: WorkShop Compilers 4.2 30 Oct 1996 C 4.2\}
\question 19mar:3dnow What's the difference between \courier{--enable-3dnow\} and \courier{--enable-k7\}?
\courier{--enable-k7\} enables 3DNow! instructions on K7 processors
(AMD Athlon and its variants). K7 support is provided by assembly
routines generated by a special purpose compiler.
As of fftw-3.2, --enable-k7 is no longer supported.
\courier{--enable-3dnow\} enables generic 3DNow! support using
\courier{gcc\} builtin functions. This works on earlier AMD
processors, but it is not as fast as our special assembly routines.
As of fftw-3.1, --enable-3dnow is no longer supported.
\question 18apr:fma What's the difference between the fma and the non-fma versions?
The fma version tries to exploit the fused multiply-add instructions
implemented in many processors such as PowerPC, ia-64, and MIPS. The
two FFTW packages are otherwise identical. In FFTW 3.1, the fma and
non-fma versions were merged together into a single package, and the
\courier{configure\} script attempts to automatically guess which
version to use.
The FFTW 3.1 \courier{configure\} script enables fma by default on
PowerPC, Itanium, and PA-RISC, and disables it otherwise. You can
force one or the other by using the \courier{--enable-fma\} or
\courier{--disable-fma\} flag for \courier{configure\}.
Definitely use fma if you have a PowerPC-based system with
\courier{gcc\} (or IBM \courier{xlc\}). This includes all GNU/Linux
systems for PowerPC and the older PowerPC-based MacOS systems. Also
use it on PA-RISC and Itanium with the HP/UX compiler.
Definitely do not use the fma version if you have an ia-32 processor
(Intel, AMD, MacOS on Intel, etcetera).
For other architectures/compilers, the situation is not so clear. For
example, ia-64 has the fma instruction, but \courier{gcc-3.2\} appears
not to exploit it correctly. Other compilers may do the right thing,
but we have not tried them. Please send us your feedback so that we
can update this FAQ entry.
\question 26aug:languages Which language is FFTW written in?
FFTW is written in ANSI C. Most of the code, however, was
automatically generated by a program called \courier{genfft\}, written
in the Objective Caml dialect of ML. You do not need to know ML or to
have an Objective Caml compiler in order to use FFTW.
\courier{genfft\} is provided with the FFTW sources, which means that
you can play with the code generator if you want. In this case, you
need a working Objective Caml system. Objective Caml is available
from \docref{the Caml web page\}.
\question 26aug:fortran Can I call FFTW from Fortran?
Yes, FFTW (versions 1.3 and higher) contains a Fortran-callable
interface, documented in the FFTW manual.
By default, FFTW configures its Fortran interface to work with the
first compiler it finds, e.g. \courier{g77\}. To configure for a
different, incompatible Fortran compiler \courier{foobar\}, use
\courier{./configure F77=foobar\} when installing FFTW. (In the case
of \courier{g77\}, however, FFTW 3.x also includes an extra set of
Fortran-callable routines with one less underscore at the end of
identifiers, which should cover most other Fortran compilers on Linux
at least.)
\question 26aug:cplusplus Can I call FFTW from C++?
Most definitely. FFTW should compile and/or link under any C++
compiler. Moreover, it is likely that the C++ \courier{<complex>\}
template class is bit-compatible with FFTW's complex-number format
(see the FFTW manual for more details).
\question 26aug:whynotfortran Why isn't FFTW written in Fortran/C++?
Because we don't like those languages, and neither approaches the
portability of C.
\question 29mar:singleprec How do I compile FFTW to run in single precision?
On a Unix system: \courier{configure --enable-float\}. On a non-Unix
system: edit \courier{config.h\} to \courier{#define\} the symbol
\courier{FFTW_SINGLE\} (for FFTW 3.x). In both cases, you must then
recompile FFTW. In FFTW 3, all FFTW identifiers will then begin with
\courier{fftwf_\} instead of \courier{fftw_\}.
\question 28mar:64bitk7 --enable-k7 does not work on x86-64
Support for --enable-k7 was discontinued in fftw-3.2.
The fftw-3.1 release supports --enable-k7. This option only works on
32-bit x86 machines that implement 3DNow!, including the AMD Athlon
and the AMD Opteron in 32-bit mode. --enable-k7 does not work on AMD
Opteron in 64-bit mode. Use --enable-sse for x86-64 machines.
FFTW supports 3DNow! by means of assembly code generated by a
special-purpose compiler. It is hard to produce assembly code that
works in both 32-bit and 64-bit mode.
\comment ######################################################################
\section Using FFTW
\question 15mar:fftw2to3 Why not support the FFTW 2 interface in FFTW 3?
FFTW 3 has semantics incompatible with earlier versions: its plans can
only be used for a given stride, multiplicity, and other
characteristics of the input and output arrays; these stronger
semantics are necessary for performance reasons. Thus, it is
impossible to efficiently emulate the older interface (whose plans can
be used for any transform of the same size). We believe that it
should be possible to upgrade most programs without any difficulty,
however.
\question 20mar:planperarray Why do FFTW 3 plans encapsulate the input/output arrays and not just the algorithm?
There are several reasons:
\call startlist
\call item
It was important for performance reasons that the plan be specific to
array characteristics like the stride (and alignment, for SIMD), and
requiring that the user maintain these invariants is error prone.
\call item
In most high-performance applications, as far as we can tell, you are
usually transforming the same array over and over, so FFTW's semantics
should not be a burden.
\call item
If you need to transform another array of the same size, creating a
new plan once the first exists is a cheap operation.
\call item
If you need to transform many arrays of the same size at once, you
should really use the \courier{plan_many\} routines in FFTW's "advanced"
interface.
\call item
If the abovementioned array characteristics are the same, you are
willing to pay close attention to the documentation, and you really
need to, we provide a "new-array execution" interface to apply a plan
to a new array.
\call endlist
\question 25may:slow FFTW seems really slow.
You are probably recreating the plan before every transform, rather
than creating it once and reusing it for all transforms of the same
size. FFTW is designed to be used in the following way:
\call startlist
\call item
First, you create a plan. This will take several seconds.
\call item
Then, you reuse the plan many times to perform FFTs. These are fast.
\call endlist
If you don't need to compute many transforms and the time for the
planner is significant, you have two options. First, you can use the
\courier{FFTW_ESTIMATE\} option in the planner, which uses heuristics
instead of runtime measurements and produces a good plan in a short
time. Second, you can use the wisdom feature to precompute the plan;
see \qref savePlans
\question 22oct:slows FFTW slows down after repeated calls.
Probably, NaNs or similar are creeping into your data, and the
slowdown is due to the resulting floating-point exceptions. For
example, be aware that repeatedly FFTing the same array is a diverging
process (because FFTW computes the unnormalized transform).
\question 22oct:segfault An FFTW routine is crashing when I call it.
Did the FFTW test programs pass (\courier{make check\}, or \courier{cd
tests; make bigcheck\} if you want to be paranoid)? If so, you almost
certainly have a bug in your own code. For example, you could be
passing invalid arguments (such as wrongly-sized arrays) to FFTW, or
you could simply have memory corruption elsewhere in your program that
causes random crashes later on. Please don't complain to us unless
you can come up with a minimal self-contained program (preferably
under 30 lines) that illustrates the problem.
\question 22oct:fortran64 My Fortran program crashes when calling FFTW.
As described in the manual, on 64-bit machines you must store the
plans in variables large enough to hold a pointer, for example
\courier{integer*8\}. We recommend using \courier{integer*8\} on
32-bit machines as well, to simplify porting.
\question 24mar:conventions FFTW gives results different from my old FFT.
People follow many different conventions for the DFT, and you should
be sure to know the ones that we use (described in the FFTW manual).
In particular, you should be aware that the
\courier{FFTW_FORWARD\}/\courier{FFTW_BACKWARD\} directions correspond
to signs of -1/+1 in the exponent of the DFT definition.
(\italic{Numerical Recipes\} uses the opposite convention.)
You should also know that we compute an unnormalized transform. In
contrast, Matlab is an example of program that computes a normalized
transform. See \qref whyscaled.
Finally, note that floating-point arithmetic is not exact, so
different FFT algorithms will give slightly different results (on the
order of the numerical accuracy; typically a fractional difference of
1e-15 or so in double precision).
\question 31aug:nondeterministic FFTW gives different results between runs
If you use \courier{FFTW_MEASURE\} or \courier{FFTW_PATIENT\} mode,
then the algorithm FFTW employs is not deterministic: it depends on
runtime performance measurements. This will cause the results to vary
slightly from run to run. However, the differences should be slight,
on the order of the floating-point precision, and therefore should
have no practical impact on most applications.
If you use saved plans (wisdom) or \courier{FFTW_ESTIMATE\} mode,
however, then the algorithm is deterministic and the results should be
identical between runs.
\question 26aug:savePlans Can I save FFTW's plans?
Yes. Starting with version 1.2, FFTW provides the \courier{wisdom\}
mechanism for saving plans; see the FFTW manual.
\question 14sep:whyscaled Why does your inverse transform return a scaled result?
Computing the forward transform followed by the backward transform (or
vice versa) yields the original array scaled by the size of the array.
(For multi-dimensional transforms, the size of the array is the
product of the dimensions.) We could, instead, have chosen a
normalization that would have returned the unscaled array. Or, to
accomodate the many conventions in this matter, the transform routines
could have accepted a "scale factor" parameter. We did not do this,
however, for two reasons. First, we didn't want to sacrifice
performance in the common case where the scale factor is 1. Second, in
real applications the FFT is followed or preceded by some computation
on the data, into which the scale factor can typically be absorbed at
little or no cost.
\question 02dec:centerorigin How can I make FFTW put the origin (zero frequency) at the center of its output?
For human viewing of a spectrum, it is often convenient to put the
origin in frequency space at the center of the output array, rather
than in the zero-th element (the default in FFTW). If all of the
dimensions of your array are even, you can accomplish this by simply
multiplying each element of the input array by (-1)^(i + j + ...),
where i, j, etcetera are the indices of the element. (This trick is a
general property of the DFT, and is not specific to FFTW.)
\question 08may:imageaudio How do I FFT an image/audio file in \italic{foobar\} format?
FFTW performs an FFT on an array of floating-point values. You can
certainly use it to compute the transform of an image or audio stream,
but you are responsible for figuring out your data format and
converting it to the form FFTW requires.
\question 09apr:linkfails My program does not link (on Unix).
The libraries must be listed in the correct order (\courier{-lfftw3
-lm\} for FFTW 3.x) and \italic{after\} your program sources/objects.
(The general rule is that if \italic{A\} uses \italic{B\}, then
\italic{A\} must be listed before \italic{B\} in the link command.).
\question 15mar:linkheader I included your header, but linking still fails.
You're a C++ programmer, aren't you? You have to compile the FFTW
library and link it into your program, not just \courier{#include
<fftw3.h>\}. (Yes, this is really a FAQ.)
\question 22oct:nostack My program crashes, complaining about stack space.
You cannot declare large arrays with automatic storage (e.g. via
\courier{fftw_complex array[N]\}); you should use
\courier{fftw_malloc\} (or equivalent) to allocate the arrays you want
to transform if they are larger than a few hundred elements.
\question 13may:leaks FFTW seems to have a memory leak.
After you create a plan, FFTW caches the information required to
quickly recreate the plan. (See \qref savePlans) It also maintains a
small amount of other persistent memory. You can deallocate all of
FFTW's internally allocated memory, if you wish, by calling
\courier{fftw_cleanup()\}, as documented in the manual.
\question 16may:allzero The output of FFTW's transform is all zeros.
You should initialize your input array \italic{after\} creating the
plan, unless you use \courier{FFTW_ESTIMATE\}: planning with
\courier{FFTW_MEASURE\} or \courier{FFTW_PATIENT\} overwrites the
input/output arrays, as described in the manual.
\question 05sep:vbetalia How do I call FFTW from the Microsoft language du jour?
Please \italic{do not\} ask us Windows-specific questions. We do not
use Windows. We know nothing about Visual Basic, Visual C++, or .NET.
Please find the appropriate Usenet discussion group and ask your
question there. See also \qref runOnWindows.
\question 15oct:pruned Can I compute only a subset of the DFT outputs?
In general, no, an FFT intrinsically computes all outputs from all
inputs. In principle, there is something called a \italic{pruned
FFT\} that can do what you want, but to compute K outputs out of N the
complexity is in general O(N log K) instead of O(N log N), thus saving
only a small additive factor in the log. (The same argument holds if
you instead have only K nonzero inputs.)
There are some specific cases in which you can get the O(N log K)
performance benefits easily, however, by combining a few ordinary
FFTs. In particular, the case where you want the first K outputs,
where K divides N, can be handled by performing N/K transforms of size
K and then summing the outputs multiplied by appropriate phase
factors. For more details, see \docref{pruned FFTs with FFTW\}.
There are also some algorithms that compute pruned transforms
\italic{approximately\}, but they are beyond the scope of this FAQ.
\question 21jan:transpose Can I use FFTW's routines for in-place and out-of-place matrix transposition?
You can use the FFTW guru interface to create a rank-0 transform of
vector rank 2 where the vector strides are transposed. (A rank-0
transform is equivalent to a 1D transform of size 1, which. just
copies the input into the output.) Specifying the same location for
the input and output makes the transpose in-place.
For double-valued data stored in row-major format, plan creation looks like
this:
\verbatim
fftw_plan plan_transpose(int rows, int cols, double *in, double *out)
{
const unsigned flags = FFTW_ESTIMATE; /* other flags are possible */
fftw_iodim howmany_dims[2];
howmany_dims[0].n = rows;
howmany_dims[0].is = cols;
howmany_dims[0].os = 1;
howmany_dims[1].n = cols;
howmany_dims[1].is = 1;
howmany_dims[1].os = rows;
return fftw_plan_guru_r2r(/*rank=*/ 0, /*dims=*/ NULL,
/*howmany_rank=*/ 2, howmany_dims,
in, out, /*kind=*/ NULL, flags);
}
\endverbatim
(This entry was written by Rhys Ulerich.)
\comment ######################################################################
\section Internals of FFTW
\question 26aug:howworks How does FFTW work?
The innovation (if it can be so called) in FFTW consists in having a
variety of composable \italic{solvers\}, representing different FFT
algorithms and implementation strategies, whose combination into a
particular \italic{plan\} for a given size can be determined at
runtime according to the characteristics of your machine/compiler.
This peculiar software architecture allows FFTW to adapt itself to
almost any machine.
For more details (albeit somewhat outdated), see the paper "FFTW: An
Adaptive Software Architecture for the FFT", by M. Frigo and
S. G. Johnson, \italic{Proc. ICASSP\} 3, 1381 (1998), also
available at \docref{the FFTW web page\}.
\question 26aug:whyfast Why is FFTW so fast?
This is a complex question, and there is no simple answer. In fact,
the authors do not fully know the answer, either. In addition to many
small performance hacks throughout FFTW, there are three general
reasons for FFTW's speed.
\call startlist
\call item
FFTW uses a variety of FFT algorithms and implementation styles
that can be arbitrarily composed to adapt itself to
a machine. See \qref howworks.
\call item
FFTW uses a code generator to produce highly-optimized
routines for computing small transforms.
\call item
FFTW uses explicit divide-and-conquer to take advantage
of the memory hierarchy.
\call endlist
For more details (albeit somewhat outdated), see the paper "FFTW: An
Adaptive Software Architecture for the FFT", by M. Frigo and
S. G. Johnson, \italic{Proc. ICASSP\} 3, 1381 (1998),
available along with other references at \docref{the FFTW web page\}.
\comment ######################################################################
\section Known bugs
\question 27aug:rfftwndbug FFTW 1.1 crashes in rfftwnd on Linux.
This bug was fixed in FFTW 1.2. There was a bug in \courier{rfftwnd\}
causing an incorrect amount of memory to be allocated. The bug showed
up in Linux with libc-5.3.12 (and nowhere else that we know of).
\question 15oct:fftwmpibug The MPI transforms in FFTW 1.2 give incorrect results/leak memory.
These bugs were corrected in FFTW 1.2.1. The MPI transforms (really,
just the transpose routines) in FFTW 1.2 had bugs that could cause
errors in some situations.
\question 05nov:testsingbug The test programs in FFTW 1.2.1 fail when I change FFTW to use single precision.
This bug was fixed in FFTW 1.3. (Older versions of FFTW did
work in single precision, but the test programs didn't--the error
tolerances in the tests were set for double precision.)
\question 24mar:teststoobig The test program in FFTW 1.2.1 fails for n > 46340.
This bug was fixed in FFTW 1.3. FFTW 1.2.1 produced the right answer,
but the test program was wrong. For large n, n*n in the naive
transform that we used for comparison overflows 32 bit integer
precision, breaking the test.
\question 24aug:linuxthreads The threaded code fails on Linux Redhat 5.0
We had problems with glibc-2.0.5. The code should work with
glibc-2.0.7.
\question 26sep:bigrfftwnd FFTW 2.0's rfftwnd fails for rank > 1 transforms with a final dimension >= 65536.
This bug was fixed in FFTW 2.0.1. (There was a 32-bit integer overflow due
to a poorly-parenthesized expression.)
\question 26mar:primebug FFTW 2.0's complex transforms give the wrong results with prime factors 17 to 97.
There was a bug in the complex transforms that could cause incorrect
results under (hopefully rare) circumstances for lengths with
intermediate-size prime factors (17-97). This bug was fixed in FFTW
2.1.1.
\question 05apr:mpichbug FFTW 2.1.1's MPI test programs crash with MPICH.
This bug was fixed in FFTW 2.1.2. The 2.1/2.1.1 MPI test programs crashed
when using the MPICH implementation of MPI with the \courier{ch_p4\}
device (TCP/IP); the transforms themselves worked fine.
\question 25may:aixthreadbug FFTW 2.1.2's multi-threaded transforms don't work on AIX.
This bug was fixed in FFTW 2.1.3. The multi-threaded transforms in
previous versions didn't work with AIX's \courier{pthreads\}
implementation, which idiosyncratically creates threads in detached
(non-joinable) mode by default.
\question 27sep:bigprimebug FFTW 2.1.2's complex transforms give incorrect results for large prime sizes.
This bug was fixed in FFTW 2.1.3. FFTW's complex-transform algorithm
for prime sizes (in versions 2.0 to 2.1.2) had an integer overflow
problem that caused incorrect results for many primes greater than
32768 (on 32-bit machines). (Sizes without large prime factors are
not affected.)
\question 25may:solaristhreadbug FFTW 2.1.3's multi-threaded transforms don't give any speedup on Solaris.
This bug was fixed in FFTW 2.1.4. (By default, Solaris creates
threads that do not parallelize over multiple processors, so one has
to request the proper behavior specifically.)
\question 03may:aixflags FFTW 2.1.3 crashes on AIX.
The FFTW 2.1.3 \courier{configure\} script picked incorrect compiler
flags for the \courier{xlc\} compiler on newer IBM processors. This
is fixed in FFTW 2.1.4.
\comment Here it ends!

View File

@@ -0,0 +1,110 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW Frequently Asked Questions with Answers
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<META name="description"
content="Frequently asked questions and answers (FAQ) for FFTW.">
<link rel="Bookmark" title="FFTW FAQ" href="index.html">
<LINK rel="Bookmark" title="FFTW Home Page"
href="http://www.fftw.org">
<LINK rel="Bookmark" title="FFTW Manual"
href="http://www.fftw.org/doc/">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW Frequently Asked Questions with Answers
</h1>
This is the list of Frequently Asked Questions about FFTW, a
collection of fast C routines for computing the Discrete Fourier
Transform in one or more dimensions.
<h1>
Index
</h1>
<ul>
<li><b><font size="+2"><a href="section1.html" rel=subdocument>Section 1. Introduction and General Information</a></font></b>
<li><a href="section1.html#whatisfftw" rel=subdocument>Q1.1. What is FFTW?</a>
<li><a href="section1.html#whereisfftw" rel=subdocument>Q1.2. How do I obtain FFTW?</a>
<li><a href="section1.html#isfftwfree" rel=subdocument>Q1.3. Is FFTW free software?</a>
<li><a href="section1.html#nonfree" rel=subdocument>Q1.4. What is this about non-free licenses?</a>
<li><a href="section1.html#west" rel=subdocument>Q1.5. In the West? I thought MIT was in the East?</a>
<br><br><li><b><font size="+2"><a href="section2.html" rel=subdocument>Section 2. Installing FFTW</a></font></b>
<li><a href="section2.html#systems" rel=subdocument>Q2.1. Which systems does FFTW run on?</a>
<li><a href="section2.html#runOnWindows" rel=subdocument>Q2.2. Does FFTW run on Windows?</a>
<li><a href="section2.html#compilerCrashes" rel=subdocument>Q2.3. My compiler has trouble with FFTW.</a>
<li><a href="section2.html#solarisSucks" rel=subdocument>Q2.4. FFTW does not compile on Solaris, complaining about
<code>const</code>.</a>
<li><a href="section2.html#3dnow" rel=subdocument>Q2.5. What's the difference between <code>--enable-3dnow</code> and <code>--enable-k7</code>?</a>
<li><a href="section2.html#fma" rel=subdocument>Q2.6. What's the difference between the fma and the non-fma
versions?</a>
<li><a href="section2.html#languages" rel=subdocument>Q2.7. Which language is FFTW written in?</a>
<li><a href="section2.html#fortran" rel=subdocument>Q2.8. Can I call FFTW from Fortran?</a>
<li><a href="section2.html#cplusplus" rel=subdocument>Q2.9. Can I call FFTW from C++?</a>
<li><a href="section2.html#whynotfortran" rel=subdocument>Q2.10. Why isn't FFTW written in Fortran/C++?</a>
<li><a href="section2.html#singleprec" rel=subdocument>Q2.11. How do I compile FFTW to run in single precision?</a>
<li><a href="section2.html#64bitk7" rel=subdocument>Q2.12. --enable-k7 does not work on x86-64</a>
<br><br><li><b><font size="+2"><a href="section3.html" rel=subdocument>Section 3. Using FFTW</a></font></b>
<li><a href="section3.html#fftw2to3" rel=subdocument>Q3.1. Why not support the FFTW 2 interface in FFTW
3?</a>
<li><a href="section3.html#planperarray" rel=subdocument>Q3.2. Why do FFTW 3 plans encapsulate the input/output arrays and not just
the algorithm?</a>
<li><a href="section3.html#slow" rel=subdocument>Q3.3. FFTW seems really slow.</a>
<li><a href="section3.html#slows" rel=subdocument>Q3.4. FFTW slows down after repeated calls.</a>
<li><a href="section3.html#segfault" rel=subdocument>Q3.5. An FFTW routine is crashing when I call it.</a>
<li><a href="section3.html#fortran64" rel=subdocument>Q3.6. My Fortran program crashes when calling FFTW.</a>
<li><a href="section3.html#conventions" rel=subdocument>Q3.7. FFTW gives results different from my old
FFT.</a>
<li><a href="section3.html#nondeterministic" rel=subdocument>Q3.8. FFTW gives different results between runs</a>
<li><a href="section3.html#savePlans" rel=subdocument>Q3.9. Can I save FFTW's plans?</a>
<li><a href="section3.html#whyscaled" rel=subdocument>Q3.10. Why does your inverse transform return a scaled
result?</a>
<li><a href="section3.html#centerorigin" rel=subdocument>Q3.11. How can I make FFTW put the origin (zero frequency) at the center of
its output?</a>
<li><a href="section3.html#imageaudio" rel=subdocument>Q3.12. How do I FFT an image/audio file in <i>foobar</i> format?</a>
<li><a href="section3.html#linkfails" rel=subdocument>Q3.13. My program does not link (on Unix).</a>
<li><a href="section3.html#linkheader" rel=subdocument>Q3.14. I included your header, but linking still
fails.</a>
<li><a href="section3.html#nostack" rel=subdocument>Q3.15. My program crashes, complaining about stack
space.</a>
<li><a href="section3.html#leaks" rel=subdocument>Q3.16. FFTW seems to have a memory leak.</a>
<li><a href="section3.html#allzero" rel=subdocument>Q3.17. The output of FFTW's transform is all zeros.</a>
<li><a href="section3.html#vbetalia" rel=subdocument>Q3.18. How do I call FFTW from the Microsoft language du
jour?</a>
<li><a href="section3.html#pruned" rel=subdocument>Q3.19. Can I compute only a subset of the DFT outputs?</a>
<li><a href="section3.html#transpose" rel=subdocument>Q3.20. Can I use FFTW's routines for in-place and out-of-place matrix
transposition?</a>
<br><br><li><b><font size="+2"><a href="section4.html" rel=subdocument>Section 4. Internals of FFTW</a></font></b>
<li><a href="section4.html#howworks" rel=subdocument>Q4.1. How does FFTW work?</a>
<li><a href="section4.html#whyfast" rel=subdocument>Q4.2. Why is FFTW so fast?</a>
<br><br><li><b><font size="+2"><a href="section5.html" rel=subdocument>Section 5. Known bugs</a></font></b>
<li><a href="section5.html#rfftwndbug" rel=subdocument>Q5.1. FFTW 1.1 crashes in rfftwnd on Linux.</a>
<li><a href="section5.html#fftwmpibug" rel=subdocument>Q5.2. The MPI transforms in FFTW 1.2 give incorrect results/leak
memory.</a>
<li><a href="section5.html#testsingbug" rel=subdocument>Q5.3. The test programs in FFTW 1.2.1 fail when I change FFTW to use single
precision.</a>
<li><a href="section5.html#teststoobig" rel=subdocument>Q5.4. The test program in FFTW 1.2.1 fails for n &gt;
46340.</a>
<li><a href="section5.html#linuxthreads" rel=subdocument>Q5.5. The threaded code fails on Linux Redhat 5.0</a>
<li><a href="section5.html#bigrfftwnd" rel=subdocument>Q5.6. FFTW 2.0's rfftwnd fails for rank &gt; 1 transforms with a final
dimension &gt;= 65536.</a>
<li><a href="section5.html#primebug" rel=subdocument>Q5.7. FFTW 2.0's complex transforms give the wrong results with prime
factors 17 to 97.</a>
<li><a href="section5.html#mpichbug" rel=subdocument>Q5.8. FFTW 2.1.1's MPI test programs crash with
MPICH.</a>
<li><a href="section5.html#aixthreadbug" rel=subdocument>Q5.9. FFTW 2.1.2's multi-threaded transforms don't work on
AIX.</a>
<li><a href="section5.html#bigprimebug" rel=subdocument>Q5.10. FFTW 2.1.2's complex transforms give incorrect results for large prime
sizes.</a>
<li><a href="section5.html#solaristhreadbug" rel=subdocument>Q5.11. FFTW 2.1.3's multi-threaded transforms don't give any speedup on
Solaris.</a>
<li><a href="section5.html#aixflags" rel=subdocument>Q5.12. FFTW 2.1.3 crashes on AIX.</a>
</ul><hr>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,85 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW FAQ - Section 1
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<link rel="Next" href="section2.html"><link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW FAQ - Section 1 <br>
Introduction and General Information
</h1>
<ul>
<li><a href="#whatisfftw" rel=subdocument>Q1.1. What is FFTW?</a>
<li><a href="#whereisfftw" rel=subdocument>Q1.2. How do I obtain FFTW?</a>
<li><a href="#isfftwfree" rel=subdocument>Q1.3. Is FFTW free software?</a>
<li><a href="#nonfree" rel=subdocument>Q1.4. What is this about non-free licenses?</a>
<li><a href="#west" rel=subdocument>Q1.5. In the West? I thought MIT was in the East?</a>
</ul><hr>
<h2><A name="whatisfftw">
Question 1.1. What is FFTW?
</A></h2>
FFTW is a free collection of fast C routines for computing the
Discrete Fourier Transform in one or more dimensions. It includes
complex, real, symmetric, and parallel transforms, and can handle
arbitrary array sizes efficiently. FFTW is typically faster than
other publically-available FFT implementations, and is even
competitive with vendor-tuned libraries. (See our web page for
extensive benchmarks.) To achieve this performance, FFTW uses novel
code-generation and runtime self-optimization techniques (along with
many other tricks).
<h2><A name="whereisfftw">
Question 1.2. How do I obtain FFTW?
</A></h2>
FFTW can be found at <A href="http://www.fftw.org">the FFTW web page</A>. You can also retrieve it from <code>ftp.fftw.org</code> in <A href="ftp://ftp.fftw.org/pub/fftw"><code>/pub/fftw</code></A>.
<h2><A name="isfftwfree">
Question 1.3. Is FFTW free software?
</A></h2>
Starting with version 1.3, FFTW is Free Software in the technical
sense defined by the Free Software Foundation (see
<A href="http://www.gnu.org/philosophy/categories.html">Categories of Free and Non-Free Software</A>), and is distributed under the terms of the GNU General Public License. Previous versions of FFTW were
distributed without fee for noncommercial use, but were not
technically ``free.''
<p>
Non-free licenses for FFTW are also available that permit different
terms of use than the GPL.
<h2><A name="nonfree">
Question 1.4. What is this about non-free
licenses?
</A></h2>
The non-free licenses are for companies that wish to use FFTW in their
products but are unwilling to release their software under the GPL
(which would require them to release source code and allow free
redistribution). Such users can purchase an unlimited-use license
from MIT. Contact us for more details.
<p>
We could instead have released FFTW under the LGPL, or even disallowed
non-Free usage. Suffice it to say, however, that MIT owns the
copyright to FFTW and they only let us GPL it because we convinced
them that it would neither affect their licensing revenue nor irritate
existing licensees.
<h2><A name="west">
Question 1.5. In the West? I thought MIT was in the
East?
</A></h2>
Not to an Italian. You could say that we're a Spaghetti Western
(with apologies to Sergio Leone). <hr>
Next: <a href="section2.html" rel=precedes>Installing FFTW</a>.<br>
<a href="index.html" rev=subdocument>Return to contents</a>.<p>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,285 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW FAQ - Section 2
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<link rel="Next" href="section3.html"><link rel="Previous" href="section1.html"><link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW FAQ - Section 2 <br>
Installing FFTW
</h1>
<ul>
<li><a href="#systems" rel=subdocument>Q2.1. Which systems does FFTW run on?</a>
<li><a href="#runOnWindows" rel=subdocument>Q2.2. Does FFTW run on Windows?</a>
<li><a href="#compilerCrashes" rel=subdocument>Q2.3. My compiler has trouble with FFTW.</a>
<li><a href="#solarisSucks" rel=subdocument>Q2.4. FFTW does not compile on Solaris, complaining about
<code>const</code>.</a>
<li><a href="#3dnow" rel=subdocument>Q2.5. What's the difference between <code>--enable-3dnow</code> and <code>--enable-k7</code>?</a>
<li><a href="#fma" rel=subdocument>Q2.6. What's the difference between the fma and the non-fma
versions?</a>
<li><a href="#languages" rel=subdocument>Q2.7. Which language is FFTW written in?</a>
<li><a href="#fortran" rel=subdocument>Q2.8. Can I call FFTW from Fortran?</a>
<li><a href="#cplusplus" rel=subdocument>Q2.9. Can I call FFTW from C++?</a>
<li><a href="#whynotfortran" rel=subdocument>Q2.10. Why isn't FFTW written in Fortran/C++?</a>
<li><a href="#singleprec" rel=subdocument>Q2.11. How do I compile FFTW to run in single precision?</a>
<li><a href="#64bitk7" rel=subdocument>Q2.12. --enable-k7 does not work on x86-64</a>
</ul><hr>
<h2><A name="systems">
Question 2.1. Which systems does FFTW run
on?
</A></h2>
FFTW is written in ANSI C, and should work on any system with a decent
C compiler. (See also <A href="#runOnWindows">Q2.2 `Does FFTW run on Windows?'</A>, <A href="#compilerCrashes">Q2.3 `My compiler has trouble with FFTW.'</A>.) FFTW can also take advantage of certain hardware-specific features,
such as cycle counters and SIMD instructions, but this is optional.
<h2><A name="runOnWindows">
Question 2.2. Does FFTW run on Windows?
</A></h2>
Yes, many people have reported successfully using FFTW on Windows with
various compilers. FFTW was not developed on Windows, but the source
code is essentially straight ANSI C. See also the
<A href="http://www.fftw.org/install/windows.html">FFTW Windows installation notes</A>, <A href="#compilerCrashes">Q2.3 `My compiler has trouble with FFTW.'</A>, and <A href="section3.html#vbetalia">Q3.18 `How do I call FFTW from the Microsoft language du
jour?'</A>.
<h2><A name="compilerCrashes">
Question 2.3. My compiler has trouble with
FFTW.
</A></h2>
Complain fiercely to the vendor of the compiler.
<p>
We have successfully used <code>gcc</code> 3.2.x on x86 and PPC, a recent Compaq C compiler for Alpha, version 6 of IBM's
<code>xlc</code> compiler for AIX, Intel's <code>icc</code> versions 5-7, and Sun WorkShop <code>cc</code> version 6.
<p>
FFTW is likely to push compilers to their limits, however, and several
compiler bugs have been exposed by FFTW. A partial list follows.
<p>
<code>gcc</code> 2.95.x for Solaris/SPARC produces incorrect code for
the test program (workaround: recompile the
<code>libbench2</code> directory with <code>-O2</code>).
<p>
NetBSD/macppc 1.6 comes with a <code>gcc</code> version that also miscompiles the test program. (Please report a workaround if you know
one.)
<p>
<code>gcc</code> 3.2.3 for ARM reportedly crashes during compilation.
This bug is reportedly fixed in later versions of
<code>gcc</code>.
<p>
Versions 8.0 and 8.1 of Intel's <code>icc</code> falsely claim to be <code>gcc</code>, so you should specify <code>CC=&quot;icc -no-gcc&quot;</code>; this is automatic in FFTW 3.1. <code>icc-8.0.066</code> reportely produces incorrect code for FFTW 2.1.5, but is fixed in version 8.1.
<code>icc-7.1</code> compiler build 20030402Z appears to produce
incorrect dependencies, causing the compilation to fail.
<code>icc-7.1</code> build 20030307Z appears to work fine. (Use
<code>icc -V</code> to check which build you have.) As of 2003/04/18,
build 20030402Z appears not to be available any longer on Intel's
website, whereas the older build 20030307Z is available.
<p>
<code>ranlib</code> of GNU <code>binutils</code> 2.9.1 on Irix has been observed to corrupt the FFTW libraries, causing a link failure when
FFTW is compiled. Since <code>ranlib</code> is completely superfluous on Irix, we suggest deleting it from your system and replacing it with
a symbolic link to <code>/bin/echo</code>.
<p>
If support for SIMD instructions is enabled in FFTW, further compiler
problems may appear:
<p>
<code>gcc</code> 3.4.[0123] for x86 produces incorrect SSE2 code for
FFTW when <code>-O2</code> (the best choice for FFTW) is used, causing
FFTW to crash (<code>make check</code> crashes). This bug is fixed in <code>gcc</code> 3.4.4. On x86_64 (amd64/em64t), <code>gcc</code> 3.4.4 reportedly still has a similar problem, but this is fixed as of
<code>gcc</code> 3.4.6.
<p>
<code>gcc-3.2</code> for x86 produces incorrect SIMD code if
<code>-O3</code> is used. The same compiler produces incorrect SIMD
code if no optimization is used, too. When using
<code>gcc-3.2</code>, it is a good idea not to change the default
<code>CFLAGS</code> selected by the <code>configure</code> script.
<p>
Some 3.0.x and 3.1.x versions of <code>gcc</code> on <code>x86</code> may crash. <code>gcc</code> so-called 2.96 shipping with RedHat 7.3 crashes
when compiling SIMD code. In both cases, please upgrade to
<code>gcc-3.2</code> or later.
<p>
Intel's <code>icc</code> 6.0 misaligns SSE constants, but FFTW has a
workaround. <code>icc</code> 8.x fails to compile FFTW 3.0.x because it
falsely claims to be <code>gcc</code>; we believe this to be a bug in <code>icc</code>, but FFTW 3.1 has a workaround.
<p>
Visual C++ 2003 reportedly produces incorrect code for SSE/SSE2 when
compiling FFTW. This bug was reportedly fixed in VC++ 2005;
alternatively, you could switch to the Intel compiler. VC++ 6.0 also
reportedly produces incorrect code for the file
<code>reodft11e-r2hc-odd.c</code> unless optimizations are disabled for that file.
<p>
<code>gcc</code> 2.95 on MacOS X miscompiles AltiVec code (fixed in
later versions). <code>gcc</code> 3.2.x miscompiles AltiVec permutations, but FFTW has a workaround.
<code>gcc</code> 4.0.1 on MacOS for Intel crashes when compiling FFTW; a workaround is to
compile one file without optimization: <code>cd kernel; make CFLAGS=&quot; &quot; trig.lo</code>.
<p>
<code>gcc</code> 4.1.1 reportedly crashes when compiling FFTW for MIPS;
the workaround is to compile the file it crashes on
(<code>t2_64.c</code>) with a lower optimization level.
<p>
<code>gcc</code> versions 4.1.2 to 4.2.0 for x86 reportedly miscompile
FFTW 3.1's test program, causing <code>make check</code> to crash (<code>gcc</code> bug #26528). The bug was reportedly fixed in
<code>gcc</code> version 4.2.1 and later. A workaround is to compile
<code>libbench2/verify-lib.c</code> without optimization.
<h2><A name="solarisSucks">
Question 2.4. FFTW does not compile on Solaris, complaining about
<code>const</code>.
</A></h2>
We know that at least on Solaris 2.5.x with Sun's compilers 4.2 you
might get error messages from <code>make</code> such as
<p>
<code>&quot;./fftw.h&quot;, line 88: warning: const is a keyword in ANSI
C</code>
<p>
This is the case when the <code>configure</code> script reports that <code>const</code> does not work:
<p>
<code>checking for working const... (cached) no</code>
<p>
You should be aware that Solaris comes with two compilers, namely,
<code>/opt/SUNWspro/SC4.2/bin/cc</code> and <code>/usr/ucb/cc</code>. The latter compiler is non-ANSI. Indeed, it is a perverse shell script
that calls the real compiler in non-ANSI mode. In order
to compile FFTW, change your path so that the right
<code>cc</code> is used.
<p>
To know whether your compiler is the right one, type
<code>cc -V</code>. If the compiler prints ``<code>ucbcc</code>'', as in
<p>
<code>ucbcc: WorkShop Compilers 4.2 30 Oct 1996 C
4.2</code>
<p>
then the compiler is wrong. The right message is something like
<p>
<code>cc: WorkShop Compilers 4.2 30 Oct 1996 C
4.2</code>
<h2><A name="3dnow">
Question 2.5. What's the difference between
<code>--enable-3dnow</code> and <code>--enable-k7</code>?
</A></h2>
<code>--enable-k7</code> enables 3DNow! instructions on K7 processors
(AMD Athlon and its variants). K7 support is provided by assembly
routines generated by a special purpose compiler.
As of fftw-3.2, --enable-k7 is no longer supported.
<p>
<code>--enable-3dnow</code> enables generic 3DNow! support using <code>gcc</code> builtin functions. This works on earlier AMD
processors, but it is not as fast as our special assembly routines.
As of fftw-3.1, --enable-3dnow is no longer supported.
<h2><A name="fma">
Question 2.6. What's the difference between the fma and the non-fma
versions?
</A></h2>
The fma version tries to exploit the fused multiply-add instructions
implemented in many processors such as PowerPC, ia-64, and MIPS. The
two FFTW packages are otherwise identical. In FFTW 3.1, the fma and
non-fma versions were merged together into a single package, and the
<code>configure</code> script attempts to automatically guess which
version to use.
<p>
The FFTW 3.1 <code>configure</code> script enables fma by default on PowerPC, Itanium, and PA-RISC, and disables it otherwise. You can
force one or the other by using the <code>--enable-fma</code> or <code>--disable-fma</code> flag for <code>configure</code>.
<p>
Definitely use fma if you have a PowerPC-based system with
<code>gcc</code> (or IBM <code>xlc</code>). This includes all GNU/Linux systems for PowerPC and the older PowerPC-based MacOS systems. Also
use it on PA-RISC and Itanium with the HP/UX compiler.
<p>
Definitely do not use the fma version if you have an ia-32 processor
(Intel, AMD, MacOS on Intel, etcetera).
<p>
For other architectures/compilers, the situation is not so clear. For
example, ia-64 has the fma instruction, but
<code>gcc-3.2</code> appears not to exploit it correctly. Other compilers may do the right thing,
but we have not tried them. Please send us your feedback so that we
can update this FAQ entry.
<h2><A name="languages">
Question 2.7. Which language is FFTW written
in?
</A></h2>
FFTW is written in ANSI C. Most of the code, however, was
automatically generated by a program called
<code>genfft</code>, written in the Objective Caml dialect of ML. You do not need to know ML or to
have an Objective Caml compiler in order to use FFTW.
<p>
<code>genfft</code> is provided with the FFTW sources, which means that
you can play with the code generator if you want. In this case, you
need a working Objective Caml system. Objective Caml is available
from <A href="http://caml.inria.fr">the Caml web page</A>.
<h2><A name="fortran">
Question 2.8. Can I call FFTW from Fortran?
</A></h2>
Yes, FFTW (versions 1.3 and higher) contains a Fortran-callable
interface, documented in the FFTW manual.
<p>
By default, FFTW configures its Fortran interface to work with the
first compiler it finds, e.g. <code>g77</code>. To configure for a different, incompatible Fortran compiler
<code>foobar</code>, use <code>./configure F77=foobar</code> when installing FFTW. (In the case of <code>g77</code>, however, FFTW 3.x also includes an extra set of
Fortran-callable routines with one less underscore at the end of
identifiers, which should cover most other Fortran compilers on Linux
at least.)
<h2><A name="cplusplus">
Question 2.9. Can I call FFTW from C++?
</A></h2>
Most definitely. FFTW should compile and/or link under any C++
compiler. Moreover, it is likely that the C++
<code>&lt;complex&gt;</code> template class is bit-compatible with FFTW's complex-number format
(see the FFTW manual for more details).
<h2><A name="whynotfortran">
Question 2.10. Why isn't FFTW written in
Fortran/C++?
</A></h2>
Because we don't like those languages, and neither approaches the
portability of C.
<h2><A name="singleprec">
Question 2.11. How do I compile FFTW to run in single
precision?
</A></h2>
On a Unix system: <code>configure --enable-float</code>. On a non-Unix system: edit <code>config.h</code> to <code>#define</code> the symbol <code>FFTW_SINGLE</code> (for FFTW 3.x). In both cases, you must then
recompile FFTW. In FFTW 3, all FFTW identifiers will then begin with
<code>fftwf_</code> instead of <code>fftw_</code>.
<h2><A name="64bitk7">
Question 2.12. --enable-k7 does not work on
x86-64
</A></h2>
Support for --enable-k7 was discontinued in fftw-3.2.
<p>
The fftw-3.1 release supports --enable-k7. This option only works on
32-bit x86 machines that implement 3DNow!, including the AMD Athlon
and the AMD Opteron in 32-bit mode. --enable-k7 does not work on AMD
Opteron in 64-bit mode. Use --enable-sse for x86-64 machines.
<p>
FFTW supports 3DNow! by means of assembly code generated by a
special-purpose compiler. It is hard to produce assembly code that
works in both 32-bit and 64-bit mode. <hr>
Next: <a href="section3.html" rel=precedes>Using FFTW</a>.<br>
Back: <a href="section1.html" rev=precedes>Introduction and General Information</a>.<br>
<a href="index.html" rev=subdocument>Return to contents</a>.<p>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,334 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW FAQ - Section 3
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<link rel="Next" href="section4.html"><link rel="Previous" href="section2.html"><link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW FAQ - Section 3 <br>
Using FFTW
</h1>
<ul>
<li><a href="#fftw2to3" rel=subdocument>Q3.1. Why not support the FFTW 2 interface in FFTW
3?</a>
<li><a href="#planperarray" rel=subdocument>Q3.2. Why do FFTW 3 plans encapsulate the input/output arrays and not just
the algorithm?</a>
<li><a href="#slow" rel=subdocument>Q3.3. FFTW seems really slow.</a>
<li><a href="#slows" rel=subdocument>Q3.4. FFTW slows down after repeated calls.</a>
<li><a href="#segfault" rel=subdocument>Q3.5. An FFTW routine is crashing when I call it.</a>
<li><a href="#fortran64" rel=subdocument>Q3.6. My Fortran program crashes when calling FFTW.</a>
<li><a href="#conventions" rel=subdocument>Q3.7. FFTW gives results different from my old
FFT.</a>
<li><a href="#nondeterministic" rel=subdocument>Q3.8. FFTW gives different results between runs</a>
<li><a href="#savePlans" rel=subdocument>Q3.9. Can I save FFTW's plans?</a>
<li><a href="#whyscaled" rel=subdocument>Q3.10. Why does your inverse transform return a scaled
result?</a>
<li><a href="#centerorigin" rel=subdocument>Q3.11. How can I make FFTW put the origin (zero frequency) at the center of
its output?</a>
<li><a href="#imageaudio" rel=subdocument>Q3.12. How do I FFT an image/audio file in <i>foobar</i> format?</a>
<li><a href="#linkfails" rel=subdocument>Q3.13. My program does not link (on Unix).</a>
<li><a href="#linkheader" rel=subdocument>Q3.14. I included your header, but linking still
fails.</a>
<li><a href="#nostack" rel=subdocument>Q3.15. My program crashes, complaining about stack
space.</a>
<li><a href="#leaks" rel=subdocument>Q3.16. FFTW seems to have a memory leak.</a>
<li><a href="#allzero" rel=subdocument>Q3.17. The output of FFTW's transform is all zeros.</a>
<li><a href="#vbetalia" rel=subdocument>Q3.18. How do I call FFTW from the Microsoft language du
jour?</a>
<li><a href="#pruned" rel=subdocument>Q3.19. Can I compute only a subset of the DFT outputs?</a>
<li><a href="#transpose" rel=subdocument>Q3.20. Can I use FFTW's routines for in-place and out-of-place matrix
transposition?</a>
</ul><hr>
<h2><A name="fftw2to3">
Question 3.1. Why not support the FFTW 2 interface in FFTW
3?
</A></h2>
FFTW 3 has semantics incompatible with earlier versions: its plans can
only be used for a given stride, multiplicity, and other
characteristics of the input and output arrays; these stronger
semantics are necessary for performance reasons. Thus, it is
impossible to efficiently emulate the older interface (whose plans can
be used for any transform of the same size). We believe that it
should be possible to upgrade most programs without any difficulty,
however.
<h2><A name="planperarray">
Question 3.2. Why do FFTW 3 plans encapsulate the input/output arrays
and not just the algorithm?
</A></h2>
There are several reasons:
<ul>
<li>It was important for performance reasons that the plan be specific to
array characteristics like the stride (and alignment, for SIMD), and
requiring that the user maintain these invariants is error prone.
<li>In most high-performance applications, as far as we can tell, you are
usually transforming the same array over and over, so FFTW's semantics
should not be a burden.
<li>If you need to transform another array of the same size, creating a
new plan once the first exists is a cheap operation.
<li>If you need to transform many arrays of the same size at once, you
should really use the <code>plan_many</code> routines in FFTW's &quot;advanced&quot;
interface.
<li>If the abovementioned array characteristics are the same, you are
willing to pay close attention to the documentation, and you really
need to, we provide a &quot;new-array execution&quot; interface to
apply a plan to a new array.
</ul>
<h2><A name="slow">
Question 3.3. FFTW seems really slow.
</A></h2>
You are probably recreating the plan before every transform, rather
than creating it once and reusing it for all transforms of the same
size. FFTW is designed to be used in the following way:
<ul>
<li>First, you create a plan. This will take several seconds.
<li>Then, you reuse the plan many times to perform FFTs. These are fast.
</ul>
If you don't need to compute many transforms and the time for the
planner is significant, you have two options. First, you can use the
<code>FFTW_ESTIMATE</code> option in the planner, which uses heuristics
instead of runtime measurements and produces a good plan in a short
time. Second, you can use the wisdom feature to precompute the plan;
see <A href="#savePlans">Q3.9 `Can I save FFTW's plans?'</A>
<h2><A name="slows">
Question 3.4. FFTW slows down after repeated
calls.
</A></h2>
Probably, NaNs or similar are creeping into your data, and the
slowdown is due to the resulting floating-point exceptions. For
example, be aware that repeatedly FFTing the same array is a diverging
process (because FFTW computes the unnormalized transform).
<h2><A name="segfault">
Question 3.5. An FFTW routine is crashing when I call
it.
</A></h2>
Did the FFTW test programs pass (<code>make check</code>, or <code>cd tests; make bigcheck</code> if you want to be paranoid)? If so, you almost
certainly have a bug in your own code. For example, you could be
passing invalid arguments (such as wrongly-sized arrays) to FFTW, or
you could simply have memory corruption elsewhere in your program that
causes random crashes later on. Please don't complain to us unless
you can come up with a minimal self-contained program (preferably
under 30 lines) that illustrates the problem.
<h2><A name="fortran64">
Question 3.6. My Fortran program crashes when calling
FFTW.
</A></h2>
As described in the manual, on 64-bit machines you must store the
plans in variables large enough to hold a pointer, for example
<code>integer*8</code>. We recommend using <code>integer*8</code> on 32-bit machines as well, to simplify porting.
<h2><A name="conventions">
Question 3.7. FFTW gives results different from my old
FFT.
</A></h2>
People follow many different conventions for the DFT, and you should
be sure to know the ones that we use (described in the FFTW manual).
In particular, you should be aware that the
<code>FFTW_FORWARD</code>/<code>FFTW_BACKWARD</code> directions correspond to signs of -1/+1 in the exponent of the DFT definition.
(<i>Numerical Recipes</i> uses the opposite convention.)
<p>
You should also know that we compute an unnormalized transform. In
contrast, Matlab is an example of program that computes a normalized
transform. See <A href="#whyscaled">Q3.10 `Why does your inverse transform return a scaled
result?'</A>.
<p>
Finally, note that floating-point arithmetic is not exact, so
different FFT algorithms will give slightly different results (on the
order of the numerical accuracy; typically a fractional difference of
1e-15 or so in double precision).
<h2><A name="nondeterministic">
Question 3.8. FFTW gives different results between
runs
</A></h2>
If you use <code>FFTW_MEASURE</code> or <code>FFTW_PATIENT</code> mode, then the algorithm FFTW employs is not deterministic: it depends on
runtime performance measurements. This will cause the results to vary
slightly from run to run. However, the differences should be slight,
on the order of the floating-point precision, and therefore should
have no practical impact on most applications.
<p>
If you use saved plans (wisdom) or <code>FFTW_ESTIMATE</code> mode, however, then the algorithm is deterministic and the results should be
identical between runs.
<h2><A name="savePlans">
Question 3.9. Can I save FFTW's plans?
</A></h2>
Yes. Starting with version 1.2, FFTW provides the
<code>wisdom</code> mechanism for saving plans; see the FFTW manual.
<h2><A name="whyscaled">
Question 3.10. Why does your inverse transform return a scaled
result?
</A></h2>
Computing the forward transform followed by the backward transform (or
vice versa) yields the original array scaled by the size of the array.
(For multi-dimensional transforms, the size of the array is the
product of the dimensions.) We could, instead, have chosen a
normalization that would have returned the unscaled array. Or, to
accomodate the many conventions in this matter, the transform routines
could have accepted a &quot;scale factor&quot; parameter. We did not
do this, however, for two reasons. First, we didn't want to sacrifice
performance in the common case where the scale factor is 1. Second, in
real applications the FFT is followed or preceded by some computation
on the data, into which the scale factor can typically be absorbed at
little or no cost.
<h2><A name="centerorigin">
Question 3.11. How can I make FFTW put the origin (zero frequency) at
the center of its output?
</A></h2>
For human viewing of a spectrum, it is often convenient to put the
origin in frequency space at the center of the output array, rather
than in the zero-th element (the default in FFTW). If all of the
dimensions of your array are even, you can accomplish this by simply
multiplying each element of the input array by (-1)^(i + j + ...),
where i, j, etcetera are the indices of the element. (This trick is a
general property of the DFT, and is not specific to FFTW.)
<h2><A name="imageaudio">
Question 3.12. How do I FFT an image/audio file in
<i>foobar</i> format?
</A></h2>
FFTW performs an FFT on an array of floating-point values. You can
certainly use it to compute the transform of an image or audio stream,
but you are responsible for figuring out your data format and
converting it to the form FFTW requires.
<h2><A name="linkfails">
Question 3.13. My program does not link (on
Unix).
</A></h2>
The libraries must be listed in the correct order
(<code>-lfftw3 -lm</code> for FFTW 3.x) and <i>after</i> your program sources/objects. (The general rule is that if <i>A</i> uses <i>B</i>, then <i>A</i> must be listed before <i>B</i> in the link command.).
<h2><A name="linkheader">
Question 3.14. I included your header, but linking still
fails.
</A></h2>
You're a C++ programmer, aren't you? You have to compile the FFTW
library and link it into your program, not just
<code>#include &lt;fftw3.h&gt;</code>. (Yes, this is really a FAQ.)
<h2><A name="nostack">
Question 3.15. My program crashes, complaining about stack
space.
</A></h2>
You cannot declare large arrays with automatic storage (e.g. via
<code>fftw_complex array[N]</code>); you should use <code>fftw_malloc</code> (or equivalent) to allocate the arrays you want
to transform if they are larger than a few hundred elements.
<h2><A name="leaks">
Question 3.16. FFTW seems to have a memory
leak.
</A></h2>
After you create a plan, FFTW caches the information required to
quickly recreate the plan. (See <A href="#savePlans">Q3.9 `Can I save FFTW's plans?'</A>) It also maintains a small amount of other persistent memory. You can deallocate all of
FFTW's internally allocated memory, if you wish, by calling
<code>fftw_cleanup()</code>, as documented in the manual.
<h2><A name="allzero">
Question 3.17. The output of FFTW's transform is all
zeros.
</A></h2>
You should initialize your input array <i>after</i> creating the plan, unless you use <code>FFTW_ESTIMATE</code>: planning with <code>FFTW_MEASURE</code> or <code>FFTW_PATIENT</code> overwrites the input/output arrays, as described in the manual.
<h2><A name="vbetalia">
Question 3.18. How do I call FFTW from the Microsoft language du
jour?
</A></h2>
Please <i>do not</i> ask us Windows-specific questions. We do not
use Windows. We know nothing about Visual Basic, Visual C++, or .NET.
Please find the appropriate Usenet discussion group and ask your
question there. See also <A href="section2.html#runOnWindows">Q2.2 `Does FFTW run on Windows?'</A>.
<h2><A name="pruned">
Question 3.19. Can I compute only a subset of the DFT
outputs?
</A></h2>
In general, no, an FFT intrinsically computes all outputs from all
inputs. In principle, there is something called a
<i>pruned FFT</i> that can do what you want, but to compute K outputs out of N the
complexity is in general O(N log K) instead of O(N log N), thus saving
only a small additive factor in the log. (The same argument holds if
you instead have only K nonzero inputs.)
<p>
There are some specific cases in which you can get the O(N log K)
performance benefits easily, however, by combining a few ordinary
FFTs. In particular, the case where you want the first K outputs,
where K divides N, can be handled by performing N/K transforms of size
K and then summing the outputs multiplied by appropriate phase
factors. For more details, see <A href="http://www.fftw.org/pruned.html">pruned FFTs with FFTW</A>.
<p>
There are also some algorithms that compute pruned transforms
<i>approximately</i>, but they are beyond the scope of this FAQ.
<h2><A name="transpose">
Question 3.20. Can I use FFTW's routines for in-place and
out-of-place matrix transposition?
</A></h2>
You can use the FFTW guru interface to create a rank-0 transform of
vector rank 2 where the vector strides are transposed. (A rank-0
transform is equivalent to a 1D transform of size 1, which. just
copies the input into the output.) Specifying the same location for
the input and output makes the transpose in-place.
<p>
For double-valued data stored in row-major format, plan creation looks
like this: <pre>
fftw_plan plan_transpose(int rows, int cols, double *in, double *out)
{
const unsigned flags = FFTW_ESTIMATE; /* other flags are possible */
fftw_iodim howmany_dims[2];
howmany_dims[0].n = rows;
howmany_dims[0].is = cols;
howmany_dims[0].os = 1;
howmany_dims[1].n = cols;
howmany_dims[1].is = 1;
howmany_dims[1].os = rows;
return fftw_plan_guru_r2r(/*rank=*/ 0, /*dims=*/ NULL,
/*howmany_rank=*/ 2, howmany_dims,
in, out, /*kind=*/ NULL, flags);
}
</pre>
(This entry was written by Rhys Ulerich.)
<hr>
Next: <a href="section4.html" rel=precedes>Internals of FFTW</a>.<br>
Back: <a href="section2.html" rev=precedes>Installing FFTW</a>.<br>
<a href="index.html" rev=subdocument>Return to contents</a>.<p>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,64 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW FAQ - Section 4
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<link rel="Next" href="section5.html"><link rel="Previous" href="section3.html"><link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW FAQ - Section 4 <br>
Internals of FFTW
</h1>
<ul>
<li><a href="#howworks" rel=subdocument>Q4.1. How does FFTW work?</a>
<li><a href="#whyfast" rel=subdocument>Q4.2. Why is FFTW so fast?</a>
</ul><hr>
<h2><A name="howworks">
Question 4.1. How does FFTW work?
</A></h2>
The innovation (if it can be so called) in FFTW consists in having a
variety of composable <i>solvers</i>, representing different FFT algorithms and implementation strategies, whose combination into a
particular <i>plan</i> for a given size can be determined at runtime according to the characteristics of your machine/compiler.
This peculiar software architecture allows FFTW to adapt itself to
almost any machine.
<p>
For more details (albeit somewhat outdated), see the paper &quot;FFTW:
An Adaptive Software Architecture for the FFT&quot;, by M. Frigo and
S. G. Johnson, <i>Proc. ICASSP</i> 3, 1381 (1998), also available at <A href="http://www.fftw.org">the FFTW web page</A>.
<h2><A name="whyfast">
Question 4.2. Why is FFTW so fast?
</A></h2>
This is a complex question, and there is no simple answer. In fact,
the authors do not fully know the answer, either. In addition to many
small performance hacks throughout FFTW, there are three general
reasons for FFTW's speed.
<ul>
<li> FFTW uses a variety of FFT algorithms and implementation styles
that can be arbitrarily composed to adapt itself to
a machine. See <A href="#howworks">Q4.1 `How does FFTW work?'</A>.
<li> FFTW uses a code generator to produce highly-optimized
routines for computing small transforms.
<li> FFTW uses explicit divide-and-conquer to take advantage
of the memory hierarchy.
</ul>
For more details (albeit somewhat outdated), see the paper &quot;FFTW:
An Adaptive Software Architecture for the FFT&quot;, by M. Frigo and
S. G. Johnson, <i>Proc. ICASSP</i> 3, 1381 (1998), available along with other references at
<A href="http://www.fftw.org">the FFTW web page</A>. <hr>
Next: <a href="section5.html" rel=precedes>Known bugs</a>.<br>
Back: <a href="section3.html" rev=precedes>Using FFTW</a>.<br>
<a href="index.html" rev=subdocument>Return to contents</a>.<p>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,148 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head><title>
FFTW FAQ - Section 5
</title>
<link rev="made" href="mailto:fftw@fftw.org">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<link rel="Previous" href="section4.html"><link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
FFTW FAQ - Section 5 <br>
Known bugs
</h1>
<ul>
<li><a href="#rfftwndbug" rel=subdocument>Q5.1. FFTW 1.1 crashes in rfftwnd on Linux.</a>
<li><a href="#fftwmpibug" rel=subdocument>Q5.2. The MPI transforms in FFTW 1.2 give incorrect results/leak
memory.</a>
<li><a href="#testsingbug" rel=subdocument>Q5.3. The test programs in FFTW 1.2.1 fail when I change FFTW to use single
precision.</a>
<li><a href="#teststoobig" rel=subdocument>Q5.4. The test program in FFTW 1.2.1 fails for n &gt;
46340.</a>
<li><a href="#linuxthreads" rel=subdocument>Q5.5. The threaded code fails on Linux Redhat 5.0</a>
<li><a href="#bigrfftwnd" rel=subdocument>Q5.6. FFTW 2.0's rfftwnd fails for rank &gt; 1 transforms with a final
dimension &gt;= 65536.</a>
<li><a href="#primebug" rel=subdocument>Q5.7. FFTW 2.0's complex transforms give the wrong results with prime
factors 17 to 97.</a>
<li><a href="#mpichbug" rel=subdocument>Q5.8. FFTW 2.1.1's MPI test programs crash with
MPICH.</a>
<li><a href="#aixthreadbug" rel=subdocument>Q5.9. FFTW 2.1.2's multi-threaded transforms don't work on
AIX.</a>
<li><a href="#bigprimebug" rel=subdocument>Q5.10. FFTW 2.1.2's complex transforms give incorrect results for large prime
sizes.</a>
<li><a href="#solaristhreadbug" rel=subdocument>Q5.11. FFTW 2.1.3's multi-threaded transforms don't give any speedup on
Solaris.</a>
<li><a href="#aixflags" rel=subdocument>Q5.12. FFTW 2.1.3 crashes on AIX.</a>
</ul><hr>
<h2><A name="rfftwndbug">
Question 5.1. FFTW 1.1 crashes in rfftwnd on
Linux.
</A></h2>
This bug was fixed in FFTW 1.2. There was a bug in
<code>rfftwnd</code> causing an incorrect amount of memory to be allocated. The bug showed
up in Linux with libc-5.3.12 (and nowhere else that we know of).
<h2><A name="fftwmpibug">
Question 5.2. The MPI transforms in FFTW 1.2 give incorrect
results/leak memory.
</A></h2>
These bugs were corrected in FFTW 1.2.1. The MPI transforms (really,
just the transpose routines) in FFTW 1.2 had bugs that could cause
errors in some situations.
<h2><A name="testsingbug">
Question 5.3. The test programs in FFTW 1.2.1 fail when I change FFTW
to use single precision.
</A></h2>
This bug was fixed in FFTW 1.3. (Older versions of FFTW did
work in single precision, but the test programs didn't--the error
tolerances in the tests were set for double precision.)
<h2><A name="teststoobig">
Question 5.4. The test program in FFTW 1.2.1 fails for n &gt;
46340.
</A></h2>
This bug was fixed in FFTW 1.3. FFTW 1.2.1 produced the right answer,
but the test program was wrong. For large n, n*n in the naive
transform that we used for comparison overflows 32 bit integer
precision, breaking the test.
<h2><A name="linuxthreads">
Question 5.5. The threaded code fails on Linux Redhat
5.0
</A></h2>
We had problems with glibc-2.0.5. The code should work with
glibc-2.0.7.
<h2><A name="bigrfftwnd">
Question 5.6. FFTW 2.0's rfftwnd fails for rank &gt; 1 transforms
with a final dimension &gt;= 65536.
</A></h2>
This bug was fixed in FFTW 2.0.1. (There was a 32-bit integer
overflow due to a poorly-parenthesized expression.)
<h2><A name="primebug">
Question 5.7. FFTW 2.0's complex transforms give the wrong results
with prime factors 17 to 97.
</A></h2>
There was a bug in the complex transforms that could cause incorrect
results under (hopefully rare) circumstances for lengths with
intermediate-size prime factors (17-97). This bug was fixed in FFTW
2.1.1.
<h2><A name="mpichbug">
Question 5.8. FFTW 2.1.1's MPI test programs crash with
MPICH.
</A></h2>
This bug was fixed in FFTW 2.1.2. The 2.1/2.1.1 MPI test programs
crashed when using the MPICH implementation of MPI with the
<code>ch_p4</code> device (TCP/IP); the transforms themselves worked fine.
<h2><A name="aixthreadbug">
Question 5.9. FFTW 2.1.2's multi-threaded transforms don't work on
AIX.
</A></h2>
This bug was fixed in FFTW 2.1.3. The multi-threaded transforms in
previous versions didn't work with AIX's
<code>pthreads</code> implementation, which idiosyncratically creates threads in detached
(non-joinable) mode by default.
<h2><A name="bigprimebug">
Question 5.10. FFTW 2.1.2's complex transforms give incorrect results
for large prime sizes.
</A></h2>
This bug was fixed in FFTW 2.1.3. FFTW's complex-transform algorithm
for prime sizes (in versions 2.0 to 2.1.2) had an integer overflow
problem that caused incorrect results for many primes greater than
32768 (on 32-bit machines). (Sizes without large prime factors are
not affected.)
<h2><A name="solaristhreadbug">
Question 5.11. FFTW 2.1.3's multi-threaded transforms don't give any
speedup on Solaris.
</A></h2>
This bug was fixed in FFTW 2.1.4. (By default, Solaris creates
threads that do not parallelize over multiple processors, so one has
to request the proper behavior specifically.)
<h2><A name="aixflags">
Question 5.12. FFTW 2.1.3 crashes on AIX.
</A></h2>
The FFTW 2.1.3 <code>configure</code> script picked incorrect compiler flags for the <code>xlc</code> compiler on newer IBM processors. This
is fixed in FFTW 2.1.4. <hr>
Back: <a href="section4.html" rev=precedes>Internals of FFTW</a>.<br>
<a href="index.html" rev=subdocument>Return to contents</a>.<p>
<address>
<A href="http://www.fftw.org">Matteo Frigo and Steven G. Johnson</A> / <A href="mailto:fftw@fftw.org">fftw@fftw.org</A>
- 14 September 2021
</address><br>
Extracted from FFTW Frequently Asked Questions with Answers,
Copyright &copy; 2021 Matteo Frigo and Massachusetts Institute of Technology.
</body></html>

View File

@@ -0,0 +1,7 @@
\ References for the FFTW FAQ
\
the FFTW web page \ http://www.fftw.org
FFTW Windows installation notes \ http://www.fftw.org/install/windows.html
Categories of Free and Non-Free Software \ http://www.gnu.org/philosophy/categories.html
the Caml web page \ http://caml.inria.fr
pruned FFTs with FFTW \ http://www.fftw.org/pruned.html

View File

@@ -0,0 +1,189 @@
## ASCII output
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
sub ascii_init {
open(ASCII,">$prefix.ascii");
}
sub ascii_startmajorheading {
print ASCII '='x79,"\n\n";
$ascii_status= 'h';
&ascii_text($_[0] ? "Section $_[0]. " : '');
}
sub ascii_startminorheading {
print ASCII '-'x79,"\n\n";
$ascii_status= 'h';
}
sub ascii_italic { &ascii_text('*'); }
sub ascii_enditalic { $ascii_para .= '*'; }
sub ascii_email { &ascii_text('<'); } sub ascii_endemail { &ascii_text('>'); }
sub ascii_ftpon { } sub ascii_endftpon { }
sub ascii_ftpin { } sub ascii_endftpin { }
sub ascii_docref { } sub ascii_enddocref { }
sub ascii_courier { } sub ascii_endcourier { }
sub ascii_newsgroup { } sub ascii_endnewsgroup { }
sub ascii_ftpsilent { $ascii_ignore++; }
sub ascii_endftpsilent { $ascii_ignore--; }
sub ascii_text {
return if $ascii_ignore;
if ($ascii_status eq '') {
$ascii_status= 'p';
}
$ascii_para .= $_[0];
}
sub ascii_tab {
local ($n) = $_[0]-length($ascii_para);
$ascii_para .= ' 'x$n if $n>0;
}
sub ascii_newline {
return unless $ascii_status eq 'p';
&ascii_writepara;
}
sub ascii_writepara {
local ($thisline, $thisword, $rest);
for (;;) {
last unless $ascii_para =~ m/\S/;
$thisline= $ascii_indentstring;
for (;;) {
last unless $ascii_para =~ m/^(\s*\S+)/;
unless (length($1) + length($thisline) < 75 ||
length($thisline) == length($ascii_indentstring)) {
last;
}
$thisline .= $1;
$ascii_para= $';
}
$ascii_para =~ s/^\s*//;
print ASCII $thisline,"\n";
$ascii_indentstring= $ascii_nextindent;
last unless length($ascii_para);
}
$ascii_status= ''; $ascii_para= '';
}
sub ascii_endpara {
return unless $ascii_status eq 'p';
&ascii_writepara;
print ASCII "\n";
}
sub ascii_endheading {
$ascii_para =~ s/\s*$//;
print ASCII "$ascii_para\n\n";
$ascii_status= '';
$ascii_para= '';
}
sub ascii_endmajorheading { &ascii_endheading(@_); }
sub ascii_endminorheading { &ascii_endheading(@_); }
sub ascii_startverbatim {
$ascii_vstatus= $ascii_status;
&ascii_writepara;
}
sub ascii_verbatim {
print ASCII $_[0],"\n";
}
sub ascii_endverbatim {
$ascii_status= $ascii_vstatus;
}
sub ascii_finish {
close(ASCII);
}
sub ascii_startindex { $ascii_status= ''; }
sub ascii_endindex { $ascii_status= 'p'; }
sub ascii_endindexitem {
printf ASCII " %-11s %-.66s\n",$ascii_left,$ascii_para;
$ascii_status= 'p';
$ascii_para= '';
}
sub ascii_startindexitem {
$ascii_left= $_[1];
}
sub ascii_startindexmainitem {
$ascii_left= $_[1];
print ASCII "\n" if $ascii_status eq 'p';
}
sub ascii_startindent {
$ascii_istatus= $ascii_status;
&ascii_writepara;
$ascii_indentstring= " $ascii_indentstring";
$ascii_nextindent= " $ascii_nextindent";
}
sub ascii_endindent {
$ascii_indentstring =~ s/^ //;
$ascii_nextindent =~ s/^ //;
$ascii_status= $ascii_istatus;
}
sub ascii_startpackedlist { $ascii_plc=0; }
sub ascii_endpackedlist { &ascii_newline if !$ascii_plc; }
sub ascii_packeditem {
&ascii_newline if !$ascii_plc;
&ascii_tab($ascii_plc*40+5);
$ascii_plc= !$ascii_plc;
}
sub ascii_startlist {
&ascii_endpara;
$ascii_indentstring= " $ascii_indentstring";
$ascii_nextindent= " $ascii_nextindent";
}
sub ascii_endlist {
&ascii_endpara;
$ascii_indentstring =~ s/^ //;
$ascii_nextindent =~ s/^ //;
}
sub ascii_item {
&ascii_newline;
$ascii_indentstring =~ s/ $/* /;
}
sub ascii_pageref {
&ascii_text("Q$_[1] \`");
}
sub ascii_endpageref {
&ascii_text("'");
}
1;

View File

@@ -0,0 +1,337 @@
## HTML output
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
%saniarray= ('<','lt', '>','gt', '&','amp', '"','quot');
sub html_init {
$html_prefix = './'.$prefix;
$html_prefix =~ s:^\.//:/:;
system('rm','-r',"$html_prefix.html");
system('mkdir',"$html_prefix.html");
open(HTML,">$html_prefix.html/index.html");
print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
print HTML "<html>\n";
$html_needpara= -1;
$html_end='';
chop($html_date=`date '+%d %B %Y'`);
chop($html_year=`date '+%Y'`);
}
sub html_startup {
print HTML <<END;
<head><title>
$user_title
</title>
<link rev="made" href="mailto:$user_authormail">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
<META name="description"
content="Frequently asked questions and answers (FAQ) for FFTW.">
<link rel="Bookmark" title="FFTW FAQ" href="index.html">
<LINK rel="Bookmark" title="FFTW Home Page"
href="http://www.fftw.org">
<LINK rel="Bookmark" title="FFTW Manual"
href="http://www.fftw.org/doc/">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
$user_title
</h1>
END
&html_readrefs($_[0]);
if (length($user_copyrightref)) {
local ($refn) = $qrefn{$user_copyrightref};
if (!length($refn)) {
warn "unknown question (copyright) `$user_copyrightref'";
}
$refn =~ m/(\d+)\.(\d+)/;
local ($s,$n) = ($1,$2);
$html_copyrighthref= ($s == $html_sectionn)?'':"section$s.html";
$html_copyrighthref.= "#$qn2ref{$s,$n}";
}
}
sub html_close {
print HTML $html_end,"<address>\n$user_author\n";
print HTML "- $html_date\n</address><br>\n";
print HTML "Extracted from $user_title,\n";
print HTML "<A href=\"$html_copyrighthref\">" if length($html_copyrighthref);
print HTML "Copyright &copy; $html_year $user_copyholder.";
print HTML "</A>" if length($html_copyrighthref);
print HTML "\n</body></html>\n";
close(HTML);
}
sub html_startmajorheading {
local ($ref, $this,$next,$back) = @_;
local ($nextt,$backt);
$this =~ s/^Section /section/; $html_sectionn= $ref;
$next =~ s/^Section /section/ && ($nextt= $sn2title{$'});
$back =~ s/^Section /section/ ? ($backt= $sn2title{$'}) : ($back='');
if ($html_sectionn) {
&html_close;
open(HTML,">$html_prefix.html/$this.html");
print HTML "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n";
print HTML "<html>\n";
$html_end= "<hr>\n";
$html_end.= "Next: <a href=\"$next.html\" rel=precedes>$nextt</a>.<br>\n"
if $next;
$html_end.= "Back: <a href=\"$back.html\" rev=precedes>$backt</a>.<br>\n"
if $back;
$html_end.= "<a href=\"index.html\" rev=subdocument>";
$html_end.= "Return to contents</a>.<p>\n";
print HTML <<END;
<head><title>
$user_brieftitle - Section $html_sectionn
</title>
<link rev="made" href="mailto:$user_authormail">
<link rel="Contents" href="index.html">
<link rel="Start" href="index.html">
END
print HTML "<link rel=\"Next\" href=\"$next.html\">" if $next;
print HTML "<link rel=\"Previous\" href=\"$back.html\">" if $back;
print HTML <<END;
<link rel="Bookmark" title="FFTW FAQ" href="index.html">
</head><body text="#000000" bgcolor="#FFFFFF"><h1>
$user_brieftitle - Section $html_sectionn <br>
END
$html_needpara= -1;
}
else {
print HTML "\n<h1>\n";
$html_needpara=-1;
}
}
sub html_endmajorheading {
print HTML "\n</h1>\n\n";
$html_needpara=-1;
}
sub html_startminorheading {
local ($ref, $this) = @_;
$html_needpara=0;
$this =~ m/^Question (\d+)\.(\d+)/;
local ($s,$n) = ($1,$2);
print HTML "\n<h2><A name=\"$qn2ref{$s,$n}\">\n";
}
sub html_endminorheading {
print HTML "\n</A></h2>\n\n";
$html_needpara=-1;
}
sub html_newsgroup { &arg('newsgroup'); }
sub html_endnewsgroup { &endarg('newsgroup'); }
sub html_do_newsgroup {
print HTML "<A href=\"news:$_[0]\"><code>$_[0]</code></A>";
}
sub html_email { &arg('email'); }
sub html_endemail { &endarg('email'); }
sub html_do_email {
print HTML "<A href=\"mailto:$_[0]\"><code>$_[0]</code></A>";
}
sub html_courier { print HTML "<code>" ; }
sub html_endcourier { print HTML "</code>"; }
sub html_italic { print HTML "<i>" ; }
sub html_enditalic { print HTML "</i>" ; }
sub html_docref { &arg('docref'); }
sub html_enddocref { &endarg('docref'); }
sub html_do_docref {
if (!defined($html_refval{$_[0]})) {
warn "undefined HTML reference $_[0]";
$html_refval{$n}='UNDEFINED';
}
print HTML "<A href=\"$html_refval{$_[0]}\">";
&recurse($_[0]);
print HTML "</A>";
}
sub html_readrefs {
local ($p);
open(HTMLREFS,"<$_[0]") || (warn("failed to open HTML refs $_[0]: $!"),return);
while(<HTMLREFS>) {
next if m/^\\\s/;
s/\s*\n$//;
if (s/^\\prefix\s*//) {
$p= $'; next;
} elsif (s/^\s*(\S.*\S)\s*\\\s*//) {
$_=$1; $v=$';
s/\\\\/\\/g;
$html_refval{$_}= $p.$v;
} else {
warn("ununderstood line in HTML refs >$_<");
}
}
close(HTMLREFS);
}
sub html_ftpsilent { &arg('ftpsilent'); }
sub html_endftpsilent { &endarg('ftpsilent'); }
sub html_do_ftpsilent {
if ($_[0] =~ m/:/) {
$html_ftpsite= $`;
$html_ftpdir= $'.'/';
} else {
$html_ftpsite= $_[0];
$html_ftpdir= '';
}
}
sub html_ftpon { &arg('ftpon'); }
sub html_endftpon { &endarg('ftpon'); }
sub html_do_ftpon {
#print STDERR "ftpon($_[0])\n";
$html_ftpsite= $_[0]; $html_ftpdir= '';
print HTML "<code>";
&recurse($_[0]);
print HTML "</code>";
}
sub html_ftpin { &arg('ftpin'); }
sub html_endftpin { &endarg('ftpin'); }
sub html_do_ftpin {
#print STDERR "ftpin($_[0])\n";
print HTML "<A href=\"ftp://$html_ftpsite$html_ftpdir$_[0]\"><code>";
&recurse($_[0]);
print HTML "</code></A>";
}
sub html_text {
print HTML "\n<p>\n" if $html_needpara > 0;
$html_needpara=0;
$html_stuff= &html_sanitise($_[0]);
while ($html_stuff =~ s/^(.{40,70}) //) {
print HTML "$1\n";
}
print HTML $html_stuff;
}
sub html_tab {
$htmltabignore++ || warn "html tab ignored";
}
sub html_newline { print HTML "<br>\n" ; }
sub html_startverbatim { print HTML "<pre>\n" ; }
sub html_verbatim { print HTML &html_sanitise($_[0]),"\n"; }
sub html_endverbatim { print HTML "</pre>\n" ; $html_needpara= -1; }
sub html_endpara {
$html_needpara || $html_needpara++;
}
sub html_finish {
&html_close;
}
sub html_startindex {
print HTML "<ul>\n";
}
sub html_endindex {
print HTML "</ul><hr>\n";
}
sub html_startindexitem {
local ($ref,$qval) = @_;
$qval =~ m/Q(\d+)\.(\d+)/;
local ($s,$n) = ($1,$2);
print HTML "<li><a href=\"";
print HTML ($s == $html_sectionn)?'':"section$s.html";
print HTML "#$qn2ref{$s,$n}\" rel=subdocument>Q$s.$n. ";
$html_indexunhead='';
}
sub html_startindexmainitem {
local ($ref,$s) = @_;
$s =~ m/\d+/; $s= $&;
print HTML "<br><br>" if ($s > 1);
print HTML "<li><b><font size=\"+2\"><a href=\"section$s.html\" rel=subdocument>Section $s. ";
$html_indexunhead='</font></b>';
}
sub html_endindexitem {
print HTML "</a>$html_indexunhead\n";
}
sub html_startlist {
print HTML "\n";
$html_itemend="<ul>";
}
sub html_endlist {
print HTML "$html_itemend\n</ul>\n";
$html_needpara=-1
}
sub html_item {
print HTML "$html_itemend\n<li>";
$html_itemend="";
$html_needpara=-1;
}
sub html_startpackedlist {
print HTML "\n";
$html_itemend="<dir>";
}
sub html_endpackedlist {
print HTML "$html_itemend\n</dir>\n";
$html_needpara=-1;
}
sub html_packeditem {
print HTML "$html_itemend\n<li>";
$html_itemend="";
$html_needpara=-1;
}
sub html_startindent { print HTML "<blockquote>\n"; }
sub html_endindent { print HTML "</blockquote>\n"; }
sub html_pageref {
local ($ref,$sq) = @_;
$sq =~ m/(\d+)\.(\d+)/;
local ($s,$n) = ($1,$2);
print HTML "<A href=\"";
print HTML ($s == $html_sectionn)?'':"section$s.html";
print HTML "#$qn2ref{$s,$n}\">Q$sq \`";
}
sub html_endpageref {
print HTML "'</A>";
}
sub html_sanitise {
local ($in) = @_;
local ($out);
while ($in =~ m/[<>&"]/) {
$out.= $`. '&'. $saniarray{$&}. ';';
$in=$';
}
$out.= $in;
$out;
}
1;

View File

@@ -0,0 +1,226 @@
## Info output
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
sub info_init {
open(INFO,">$prefix.info");
print INFO <<END;
Info file: $prefix.info, -*-Text-*-
produced by bfnnconv.pl from the Bizarre Format With No Name.
END
}
sub info_heading {
# refstring Node Next Previous Up
print INFO "\nFile: $prefix.info, Node: $_[1]";
print INFO ", Next: $_[2]" if length($_[2]);
print INFO ", Previous: $_[3]" if length($_[3]);
print INFO ", Up: $_[4]" if length($_[4]);
print INFO "\n\n";
$info_status= '';
}
sub info_startmajorheading {
return if $_[0] eq '0';
&info_heading('s_'.$_[0],@_[1..$#_],'Top');
}
sub info_startminorheading {
&info_heading(@_);
}
sub info_italic { &info_text('*'); }
sub info_enditalic { $info_para .= '*'; }
sub info_email { &info_text('<'); } sub info_endemail { &info_text('>'); }
sub info_ftpon { } sub info_endftpon { }
sub info_ftpin { } sub info_endftpin { }
sub info_docref { } sub info_enddocref { }
sub info_courier { } sub info_endcourier { }
sub info_newsgroup { } sub info_endnewsgroup { }
sub info_ftpsilent { $info_ignore++; }
sub info_endftpsilent { $info_ignore--; }
sub info_text {
return if $info_ignore;
if ($info_status eq '') {
$info_status= 'p';
}
$info_para .= $_[0];
}
sub info_tab {
local ($n) = $_[0]-length($info_para);
$info_para .= ' 'x$n if $n>0;
}
sub info_newline {
return unless $info_status eq 'p';
print INFO &info_writepara;
}
sub info_writepara {
local ($thisline, $thisword, $rest, $output);
for (;;) {
last unless $info_para =~ m/\S/;
$thisline= $info_indentstring;
for (;;) {
last unless $info_para =~ m/^(\s*\S+)/;
unless (length($1) + length($thisline) < 75 ||
length($thisline) == length($info_indentstring)) {
last;
}
$thisline .= $1;
$info_para= $';
}
$info_para =~ s/^\s*//;
$output.= $thisline."\n";
$info_indentstring= $info_nextindent;
last unless length($info_para);
}
$info_status= ''; $info_para= '';
return $output;
}
sub info_endpara {
return unless $info_status eq 'p';
print INFO &info_writepara;
print INFO "\n";
}
sub info_endheading {
$info_para =~ s/\s*$//;
print INFO "$info_para\n\n";
$info_status= '';
$info_para= '';
}
sub info_endmajorheading { &info_endheading(@_); }
sub info_endminorheading { &info_endheading(@_); }
sub info_startverbatim {
print INFO &info_writepara;
}
sub info_verbatim {
print INFO $_[0],"\n";
}
sub info_endverbatim {
$info_status= $info_vstatus;
}
sub info_finish {
close(INFO);
}
sub info_startindex {
&info_endpara;
$info_moredetail= '';
$info_status= '';
}
sub info_endindex {
print INFO "$info_moredetail\n" if length($info_moredetail);
}
sub info_endindexitem {
$info_indentstring= sprintf("* %-17s ",$info_label.'::');
$info_nextindent= ' 'x20;
local ($txt);
$txt= &info_writepara;
if ($info_main) {
print INFO $label.$txt;
$txt =~ s/^.{20}//;
$info_moredetail.= $txt;
} else {
$info_moredetail.= $label.$txt;
}
$info_indentstring= $info_nextindent= '';
$info_status='p';
}
sub info_startindexitem {
print INFO "* Menu:\n" if $info_status eq '';
$info_status= '';
$info_label= $_[2];
$info_main= 0;
}
sub info_startindexmainitem {
print INFO "* Menu:\n" if $info_status eq '';
$info_label= $_[2];
$info_main= 1;
$info_moredetail .= "\n$_[2], ";
$info_status= '';
}
sub info_startindent {
$info_istatus= $info_status;
print INFO &info_writepara;
$info_indentstring= " $info_indentstring";
$info_nextindent= " $info_nextindent";
}
sub info_endindent {
$info_indentstring =~ s/^ //;
$info_nextindent =~ s/^ //;
$info_status= $info_istatus;
}
sub info_startpackedlist { $info_plc=0; }
sub info_endpackedlist { &info_newline if !$info_plc; }
sub info_packeditem {
&info_newline if !$info_plc;
&info_tab($info_plc*40+5);
$info_plc= !$info_plc;
}
sub info_startlist {
$info_istatus= $info_status;
print INFO &info_writepara;
$info_indentstring= " $info_indentstring";
$info_nextindent= " $info_nextindent";
}
sub info_endlist {
$info_indentstring =~ s/^ //;
$info_nextindent =~ s/^ //;
$info_status= $info_lstatus;
}
sub info_item {
&info_newline;
$info_indentstring =~ s/ $/* /;
}
sub info_pageref {
&info_text("*Note Question $_[1]:: \`");
}
sub info_endpageref {
&info_text("'");
}
1;

View File

@@ -0,0 +1,242 @@
## Lout output
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
sub lout_init {
open(LOUT,">$prefix.lout");
chop($dprint= `date '+%d %B %Y'`);
$dprint =~ s/^0//;
}
sub lout_startup {
local ($lbs) = &lout_sanitise($user_brieftitle);
print LOUT <<END;
\@SysInclude{ fontdefs }
\@SysInclude{ langdefs }
\@SysInclude{ dl }
\@SysInclude{ docf }
\@Use { \@DocumentLayout
\@OddTop { \@Null }
\@EvenTop { \@Null }
\@StartOddTop { \@Null }
\@StartEvenTop { \@Null }
\@OddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
\@EvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
\@StartOddFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
\@StartEvenFoot { { $lbs } \@Centre{ - \@PageNum - } \@Right{ $dprint } }
\@ParaGap { 1.70vx }
\@InitialBreak { 1.0fx ragged hyphen }
}
\@Use { \@OrdinaryLayout }
END
$lout_textstatus= 'p';
}
sub lout_pageref {
print LOUT "Q$_[1] (page {\@PageOf{$_[0]}}) ";
&lout_text("\`");
}
sub lout_endpageref {
&lout_text("'");
}
sub lout_finish {
print LOUT "\@End \@Text\n";
close(L);
}
sub lout_startmajorheading {
$lout_styles .= 'h';
print LOUT <<END
\@CNP
{
newpath 0 ysize 0.3 ft sub moveto
xsize 0 rlineto
0 0.2 ft rlineto
xsize neg 0 rlineto
closepath fill
} \@Graphic { //1.6f \@HAdjust \@Heading{
END
;
$endh= "}\n{\@PageMark s_$_[0]}\n/1.0fo\n";
&lout_text($_[0] ? "Section $_[0]. " : '');
}
sub lout_startminorheading {
$lout_styles .= 'h';
print LOUT "//0.2f \@CNP {\@PageMark $_[0]} \@Heading{\n";
$endh= '';
}
sub lout_endheading {
$lout_styles =~ s/.$//; print LOUT "}\n$endh";
$lout_status= 'p';
}
sub lout_endmajorheading { &lout_endheading(@_); }
sub lout_endminorheading { &lout_endheading(@_); }
sub lout_courier {
$lout_styles .= 'f';
print LOUT "{{0.7 1.0} \@Scale {Courier Bold} \@Font {";
}
sub lout_endcourier {
$lout_styles =~ s/.$//; print LOUT "}}";
}
sub lout_italic { $lout_styles .= 'f'; print LOUT "{Slope \@Font {"; }
sub lout_enditalic { $lout_styles =~ s/.$//; print LOUT "}}"; }
sub lout_startindent { $lout_styles .= 'i'; print LOUT "\@IndentedDisplay {\n"; }
sub lout_endindent {
&lout_endpara;
$lout_styles =~ s/.$//; print LOUT "}\n\@LP\n";
}
sub lout_startpackedlist { $lout_plc=-1; }
sub lout_endpackedlist { &lout_newline if !$lout_plc; }
sub lout_packeditem {
&lout_newline if !$lout_plc;
&lout_tab(($lout_plc>0)*40+5);
$lout_plc= !$lout_plc;
}
sub lout_startlist {
&lout_endpara;
print LOUT "\@RawIndentedList style {\@Bullet} indent {0.5i} gap {1.1vx}\n";
$lout_styles .= 'l';
$lout_status= '';
}
sub lout_endlist {
&lout_endpara;
print LOUT "\@EndList\n\n";
$lout_styles =~ s/.$//;
}
sub lout_item {
&lout_endpara;
print LOUT "\@ListItem{";
$lout_styles.= 'I';
}
sub lout_startindex {
print LOUT "//0.0fe\n";
}
sub lout_endindex {
$lout_status='p';
}
sub lout_startindexmainitem {
$lout_marker= $_[0];
$lout_status= '';
print LOUT "//0.3vx Bold \@Font \@HAdjust { \@HContract { { $_[1] } |3cx {";
$lout_iiendheight= '1.00';
$lout_styles .= 'X';
}
sub lout_startindexitem {
$lout_marker= $_[0];
print LOUT "\@HAdjust { \@HContract { { $_[1] } |3cx {";
$lout_iiendheight= '0.95';
$lout_styles .= 'X';
}
sub lout_endindexitem {
print LOUT "} } |0c \@PageOf { $lout_marker } } //${lout_iiendheight}vx\n";
$lout_styles =~ s/.$//;
}
sub lout_email { &lout_courier; &lout_text('<'); }
sub lout_endemail { &lout_text('>'); &lout_endcourier; }
sub lout_ftpon { &lout_courier; } sub lout_endftpon { &lout_endcourier; }
sub lout_ftpin { &lout_courier; } sub lout_endftpin { &lout_endcourier; }
sub lout_docref { } sub lout_enddocref { }
sub lout_ftpsilent { $lout_ignore++; }
sub lout_endftpsilent { $lout_ignore--; }
sub lout_newsgroup { &lout_courier; }
sub lout_endnewsgroup { &lout_endcourier; }
sub lout_text {
return if $lout_ignore;
$lout_status= 'p';
$_= &lout_sanitise($_[0]);
s/ $/\n/ unless $lout_styles =~ m/[fhX]/;
print LOUT $_;
}
sub lout_tab {
local ($size) = $_[0]*0.5;
print LOUT " |${size}ft ";
}
sub lout_newline {
print LOUT " //1.0vx\n";
}
sub lout_sanitise {
local ($in) = @_;
local ($out);
$in= ' '.$in.' ';
$out='';
while ($in =~ m/(\s)(\S*[\@\/|\\\"\^\&\{\}\#]\S*)(\s)/) {
$out .= $`.$1;
$in = $3.$';
$_= $2;
s/[\\\"]/\\$&/g;
$out .= '"'.$_.'"';
}
$out .= $in;
$out =~ s/^ //; $out =~ s/ $//;
$out;
}
sub lout_endpara {
return if $lout_status eq '';
if ($lout_styles eq '') {
print LOUT "\@LP\n\n";
} elsif ($lout_styles =~ s/I$//) {
print LOUT "}\n";
}
$lout_status= '';
}
sub lout_startverbatim {
print LOUT "//0.4f\n\@RawIndentedDisplay lines \@Break".
" { {0.7 1.0} \@Scale {Courier Bold} \@Font {\n";
}
sub lout_verbatim {
$_= $_[0];
s/^\s*//;
print LOUT &lout_sanitise($_),"\n";
}
sub lout_endverbatim { print LOUT "}\n}\n//0.4f\n"; }
1;

View File

@@ -0,0 +1,189 @@
## POST output
# Copyright (C) 1993-1995 Ian Jackson.
# This file 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, or (at your option)
# any later version.
# It 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 GNU Emacs; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# (Note: I do not consider works produced using these BFNN processing
# tools to be derivative works of the tools, so they are NOT covered
# by the GPL. However, I would appreciate it if you credited me if
# appropriate in any documents you format using BFNN.)
sub post_init {
open(POST,">$prefix.post");
}
sub post_startmajorheading {
print POST '='x79,"\n\n";
$post_status= 'h';
&post_text($_[0] ? "Section $_[0]. " : '');
}
sub post_startminorheading {
print POST '-'x77,"\n\n";
$post_status= 'h';
}
sub post_italic { &post_text('*'); }
sub post_enditalic { $post_para .= '*'; }
sub post_email { &post_text('<'); } sub post_endemail { &post_text('>'); }
sub post_ftpon { } sub post_endftpon { }
sub post_ftpin { } sub post_endftpin { }
sub post_docref { } sub post_enddocref { }
sub post_courier { } sub post_endcourier { }
sub post_newsgroup { } sub post_endnewsgroup { }
sub post_ftpsilent { $post_ignore++; }
sub post_endftpsilent { $post_ignore--; }
sub post_text {
return if $post_ignore;
if ($post_status eq '') {
$post_status= 'p';
}
$post_para .= $_[0];
}
sub post_tab {
local ($n) = $_[0]-length($post_para);
$post_para .= ' 'x$n if $n>0;
}
sub post_newline {
return unless $post_status eq 'p';
&post_writepara;
}
sub post_writepara {
local ($thisline, $thisword, $rest);
for (;;) {
last unless $post_para =~ m/\S/;
$thisline= $post_indentstring;
for (;;) {
last unless $post_para =~ m/^(\s*\S+)/;
unless (length($1) + length($thisline) < 75 ||
length($thisline) == length($post_indentstring)) {
last;
}
$thisline .= $1;
$post_para= $';
}
$post_para =~ s/^\s*//;
print POST $thisline,"\n";
$post_indentstring= $post_nextindent;
last unless length($post_para);
}
$post_status= ''; $post_para= '';
}
sub post_endpara {
return unless $post_status eq 'p';
&post_writepara;
print POST "\n";
}
sub post_endheading {
$post_para =~ s/\s*$//;
print POST "$post_para\n\n";
$post_status= '';
$post_para= '';
}
sub post_endmajorheading { &post_endheading(@_); }
sub post_endminorheading { &post_endheading(@_); }
sub post_startverbatim {
$post_vstatus= $post_status;
&post_writepara;
}
sub post_verbatim {
print POST $_[0],"\n";
}
sub post_endverbatim {
$post_status= $post_vstatus;
}
sub post_finish {
close(POST);
}
sub post_startindex { $post_status= ''; }
sub post_endindex { $post_status= 'p'; }
sub post_endindexitem {
printf POST " %-11s %-.66s\n",$post_left,$post_para;
$post_status= 'p';
$post_para= '';
}
sub post_startindexitem {
$post_left= $_[1];
}
sub post_startindexmainitem {
$post_left= $_[1];
print POST "\n" if $post_status eq 'p';
}
sub post_startindent {
$post_istatus= $post_status;
&post_writepara;
$post_indentstring= " $post_indentstring";
$post_nextindent= " $post_nextindent";
}
sub post_endindent {
$post_indentstring =~ s/^ //;
$post_nextindent =~ s/^ //;
$post_status= $post_istatus;
}
sub post_startpackedlist { $post_plc=0; }
sub post_endpackedlist { &post_newline if !$post_plc; }
sub post_packeditem {
&post_newline if !$post_plc;
&post_tab($post_plc*40+5);
$post_plc= !$post_plc;
}
sub post_startlist {
&post_endpara;
$post_indentstring= " $post_indentstring";
$post_nextindent= " $post_nextindent";
}
sub post_endlist {
&post_endpara;
$post_indentstring =~ s/^ //;
$post_nextindent =~ s/^ //;
}
sub post_item {
&post_newline;
$post_indentstring =~ s/ $/* /;
}
sub post_pageref {
&post_text("Q$_[1] \`");
}
sub post_endpageref {
&post_text("'");
}
1;