diff options
Diffstat (limited to 'nist')
-rw-r--r-- | nist/Makefile.am | 22 | ||||
-rw-r--r-- | nist/Makefile.in | 576 | ||||
-rw-r--r-- | nist/cephes-protos.h | 180 | ||||
-rw-r--r-- | nist/cephes.c | 1327 | ||||
-rw-r--r-- | nist/dfft.c | 1381 | ||||
-rw-r--r-- | nist/matrix.c | 168 | ||||
-rw-r--r-- | nist/matrix.h | 19 | ||||
-rw-r--r-- | nist/mconf.h | 169 | ||||
-rw-r--r-- | nist/nist.c | 57 | ||||
-rw-r--r-- | nist/nist.h | 33 | ||||
-rw-r--r-- | nist/packtest.c | 2252 | ||||
-rw-r--r-- | nist/special-functions.c | 32 | ||||
-rw-r--r-- | nist/special-functions.h | 14 | ||||
-rw-r--r-- | nist/template9 | 148 |
14 files changed, 6378 insertions, 0 deletions
diff --git a/nist/Makefile.am b/nist/Makefile.am new file mode 100644 index 0000000..bbaaf17 --- /dev/null +++ b/nist/Makefile.am @@ -0,0 +1,22 @@ +## Process this file with automake to produce Makefile.in. + + +if ENABLE_NIST_TEST +check_PROGRAMS = nist +endif + +AM_CFLAGS=-Wall + +nist_LDADD = -lm + +nist_SOURCES = cephes.c dfft.c matrix.c nist.c packtest.c special-functions.c cephes-protos.h matrix.h mconf.h special-functions.h nist.h + +CLEANFILES = sample nist.out + +MAINTAINERCLEANFILES = Makefile.in + +if ENABLE_NIST_TEST +check-local: + ../src/haveged -n 16M $* + ./nist sample ${srcdir} +endif
\ No newline at end of file diff --git a/nist/Makefile.in b/nist/Makefile.in new file mode 100644 index 0000000..82999a1 --- /dev/null +++ b/nist/Makefile.in @@ -0,0 +1,576 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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@ +@ENABLE_NIST_TEST_TRUE@check_PROGRAMS = nist$(EXEEXT) +subdir = nist +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +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_nist_OBJECTS = cephes.$(OBJEXT) dfft.$(OBJEXT) matrix.$(OBJEXT) \ + nist.$(OBJEXT) packtest.$(OBJEXT) special-functions.$(OBJEXT) +nist_OBJECTS = $(am_nist_OBJECTS) +nist_DEPENDENCIES = +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +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 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = +am__maybe_remake_depfiles = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nist_SOURCES) +DIST_SOURCES = $(nist_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) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVEGE_LT_VERSION = @HAVEGE_LT_VERSION@ +HA_DISTRO = @HA_DISTRO@ +HA_LDFLAGS = @HA_LDFLAGS@ +HA_UNITD = @HA_UNITD@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +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@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +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@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +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@ +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@ +AM_CFLAGS = -Wall +nist_LDADD = -lm +nist_SOURCES = cephes.c dfft.c matrix.c nist.c packtest.c special-functions.c cephes-protos.h matrix.h mconf.h special-functions.h nist.h +CLEANFILES = sample nist.out +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(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 --ignore-deps nist/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu --ignore-deps nist/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: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +nist$(EXEEXT): $(nist_OBJECTS) $(nist_DEPENDENCIES) $(EXTRA_nist_DEPENDENCIES) + @rm -f nist$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(nist_OBJECTS) $(nist_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(AM_V_CC)$(COMPILE) -c -o $@ $< + +.c.obj: + $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: + $(AM_V_CC)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +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 +@ENABLE_NIST_TEST_FALSE@check-local: +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-local +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +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-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am check-local clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-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-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@ENABLE_NIST_TEST_TRUE@check-local: +@ENABLE_NIST_TEST_TRUE@ ../src/haveged -n 16M $* +@ENABLE_NIST_TEST_TRUE@ ./nist sample ${srcdir} + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/nist/cephes-protos.h b/nist/cephes-protos.h new file mode 100644 index 0000000..1041936 --- /dev/null +++ b/nist/cephes-protos.h @@ -0,0 +1,180 @@ +/* + * This file was automatically generated by version 1.7 of cextract. + * Manual editing not recommended. + * + * Created: Fri Mar 31 19:17:33 1995 + */ +extern double acosh ( double x ); +extern int airy ( double x, double *ai, double *aip, double *bi, double *bip ); +extern double asin ( double x ); +extern double acos ( double x ); +extern double asinh ( double x ); +extern double atan ( double x ); +extern double atan2 ( double y, double x ); +extern double atanh ( double x ); +extern double bdtrc ( int k, int n, double p ); +extern double bdtr ( int k, int n, double p ); +extern double bdtri ( int k, int n, double y ); +extern double beta ( double a, double b ); +extern double lbeta ( double a, double b ); +extern double btdtr ( double a, double b, double x ); +extern double cbrt ( double x ); +extern double chbevl ( double x, void *P, int n ); +extern double chdtrc ( double df, double x ); +extern double chdtr ( double df, double x ); +extern double chdtri ( double df, double y ); +// extern void clog ( cmplx *z, cmplx *w ); +extern void _cexp ( cmplx *z, cmplx *w ); +extern void _csin ( cmplx *z, cmplx *w ); +extern void _ccos ( cmplx *z, cmplx *w ); +extern void _ctan ( cmplx *z, cmplx *w ); +extern void _ccot ( cmplx *z, cmplx *w ); +extern void _casin ( cmplx *z, cmplx *w ); +extern void _cacos ( cmplx *z, cmplx *w ); +extern void _catan ( cmplx *z, cmplx *w ); +extern void cadd ( cmplx *a, cmplx *b, cmplx *c ); +extern void csub ( cmplx *a, cmplx *b, cmplx *c ); +extern void cmul ( cmplx *a, cmplx *b, cmplx *c ); +extern void cdiv ( cmplx *a, cmplx *b, cmplx *c ); +extern void cmov ( void *a, void *b ); +extern void cneg ( cmplx *a ); +//extern double _cabs ( cmplx *z ); +extern void _csqrt ( cmplx *z, cmplx *w ); +extern double hypot ( double x, double y ); +extern double cosh ( double x ); +extern double dawsn ( double xx ); +extern void eigens ( double A[], double RR[], double E[], int N ); +extern double ellie ( double phi, double m ); +extern double ellik ( double phi, double m ); +extern double ellpe ( double x ); +extern int ellpj ( double u, double m, double *sn, double *cn, double *dn, double *ph ); +extern double ellpk ( double x ); +extern double exp ( double x ); +extern double exp10 ( double x ); +extern double exp1m ( double x ); +extern double exp2 ( double x ); +extern double expn ( int n, double x ); +extern double fabs ( double x ); +extern double fac ( int i ); +extern double fdtrc ( int ia, int ib, double x ); +extern double fdtr ( int ia, int ib, double x ); +extern double fdtri ( int ia, int ib, double y ); +extern int fftr ( double x[], int m0, double sine[] ); +extern double ceil ( double x ); +extern double floor ( double x ); +extern double frexp ( double x, int *pw2 ); +extern double ldexp ( double x, int pw2 ); +extern int _signbit ( double x ); +/* extern int isnan ( double x ); */ +/*extern int isfinite ( double x );*/ +extern int fresnl ( double xxa, double *ssa, double *cca ); +extern double gamma ( double x ); +extern double lgam ( double x ); +extern double gdtr ( double a, double b, double x ); +extern double gdtrc ( double a, double b, double x ); +extern int gels ( double A[], double R[], int M, double EPS, double AUX[] ); +extern double hyp2f1 ( double a, double b, double c, double x ); +extern double hyperg ( double a, double b, double x ); +extern double hyp2f0 ( double a, double b, double x, int type, double *err ); +extern double i0 ( double x ); +extern double i0e ( double x ); +extern double i1 ( double x ); +extern double i1e ( double x ); +extern double igamc ( double a, double x ); +extern double igam ( double a, double x ); +extern double igami ( double a, double y0 ); +extern double incbet ( double aa, double bb, double xx ); +extern double incbi ( double aa, double bb, double yy0 ); +extern double iv ( double v, double x ); +extern double j0 ( double x ); +extern double y0 ( double x ); +extern double j1 ( double x ); +extern double y1 ( double x ); +extern double jn ( int n, double x ); +extern double jv ( double n, double x ); +extern double k0 ( double x ); +extern double k0e ( double x ); +extern double k1 ( double x ); +extern double k1e ( double x ); +extern double kn ( int nn, double x ); +extern int levnsn ( int n, double r[], double a[], double e[], double refl[] ); +extern double log ( double x ); +extern double log10 ( double x ); +extern double _log2 ( double x ); +extern long lrand ( void ); +extern long lsqrt ( long x ); +extern int minv ( double A[], double X[], int n, double B[], int IPS[] ); +extern int mmmpy ( int r, int c, double *A, double *B, double *Y ); +extern int mtherr ( char *name, int code ); +/*extern double polevl ( double x, void *P, int N ); +extern double p1evl ( double x, void *P, int N );*/ +extern int mtransp ( int n, double *A, double *T ); +extern int mvmpy ( int r, int c, double *A, double *V, double *Y ); +extern double nbdtrc ( int k, int n, double p ); +extern double nbdtr ( int k, int n, double p ); +extern double nbdtri ( int k, int n, double p ); +extern double ndtr ( double a ); +extern double erfc ( double a ); +extern double erf ( double x ); +extern double ndtri ( double y0 ); +extern double pdtrc ( int k, double m ); +extern double pdtr ( int k, double m ); +extern double pdtri ( int k, double y ); +extern double pow ( double x, double y ); +extern double powi ( double x, int nn ); +extern double psi ( double x ); +extern void revers ( double y[], double x[], int n ); +extern double rgamma ( double x ); +extern double round ( double x ); +extern int sprec ( void ); +extern int dprec ( void ); +extern int ldprec ( void ); +extern int shichi ( double x, double *si, double *ci ); +extern int sici ( double x, double *si, double *ci ); +extern double simpsn ( double f[], double delta ); +extern int simq ( double A[], double B[], double X[], int n, int flag, int IPS[] ); +extern double sin ( double x ); +extern double cos ( double x ); +extern double radian ( double d, double m, double s ); +/* +extern int sincos ( double x, double *s, double *c, int flg ); +*/ +extern double sindg ( double x ); +extern double cosdg ( double x ); +extern double sinh ( double x ); +extern double spence ( double x ); +extern double sqrt ( double x ); +extern double stdtr ( int k, double t ); +extern double stdtri ( int k, double p ); +extern double onef2 ( double a, double b, double c, double x, double *err ); +extern double threef0 ( double a, double b, double c, double x, double *err ); +extern double struve ( double v, double x ); +extern double tan ( double x ); +extern double cot ( double x ); +extern double tandg ( double x ); +extern double cotdg ( double x ); +extern double tanh ( double x ); +extern double log1p ( double x ); +extern double expm1 ( double x ); +extern double cosm1 ( double x ); +extern double yn ( int n, double x ); +extern double zeta ( double x, double q ); +extern double zetac ( double x ); +extern int drand ( double *a ); + +/* polyn.c */ +extern void polini ( int maxdeg ); +extern void polprt ( double a[], int na, int d ); +extern void polclr ( double *a, int n ); +extern void polmov ( double *a, int na, double *b ); +extern void polmul ( double a[], int na, double b[], int nb, double c[] ); +extern void poladd ( double a[], int na, double b[], int nb, double c[] ); +extern void polsub ( double a[], int na, double b[], int nb, double c[] ); +extern int poldiv ( double a[], int na, double b[], int nb, double c[] ); +extern void polsbt ( double a[], int na, double b[], int nb, double c[] ); +extern double poleva ( double a[], int na, double x ); +/* polmisc.c */ +extern void polatn ( double num[], double den[], double ans[], int nn ); +extern void polsqt ( double pol[], double ans[], int nn ); +extern void polsin ( double x[], double y[], int nn ); +extern void polcos ( double x[], double y[], int nn ); diff --git a/nist/cephes.c b/nist/cephes.c new file mode 100644 index 0000000..6fc1500 --- /dev/null +++ b/nist/cephes.c @@ -0,0 +1,1327 @@ +#include <stdio.h> +#include "mconf.h" + +double p1evl(double, double [], int); +double polevl(double, double [], int); + +#ifndef ANSIPROT +double lgam(), exp(), log(), fabs(), igam(), igamc(); +#endif + +int merror = 0; + +/* Notice: the order of appearance of the following + * messages is bound to the error codes defined + * in mconf.h. + */ +static char *ermsg[7] = { +"unknown", /* error code 0 */ +"domain", /* error code 1 */ +"singularity", /* et seq. */ +"overflow", +"underflow", +"total loss of precision", +"partial loss of precision" +}; + + + +/* const.c + * + * Globally declared constants + * + * + * + * SYNOPSIS: + * + * extern double nameofconstant; + * + * + * + * + * DESCRIPTION: + * + * This file contains a number of mathematical constants and + * also some needed size parameters of the computer arithmetic. + * The values are supplied as arrays of hexadecimal integers + * for IEEE arithmetic; arrays of octal constants for DEC + * arithmetic; and in a normal decimal scientific notation for + * other machines. The particular notation used is determined + * by a symbol (DEC, IBMPC, or UNK) defined in the include file + * mconf.h. + * + * The default size parameters are as follows. + * + * For DEC and UNK modes: + * MACHEP = 1.38777878078144567553E-17 2**-56 + * MAXLOG = 8.8029691931113054295988E1 log(2**127) + * MINLOG = -8.872283911167299960540E1 log(2**-128) + * MAXNUM = 1.701411834604692317316873e38 2**127 + * + * For IEEE arithmetic (IBMPC): + * MACHEP = 1.11022302462515654042E-16 2**-53 + * MAXLOG = 7.09782712893383996843E2 log(2**1024) + * MINLOG = -7.08396418532264106224E2 log(2**-1022) + * MAXNUM = 1.7976931348623158E308 2**1024 + * + * The global symbols for mathematical constants are + * PI = 3.14159265358979323846 pi + * PIO2 = 1.57079632679489661923 pi/2 + * PIO4 = 7.85398163397448309616E-1 pi/4 + * SQRT2 = 1.41421356237309504880 sqrt(2) + * SQRTH = 7.07106781186547524401E-1 sqrt(2)/2 + * LOG2E = 1.4426950408889634073599 1/log(2) + * SQ2OPI = 7.9788456080286535587989E-1 sqrt( 2/pi ) + * LOGE2 = 6.93147180559945309417E-1 log(2) + * LOGSQ2 = 3.46573590279972654709E-1 log(2)/2 + * THPIO4 = 2.35619449019234492885 3*pi/4 + * TWOOPI = 6.36619772367581343075535E-1 2/pi + * + * These lists are subject to change. + */ + +/* const.c */ + +/* +Cephes Math Library Release 2.3: March, 1995 +Copyright 1984, 1995 by Stephen L. Moshier +*/ + +#ifdef UNK +#if 1 +double MACHEP = 1.11022302462515654042E-16; /* 2**-53 */ +#else +double MACHEP = 1.38777878078144567553E-17; /* 2**-56 */ +#endif +double UFLOWTHRESH = 2.22507385850720138309E-308; /* 2**-1022 */ +#ifdef DENORMAL +double MAXLOG = 7.09782712893383996732E2; /* log(MAXNUM) */ +/* double MINLOG = -7.44440071921381262314E2; */ /* log(2**-1074) */ +double MINLOG = -7.451332191019412076235E2; /* log(2**-1075) */ +#else +double MAXLOG = 7.08396418532264106224E2; /* log 2**1022 */ +double MINLOG = -7.08396418532264106224E2; /* log 2**-1022 */ +#endif +double MAXNUM = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +double PI = 3.14159265358979323846; /* pi */ +double PIO2 = 1.57079632679489661923; /* pi/2 */ +double PIO4 = 7.85398163397448309616E-1; /* pi/4 */ +double SQRT2 = 1.41421356237309504880; /* sqrt(2) */ +double SQRTH = 7.07106781186547524401E-1; /* sqrt(2)/2 */ +double LOG2E = 1.4426950408889634073599; /* 1/log(2) */ +double SQ2OPI = 7.9788456080286535587989E-1; /* sqrt( 2/pi ) */ +double LOGE2 = 6.93147180559945309417E-1; /* log(2) */ +double LOGSQ2 = 3.46573590279972654709E-1; /* log(2)/2 */ +double THPIO4 = 2.35619449019234492885; /* 3*pi/4 */ +double TWOOPI = 6.36619772367581343075535E-1; /* 2/pi */ +#ifdef INFINITIES +double INFINITY = 1.0/0.0; /* 99e999; */ +#else +double INFINITY = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ +#endif +#ifdef NANS +double NAN = 1.0/0.0 - 1.0/0.0; +#else +double NAN = 0.0; +#endif +#ifdef MINUSZERO +double NEGZERO = -0.0; +#else +double NEGZERO = 0.0; +#endif +#endif + +#ifdef IBMPC + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x0000,0x0000,0x0000,0x3ca0}; +unsigned short UFLOWTHRESH[4] = {0x0000,0x0000,0x0000,0x0010}; +#ifdef DENORMAL + /* log(MAXNUM) = 7.09782712893383996732224E2 */ +unsigned short MAXLOG[4] = {0x39ef,0xfefa,0x2e42,0x4086}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/*unsigned short MINLOG[4] = {0x71c3,0x446d,0x4385,0xc087};*/ +unsigned short MINLOG[4] = {0x3052,0xd52d,0x4910,0xc087}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0xbcd2,0xdd7a,0x232b,0x4086}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xbcd2,0xdd7a,0x232b,0xc086}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0xffff,0xffff,0xffff,0x7fef}; +unsigned short PI[4] = {0x2d18,0x5444,0x21fb,0x4009}; +unsigned short PIO2[4] = {0x2d18,0x5444,0x21fb,0x3ff9}; +unsigned short PIO4[4] = {0x2d18,0x5444,0x21fb,0x3fe9}; +unsigned short SQRT2[4] = {0x3bcd,0x667f,0xa09e,0x3ff6}; +unsigned short SQRTH[4] = {0x3bcd,0x667f,0xa09e,0x3fe6}; +unsigned short LOG2E[4] = {0x82fe,0x652b,0x1547,0x3ff7}; +unsigned short SQ2OPI[4] = {0x3651,0x33d4,0x8845,0x3fe9}; +unsigned short LOGE2[4] = {0x39ef,0xfefa,0x2e42,0x3fe6}; +unsigned short LOGSQ2[4] = {0x39ef,0xfefa,0x2e42,0x3fd6}; +unsigned short THPIO4[4] = {0x21d2,0x7f33,0xd97c,0x4002}; +unsigned short TWOOPI[4] = {0xc883,0x6dc9,0x5f30,0x3fe4}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x0000,0x0000,0x0000,0x7ff0}; +#else +unsigned short INFINITY[4] = {0xffff,0xffff,0xffff,0x7fef}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x7ffc}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x8000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef MIEEE + /* 2**-53 = 1.11022302462515654042E-16 */ +unsigned short MACHEP[4] = {0x3ca0,0x0000,0x0000,0x0000}; +unsigned short UFLOWTHRESH[4] = {0x0010,0x0000,0x0000,0x0000}; +#ifdef DENORMAL + /* log(2**1024) = 7.09782712893383996843E2 */ +unsigned short MAXLOG[4] = {0x4086,0x2e42,0xfefa,0x39ef}; + /* log(2**-1074) = - -7.44440071921381262314E2 */ +/* unsigned short MINLOG[4] = {0xc087,0x4385,0x446d,0x71c3}; */ +unsigned short MINLOG[4] = {0xc087,0x4910,0xd52d,0x3052}; +#else + /* log(2**1022) = 7.08396418532264106224E2 */ +unsigned short MAXLOG[4] = {0x4086,0x232b,0xdd7a,0xbcd2}; + /* log(2**-1022) = - 7.08396418532264106224E2 */ +unsigned short MINLOG[4] = {0xc086,0x232b,0xdd7a,0xbcd2}; +#endif + /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ +unsigned short MAXNUM[4] = {0x7fef,0xffff,0xffff,0xffff}; +unsigned short PI[4] = {0x4009,0x21fb,0x5444,0x2d18}; +unsigned short PIO2[4] = {0x3ff9,0x21fb,0x5444,0x2d18}; +unsigned short PIO4[4] = {0x3fe9,0x21fb,0x5444,0x2d18}; +unsigned short SQRT2[4] = {0x3ff6,0xa09e,0x667f,0x3bcd}; +unsigned short SQRTH[4] = {0x3fe6,0xa09e,0x667f,0x3bcd}; +unsigned short LOG2E[4] = {0x3ff7,0x1547,0x652b,0x82fe}; +unsigned short SQ2OPI[4] = {0x3fe9,0x8845,0x33d4,0x3651}; +unsigned short LOGE2[4] = {0x3fe6,0x2e42,0xfefa,0x39ef}; +unsigned short LOGSQ2[4] = {0x3fd6,0x2e42,0xfefa,0x39ef}; +unsigned short THPIO4[4] = {0x4002,0xd97c,0x7f33,0x21d2}; +unsigned short TWOOPI[4] = {0x3fe4,0x5f30,0x6dc9,0xc883}; +#ifdef INFINITIES +unsigned short INFINITY[4] = {0x7ff0,0x0000,0x0000,0x0000}; +#else +unsigned short INFINITY[4] = {0x7fef,0xffff,0xffff,0xffff}; +#endif +#ifdef NANS +unsigned short NAN[4] = {0x7ff8,0x0000,0x0000,0x0000}; +#else +unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0x8000,0x0000,0x0000,0x0000}; +#else +unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; +#endif +#endif + +#ifdef DEC + /* 2**-56 = 1.38777878078144567553E-17 */ +unsigned short MACHEP[4] = {0022200,0000000,0000000,0000000}; +unsigned short UFLOWTHRESH[4] = {0x0080,0x0000,0x0000,0x0000}; + /* log 2**127 = 88.029691931113054295988 */ +unsigned short MAXLOG[4] = {041660,007463,0143742,025733,}; + /* log 2**-128 = -88.72283911167299960540 */ +unsigned short MINLOG[4] = {0141661,071027,0173721,0147572,}; + /* 2**127 = 1.701411834604692317316873e38 */ +unsigned short MAXNUM[4] = {077777,0177777,0177777,0177777,}; +unsigned short PI[4] = {040511,007732,0121041,064302,}; +unsigned short PIO2[4] = {040311,007732,0121041,064302,}; +unsigned short PIO4[4] = {040111,007732,0121041,064302,}; +unsigned short SQRT2[4] = {040265,002363,031771,0157145,}; +unsigned short SQRTH[4] = {040065,002363,031771,0157144,}; +unsigned short LOG2E[4] = {040270,0125073,024534,013761,}; +unsigned short SQ2OPI[4] = {040114,041051,0117241,0131204,}; +unsigned short LOGE2[4] = {040061,071027,0173721,0147572,}; +unsigned short LOGSQ2[4] = {037661,071027,0173721,0147572,}; +unsigned short THPIO4[4] = {040426,0145743,0174631,007222,}; +unsigned short TWOOPI[4] = {040042,0174603,067116,042025,}; +/* Approximate infinity by MAXNUM. */ +unsigned short INFINITY[4] = {077777,0177777,0177777,0177777,}; +unsigned short NAN[4] = {0000000,0000000,0000000,0000000}; +#ifdef MINUSZERO +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0100000}; +#else +unsigned short NEGZERO[4] = {0000000,0000000,0000000,0000000}; +#endif +#endif + +#ifndef UNK +extern unsigned short MACHEP[]; +extern unsigned short UFLOWTHRESH[]; +extern unsigned short MAXLOG[]; +extern unsigned short UNDLOG[]; +extern unsigned short MINLOG[]; +extern unsigned short MAXNUM[]; +extern unsigned short PI[]; +extern unsigned short PIO2[]; +extern unsigned short PIO4[]; +extern unsigned short SQRT2[]; +extern unsigned short SQRTH[]; +extern unsigned short LOG2E[]; +extern unsigned short SQ2OPI[]; +extern unsigned short LOGE2[]; +extern unsigned short LOGSQ2[]; +extern unsigned short THPIO4[]; +extern unsigned short TWOOPI[]; +extern unsigned short INFINITY[]; +extern unsigned short NAN[]; +extern unsigned short NEGZERO[]; +#endif + +extern double MACHEP, MAXLOG; +static double big = 4.503599627370496e15; +static double biginv = 2.22044604925031308085e-16; + +#ifdef UNK +static double P[] = { + 1.60119522476751861407E-4, + 1.19135147006586384913E-3, + 1.04213797561761569935E-2, + 4.76367800457137231464E-2, + 2.07448227648435975150E-1, + 4.94214826801497100753E-1, + 9.99999999999999996796E-1 +}; +static double Q[] = { +-2.31581873324120129819E-5, + 5.39605580493303397842E-4, +-4.45641913851797240494E-3, + 1.18139785222060435552E-2, + 3.58236398605498653373E-2, +-2.34591795718243348568E-1, + 7.14304917030273074085E-2, + 1.00000000000000000320E0 +}; +#define MAXGAM 171.624376956302725 +static double LOGPI = 1.14472988584940017414; +#endif + +#ifdef DEC +static unsigned short P[] = { +0035047,0162701,0146301,0005234, +0035634,0023437,0032065,0176530, +0036452,0137157,0047330,0122574, +0037103,0017310,0143041,0017232, +0037524,0066516,0162563,0164605, +0037775,0004671,0146237,0014222, +0040200,0000000,0000000,0000000 +}; +static unsigned short Q[] = { +0134302,0041724,0020006,0116565, +0035415,0072121,0044251,0025634, +0136222,0003447,0035205,0121114, +0036501,0107552,0154335,0104271, +0037022,0135717,0014776,0171471, +0137560,0034324,0165024,0037021, +0037222,0045046,0047151,0161213, +0040200,0000000,0000000,0000000 +}; +#define MAXGAM 34.84425627277176174 +static unsigned short LPI[4] = { +0040222,0103202,0043475,0006750, +}; +#define LOGPI *(double *)LPI +#endif + +#ifdef IBMPC +static unsigned short P[] = { +0x2153,0x3998,0xfcb8,0x3f24, +0xbfab,0xe686,0x84e3,0x3f53, +0x14b0,0xe9db,0x57cd,0x3f85, +0x23d3,0x18c4,0x63d9,0x3fa8, +0x7d31,0xdcae,0x8da9,0x3fca, +0xe312,0x3993,0xa137,0x3fdf, +0x0000,0x0000,0x0000,0x3ff0 +}; +static unsigned short Q[] = { +0xd3af,0x8400,0x487a,0xbef8, +0x2573,0x2915,0xae8a,0x3f41, +0xb44a,0xe750,0x40e4,0xbf72, +0xb117,0x5b1b,0x31ed,0x3f88, +0xde67,0xe33f,0x5779,0x3fa2, +0x87c2,0x9d42,0x071a,0xbfce, +0x3c51,0xc9cd,0x4944,0x3fb2, +0x0000,0x0000,0x0000,0x3ff0 +}; +#define MAXGAM 171.624376956302725 +static unsigned short LPI[4] = { +0xa1bd,0x48e7,0x50d0,0x3ff2, +}; +#define LOGPI *(double *)LPI +#endif + +#ifdef MIEEE +static unsigned short P[] = { +0x3f24,0xfcb8,0x3998,0x2153, +0x3f53,0x84e3,0xe686,0xbfab, +0x3f85,0x57cd,0xe9db,0x14b0, +0x3fa8,0x63d9,0x18c4,0x23d3, +0x3fca,0x8da9,0xdcae,0x7d31, +0x3fdf,0xa137,0x3993,0xe312, +0x3ff0,0x0000,0x0000,0x0000 +}; +static unsigned short Q[] = { +0xbef8,0x487a,0x8400,0xd3af, +0x3f41,0xae8a,0x2915,0x2573, +0xbf72,0x40e4,0xe750,0xb44a, +0x3f88,0x31ed,0x5b1b,0xb117, +0x3fa2,0x5779,0xe33f,0xde67, +0xbfce,0x071a,0x9d42,0x87c2, +0x3fb2,0x4944,0xc9cd,0x3c51, +0x3ff0,0x0000,0x0000,0x0000 +}; +#define MAXGAM 171.624376956302725 +static unsigned short LPI[4] = { +0x3ff2,0x50d0,0x48e7,0xa1bd, +}; +#define LOGPI *(double *)LPI +#endif + +/* Stirling's formula for the gamma function */ +#if UNK +static double STIR[5] = { + 7.87311395793093628397E-4, +-2.29549961613378126380E-4, +-2.68132617805781232825E-3, + 3.47222221605458667310E-3, + 8.33333333333482257126E-2, +}; +#define MAXSTIR 143.01608 +static double SQTPI = 2.50662827463100050242E0; +#endif +#if DEC +static unsigned short STIR[20] = { +0035516,0061622,0144553,0112224, +0135160,0131531,0037460,0165740, +0136057,0134460,0037242,0077270, +0036143,0107070,0156306,0027751, +0037252,0125252,0125252,0146064, +}; +#define MAXSTIR 26.77 +static unsigned short SQT[4] = { +0040440,0066230,0177661,0034055, +}; +#define SQTPI *(double *)SQT +#endif +#if IBMPC +static unsigned short STIR[20] = { +0x7293,0x592d,0xcc72,0x3f49, +0x1d7c,0x27e6,0x166b,0xbf2e, +0x4fd7,0x07d4,0xf726,0xbf65, +0xc5fd,0x1b98,0x71c7,0x3f6c, +0x5986,0x5555,0x5555,0x3fb5, +}; +#define MAXSTIR 143.01608 +static unsigned short SQT[4] = { +0x2706,0x1ff6,0x0d93,0x4004, +}; +#define SQTPI *(double *)SQT +#endif +#if MIEEE +static unsigned short STIR[20] = { +0x3f49,0xcc72,0x592d,0x7293, +0xbf2e,0x166b,0x27e6,0x1d7c, +0xbf65,0xf726,0x07d4,0x4fd7, +0x3f6c,0x71c7,0x1b98,0xc5fd, +0x3fb5,0x5555,0x5555,0x5986, +}; +#define MAXSTIR 143.01608 +static unsigned short SQT[4] = { +0x4004,0x0d93,0x1ff6,0x2706, +}; +#define SQTPI *(double *)SQT +#endif + +int sgngam = 0; +extern int sgngam; +extern double MAXLOG, MAXNUM, PI; +#ifndef ANSIPROT +double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs(); +int isnan(), isfinite(); +#endif +#ifdef INFINITIES +extern double INFINITY; +#endif +#ifdef NANS +extern double NAN; +#endif + +/* igam.c + * + * Incomplete gamma integral + * + * + * + * SYNOPSIS: + * + * double a, x, y, igam(); + * + * y = igam( a, x ); + * + * DESCRIPTION: + * + * The function is defined by + * + * x + * - + * 1 | | -t a-1 + * igam(a,x) = ----- | e t dt. + * - | | + * | (a) - + * 0 + * + * + * In this implementation both arguments must be positive. + * The integral is evaluated by either a power series or + * continued fraction expansion, depending on the relative + * values of a and x. + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0,30 200000 3.6e-14 2.9e-15 + * IEEE 0,100 300000 9.9e-14 1.5e-14 + */ +/* igamc() + * + * Complemented incomplete gamma integral + * + * + * + * SYNOPSIS: + * + * double a, x, y, igamc(); + * + * y = igamc( a, x ); + * + * DESCRIPTION: + * + * The function is defined by + * + * + * igamc(a,x) = 1 - igam(a,x) + * + * inf. + * - + * 1 | | -t a-1 + * = ----- | e t dt. + * - | | + * | (a) - + * x + * + * + * In this implementation both arguments must be positive. + * The integral is evaluated by either a power series or + * continued fraction expansion, depending on the relative + * values of a and x. + * + * ACCURACY: + * + * Tested at random a, x. + * a x Relative error: + * arithmetic domain domain # trials peak rms + * IEEE 0.5,100 0,100 200000 1.9e-14 1.7e-15 + * IEEE 0.01,0.5 0,100 200000 1.4e-13 1.6e-15 + */ + +/* +Cephes Math Library Release 2.0: April, 1987 +Copyright 1985, 1987 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +double igamc( a, x ) +double a, x; +{ +double ans, ax, c, yc, r, t, y, z; +double pk, pkm1, pkm2, qk, qkm1, qkm2; + +if( (x <= 0) || ( a <= 0) ) + return( 1.0 ); + +if( (x < 1.0) || (x < a) ) + return( 1.e0 - igam(a,x) ); + +ax = a * log(x) - x - lgam(a); +if( ax < -MAXLOG ) + { + mtherr( "igamc", UNDERFLOW ); + return( 0.0 ); + } +ax = exp(ax); + +/* continued fraction */ +y = 1.0 - a; +z = x + y + 1.0; +c = 0.0; +pkm2 = 1.0; +qkm2 = x; +pkm1 = x + 1.0; +qkm1 = z * x; +ans = pkm1/qkm1; + +do + { + c += 1.0; + y += 1.0; + z += 2.0; + yc = y * c; + pk = pkm1 * z - pkm2 * yc; + qk = qkm1 * z - qkm2 * yc; + if( qk != 0 ) + { + r = pk/qk; + t = fabs( (ans - r)/r ); + ans = r; + } + else + t = 1.0; + pkm2 = pkm1; + pkm1 = pk; + qkm2 = qkm1; + qkm1 = qk; + if( fabs(pk) > big ) + { + pkm2 *= biginv; + pkm1 *= biginv; + qkm2 *= biginv; + qkm1 *= biginv; + } + } +while( t > MACHEP ); + +return( ans * ax ); +} + + + +/* left tail of incomplete gamma function: + * + * inf. k + * a -x - x + * x e > ---------- + * - - + * k=0 | (a+k+1) + * + */ + +double igam( a, x ) +double a, x; +{ +double ans, ax, c, r; + +if( (x <= 0) || ( a <= 0) ) + return( 0.0 ); + +if( (x > 1.0) && (x > a ) ) + return( 1.e0 - igamc(a,x) ); + +/* Compute x**a * exp(-x) / gamma(a) */ +ax = a * log(x) - x - lgam(a); +if( ax < -MAXLOG ) + { + mtherr( "igam", UNDERFLOW ); + return( 0.0 ); + } +ax = exp(ax); + +/* power series */ +r = a; +c = 1.0; +ans = 1.0; + +do + { + r += 1.0; + c *= x/r; + ans += c; + } +while( c/ans > MACHEP ); + +return( ans * ax/a ); +} + +/* gamma.c + * + * Gamma function + * + * + * + * SYNOPSIS: + * + * double x, y, gamma(); + * extern int sgngam; + * + * y = gamma( x ); + * + * + * + * DESCRIPTION: + * + * Returns gamma function of the argument. The result is + * correctly signed, and the sign (+1 or -1) is also + * returned in a global (extern) variable named sgngam. + * This variable is also filled in by the logarithmic gamma + * function lgam(). + * + * Arguments |x| <= 34 are reduced by recurrence and the function + * approximated by a rational function of degree 6/7 in the + * interval (2,3). Large arguments are handled by Stirling's + * formula. Large negative arguments are made positive using + * a reflection formula. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -34, 34 10000 1.3e-16 2.5e-17 + * IEEE -170,-33 20000 2.3e-15 3.3e-16 + * IEEE -33, 33 20000 9.4e-16 2.2e-16 + * IEEE 33, 171.6 20000 2.3e-15 3.2e-16 + * + * Error for arguments outside the test range will be larger + * owing to error amplification by the exponential function. + * + */ +/* lgam() + * + * Natural logarithm of gamma function + * + * + * + * SYNOPSIS: + * + * double x, y, lgam(); + * extern int sgngam; + * + * y = lgam( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of the absolute + * value of the gamma function of the argument. + * The sign (+1 or -1) of the gamma function is returned in a + * global (extern) variable named sgngam. + * + * For arguments greater than 13, the logarithm of the gamma + * function is approximated by the logarithmic version of + * Stirling's formula using a polynomial approximation of + * degree 4. Arguments between -33 and +33 are reduced by + * recurrence to the interval [2,3] of a rational approximation. + * The cosecant reflection formula is employed for arguments + * less than -33. + * + * Arguments greater than MAXLGM return MAXNUM and an error + * message. MAXLGM = 2.035093e36 for DEC + * arithmetic or 2.556348e305 for IEEE arithmetic. + * + * + * + * ACCURACY: + * + * + * arithmetic domain # trials peak rms + * DEC 0, 3 7000 5.2e-17 1.3e-17 + * DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18 + * IEEE 0, 3 28000 5.4e-16 1.1e-16 + * IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17 + * The error criterion was relative when the function magnitude + * was greater than one but absolute when it was less than one. + * + * The following test used the relative error criterion, though + * at certain points the relative error could be much higher than + * indicated. + * IEEE -200, -4 10000 4.8e-16 1.3e-16 + * + */ + +/* gamma.c */ +/* gamma function */ + +/* +Cephes Math Library Release 2.2: July, 1992 +Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +/* Gamma function computed by Stirling's formula. + * The polynomial STIR is valid for 33 <= x <= 172. + */ +static double stirf(x) +double x; +{ +double y, w, v; + +w = 1.0/x; +w = 1.0 + w * polevl( w, STIR, 4 ); +y = exp(x); +if( x > MAXSTIR ) + { /* Avoid overflow in pow() */ + v = pow( x, 0.5 * x - 0.25 ); + y = v * (v / y); + } +else + { + y = pow( x, x - 0.5 ) / y; + } +y = SQTPI * y * w; +return( y ); +} + + + +double gamma(x) +double x; +{ +double p, q, z; +int i; + +sgngam = 1; +#ifdef NANS +if( isnan(x) ) + return(x); +#endif +#ifdef INFINITIES +#ifdef NANS +if( x == INFINITY ) + return(x); +if( x == -INFINITY ) + return(NAN); +#else +if( !isfinite(x) ) + return(x); +#endif +#endif +q = fabs(x); + +if( q > 33.0 ) + { + if( x < 0.0 ) + { + p = floor(q); + if( p == q ) + { +#ifdef NANS +gamnan: + mtherr( "gamma", DOMAIN ); + return (NAN); +#else + goto goverf; +#endif + } + i = p; + if( (i & 1) == 0 ) + sgngam = -1; + z = q - p; + if( z > 0.5 ) + { + p += 1.0; + z = q - p; + } + z = q * sin( PI * z ); + if( z == 0.0 ) + { +#ifdef INFINITIES + return( sgngam * INFINITY); +#else +goverf: + mtherr( "gamma", OVERFLOW ); + return( sgngam * MAXNUM); +#endif + } + z = fabs(z); + z = PI/(z * stirf(q) ); + } + else + { + z = stirf(x); + } + return( sgngam * z ); + } + +z = 1.0; +while( x >= 3.0 ) + { + x -= 1.0; + z *= x; + } + +while( x < 0.0 ) + { + if( x > -1.E-9 ) + goto small; + z /= x; + x += 1.0; + } + +while( x < 2.0 ) + { + if( x < 1.e-9 ) + goto small; + z /= x; + x += 1.0; + } + +if( x == 2.0 ) + return(z); + +x -= 2.0; +p = polevl( x, P, 6 ); +q = polevl( x, Q, 7 ); +return( z * p / q ); + +small: +if( x == 0.0 ) + { +#ifdef INFINITIES +#ifdef NANS + goto gamnan; +#else + return( INFINITY ); +#endif +#else + mtherr( "gamma", SING ); + return( MAXNUM ); +#endif + } +else + return( z/((1.0 + 0.5772156649015329 * x) * x) ); +} + + + +/* A[]: Stirling's formula expansion of log gamma + * B[], C[]: log gamma function between 2 and 3 + */ +#ifdef UNK +static double A[] = { + 8.11614167470508450300E-4, +-5.95061904284301438324E-4, + 7.93650340457716943945E-4, +-2.77777777730099687205E-3, + 8.33333333333331927722E-2 +}; +static double B[] = { +-1.37825152569120859100E3, +-3.88016315134637840924E4, +-3.31612992738871184744E5, +-1.16237097492762307383E6, +-1.72173700820839662146E6, +-8.53555664245765465627E5 +}; +static double C[] = { +/* 1.00000000000000000000E0, */ +-3.51815701436523470549E2, +-1.70642106651881159223E4, +-2.20528590553854454839E5, +-1.13933444367982507207E6, +-2.53252307177582951285E6, +-2.01889141433532773231E6 +}; +/* log( sqrt( 2*pi ) ) */ +static double LS2PI = 0.91893853320467274178; +#define MAXLGM 2.556348e305 +#endif + +#ifdef DEC +static unsigned short A[] = { +0035524,0141201,0034633,0031405, +0135433,0176755,0126007,0045030, +0035520,0006371,0003342,0172730, +0136066,0005540,0132605,0026407, +0037252,0125252,0125252,0125132 +}; +static unsigned short B[] = { +0142654,0044014,0077633,0035410, +0144027,0110641,0125335,0144760, +0144641,0165637,0142204,0047447, +0145215,0162027,0146246,0155211, +0145322,0026110,0010317,0110130, +0145120,0061472,0120300,0025363 +}; +static unsigned short C[] = { +/*0040200,0000000,0000000,0000000*/ +0142257,0164150,0163630,0112622, +0143605,0050153,0156116,0135272, +0144527,0056045,0145642,0062332, +0145213,0012063,0106250,0001025, +0145432,0111254,0044577,0115142, +0145366,0071133,0050217,0005122 +}; +/* log( sqrt( 2*pi ) ) */ +static unsigned short LS2P[] = {040153,037616,041445,0172645,}; +#define LS2PI *(double *)LS2P +#define MAXLGM 2.035093e36 +#endif + +#ifdef IBMPC +static unsigned short A[] = { +0x6661,0x2733,0x9850,0x3f4a, +0xe943,0xb580,0x7fbd,0xbf43, +0x5ebb,0x20dc,0x019f,0x3f4a, +0xa5a1,0x16b0,0xc16c,0xbf66, +0x554b,0x5555,0x5555,0x3fb5 +}; +static unsigned short B[] = { +0x6761,0x8ff3,0x8901,0xc095, +0xb93e,0x355b,0xf234,0xc0e2, +0x89e5,0xf890,0x3d73,0xc114, +0xdb51,0xf994,0xbc82,0xc131, +0xf20b,0x0219,0x4589,0xc13a, +0x055e,0x5418,0x0c67,0xc12a +}; +static unsigned short C[] = { +/*0x0000,0x0000,0x0000,0x3ff0,*/ +0x12b2,0x1cf3,0xfd0d,0xc075, +0xd757,0x7b89,0xaa0d,0xc0d0, +0x4c9b,0xb974,0xeb84,0xc10a, +0x0043,0x7195,0x6286,0xc131, +0xf34c,0x892f,0x5255,0xc143, +0xe14a,0x6a11,0xce4b,0xc13e +}; +/* log( sqrt( 2*pi ) ) */ +static unsigned short LS2P[] = { +0xbeb5,0xc864,0x67f1,0x3fed +}; +#define LS2PI *(double *)LS2P +#define MAXLGM 2.556348e305 +#endif + +#ifdef MIEEE +static unsigned short A[] = { +0x3f4a,0x9850,0x2733,0x6661, +0xbf43,0x7fbd,0xb580,0xe943, +0x3f4a,0x019f,0x20dc,0x5ebb, +0xbf66,0xc16c,0x16b0,0xa5a1, +0x3fb5,0x5555,0x5555,0x554b +}; +static unsigned short B[] = { +0xc095,0x8901,0x8ff3,0x6761, +0xc0e2,0xf234,0x355b,0xb93e, +0xc114,0x3d73,0xf890,0x89e5, +0xc131,0xbc82,0xf994,0xdb51, +0xc13a,0x4589,0x0219,0xf20b, +0xc12a,0x0c67,0x5418,0x055e +}; +static unsigned short C[] = { +0xc075,0xfd0d,0x1cf3,0x12b2, +0xc0d0,0xaa0d,0x7b89,0xd757, +0xc10a,0xeb84,0xb974,0x4c9b, +0xc131,0x6286,0x7195,0x0043, +0xc143,0x5255,0x892f,0xf34c, +0xc13e,0xce4b,0x6a11,0xe14a +}; +/* log( sqrt( 2*pi ) ) */ +static unsigned short LS2P[] = { +0x3fed,0x67f1,0xc864,0xbeb5 +}; +#define LS2PI *(double *)LS2P +#define MAXLGM 2.556348e305 +#endif + + +/* Logarithm of gamma function */ + + +double lgam(x) +double x; +{ +double p, q, u, w, z; +int i; + +sgngam = 1; +#ifdef NANS +if( isnan(x) ) + return(x); +#endif + +#ifdef INFINITIES +if( !isfinite(x) ) + return(INFINITY); +#endif + +if( x < -34.0 ) + { + q = -x; + w = lgam(q); /* note this modifies sgngam! */ + p = floor(q); + if( p == q ) + { +lgsing: +#ifdef INFINITIES + mtherr( "lgam", SING ); + return (INFINITY); +#else + goto loverf; +#endif + } + i = p; + if( (i & 1) == 0 ) + sgngam = -1; + else + sgngam = 1; + z = q - p; + if( z > 0.5 ) + { + p += 1.0; + z = p - q; + } + z = q * sin( PI * z ); + if( z == 0.0 ) + goto lgsing; +/* z = log(PI) - log( z ) - w;*/ + z = LOGPI - log( z ) - w; + return( z ); + } + +if( x < 13.0 ) + { + z = 1.0; + p = 0.0; + u = x; + while( u >= 3.0 ) + { + p -= 1.0; + u = x + p; + z *= u; + } + while( u < 2.0 ) + { + if( u == 0.0 ) + goto lgsing; + z /= u; + p += 1.0; + u = x + p; + } + if( z < 0.0 ) + { + sgngam = -1; + z = -z; + } + else + sgngam = 1; + if( u == 2.0 ) + return( log(z) ); + p -= 2.0; + x = x + p; + p = x * polevl( x, B, 5 ) / p1evl( x, C, 6); + return( log(z) + p ); + } + +if( x > MAXLGM ) + { +#ifdef INFINITIES + return( sgngam * INFINITY ); +#else +loverf: + mtherr( "lgam", OVERFLOW ); + return( sgngam * MAXNUM ); +#endif + } + +q = ( x - 0.5 ) * log(x) - x + LS2PI; +if( x > 1.0e8 ) + return( q ); + +p = 1.0/(x*x); +if( x >= 1000.0 ) + q += (( 7.9365079365079365079365e-4 * p + - 2.7777777777777777777778e-3) *p + + 0.0833333333333333333333) / x; +else + q += polevl( p, A, 4 ) / x; +return( q ); +} + +/* mtherr.c + * + * Library common error handling routine + * + * + * + * SYNOPSIS: + * + * char *fctnam; + * int code; + * int mtherr(); + * + * mtherr( fctnam, code ); + * + * + * + * DESCRIPTION: + * + * This routine may be called to report one of the following + * error conditions (in the include file mconf.h). + * + * Mnemonic Value Significance + * + * DOMAIN 1 argument domain error + * SING 2 function singularity + * OVERFLOW 3 overflow range error + * UNDERFLOW 4 underflow range error + * TLOSS 5 total loss of precision + * PLOSS 6 partial loss of precision + * EDOM 33 Unix domain error code + * ERANGE 34 Unix range error code + * + * The default version of the file prints the function name, + * passed to it by the pointer fctnam, followed by the + * error condition. The display is directed to the standard + * output device. The routine then returns to the calling + * program. Users may wish to modify the program to abort by + * calling exit() under severe error conditions such as domain + * errors. + * + * Since all error conditions pass control to this function, + * the display may be easily changed, eliminated, or directed + * to an error logging device. + * + * SEE ALSO: + * + * mconf.h + * + */ + +/* +Cephes Math Library Release 2.0: April, 1987 +Copyright 1984, 1987 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +int mtherr( name, code ) +char *name; +int code; +{ + +/* Display string passed by calling program, + * which is supposed to be the name of the + * function in which the error occurred: + */ +printf("\n%s ", name); + +/* Set global error message word */ +merror = code; + +/* Display error message defined + * by the code argument. + */ +if( (code <= 0) || (code >= 7) ) + code = 0; +printf( "%s error\n", ermsg[code] ); + +/* Return to calling + * program + */ +return( 0 ); +} + +/* polevl.c + * p1evl.c + * + * Evaluate polynomial + * + * + * + * SYNOPSIS: + * + * int N; + * double x, y, coef[N+1], polevl[]; + * + * y = polevl( x, coef, N ); + * + * + * + * DESCRIPTION: + * + * Evaluates polynomial of degree N: + * + * 2 N + * y = C + C x + C x +...+ C x + * 0 1 2 N + * + * Coefficients are stored in reverse order: + * + * coef[0] = C , ..., coef[N] = C . + * N 0 + * + * The function p1evl() assumes that coef[N] = 1.0 and is + * omitted from the array. Its calling arguments are + * otherwise the same as polevl(). + * + * + * SPEED: + * + * In the interest of speed, there are no checks for out + * of bounds arithmetic. This routine is used by most of + * the functions in the library. Depending on available + * equipment features, the user may wish to rewrite the + * program in microcode or assembly language. + * + */ + + +/* +Cephes Math Library Release 2.1: December, 1988 +Copyright 1984, 1987, 1988 by Stephen L. Moshier +Direct inquiries to 30 Frost Street, Cambridge, MA 02140 +*/ + +double polevl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +int i; +double *p; + +p = coef; +ans = *p++; +i = N; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} + +/* p1evl() */ +/* N + * Evaluate polynomial when coefficient of x is 1.0. + * Otherwise same as polevl. + */ + +double p1evl( x, coef, N ) +double x; +double coef[]; +int N; +{ +double ans; +double *p; +int i; + +p = coef; +ans = x + *p++; +i = N-1; + +do + ans = ans * x + *p++; +while( --i ); + +return( ans ); +} diff --git a/nist/dfft.c b/nist/dfft.c new file mode 100644 index 0000000..482a868 --- /dev/null +++ b/nist/dfft.c @@ -0,0 +1,1381 @@ +/* Notes from RFB: + + Looks like the user-level routines are: + + Real FFT + + void __ogg_fdrffti(int n, double *wsave, int *ifac) + void __ogg_fdrfftf(int n,double *r,double *wsave,int *ifac) + void __ogg_fdrfftb(int n, double *r, double *wsave, int *ifac) + + __ogg_fdrffti == initialization + __ogg_fdrfftf == forward transform + __ogg_fdrfftb == backward transform + + Parameters are + n == length of sequence + r == sequence to be transformed (input) + == transformed sequence (output) + wsave == work array of length 2n (allocated by caller) + ifac == work array of length 15 (allocated by caller) + + Cosine quarter-wave FFT + + void __ogg_fdcosqi(int n, double *wsave, int *ifac) + void __ogg_fdcosqf(int n,double *x,double *wsave,int *ifac) + void __ogg_fdcosqb(int n,double *x,double *wsave,int *ifac) +*/ + +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggSQUISH SOFTWARE CODEC SOURCE CODE. * + * * + ******************************************************************** + + file: fft.c + function: Fast discrete Fourier and cosine transforms and inverses + author: Monty <xiphmont@mit.edu> + modifications by: Monty + last modification date: Jul 1 1996 + + ********************************************************************/ + +/* These Fourier routines were originally based on the Fourier + routines of the same names from the NETLIB bihar and fftpack + fortran libraries developed by Paul N. Swarztrauber at the National + Center for Atmospheric Research in Boulder, CO USA. They have been + reimplemented in C and optimized in a few ways for OggSquish. */ + +/* As the original fortran libraries are public domain, the C Fourier + routines in this file are hereby released to the public domain as + well. The C routines here produce output exactly equivalent to the + original fortran routines. Of particular interest are the facts + that (like the original fortran), these routines can work on + arbitrary length vectors that need not be powers of two in + length. */ + +#include <math.h> +#define STIN static + +static void drfti1(int n, double *wa, int *ifac){ + static int ntryh[4] = { 4,2,3,5 }; + static double tpi = 6.28318530717958647692528676655900577; + double arg,argh,argld,fi; + int ntry=0,i,j=-1; + int k1, l1, l2, ib; + int ld, ii, ip, is, nq, nr; + int ido, ipm, nfm1; + int nl=n; + int nf=0; + + L101: + j++; + if (j < 4) + ntry=ntryh[j]; + else + ntry+=2; + + L104: + nq=nl/ntry; + nr=nl-ntry*nq; + if (nr!=0) goto L101; + + nf++; + ifac[nf+1]=ntry; + nl=nq; + if(ntry!=2)goto L107; + if(nf==1)goto L107; + + for (i=1;i<nf;i++){ + ib=nf-i+1; + ifac[ib+1]=ifac[ib]; + } + ifac[2] = 2; + + L107: + if(nl!=1)goto L104; + ifac[0]=n; + ifac[1]=nf; + argh=tpi/n; + is=0; + nfm1=nf-1; + l1=1; + + if(nfm1==0)return; + + for (k1=0;k1<nfm1;k1++){ + ip=ifac[k1+2]; + ld=0; + l2=l1*ip; + ido=n/l2; + ipm=ip-1; + + for (j=0;j<ipm;j++){ + ld+=l1; + i=is; + argld=(double)ld*argh; + fi=0.; + for (ii=2;ii<ido;ii+=2){ + fi+=1.; + arg=fi*argld; + wa[i++]=cos(arg); + wa[i++]=sin(arg); + } + is+=ido; + } + l1=l2; + } +} + +void __ogg_fdrffti(int n, double *wsave, int *ifac){ + + if (n == 1) return; + drfti1(n, wsave+n, ifac); +} + +void __ogg_fdcosqi(int n, double *wsave, int *ifac){ + static double pih = 1.57079632679489661923132169163975; + static int k; + static double fk, dt; + + dt=pih/n; + fk=0.; + for(k=0;k<n;k++){ + fk+=1.; + wsave[k] = cos(fk*dt); + } + + __ogg_fdrffti(n, wsave+n,ifac); +} + +STIN void dradf2(int ido,int l1,double *cc,double *ch,double *wa1){ + int i,k; + double ti2,tr2; + int t0,t1,t2,t3,t4,t5,t6; + + t1=0; + t0=(t2=l1*ido); + t3=ido<<1; + for(k=0;k<l1;k++){ + ch[t1<<1]=cc[t1]+cc[t2]; + ch[(t1<<1)+t3-1]=cc[t1]-cc[t2]; + t1+=ido; + t2+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=t0; + for(k=0;k<l1;k++){ + t3=t2; + t4=(t1<<1)+(ido<<1); + t5=t1; + t6=t1+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4-=2; + t5+=2; + t6+=2; + tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + ch[t6]=cc[t5]+ti2; + ch[t4]=ti2-cc[t5]; + ch[t6-1]=cc[t5-1]+tr2; + ch[t4-1]=cc[t5-1]-tr2; + } + t1+=ido; + t2+=ido; + } + + if(ido%2==1)return; + + L105: + t3=(t2=(t1=ido)-1); + t2+=t0; + for(k=0;k<l1;k++){ + ch[t1]=-cc[t2]; + ch[t1-1]=cc[t3]; + t1+=ido<<1; + t2+=ido; + t3+=ido; + } +} + +STIN void dradf4(int ido,int l1,double *cc,double *ch,double *wa1, + double *wa2,double *wa3){ + static double hsqt2 = .70710678118654752440084436210485; + int i,k,t0,t1,t2,t3,t4,t5,t6; + double ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=t0; + t4=t1<<1; + t2=t1+(t1<<1); + t3=0; + + for(k=0;k<l1;k++){ + tr1=cc[t1]+cc[t2]; + tr2=cc[t3]+cc[t4]; + ch[t5=t3<<2]=tr1+tr2; + ch[(ido<<2)+t5-1]=tr2-tr1; + ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4]; + ch[t5]=cc[t2]-cc[t1]; + + t1+=ido; + t2+=ido; + t3+=ido; + t4+=ido; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + for(k=0;k<l1;k++){ + t2=t1; + t4=t1<<2; + t5=(t6=ido<<1)+t4; + for(i=2;i<ido;i+=2){ + t3=(t2+=2); + t4+=2; + t5-=2; + + t3+=t0; + cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3]; + ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1]; + t3+=t0; + cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3]; + ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1]; + t3+=t0; + cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3]; + ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1]; + + tr1=cr2+cr4; + tr4=cr4-cr2; + ti1=ci2+ci4; + ti4=ci2-ci4; + ti2=cc[t2]+ci3; + ti3=cc[t2]-ci3; + tr2=cc[t2-1]+cr3; + tr3=cc[t2-1]-cr3; + + + ch[t4-1]=tr1+tr2; + ch[t4]=ti1+ti2; + + ch[t5-1]=tr3-ti4; + ch[t5]=tr4-ti3; + + ch[t4+t6-1]=ti4+tr3; + ch[t4+t6]=tr4+ti3; + + ch[t5+t6-1]=tr2-tr1; + ch[t5+t6]=ti1-ti2; + } + t1+=ido; + } + if(ido%2==1)return; + + L105: + + t2=(t1=t0+ido-1)+(t0<<1); + t3=ido<<2; + t4=ido; + t5=ido<<1; + t6=ido; + + for(k=0;k<l1;k++){ + ti1=-hsqt2*(cc[t1]+cc[t2]); + tr1=hsqt2*(cc[t1]-cc[t2]); + ch[t4-1]=tr1+cc[t6-1]; + ch[t4+t5-1]=cc[t6-1]-tr1; + ch[t4]=ti1-cc[t1+t0]; + ch[t4+t5]=ti1+cc[t1+t0]; + t1+=ido; + t2+=ido; + t4+=t3; + t6+=ido; + } +} + +STIN void dradfg(int ido,int ip,int l1,int idl1,double *cc,double *c1, + double *c2,double *ch,double *ch2,double *wa){ + + static double tpi=6.28318530717958647692528676655900577; + int idij,ipph,i,j,k,l,ic,ik,is; + int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + double dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + double dcp,arg,dsp,ar1h,ar2h; + int idp2,ipp2; + + arg=tpi/(double)ip; + dcp=cos(arg); + dsp=sin(arg); + ipph=(ip+1)>>1; + ipp2=ip; + idp2=ido; + nbd=(ido-1)>>1; + t0=l1*ido; + t10=ip*ido; + + if(ido==1)goto L119; + for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + ch[t2]=c1[t2]; + t2+=ido; + } + } + + is=-ido; + t1=0; + if(nbd>l1){ + for(j=1;j<ip;j++){ + t1+=t0; + is+=ido; + t2= -ido+t1; + for(k=0;k<l1;k++){ + idij=is-1; + t2+=ido; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + } + } + } + }else{ + + for(j=1;j<ip;j++){ + is+=ido; + idij=is-1; + t1+=t0; + t2=t1; + for(i=2;i<ido;i+=2){ + idij+=2; + t2+=2; + t3=t2; + for(k=0;k<l1;k++){ + ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3]; + ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1]; + t3+=ido; + } + } + } + } + + t1=0; + t2=ipp2*t0; + if(nbd<l1){ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3-ido; + t6=t4-ido; + for(k=0;k<l1;k++){ + t5+=ido; + t6+=ido; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + } + } + }else{ + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + c1[t5-1]=ch[t5-1]+ch[t6-1]; + c1[t6-1]=ch[t5]-ch[t6]; + c1[t5]=ch[t5]+ch[t6]; + c1[t6]=ch[t6-1]-ch[t5-1]; + } + t3+=ido; + t4+=ido; + } + } + } + +L119: + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + t2=ipp2*idl1; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1-ido; + t4=t2-ido; + for(k=0;k<l1;k++){ + t3+=ido; + t4+=ido; + c1[t3]=ch[t3]+ch[t4]; + c1[t4]=ch[t4]-ch[t3]; + } + } + + ar1=1.; + ai1=0.; + t1=0; + t2=ipp2*idl1; + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=t3; + t7=idl1; + + for(ik=0;ik<idl1;ik++){ + ch2[t4++]=c2[ik]+ar1*c2[t7++]; + ch2[t5++]=ai1*c2[t6++]; + } + + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t4=idl1; + t5=(ipp2-1)*idl1; + for(j=2;j<ipph;j++){ + t4+=idl1; + t5-=idl1; + + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + + t6=t1; + t7=t2; + t8=t4; + t9=t5; + for(ik=0;ik<idl1;ik++){ + ch2[t6++]+=ar2*c2[t8++]; + ch2[t7++]+=ai2*c2[t9++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++]; + } + + if(ido<l1)goto L132; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++)cc[t4++]=ch[t3++]; + t1+=ido; + t2+=t10; + } + + goto L135; + + L132: + for(i=0;i<ido;i++){ + t1=i; + t2=i; + for(k=0;k<l1;k++){ + cc[t2]=ch[t1]; + t1+=ido; + t2+=t10; + } + } + + L135: + t1=0; + t2=ido<<1; + t3=0; + t4=ipp2*t0; + for(j=1;j<ipph;j++){ + + t1+=t2; + t3+=t0; + t4-=t0; + + t5=t1; + t6=t3; + t7=t4; + + for(k=0;k<l1;k++){ + cc[t5-1]=ch[t6]; + cc[t5]=ch[t7]; + t5+=t10; + t6+=ido; + t7+=ido; + } + } + + if(ido==1)return; + if(nbd<l1)goto L141; + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + t6=t1; + t7=t3; + t8=t4; + t9=t5; + for(k=0;k<l1;k++){ + for(i=2;i<ido;i+=2){ + ic=idp2-i; + cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1]; + cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1]; + cc[i+t7]=ch[i+t8]+ch[i+t9]; + cc[ic+t6]=ch[i+t9]-ch[i+t8]; + } + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + return; + + L141: + + t1=-ido; + t3=0; + t4=0; + t5=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t2; + t3+=t2; + t4+=t0; + t5-=t0; + for(i=2;i<ido;i+=2){ + t6=idp2+t1-i; + t7=i+t3; + t8=i+t4; + t9=i+t5; + for(k=0;k<l1;k++){ + cc[t7-1]=ch[t8-1]+ch[t9-1]; + cc[t6-1]=ch[t8-1]-ch[t9-1]; + cc[t7]=ch[t8]+ch[t9]; + cc[t6]=ch[t9]-ch[t8]; + t6+=t10; + t7+=t10; + t8+=ido; + t9+=ido; + } + } + } +} + +STIN void drftf1(int n,double *c,double *ch,double *wa,int *ifac){ + int i,k1,l1,l2; + int na,kh,nf; + int ip,iw,ido,idl1,ix2,ix3; + + nf=ifac[1]; + na=1; + l2=n; + iw=n; + + for(k1=0;k1<nf;k1++){ + kh=nf-k1; + ip=ifac[kh+1]; + l1=l2/ip; + ido=n/l2; + idl1=ido*l1; + iw-=(ip-1)*ido; + na=1-na; + + if(ip!=4)goto L102; + + ix2=iw+ido; + ix3=ix2+ido; + if(na!=0) + dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + goto L110; + + L102: + if(ip!=2)goto L104; + if(na!=0)goto L103; + + dradf2(ido,l1,c,ch,wa+iw-1); + goto L110; + + L103: + dradf2(ido,l1,ch,c,wa+iw-1); + goto L110; + + L104: + if(ido==1)na=1-na; + if(na!=0)goto L109; + + dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + na=1; + goto L110; + + L109: + dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + na=0; + + L110: + l2=l1; + } + + if(na==1)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +void __ogg_fdrfftf(int n,double *r,double *wsave,int *ifac){ + if(n==1)return; + drftf1(n,r,wsave,wsave+n,ifac); +} + +STIN void dcsqf1(int n,double *x,double *w,double *xh,int *ifac){ + int modn,i,k,kc; + int np2,ns2; + double xim1; + + ns2=(n+1)>>1; + np2=n; + + kc=np2; + for(k=1;k<ns2;k++){ + kc--; + xh[k]=x[k]+x[kc]; + xh[kc]=x[k]-x[kc]; + } + + modn=n%2; + if(modn==0)xh[ns2]=x[ns2]+x[ns2]; + + for(k=1;k<ns2;k++){ + kc=np2-k; + x[k]=w[k-1]*xh[kc]+w[kc-1]*xh[k]; + x[kc]=w[k-1]*xh[k]-w[kc-1]*xh[kc]; + } + + if(modn==0)x[ns2]=w[ns2-1]*xh[ns2]; + + __ogg_fdrfftf(n,x,xh,ifac); + + for(i=2;i<n;i+=2){ + xim1=x[i-1]-x[i]; + x[i]=x[i-1]+x[i]; + x[i-1]=xim1; + } +} + +void __ogg_fdcosqf(int n,double *x,double *wsave,int *ifac){ + static double sqrt2=1.4142135623730950488016887242097; + double tsqx; + + switch(n){ + case 0:case 1: + return; + case 2: + tsqx=sqrt2*x[1]; + x[1]=x[0]-tsqx; + x[0]+=tsqx; + return; + default: + dcsqf1(n,x,wsave,wsave+n,ifac); + return; + } +} + +STIN void dradb2(int ido,int l1,double *cc,double *ch,double *wa1){ + int i,k,t0,t1,t2,t3,t4,t5,t6; + double ti2,tr2; + + t0=l1*ido; + + t1=0; + t2=0; + t3=(ido<<1)-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t3+t2]; + ch[t1+t0]=cc[t2]-cc[t3+t2]; + t2=(t1+=ido)<<1; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t5=(t4=t2)+(ido<<1); + t6=t0+t1; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5-=2; + t6+=2; + ch[t3-1]=cc[t4-1]+cc[t5-1]; + tr2=cc[t4-1]-cc[t5-1]; + ch[t3]=cc[t4]-cc[t5]; + ti2=cc[t4]+cc[t5]; + ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2; + ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2; + } + t2=(t1+=ido)<<1; + } + + if(ido%2==1)return; + +L105: + t1=ido-1; + t2=ido-1; + for(k=0;k<l1;k++){ + ch[t1]=cc[t2]+cc[t2]; + ch[t1+t0]=-(cc[t2+1]+cc[t2+1]); + t1+=ido; + t2+=ido<<1; + } +} + +STIN void dradb3(int ido,int l1,double *cc,double *ch,double *wa1, + double *wa2){ + static double taur = -.5; + static double taui = .86602540378443864676372317075293618; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; + double ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2; + t0=l1*ido; + + t1=0; + t2=t0<<1; + t3=ido<<1; + t4=ido+(ido<<1); + t5=0; + for(k=0;k<l1;k++){ + tr2=cc[t3-1]+cc[t3-1]; + cr2=cc[t5]+(taur*tr2); + ch[t1]=cc[t5]+tr2; + ci3=taui*(cc[t3]+cc[t3]); + ch[t1+t0]=cr2-ci3; + ch[t1+t2]=cr2+ci3; + t1+=ido; + t3+=t4; + t5+=t4; + } + + if(ido==1)return; + + t1=0; + t3=ido<<1; + for(k=0;k<l1;k++){ + t7=t1+(t1<<1); + t6=(t5=t7+t3); + t8=t1; + t10=(t9=t1+t0)+t0; + + for(i=2;i<ido;i+=2){ + t5+=2; + t6-=2; + t7+=2; + t8+=2; + t9+=2; + t10+=2; + tr2=cc[t5-1]+cc[t6-1]; + cr2=cc[t7-1]+(taur*tr2); + ch[t8-1]=cc[t7-1]+tr2; + ti2=cc[t5]-cc[t6]; + ci2=cc[t7]+(taur*ti2); + ch[t8]=cc[t7]+ti2; + cr3=taui*(cc[t5-1]-cc[t6-1]); + ci3=taui*(cc[t5]+cc[t6]); + dr2=cr2-ci3; + dr3=cr2+ci3; + di2=ci2+cr3; + di3=ci2-cr3; + ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2; + ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2; + ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3; + ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3; + } + t1+=ido; + } +} + +STIN void dradb4(int ido,int l1,double *cc,double *ch,double *wa1, + double *wa2,double *wa3){ + static double sqrt2=1.4142135623730950488016887242097; + int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8; + double ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4; + t0=l1*ido; + + t1=0; + t2=ido<<2; + t3=0; + t6=ido<<1; + for(k=0;k<l1;k++){ + t4=t3+t6; + t5=t1; + tr3=cc[t4-1]+cc[t4-1]; + tr4=cc[t4]+cc[t4]; + tr1=cc[t3]-cc[(t4+=t6)-1]; + tr2=cc[t3]+cc[t4-1]; + ch[t5]=tr2+tr3; + ch[t5+=t0]=tr1-tr4; + ch[t5+=t0]=tr2-tr3; + ch[t5+=t0]=tr1+tr4; + t1+=ido; + t3+=t2; + } + + if(ido<2)return; + if(ido==2)goto L105; + + t1=0; + for(k=0;k<l1;k++){ + t5=(t4=(t3=(t2=t1<<2)+t6))+t6; + t7=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + t3+=2; + t4-=2; + t5-=2; + t7+=2; + ti1=cc[t2]+cc[t5]; + ti2=cc[t2]-cc[t5]; + ti3=cc[t3]-cc[t4]; + tr4=cc[t3]+cc[t4]; + tr1=cc[t2-1]-cc[t5-1]; + tr2=cc[t2-1]+cc[t5-1]; + ti4=cc[t3-1]-cc[t4-1]; + tr3=cc[t3-1]+cc[t4-1]; + ch[t7-1]=tr2+tr3; + cr3=tr2-tr3; + ch[t7]=ti2+ti3; + ci3=ti2-ti3; + cr2=tr1-tr4; + cr4=tr1+tr4; + ci2=ti1+ti4; + ci4=ti1-ti4; + + ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2; + ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2; + ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3; + ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3; + ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4; + ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4; + } + t1+=ido; + } + + if(ido%2 == 1)return; + + L105: + + t1=ido; + t2=ido<<2; + t3=ido-1; + t4=ido+(ido<<1); + for(k=0;k<l1;k++){ + t5=t3; + ti1=cc[t1]+cc[t4]; + ti2=cc[t4]-cc[t1]; + tr1=cc[t1-1]-cc[t4-1]; + tr2=cc[t1-1]+cc[t4-1]; + ch[t5]=tr2+tr2; + ch[t5+=t0]=sqrt2*(tr1-ti1); + ch[t5+=t0]=ti2+ti2; + ch[t5+=t0]=-sqrt2*(tr1+ti1); + + t3+=ido; + t1+=t2; + t4+=t2; + } +} + +STIN void dradbg(int ido,int ip,int l1,int idl1,double *cc,double *c1, + double *c2,double *ch,double *ch2,double *wa){ + static double tpi=6.28318530717958647692528676655900577; + int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, + t11,t12; + double dc2,ai1,ai2,ar1,ar2,ds2; + int nbd; + double dcp,arg,dsp,ar1h,ar2h; + int ipp2; + + t10=ip*ido; + t0=l1*ido; + arg=tpi/(double)ip; + dcp=cos(arg); + dsp=sin(arg); + nbd=(ido-1)>>1; + ipp2=ip; + ipph=(ip+1)>>1; + if(ido<l1)goto L103; + + t1=0; + t2=0; + for(k=0;k<l1;k++){ + t3=t1; + t4=t2; + for(i=0;i<ido;i++){ + ch[t3]=cc[t4]; + t3++; + t4++; + } + t1+=ido; + t2+=t10; + } + goto L106; + + L103: + t1=0; + for(i=0;i<ido;i++){ + t2=t1; + t3=t1; + for(k=0;k<l1;k++){ + ch[t2]=cc[t3]; + t2+=ido; + t3+=t10; + } + t1++; + } + + L106: + t1=0; + t2=ipp2*t0; + t7=(t5=ido<<1); + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t6=t5; + for(k=0;k<l1;k++){ + ch[t3]=cc[t6-1]+cc[t6-1]; + ch[t4]=cc[t6]+cc[t6]; + t3+=ido; + t4+=ido; + t6+=t10; + } + t5+=t7; + } + + if (ido == 1)goto L116; + if(nbd<l1)goto L112; + + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + + t7+=(ido<<1); + t8=t7; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + t9=t8; + t11=t8; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + t9+=2; + t11-=2; + ch[t5-1]=cc[t9-1]+cc[t11-1]; + ch[t6-1]=cc[t9-1]-cc[t11-1]; + ch[t5]=cc[t9]-cc[t11]; + ch[t6]=cc[t9]+cc[t11]; + } + t3+=ido; + t4+=ido; + t8+=t10; + } + } + goto L116; + + L112: + t1=0; + t2=ipp2*t0; + t7=0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + t7+=(ido<<1); + t8=t7; + t9=t7; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t8+=2; + t9-=2; + t5=t3; + t6=t4; + t11=t8; + t12=t9; + for(k=0;k<l1;k++){ + ch[t5-1]=cc[t11-1]+cc[t12-1]; + ch[t6-1]=cc[t11-1]-cc[t12-1]; + ch[t5]=cc[t11]-cc[t12]; + ch[t6]=cc[t11]+cc[t12]; + t5+=ido; + t6+=ido; + t11+=t10; + t12+=t10; + } + } + } + +L116: + ar1=1.; + ai1=0.; + t1=0; + t9=(t2=ipp2*idl1); + t3=(ip-1)*idl1; + for(l=1;l<ipph;l++){ + t1+=idl1; + t2-=idl1; + + ar1h=dcp*ar1-dsp*ai1; + ai1=dcp*ai1+dsp*ar1; + ar1=ar1h; + t4=t1; + t5=t2; + t6=0; + t7=idl1; + t8=t3; + for(ik=0;ik<idl1;ik++){ + c2[t4++]=ch2[t6++]+ar1*ch2[t7++]; + c2[t5++]=ai1*ch2[t8++]; + } + dc2=ar1; + ds2=ai1; + ar2=ar1; + ai2=ai1; + + t6=idl1; + t7=t9-idl1; + for(j=2;j<ipph;j++){ + t6+=idl1; + t7-=idl1; + ar2h=dc2*ar2-ds2*ai2; + ai2=dc2*ai2+ds2*ar2; + ar2=ar2h; + t4=t1; + t5=t2; + t11=t6; + t12=t7; + for(ik=0;ik<idl1;ik++){ + c2[t4++]+=ar2*ch2[t11++]; + c2[t5++]+=ai2*ch2[t12++]; + } + } + } + + t1=0; + for(j=1;j<ipph;j++){ + t1+=idl1; + t2=t1; + for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++]; + } + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + ch[t3]=c1[t3]-c1[t4]; + ch[t4]=c1[t3]+c1[t4]; + t3+=ido; + t4+=ido; + } + } + + if(ido==1)goto L132; + if(nbd<l1)goto L128; + + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(k=0;k<l1;k++){ + t5=t3; + t6=t4; + for(i=2;i<ido;i+=2){ + t5+=2; + t6+=2; + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + } + t3+=ido; + t4+=ido; + } + } + goto L132; + + L128: + t1=0; + t2=ipp2*t0; + for(j=1;j<ipph;j++){ + t1+=t0; + t2-=t0; + t3=t1; + t4=t2; + for(i=2;i<ido;i+=2){ + t3+=2; + t4+=2; + t5=t3; + t6=t4; + for(k=0;k<l1;k++){ + ch[t5-1]=c1[t5-1]-c1[t6]; + ch[t6-1]=c1[t5-1]+c1[t6]; + ch[t5]=c1[t5]+c1[t6-1]; + ch[t6]=c1[t5]-c1[t6-1]; + t5+=ido; + t6+=ido; + } + } + } + +L132: + if(ido==1)return; + + for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik]; + + t1=0; + for(j=1;j<ip;j++){ + t2=(t1+=t0); + for(k=0;k<l1;k++){ + c1[t2]=ch[t2]; + t2+=ido; + } + } + + if(nbd>l1)goto L139; + + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + idij=is; + t2=t1; + for(i=2;i<ido;i+=2){ + t2+=2; + idij+=2; + t3=t2; + for(k=0;k<l1;k++){ + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + t3+=ido; + } + } + } + return; + + L139: + is= -ido-1; + t1=0; + for(j=1;j<ip;j++){ + is+=ido; + t1+=t0; + t2=t1; + for(k=0;k<l1;k++){ + idij=is; + t3=t2; + for(i=2;i<ido;i+=2){ + idij+=2; + t3+=2; + c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3]; + c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1]; + } + t2+=ido; + } + } +} + +STIN void drftb1(int n, double *c, double *ch, double *wa, int *ifac){ + int i,k1,l1,l2; + int na; + int nf,ip,iw,ix2,ix3,ido,idl1; + + nf=ifac[1]; + na=0; + l1=1; + iw=1; + + for(k1=0;k1<nf;k1++){ + ip=ifac[k1 + 2]; + l2=ip*l1; + ido=n/l2; + idl1=ido*l1; + if(ip!=4)goto L103; + ix2=iw+ido; + ix3=ix2+ido; + + if(na!=0) + dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1); + else + dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1); + na=1-na; + goto L115; + + L103: + if(ip!=2)goto L106; + + if(na!=0) + dradb2(ido,l1,ch,c,wa+iw-1); + else + dradb2(ido,l1,c,ch,wa+iw-1); + na=1-na; + goto L115; + + L106: + if(ip!=3)goto L109; + + ix2=iw+ido; + if(na!=0) + dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1); + else + dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1); + na=1-na; + goto L115; + + L109: +/* The radix five case can be translated later..... */ +/* if(ip!=5)goto L112; + + ix2=iw+ido; + ix3=ix2+ido; + ix4=ix3+ido; + if(na!=0) + dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + else + dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1); + na=1-na; + goto L115; + + L112:*/ + if(na!=0) + dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1); + else + dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1); + if(ido==1)na=1-na; + + L115: + l1=l2; + iw+=(ip-1)*ido; + } + + if(na==0)return; + + for(i=0;i<n;i++)c[i]=ch[i]; +} + +void __ogg_fdrfftb(int n, double *r, double *wsave, int *ifac){ + if (n == 1)return; + drftb1(n, r, wsave, wsave+n, ifac); +} + +STIN void dcsqb1(int n,double *x,double *w,double *xh,int *ifac){ + int modn,i,k,kc; + int np2,ns2; + double xim1; + + ns2=(n+1)>>1; + np2=n; + + for(i=2;i<n;i+=2){ + xim1=x[i-1]+x[i]; + x[i]-=x[i-1]; + x[i-1]=xim1; + } + + x[0]+=x[0]; + modn=n%2; + if(modn==0)x[n-1]+=x[n-1]; + + __ogg_fdrfftb(n,x,xh,ifac); + + kc=np2; + for(k=1;k<ns2;k++){ + kc--; + xh[k]=w[k-1]*x[kc]+w[kc-1]*x[k]; + xh[kc]=w[k-1]*x[k]-w[kc-1]*x[kc]; + } + + if(modn==0)x[ns2]=w[ns2-1]*(x[ns2]+x[ns2]); + + kc=np2; + for(k=1;k<ns2;k++){ + kc--; + x[k]=xh[k]+xh[kc]; + x[kc]=xh[k]-xh[kc]; + } + x[0]+=x[0]; +} + +void __ogg_fdcosqb(int n,double *x,double *wsave,int *ifac){ + static double tsqrt2 = 2.8284271247461900976033774484194; + double x1; + + if(n<2){ + x[0]*=4; + return; + } + if(n==2){ + x1=(x[0]+x[1])*4; + x[1]=tsqrt2*(x[0]-x[1]); + x[0]=x1; + return; + } + + dcsqb1(n,x,wsave,wsave+n,ifac); +} diff --git a/nist/matrix.c b/nist/matrix.c new file mode 100644 index 0000000..50bf007 --- /dev/null +++ b/nist/matrix.c @@ -0,0 +1,168 @@ + + +#include <stdio.h> +#include <stdlib.h> +/*#include "defs.h" +#include "proto.h"*/ +#define MIN(x,y) ((x) > (y) ? (y) : (x)) + +#include "matrix.h" + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + R A N K A L G O R I T H M R O U T I N E S + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int computeRank(int M, int Q, BitField** matrix) +{ + int i; + int rank; + int m = MIN(M,Q); + + /* FORWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */ + + for(i = 0; i < m-1; i++) { + if (matrix[i][i].b == 1) + perform_elementary_row_operations(0, i, M, Q, matrix); + else { /* matrix[i][i] = 0 */ + if (find_unit_element_and_swap(0, i, M, Q, matrix) == 1) + perform_elementary_row_operations(0, i, M, Q, matrix); + } + } + + /* BACKWARD APPLICATION OF ELEMENTARY ROW OPERATIONS */ + for(i = m-1; i > 0; i--) { + if (matrix[i][i].b == 1) + perform_elementary_row_operations(1, i, M, Q, matrix); + else { /* matrix[i][i] = 0 */ + if (find_unit_element_and_swap(1, i, M, Q, matrix) == 1) + perform_elementary_row_operations(1, i, M, Q, matrix); + } + } + rank = determine_rank(m,M,Q,matrix); + + return rank; +} + +void perform_elementary_row_operations(int flag, int i, int M, int Q, + BitField** A) +{ + int j,k; + + switch(flag) + { + case 0: for(j = i+1; j < M; j++) + if (A[j][i].b == 1) + for(k = i; k < Q; k++) + A[j][k].b = (A[j][k].b + A[i][k].b) % 2; + break; + + case 1: for(j = i-1; j >= 0; j--) + if (A[j][i].b == 1) + for(k = 0; k < Q; k++) + A[j][k].b = (A[j][k].b + A[i][k].b) % 2; + break; + default: fprintf(stderr,"ERROR IN CALL TO perform_elementary_row_operations\n"); + break; + } + return; +} + +int find_unit_element_and_swap(int flag, int i, int M, int Q, BitField** A) +{ + int index; + int row_op = 0; + + switch(flag) + { + case 0: index = i+1; + while ((index < M) && (A[index][i].b == 0)) + index++; + if (index < M) + row_op = swap_rows(i,index,Q,A); + break; + case 1: + index = i-1; + while ((index >= 0) && (A[index][i].b == 0)) + index--; + if (index >= 0) + row_op = swap_rows(i,index,Q,A); + break; + default: fprintf(stderr,"ERROW IN CALL TO find_unit_element_and_swap\n"); + break; + } + return row_op; +} + +int swap_rows(int i, int index, int Q, BitField** A) +{ + int p; + BitField temp; + + for(p = 0; p < Q; p++) { + temp.b = A[i][p].b; + A[i][p].b = A[index][p].b; + A[index][p].b = temp.b; + } + return 1; +} + +int determine_rank(int m, int M, int Q, BitField** A) +{ + int i, j, rank, allZeroes; + + /* DETERMINE RANK, THAT IS, COUNT THE NUMBER OF NONZERO ROWS */ + + rank = m; + for(i = 0; i < M; i++) { + allZeroes = 1; + for(j=0; j < Q; j++) { + if (A[i][j].b == 1) { + allZeroes = 0; + break; + } + } + if (allZeroes == 1) rank--; + } + return rank; +} + + +void display_matrix(int M, int Q, BitField** m) +{ + int i,j; + + for (i = 0; i < M; i++) { + for (j = 0; j < Q; j++) + fprintf(stderr,"%d ", m[i][j].b); + fprintf(stderr,"\n"); + } + return; +} + +void def_matrix(int M, int Q, BitField** m,int k, int *pt, int *PT, int*DATA, int *ARRAY) +{ + int i,j; + for (i = 0; i < M; i++) + for (j = 0; j < Q; j++) { + m[i][j].b = *DATA & 1; +(*PT)++; + if ((*PT) == 32) + { + *PT = 0; + (*pt)++; + *DATA = ARRAY[*pt]; + } + else + *DATA = (*DATA) >> 1; + + } + return; +} + +void delete_matrix(int M, BitField** matrix) +{ + int i; + for (i = 0; i < M; i++) + free(matrix[i]); + free(matrix); +} diff --git a/nist/matrix.h b/nist/matrix.h new file mode 100644 index 0000000..d66e9a2 --- /dev/null +++ b/nist/matrix.h @@ -0,0 +1,19 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + R A N K A L G O R I T H M F U N C T I O N P R O T O T Y P E S + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +struct bit { + unsigned char b:1; +}; +typedef struct bit BitField; + + +void perform_elementary_row_operations(int,int,int,int,BitField**); +int find_unit_element_and_swap(int,int,int,int, BitField**); +int swap_rows(int, int, int, BitField**); +int determine_rank(int, int, int, BitField**); +int computeRank(int,int,BitField**); +void define_matrix(int,int,int,BitField**); +BitField** create_matrix(int, int); +void display_matrix(int, int, BitField**); +void def_matrix(int M, int Q, BitField** m,int k, int *pt, int *PT, int*DATA, int *ARRAY); +void delete_matrix(int, BitField**); diff --git a/nist/mconf.h b/nist/mconf.h new file mode 100644 index 0000000..84c15d7 --- /dev/null +++ b/nist/mconf.h @@ -0,0 +1,169 @@ +/* mconf.h + * + * Common include file for math routines + * + * + * + * SYNOPSIS: + * + * #include "mconf.h" + * + * + * + * DESCRIPTION: + * + * This file contains definitions for error codes that are + * passed to the common error handling routine mtherr() + * (which see). + * + * The file also includes a conditional assembly definition + * for the type of computer arithmetic (IEEE, DEC, Motorola + * IEEE, or UNKnown). + * + * For Digital Equipment PDP-11 and VAX computers, certain + * IBM systems, and others that use numbers with a 56-bit + * significand, the symbol DEC should be defined. In this + * mode, most floating point constants are given as arrays + * of octal integers to eliminate decimal to binary conversion + * errors that might be introduced by the compiler. + * + * For little-endian computers, such as IBM PC, that follow the + * IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE + * Std 754-1985), the symbol IBMPC should be defined. These + * numbers have 53-bit significands. In this mode, constants + * are provided as arrays of hexadecimal 16 bit integers. + * + * Big-endian IEEE format is denoted MIEEE. On some RISC + * systems such as Sun SPARC, double precision constants + * must be stored on 8-byte address boundaries. Since integer + * arrays may be aligned differently, the MIEEE configuration + * may fail on such machines. + * + * To accommodate other types of computer arithmetic, all + * constants are also provided in a normal decimal radix + * which one can hope are correctly converted to a suitable + * format by the available C language compiler. To invoke + * this mode, define the symbol UNK. + * + * An important difference among these modes is a predefined + * set of machine arithmetic constants for each. The numbers + * MACHEP (the machine roundoff error), MAXNUM (largest number + * represented), and several other parameters are preset by + * the configuration symbol. Check the file const.c to + * ensure that these values are correct for your computer. + * + * Configurations NANS, INFINITIES, MINUSZERO, and DENORMAL + * may fail on many systems. Verify that they are supposed + * to work on your computer. + */ + +/* +Cephes Math Library Release 2.3: June, 1995 +Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier +*/ + + +/* Constant definitions for math error conditions + */ +#ifndef DOMAIN +#define DOMAIN 1 /* argument domain error */ +#define SING 2 /* argument singularity */ +#define OVERFLOW 3 /* overflow range error */ +#define UNDERFLOW 4 /* underflow range error */ +#define TLOSS 5 /* total loss of precision */ +#define PLOSS 6 /* partial loss of precision */ + +#define EDOM 33 +#define ERANGE 34 +#endif + +/* Complex numeral. */ +typedef struct + { + double r; + double i; + } cmplx; + +/* Long double complex numeral. */ +/* +typedef struct + { + long double r; + long double i; + } cmplxl; +*/ + +/* Type of computer arithmetic */ + +/* PDP-11, Pro350, VAX: + */ +/* #define DEC 1 */ + +/* Intel IEEE, low order words come first: + */ +/*#define IBMPC 1 */ + +/* Motorola IEEE, high order words come first + * (Sun 680x0 workstation): + */ +/* #define MIEEE 1 */ + +/* UNKnown arithmetic, invokes coefficients given in + * normal decimal format. Beware of range boundary + * problems (MACHEP, MAXLOG, etc. in const.c) and + * roundoff problems in pow.c: + * (Sun SPARCstation) + */ +#define UNK 1 + +/* If you define UNK, then be sure to set BIGENDIAN properly. */ +#define BIGENDIAN 0 + +/* Define this `volatile' if your compiler thinks + * that floating point arithmetic obeys the associative + * and distributive laws. It will defeat some optimizations + * (but probably not enough of them). + * + * #define VOLATILE volatile + */ +#define VOLATILE + +/* For 12-byte long doubles on an i386, pad a 16-bit short 0 + * to the end of real constants initialized by integer arrays. + * + * #define XPD 0, + * + * Otherwise, the type is 10 bytes long and XPD should be + * defined blank (e.g., Microsoft C). + * + * #define XPD + */ +#define XPD 0, + +/* Define to support tiny denormal numbers, else undefine. */ +#define DENORMAL 1 + +/* Define to ask for infinity support, else undefine. */ +/* #define INFINITIES 1 */ + +/* Define to ask for support of numbers that are Not-a-Number, + else undefine. This may automatically define INFINITIES in some files. */ +/* #define NANS 1 */ + +/* Define to distinguish between -0.0 and +0.0. */ +/* #define MINUSZERO 1 */ + +/* Define 1 for ANSI C atan2() function + See atan.c and clog.c. */ +#define ANSIC 1 + +/* Get ANSI function prototypes, if you want them. */ +#ifdef __STDC__ +#define ANSIPROT +#include "cephes-protos.h" +#else +int mtherr(); +#endif + +/* Variable for error reporting. See mtherr.c. */ +extern int merror; diff --git a/nist/nist.c b/nist/nist.c new file mode 100644 index 0000000..e68c27b --- /dev/null +++ b/nist/nist.c @@ -0,0 +1,57 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include "nist.h" + +#define _32MB (32 * 1024 * 1024) +#define _08MB (8 * 1024 * 1024) +#define _04MB (4 * 1024 * 1024) +#define _02MB (2 * 1024 * 1024) + + +static int random_pool1 [_32MB]; +char basedirname[FILENAME_MAX+1]; + +char *GetBaseDir(void) +{ + return basedirname; +} + +int main(int argc, char **argv) +{ +char *filename = ""; +FILE *fp = stdin; +long result=0; + + if (argc<2 || argc>3) { + printf("Usage sts <file> [<template directory>]\n"); + return 1; + } + /** + * get optional directory name + */ + basedirname[0] = 0; + if (argc>2) { + strcat(basedirname, argv[2]); + strcat(basedirname, "/"); + } + +filename = argv[1]; +if ((fp = fopen(filename, "rb")) == NULL) { + printf("Cannot open file %s\n", filename); + return 2; + } +result = fread(random_pool1,sizeof(int),_04MB,fp); +fclose(fp); +if (result!=_04MB) { + printf("16MB sample required %ld != %d\n",result, _04MB); + return 3; + } +if (PackTestF (random_pool1, _04MB, "nist.out") < 8) { + if (PackTestL (random_pool1, _04MB, "nist.out") < 8) + return 0; + return 5; + } +return 4; +} diff --git a/nist/nist.h b/nist/nist.h new file mode 100644 index 0000000..b5962cd --- /dev/null +++ b/nist/nist.h @@ -0,0 +1,33 @@ +/** + * Supply function prototypes for the test suite. + */ +int PackTestF (int *ARRAY, int ArraySize, char *C); +int PackTestL (int *ARRAY, int ArraySize, char *C); + +int ApproximateEntropy (int mmin, int mmax, int n, int *ARRAY); +int BlockFrequency (int ArraySize, int m, int *ARRAY); +int CumulativeSums (int n, int *ARRAY); +int DiscreteFourierTransform (int N, int *ARRAY); +int Frequency (int n, int *ARRAY); +int LempelZivCompression (int n, int *ARRAY, int *DATA, int *pt, int *PT); +int LinearComplexity (int M, int N, int *ARRAY, int PT); +int LongestRunOfOnes (int n, int *ARRAY); +int NonOverlappingTemplateMatchings (int m, int n, int *ARRAY); +int OverlappingTemplateMatchings (int m, int n, int *ARRAY); +int RandomExcursions (int n, int *ARRAY); +int RandomExcursionsVariant (int n, int *ARRAY); +int Rank (int n, int *ARRAY); +int Runs (int n, int *ARRAY); +int Serial (int m, int n, int *ARRAY, int PT); +int UNIVERSAL (int n, int *ARRAY); +int Universal (int n, int *ARRAY); + +double psi2 (int m, int n, int *ARRAY, int PT); +/** + * From dfft.c + */ +void __ogg_fdrffti(int n, double *wsave, int *ifac); +void __ogg_fdrfftf(int n,double *r,double *wsave,int *ifac); + +char *GetBaseDir(void); + diff --git a/nist/packtest.c b/nist/packtest.c new file mode 100644 index 0000000..879cd73 --- /dev/null +++ b/nist/packtest.c @@ -0,0 +1,2252 @@ +/* -------------------------------------------------------------------------- + Title : The NIST Statistical Test Suite + + Date : December 1999 + + Programmer : Juan Soto + + Summary : For use in the evaluation of the randomness of bitstreams + produced by cryptographic random number generators. + + Package : Version 1.0 + + Copyright : (c) 1999 by the National Institute Of Standards & Technology + + History : Version 1.0 by J. Soto, October 1999 + Revised by J. Soto, November 1999 + + Keywords : Pseudorandom Number Generator (PRNG), Randomness, Statistical + Tests, Complementary Error functions, Incomplete Gamma + Function, Random Walks, Rank, Fast Fourier Transform, + Template, Cryptographically Secure PRNG (CSPRNG), + Approximate Entropy (ApEn), Secure Hash Algorithm (SHA-1), + Blum-Blum-Shub (BBS) CSPRNG, Micali-Schnorr (MS) CSPRNG, + + Source : David Banks, Elaine Barker, James Dray, Allen Heckert, + Stefan Leigh, Mark Levenson, James Nechvatal, Andrew Rukhin, + Miles Smid, Juan Soto, Mark Vangel, and San Vo. + + Technical + Assistance : Lawrence Bassham, Ron Boisvert, James Filliben, Sharon Keller, + Daniel Lozier, and Bert Rust. + + Warning : Portability Issues. + + Limitation : Amount of memory allocated for workspace. + + Restrictions: Permission to use, copy, and modify this software without + fee is hereby granted, provided that this entire notice is + included in all copies of any software which is or includes + a copy or modification of this software and in all copies + of the supporting documentation for such software. + -------------------------------------------------------------------------- */ + +/* -------------------------------------------------------------------------- + * Derived by Andre Seznec (IRISA/INRIA - www.irisa.fr/caps) to overcome the + * limitations on the sequences size. It should now work on sequences larger + * than 1MB and smaller than 256MB. + * + * Modified on March 2002, last update on June 2002 + * + * Modified Aug 2008 for clean compilation under gcc 4.4 + * -------------------------------------------------------------------------- + */ +#ifndef NOIO +#define IO +#endif +#define LinuxorUnix +#ifdef WIN +#ifndef CYGWIN +#undef LinuxorUnix +/* same libraries are available*/ +#endif +#endif + +#ifdef LinuxorUnix + +#define MAX(x,y) ((x) < (y) ? (y) : (x)) +#define MOD(x,y) (((x) % (y)) < 0 ? ((x) % (y)) + (y) : ((x) % (y))) + + +#include <stdio.h> +#include <math.h> +#include <stdlib.h> +#include "special-functions.h" +#include "mconf.h" +#include "matrix.h" +#include "nist.h" + +#define THRESHOLDFAIL 0.001 +static int TotalTEST = 0; + +/* + * on Windows systems, we encountered difficulties with the memory allocation + * libraries, therefor we used our own allocation technique in a big array + */ + +#define BIGSIZE 32768*1024 +char BigArray[BIGSIZE]; +int PtBigArray = 0; +char * +MYCALLOC (int n, int S) +{ + int i, OldPt; + OldPt = PtBigArray; + PtBigArray += ((n * S + 16) & 0xfffffff0); + if (PtBigArray >= BIGSIZE) + { + printf ("Pb memory allocation in PackTest\n"); + exit (1); + } + for (i = OldPt; i < PtBigArray; i++) + BigArray[i] = 0; + + return (&BigArray[OldPt]); +} + +void +MYFREE (char *X) +{ + PtBigArray = (int) (X - BigArray); +} + +BitField **create_matrix (int M, int Q); + +FILE *fileout; + +int +PackTestF (int *ARRAY, int ArraySize, char *C) +{ + int i; + int TEST = 0; + int failure = 0; + +#ifdef IO + fileout = fopen (C, "w"); +#endif + if (ArraySize >= (1 << 26)) + { + fprintf (fileout, + "This test does not work for an array larger than 256Mbytes\n"); + return (failure); + } +#ifdef IO + { + printf + ("16 NIST tests to be executed: results will be written in file %s\n\n", + C); + printf + ("To maintain response time in a reasonable range,\nsome of the tests are executed on only subsequences\n\n"); + + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t Frequency test \n\n"); + fprintf (fileout, " \n\n Frequency test \n\n"); + } +#endif + for (i = 4; i < ArraySize; i = (i << 1)) + { + int inter; + inter = MOD (ARRAY[ArraySize - i], ArraySize - i); + if (failure >= 8) + { +#ifdef IO + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + + failure += Frequency (i, &ARRAY[inter]); + } + + if (failure >= 8) + { +#ifdef IO + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += Frequency (ArraySize, ARRAY); +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t Block Frequency test \n\n"); + fprintf (fileout, " \n\n Block Frequency test \n\n"); + } +#endif + for (i = 4; i < ArraySize; i = (i << 1)) + { + int inter; + inter = MOD (ARRAY[ArraySize - i], ArraySize - i); + failure += BlockFrequency (i, (32 * i / 99), &ARRAY[inter]); + } + + if (failure >= 8) + { +#ifdef IO + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += BlockFrequency (ArraySize, (32 * ArraySize / 99), ARRAY); +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t Runs test \n\n"); + fprintf (fileout, " \n\n Runs test \n\n"); + } +#endif + for (i = 4; i < ArraySize; i = (i << 1)) + { + int inter; + inter = MOD (ARRAY[ArraySize - i], ArraySize - i); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += Runs (i, &ARRAY[inter]); + } + Runs (ArraySize, ARRAY); +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t LongestRunOfOnes \n\n"); + fprintf (fileout, " \n\n LongestRunOfOnes \n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + failure += LongestRunOfOnes (((750000) >> 5) + 1, &ARRAY[index]); +if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + } + +fclose(fileout); +return(failure); +} +int +PackTestL (int *ARRAY, int ArraySize, char *C) +{ + int i; + int TEST = 4; + int DATA, pt, PT; + int failure = 0; + +#ifdef IO + fileout = fopen (C, "a"); +#endif +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, + "\t Binary Matrix Rank test on 8 random 38,912 bit slices \n\n"); + fprintf (fileout, + " \n\n Binary Matrix Rank test on 8 random 38,912 bit slices \n\n"); + } +#endif + if (ArraySize >= (1 << 26)) + { + fprintf (fileout, + "This test does not work for an array larger than 256Mbytes\n"); + return (failure); + } + + + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + failure += Rank (38192 >> 5, &ARRAY[index]); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t Discrete Fourier test by slice of 1 Mbits\n\n"); + fprintf (fileout, " \n\n Discrete Fourier test by slice of 1 Mbits\n\n"); + fprintf (fileout, " \n\n 8 random slices are picked \n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += DiscreteFourierTransform (32768, &ARRAY[index]); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t NON OVERLAPPING TEMPLATE MATCHING TEST \n"); + fprintf (fileout, "\n\n\t NON OVERLAPPING TEMPLATE MATCHING TEST \n"); + fprintf (fileout, "\t 1 random 1Mbit slices \n\n"); + } +#endif + for (i = 0; i < 1; i++) + { + int index; + index = (ArraySize) * i; + if (ArraySize > 262144) + index = index + MOD (ARRAY[index], ((ArraySize) - 32768)); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += + NonOverlappingTemplateMatchings (9, 1024 * 1024, &ARRAY[index]); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t OVERLAPPING TEMPLATE MATCHING TEST \n"); + fprintf (fileout, "\n\n\t OVERLAPPING TEMPLATE MATCHING TEST \n"); + fprintf (fileout, "\t 8 random 1000000 bits slices \n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + + failure += + OverlappingTemplateMatchings (9, 1000000 >> 5, &ARRAY[index]); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t Maurer's Universal test\n"); + fprintf (fileout, "\n\n Maurer's Universal test\n"); + fprintf + (fileout, + "\n For each of the L parameters, we test the beginning of the sequence\n\n"); + } +#endif + + if (failure >= 8) + { +#ifdef IO + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + + failure += Universal (ArraySize, ARRAY); + + TEST++; +#ifdef IO + { + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, + "\t LEMPEL-ZIV COMPRESSION TEST: 8 random slices of 1000000 bits\n\n"); + fprintf (fileout, + "\n\n\t LEMPEL-ZIV COMPRESSION TEST: 8 random slices of 1000000 bits\n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + DATA = ARRAY[index]; + pt = 0; + PT = 0; + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += + LempelZivCompression (1000000, &ARRAY[index], &DATA, &pt, &PT); + } + if (failure >= 8) + { +/* in order to enable fast detection of strong failure for random sequences*/ +#ifdef IO + fprintf (fileout, + "%d failed individual tests with THRESHOLD %f on %d individual tests before LINEAR COMPLEXITY TEST\ndon't waste your CPU time\n", + failure, THRESHOLDFAIL, TotalTEST); + fprintf (stderr, + "%d failed individual tests with THRESHOLD %f on %d individual tests before LINEAR COMPLEXITY TEST\ndon't waste your CPU time\n", + failure, THRESHOLDFAIL, TotalTEST); + +#endif + fclose (fileout); + return (failure); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, + "\t LINEAR COMPLEXITY TEST: 1 SLICE OF 4731 * 371 bits\n\n"); + fprintf (fileout, + "\n\n\t LINEAR COMPLEXITY TEST: 1 SLICE OF 4731 * 371 bits\n\n"); + } +#endif + +/* these parameters were chosen arbitraly, NIST recommendation are 500<=M<=5000, N>=200, NM >=1000000*/ + for (i = 5; i <= 5; i++) + { + int index, inter; + inter = (371 * 4731 + 32) >> 5; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + if (index + inter > ArraySize) + index = ArraySize - inter; + + + failure += LinearComplexity (4731, 371, &ARRAY[index], 0); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t SERIAL TEST BY SLICE OF 1000000 bits\n\n"); + fprintf (fileout, "\n\n\t SERIAL TEST BY SLICE OF 1000000 bits\n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += Serial (14, 1000000, &ARRAY[index], 0); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t APPROXIMATE ENTROPY TEST\n\n"); + fprintf (fileout, "\n\n\t APPROXIMATE ENTROPY TEST\n\n"); + } +#endif + failure += ApproximateEntropy (3, 17, 32 * ArraySize, ARRAY); +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, "\t CUSUM TEST\n\n"); + fprintf (fileout, "\n\n\t CUSUM TEST\n\n"); + } +#endif + for (i = 4; i < ArraySize; i = (i << 1)) + { + int inter; + fprintf (stderr, "\t\t ArraySize: %d\n", i); + inter = MOD (ARRAY[ArraySize - i], ArraySize - i); + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += CumulativeSums (32 * i, &ARRAY[inter]); + } + + if (failure >= 8) + { +#ifdef IO + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += CumulativeSums (32 * ArraySize, ARRAY); + +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, + "\t RANDOM EXCURSION TEST: 8 SLICE OF 1000000 bits\n\n"); + fprintf (fileout, + "\n\n\t RANDOM EXCURSION TEST: 8 SLICE OF 1000000 bits\n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + fprintf (stderr, "\t\t Slice number: %d\n", i); + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += RandomExcursions (1000000, &ARRAY[index >> 5]); + } +#ifdef IO + { + TEST++; + fprintf (stderr, "Test %d, ", TEST); + fprintf (stderr, + "\t RANDOM EXCURSION TEST VARIANT: 8 SLICES OF 1000000 bits\n\n"); + fprintf (fileout, + "\n\n\t RANDOM EXCURSION TEST VARIANT: 8 SLICES OF 1000000 bits\n\n"); + } +#endif + for (i = 0; i < 8; i++) + { + int index; + index = (ArraySize / 8) * i; + if (ArraySize > 262144) + index = index + (MOD (ARRAY[index], (ArraySize / 8) - 32768)); + + if (failure >= 8) + { +#ifdef IO + + + fprintf (stderr, + "%d failures at %f threshold,\nsequence should be considered as not random\n", + failure, THRESHOLDFAIL); + +#endif + return (failure); + } + + failure += RandomExcursionsVariant (1000000, &ARRAY[index >> 5]); + } + + +#ifdef IO + { + fprintf (stderr, + "%d failed individual tests with THRESHOLD %f on %d individual tests\n", + failure, THRESHOLDFAIL, TotalTEST); + fprintf (fileout, + "%d failed individual tests with THRESHOLD %f on %d individual tests\n", + failure, THRESHOLDFAIL, TotalTEST); + } +#endif + fclose (fileout); + return (failure); +} + +#define MAXNUMOFTEMPLATES 148 +int TEMPLATE[MAXNUMOFTEMPLATES]; +int Skip[MAXNUMOFTEMPLATES]; +int nu[6][MAXNUMOFTEMPLATES]; +int Wj[8][MAXNUMOFTEMPLATES]; +int W_obs[MAXNUMOFTEMPLATES]; +/* was adapted to m =9 by A. Seznec 03/04/2002*/ +int +NonOverlappingTemplateMatchings (int m, int n, int *ARRAY) +{ + FILE *fp; + double sum, chi2, p_value, lambda; + int i, j, k; + char directory[FILENAME_MAX]; + int M, N, K = 5; + int fail = 0; + double pi[6], varWj; + int DATA, PT, pt; + N = 8; + M = floor (n / N); + + + lambda = (M - m + 1) / pow (2, m); + varWj = M * (1. / pow (2., m) - (2. * m - 1.) / pow (2., 2. * m)); + sprintf (directory, "%stemplate%d", GetBaseDir(), m); + if ((fp = fopen (directory, "r")) == NULL) + { +#ifdef IO + { + fprintf (fileout, "\tTemplate file %s not existing\n", directory); + fprintf (stderr, "\tTemplate file %s not existing\n", directory); + } +#endif + exit (1); + + } + else + { + + sum = 0.0; + for (i = 0; i < 2; i++) + { /* Compute Probabilities */ + pi[i] = exp (-lambda + i * log (lambda) - lgam (i + 1)); + sum += pi[i]; + } + pi[0] = sum; + for (i = 2; i <= K; i++) + { /* Compute Probabilities */ + pi[i - 1] = exp (-lambda + i * log (lambda) - lgam (i + 1)); + sum += pi[i - 1]; + } + pi[K] = 1 - sum; + for (i = 0; i < MAXNUMOFTEMPLATES; i++) + { + int inter; + TEMPLATE[i] = 0; + for (j = 0; j < m; j++) + { + if (fscanf (fp, "%d", &inter)<1) inter=0; + TEMPLATE[i] += (inter << j); + } + } + DATA = ARRAY[0] & ((1 << m) - 1); + pt = 0; + PT = m; + + for (i = 0; i < MAXNUMOFTEMPLATES; i++) + for (k = 0; k <= K; k++) + nu[k][i] = 0; + + for (i = 0; i < N; i++) + { + for (k = 0; k < MAXNUMOFTEMPLATES; k++) + W_obs[k] = 0; + for (j = 0; j < M - m + 1; j++) + { + for (k = 0; k < MAXNUMOFTEMPLATES; k++) + { + if (Skip[k] == 0) + { + if (DATA == TEMPLATE[k]) + { + W_obs[k]++; + Skip[k] = m - 1; + } + } + else + { + Skip[k]--; + } + } + PT++; + if (PT == 32) + { + PT = 0; + pt++; + } + DATA = ((DATA << 1) + ((ARRAY[pt] >> PT) & 1)) & ((1 << m) - 1); + } +/* skipping the final values in the slice*/ + for (j = M - m + 1; j < M; j++) + { + PT++; + if (PT == 32) + { + PT = 0; + pt++; + } + DATA = ((DATA << 1) + ((ARRAY[pt] >> PT) & 1)) & ((1 << m) - 1); + } + + for (k = 0; k < MAXNUMOFTEMPLATES; k++) + { + Wj[i][k] = W_obs[k]; + } + } + } + for (k = 0; k < MAXNUMOFTEMPLATES; k++) + { + sum = 0; + chi2 = 0.0; /* Compute Chi Square */ + for (i = 0; i < N; i++) + { + chi2 += pow (((double) Wj[i][k] - lambda) / pow (varWj, 0.5), 2); + } + p_value = igamc (N / 2.0, chi2 / 2.0); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + } + fclose (fp); + return (fail); +} + +int +OverlappingTemplateMatchings (int m, int n, int *ARRAY) +{ +/* A. Seznec 03/03/2002: +I got some troubles with porting the function from the NIST package: +computation of array pi did not work satisfactory. +For m=9, I picked back values from page 34 in NIST report. +I do not have the values for m=10. + +*/ + + int i; + double sum, chi2; + int W_obs; + double p_value; + int DATA; + int M, N, j, K = 5; + unsigned int nu[6] = { 0, 0, 0, 0, 0, 0 }; + int fail = 0; + double pi[6] = + { 0.367879, 0.183940, 0.137955, 0.099634, 0.069935, 0.140657 }; + +/* double pi[6] = + { 0.143783, 0.139430, 0.137319, 0.124314, 0.106209, 0.348945 };*/ + + + int PT, pt; + pt = 0; + PT = 0; + + M = 1032; +/* N = (int) floor (n / M);*/ + N = 968; + + +/* + lambda = (double) (M - m + 1) / pow (2, m); + eta = lambda / 2.0; + sum = 0.0; + for (i = 0; i < K; i++) + { + + pi[i] = Pr (i, eta); + sum += pi[i]; + } + pi[K] = 1 - sum;*/ + DATA = ARRAY[0] & ((1 << m) - 1); + pt = 0; + PT = m; + for (i = 0; i < N; i++) + { + W_obs = 0; + for (j = 0; j < M - m + 1; j++) + { + if (DATA == ((1 << m) - 1)) + W_obs++; + PT++; + if (PT == 32) + { + PT = 0; + pt++; + } + DATA = ((DATA << 1) + ((ARRAY[pt] >> PT) & 1)) & ((1 << m) - 1); + } +/* skipping the final values in the slice*/ + for (j = M - m + 1; j < M; j++) + { + PT++; + if (PT == 32) + { + PT = 0; + pt++; + } + DATA = ((DATA << 1) + ((ARRAY[pt] >> PT) & 1)) & ((1 << m) - 1); + } + + if (W_obs <= 4) + nu[W_obs]++; + else + nu[K]++; + } + + sum = 0; + chi2 = 0.0; /* Compute Chi Square */ + for (i = 0; i < K + 1; i++) + { + chi2 += + pow ((double) nu[i] - ((double) N * pi[i]), 2) / ((double) N * pi[i]); + sum += nu[i]; + + } + p_value = igamc (K / 2., chi2 / 2.); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "m= %d, p_value= %f\n", m, p_value); + } +#endif + return (fail); +} + +int +RandomExcursionsVariant (int n, int *ARRAY) +{ + int i, p, J, x, constraint; + double p_value; + int stateX[18] = + { -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int count; + int fail = 0; + int *S_k; + int pt, PT; + if ((S_k = (int *) MYCALLOC (n, sizeof (int))) == NULL) + { + + } + else + { + J = 0; + S_k[0] = 2 * (ARRAY[0] & 1) - 1; + pt = 0; + PT = 1; + for (i = 1; i < n; i++) + { + S_k[i] = S_k[i - 1] + 2 * ((ARRAY[pt] >> PT) & 1) - 1; + PT++; + if (PT == 32) + { + pt++; + PT = 0; + } + if (S_k[i] == 0) + J++; + } + if (S_k[n - 1] != 0) + J++; + + constraint = MAX (0.005 * pow (n, 0.5), 500); + if (J < constraint) + { + +#ifdef IO + { + fprintf (fileout, + "\n\t\tWARNING: TEST NOT APPLICABLE. THERE ARE "); + fprintf (fileout, "AN\n\t INSUFFICIENT NUMBER OF CYCLES.\n"); + fprintf (fileout, + "\t\t---------------------------------------------"); + fprintf (fileout, "\n"); + } +#endif + } + + else + { + for (p = 0; p <= 17; p++) + { + x = stateX[p]; + count = 0; + for (i = 0; i < n; i++) + if (S_k[i] == x) + count++; + p_value = + erfc (fabs (count - J) / + (sqrt (2. * J * (4. * fabs (x) - 2)))); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; + +#ifdef IO + { + fprintf (fileout, "p_value= %f \n", p_value); + } +#endif + + } + } + } +#ifdef IO + { + fprintf (fileout, "\n"); + } +#endif + MYFREE ((char*)S_k); + return (fail); +} + +int +RandomExcursions (int n, int *ARRAY) +{ + int b, i, j, k, J, x; + int cycleStart, cycleStop, *cycle, *S_k; + int stateX[8] = { -4, -3, -2, -1, 1, 2, 3, 4 }; + int counter[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int PT, pt; + int fail = 0; + double p_value, sum, constraint, nu[6][8]; + double pi[5][6] = { + {0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000, 0.00000000}, + {0.5000000000, 0.2500000000, 0.1250000000, 0.06250000000, 0.03125000000, 0.0312500000}, + {0.7500000000, 0.06250000000, 0.04687500000, 0.03515625000, 0.02636718750, 0.0791015625}, + {0.8333333333, 0.02777777778, 0.02314814815, 0.01929012346, 0.01607510288, 0.0803755143}, + {0.8750000000, 0.01562500000, 0.01367187500, 0.01196289063, 0.01046752930, 0.0732727051} + }; + + + S_k = (int *) MYCALLOC (n, sizeof (int)); + cycle = (int *) MYCALLOC (MAX (1000, n / 200), sizeof (int)); + { + J = 0; /* DETERMINE CYCLES */ + + S_k[0] = 2 * (ARRAY[0] & 1) - 1; + pt = 0; + PT = 1; + for (i = 1; i < n; i++) + { + S_k[i] = S_k[i - 1] + 2 * ((ARRAY[pt] >> PT) & 1) - 1; + PT++; + if (PT == 32) + { + pt++; + PT = 0; + } + if (S_k[i] == 0) + { + J++; + if (J > MAX (1000, n / 128)) + { +#ifdef IO + { + fprintf + (fileout, + "ERROR IN FUNCTION randomExcursions: EXCEEDING THE MAX"); + fprintf (fileout, " NUMBER OF CYCLES EXPECTED\n."); + } +#endif + MYFREE ((char*)cycle); + MYFREE ((char*)S_k); + + return (fail); + } + cycle[J] = i; + } + } + if (S_k[n - 1] != 0) + { + J++; + + } + + + constraint = MAX (0.005 * pow (n, 0.5), 500); + if (J < constraint) + { + +#ifdef IO + { + fprintf (fileout, + "\t\t---------------------------------------------"); + fprintf (fileout, + "\n\t\tWARNING: TEST NOT APPLICABLE. THERE ARE "); + fprintf (fileout, "AN\n\t INSUFFICIENT NUMBER OF CYCLES.\n"); + fprintf (fileout, + "\t\t---------------------------------------------"); + fprintf (fileout, "\n"); + } +#endif + + } + else + { + cycleStart = 0; + cycleStop = cycle[1]; + for (k = 0; k < 6; k++) + for (i = 0; i < 8; i++) + nu[k][i] = 0.; + for (j = 1; j <= J; j++) + { /* FOR EACH CYCLE */ + for (i = 0; i < 8; i++) + counter[i] = 0; + for (i = cycleStart; i < cycleStop; i++) + { + if ((S_k[i] >= 1 && S_k[i] <= 4) + || (S_k[i] >= -4 && S_k[i] <= -1)) + { + if (S_k[i] < 0) + b = 4; + else + b = 3; + counter[S_k[i] + b]++; + } + } + cycleStart = cycle[j] + 1; + if (j < J) + cycleStop = cycle[j + 1]; + else + cycleStop = n; + + for (i = 0; i < 8; i++) + { + if (counter[i] >= 0 && counter[i] <= 4) + nu[counter[i]][i]++; + else if (counter[i] >= 5) + nu[5][i]++; + } + } + for (i = 0; i < 8; i++) + { + x = stateX[i]; + sum = 0.; + for (k = 0; k < 6; k++) + { + sum += pow (nu[k][i] - J * pi[(int) fabs (x)][k], 2) / + (J * pi[(int) fabs (x)][k]); + } + p_value = igamc (2.5, sum / 2.); + + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; + +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + + + + } + } + +#ifdef IO + { + fprintf (fileout, "\n"); + } +#endif + + MYFREE ((char*)cycle); + MYFREE ((char*)S_k); + } + return (fail); +} + +int +CumulativeSums (int n, int *ARRAY) +{ + int i, k, start, finish, mode; + double p_value, cusum, sum, sum1, sum2; + int z; + int pt, PT; + int fail = 0; + for (mode = 0; mode < 2; mode++) + { /* mode = {0,1} => {forward,reverse} */ + sum = 0.0; + cusum = 1.0; + if (mode == 0) + { + pt = 0; + PT = 0; + + for (i = 0; i < n; i++) + { + sum += (double) (2 * ((ARRAY[pt] >> PT) & 1) - 1); + PT++; + if (PT == 32) + { + PT = 0; + pt++; + } + cusum = MAX (cusum, fabs (sum)); + } + } + else if (mode == 1) + { + pt = (n >> 5); + PT = 31; + for (i = n - 1; i >= 0; i--) + { + sum += (double) (2 * ((ARRAY[pt] >> PT) & 1) - 1); + PT--; + if (PT == -1) + { + PT = 31; + pt--; + } + cusum = MAX (cusum, fabs (sum)); + } + } + z = (int) cusum; + + sum1 = 0.0; + start = (-n / z + 1) / 4; + finish = (n / z - 1) / 4; + for (k = start; k <= finish; k++) + sum1 += + (normal ((4 * k + 1) * z / sqrt (n)) - + normal ((4 * k - 1) * z / sqrt (n))); + + sum2 = 0.0; + start = (-n / z - 3) / 4; + finish = (n / z - 1) / 4; + for (k = start; k <= finish; k++) + sum2 += + (normal ((double) ((4 * k + 3) * z) / sqrt ((double) n)) - + normal ((double) ((4 * k + 1) * z) / sqrt (n))); + p_value = 1.0 - sum1 + sum2; + if (mode == 1) +{ if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; + +#ifdef IO + { + fprintf (fileout, "%d bits sequence, reverse p_value= %f \n", n, + p_value); + } +#endif + } + if (mode == 0){ + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; + +#ifdef IO + { + fprintf (fileout, "%d bits sequence, forward p_value= %f \n", n, + p_value); + } +#endif +} + } + return (fail); + +} + + + +int +ApproximateEntropy (int mmin, int mmax, int n, int *ARRAY) +{ + int i, blockSize, seqLength; + int powLen; + double sum, numOfBlocks, ApEn[25], apen, chi_squared, p_value; + unsigned int *P[25]; + int pt, PT, DATA; + int fail = 0; + int MaskEnt[25] = + { 0, 1, 3, 7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, + 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, + 0x1fffff, + 0x3fffff, 0x7fffff, 0xffffff + }; + + seqLength = n - (mmax); + numOfBlocks = (double) seqLength; + for (blockSize = mmin; blockSize <= mmax; blockSize++) + { + powLen = (int) pow (2, blockSize + 1); + if ((P[blockSize] = + (unsigned int *) MYCALLOC (powLen, sizeof (unsigned int))) == NULL) + { + +#ifdef IO + { + fprintf (fileout, "ApEn: Insufficient memory available.\n"); + } +#endif + exit (1); + return (fail); + } + for (i = 0; i < powLen; i++) + P[blockSize][i] = 0; + } + + for (blockSize = mmin; blockSize <= mmax; blockSize++) + { + DATA = ARRAY[0]; + pt = 0; + PT = mmax; + for (i = 0; i < seqLength; i++) + { /* COMPUTE FREQUENCY */ + + (P[blockSize][DATA & MaskEnt[blockSize]])++; + PT++; + if (PT == 32) + { + PT = 0; + pt++; + }; + DATA = (DATA << 1) + ((ARRAY[pt] >> PT) & 1); + } + } + + for (blockSize = mmin; blockSize <= mmax; blockSize++) + { + sum = 0.0; + + for (i = 0; i < (int) pow (2, blockSize); i++) + { + if (P[blockSize][i] > 0) + sum += + (((double) P[blockSize][i]) / (numOfBlocks)) * + log ((double) P[blockSize][i] / numOfBlocks); + } + + ApEn[blockSize] = sum; + } + for (blockSize = mmax; blockSize >= mmin; blockSize--) + MYFREE ((char*)P[blockSize]); + + for (i = mmin; i < mmax; i++) + { + apen = ApEn[i] - ApEn[i + 1]; + chi_squared = 2.0 * ((double) seqLength) * (log (2) - apen); + p_value = igamc (pow (2, i - 1), chi_squared / 2.); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "m= %d,\t p_value= %f, Entropy per %d bits %f \n", + i, p_value, i, -ApEn[i] / log (2)); + } +#endif + } + + return (fail); +} + +int +Serial (int m, int n, int *ARRAY, int PT) +{ + double p_value1, p_value2, psim0, psim1, psim2, del1, del2; + int fail = 0; + psim0 = psi2 (m, n, &ARRAY[PT >> 5], (PT & 31)); + psim1 = psi2 (m - 1, n, &ARRAY[PT >> 5], (PT & 31)); + psim2 = psi2 (m - 2, n, &ARRAY[PT >> 5], (PT & 31)); + del1 = psim0 - psim1; + del2 = psim0 - 2.0 * psim1 + psim2; + p_value1 = igamc (pow (2, m - 1) / 2, del1 / 2.0); + p_value2 = igamc (pow (2, m - 2) / 2, del2 / 2.0); + + if (p_value1 < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value1= %f\n", p_value1); + } +#endif + if (p_value1 < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value2= %f\n", p_value2); + } +#endif + return (fail); +} + + +double +psi2 (int m, int n, int *ARRAY, int PT) +{ + int i, j, k; + double sum, numOfBlocks; + unsigned int *P; + + if ((m == 0) || (m == -1)) + return 0.0; + numOfBlocks = n; + + P = (unsigned int*) MYCALLOC (65536, sizeof (unsigned int)); + for (i = 0; i < numOfBlocks; i++) + { /* COMPUTE FREQUENCY */ + k = 1; + for (j = 0; j < m; j++) + { + + if (((ARRAY[(MOD (PT + i + j, n) >> 5)] >> + (MOD (PT + i + j, n) & 31)) & 1) == 0) + k *= 2; + else + k = 2 * k + 1; + } + P[k - 1]++; + } + sum = 0.0; + for (i = (int) pow (2, m) - 1; i < (int) pow (2, m + 1) - 1; i++) + sum += pow (P[i], 2); + sum = (sum * pow (2, m) / (double) n) - (double) n; + MYFREE ((char*)P); + return sum; +} + + +int +LinearComplexity (int M, int N, int *ARRAY, int PT) +{ + int i, ii, j, d; + int L, m, N_, parity, sign; + double p_value, T_, mean; + int fail = 0; + int K = 6; + double pi[7] = + { 0.01047, 0.03125, 0.12500, 0.50000, 0.25000, 0.06250, 0.020833 }; + double nu[7], chi2; + int *T, *P, *B_, *C; + + B_ = (int *) MYCALLOC (M, sizeof (int)); + C = (int *) MYCALLOC (M, sizeof (int)); + P = (int *) MYCALLOC (M, sizeof (int)); + T = (int *) MYCALLOC (M, sizeof (int)); + + for (i = 0; i < K + 1; i++) + nu[i] = 0.00; + for (ii = 0; ii < N; ii++) + { + for (i = 0; i < M; i++) + { + B_[i] = 0; + C[i] = 0; + T[i] = 0; + P[i] = 0; + } + L = 0; + m = -1; + d = 0; + C[0] = 1; + B_[0] = 1; + /* DETERMINE LINEAR COMPLEXITY */ + N_ = 0; + + while (N_ < M) + { + d = + ((ARRAY[(ii * M + N_ + PT) >> 5]) >> + ((ii * M + N_ + PT) & 31)) & 1; + + for (i = 1; i <= L; i++) + + d += + (C[i] & + (((ARRAY[(ii * M + N_ - i + PT) >> 5]) >> + ((ii * M + N_ - i + PT) & 31)) & 1)); + d = d & 1; + if (d == 1) + { + for (i = 0; i < M; i++) + { + T[i] = C[i]; + P[i] = 0; + } + for (j = 0; j < M; j++) + if (B_[j] == 1) + P[j + N_ - m] = 1; + for (i = 0; i < M; i++) + C[i] = (C[i] + P[i]) & 1; + if (L <= N_ / 2) + { + L = N_ + 1 - L; + m = N_; + for (i = 0; i < M; i++) + B_[i] = T[i]; + } + } + N_++; + } + if ((parity = (M + 1) % 2) == 0) + sign = -1; + else + sign = 1; + mean = + M / 2. + (9. + sign) / 36. - 1. / pow (2, M) * (M / 3. + 2. / 9.); + if ((parity = M % 2) == 0) + sign = 1; + else + sign = -1; + T_ = sign * (L - mean) + 2. / 9.; + + if (T_ <= -2.5) + nu[0]++; + else if (T_ > -2.5 && T_ <= -1.5) + nu[1]++; + else if (T_ > -1.5 && T_ <= -0.5) + nu[2]++; + else if (T_ > -0.5 && T_ <= 0.5) + nu[3]++; + else if (T_ > 0.5 && T_ <= 1.5) + nu[4]++; + else if (T_ > 1.5 && T_ <= 2.5) + nu[5]++; + else + nu[6]++; + + + } + chi2 = 0.00; + for (i = 0; i < K + 1; i++) + chi2 += pow (nu[i] - N * pi[i], 2) / (N * pi[i]); + p_value = igamc (K / 2.0, chi2 / 2.0); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + + MYFREE ((char*)B_); + return (fail); +} + + +int +LempelZivCompression (int n, int *ARRAY, int *DATA, int *pt, int *PT) +{ + int W; /* Number of words */ + int i, j, k, prev_I, powLen, max_len; + int done = 0; + double p_value, mean=0.0, variance=0.0; + BitField *P; + int fail = 0; + W = 0; + k = (int) log (n) / log (2) + 6; + powLen = pow (2, k); + + if ((P = (BitField *) MYCALLOC (powLen, sizeof (BitField))) == NULL) + { + +#ifdef IO + { + fprintf (fileout, "\t\tLempel-Ziv Compression has been aborted,\n"); + fprintf (fileout, "\t\tdue to insufficient workspace!\n"); + } +#endif + } + else + { + for (i = 0; i < powLen; i++) + P[i].b = 0; + i = 0; + max_len = 0; + while (i <= n - 1) + { + done = 0; + j = 1; + prev_I = i; + while (!done) + { + if (2 * j + 1 <= powLen) + { + if ((*DATA & 1) == 0) + { + if (P[2 * j].b == 1) + { + j *= 2; + } + else + { + P[2 * j].b = 1; + done = 1; + } + } + else + { + if (P[2 * j + 1].b == 1) + { + j = 2 * j + 1; + } + else + { + P[2 * j + 1].b = 1; + done = 1; + } + } + (*PT)++; + if (*PT == 32) + { + (*pt)++; + *DATA = ARRAY[*pt]; + *PT = 0; + } + else + *DATA = *DATA >> 1; + i++; + if (i > n - 1) + { + done = 1; + } + if (done) + { + W++; + max_len = MAX (max_len, i - prev_I); + } + } + else + { + +#ifdef IO + { + fprintf (fileout, + "\t\tWARNING: Segmentation Violation Imminent."); + fprintf (fileout, + "\n\t Lempel-Ziv Compression Terminated.\n"); + fprintf (fileout, + "\t\t-----------------------------------------\n"); + fflush (fileout); + } +#endif + done = 1; + i = n; + } + } + } + } + switch (n) + { + case 100000: + mean = 8782.500000; + variance = 11.589744; + break; + case 200000: + mean = 16292.1000; + variance = 21.4632; + break; + case 400000: + mean = 30361.9500; + variance = 58.7868; + break; + case 600000: + mean = 43787.5000; + variance = 70.1579; + break; + case 800000: + mean = 56821.9500; + variance = 67.4184; + break; + case 1000000: /* Updated Mean and Variance 10/26/99 */ + mean = 69588.20190000; + variance = 73.23726011; + /* Previous Mean and Variance + mean = 69586.250000; + variance = 70.448718; + */ + break; + default: + break; + } + p_value = 0.5 * erfc ((mean - W) / pow (2.0 * variance, 0.5)); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + MYFREE ((char*)P); + return (fail); +} + + +int +DiscreteFourierTransform (int N, int *ARRAY) +{ + double p_value, upperBound, *m, *X; + int i, count; + double N_l, N_o, d; + double *wsave; + int n, j, J, *ifac; + int fail = 0; + n = 32 * N; + X = (double *) MYCALLOC (n, sizeof (double)); + wsave = (double *) MYCALLOC (2 * n + 15, sizeof (double)); + ifac = (int *) MYCALLOC (15, sizeof (double)); + m = (double *) MYCALLOC (n / 2 + 1, sizeof (double)); + { + J = 0; + for (i = 0; i < N; i++) + for (j = 0; j < 32; j++) + { + X[J] = (2 * ((ARRAY[i] >> j) & 1)) - 1; + J++; + } + __ogg_fdrffti (n, wsave, ifac); /* INITIALIZE WORK ARRAYS */ + __ogg_fdrfftf (n, X, wsave, ifac); /* APPLY FORWARD FFT */ + + m[0] = sqrt (X[0] * X[0]); /* COMPUTE MAGNITUDE */ + + + for (i = 0; i < n / 2; i++) + { /* DISPLAY FOURIER POINTS */ + m[i + 1] = sqrt (pow (X[2 * i + 1], 2) + pow (X[2 * i + 2], 2)); + } + count = 0; /* CONFIDENCE INTERVAL */ + upperBound = sqrt (3 * n); + for (i = 0; i < n / 2; i++) + if (m[i] < upperBound) + count++; + N_l = (double) count; /* number of peaks less than h = sqrt(3*n) */ + N_o = (double) 0.95 *n / 2.; + d = (N_l - N_o) / sqrt (n / 2. * 0.95 * 0.05); + p_value = erfc (fabs (d) / sqrt (2.)); + + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; + +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + } + MYFREE ((char*)m); + MYFREE ((char*)ifac); + MYFREE ((char*)wsave); + MYFREE ((char*)X); + return (fail); +} + +int +LongestRunOfOnes (int n, int *ARRAY) +{ + double p_value, sum, chi2; + int N, i, j; + int run, v_n_obs; + int fail = 0; +/* since we are not interested in short sequences we used only 10000*/ + + + double pi[7] = { 0.0882, 0.2092, 0.2483, 0.1933, 0.1208, 0.0675, 0.0727 }; + double K = 6; + unsigned int nu[7] = { 0, 0, 0, 0, 0, 0, 0 }; + int M = 10000; + int PT; + int pt; + int DATA; + pt = 0; + PT = 0; + DATA = ARRAY[0]; + N = (int) floor ((32 * n) / M); + for (i = 0; i < N; i++) + { + v_n_obs = 0; + run = 0; + for (j = i * M; j < (i + 1) * M; j++) + { + if (DATA & 1) + { + run++; + v_n_obs = MAX (v_n_obs, run); + } + else + run = 0; + PT++; + if (PT == 32) + { + PT = 0; + pt++; + DATA = ARRAY[pt]; + } + else + DATA = DATA >> 1; + } + if (v_n_obs <= 10) + nu[0]++; + else if (v_n_obs == 11) + nu[1]++; + else if (v_n_obs == 12) + nu[2]++; + else if (v_n_obs == 13) + nu[3]++; + else if (v_n_obs == 14) + nu[4]++; + else if (v_n_obs == 15) + nu[5]++; + else if (v_n_obs >= 16) + nu[6]++; + } + chi2 = 0.0; /* Compute Chi Square */ + sum = 0; + for (i = 0; i < ((int) K) + 1; i++) + { + chi2 += + pow ((double) nu[i] - ((double) N * pi[i]), 2) / ((double) N * pi[i]); + sum += nu[i]; + } + p_value = igamc (K / 2., chi2 / 2.); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + return (fail); +} + +int +Runs (int n, int *ARRAY) +{ + int i, j; + double argument, pi, V_n_obs, tau; + double p_value, product; + int SUM; + double N; + int fail = 0; + int V_N_obs; + N = (double) (32 * (n - 1) + 1); + + SUM = 0; + for (i = 0; i < n - 1; i++) + for (j = 0; j < 32; j++) + { + SUM += (ARRAY[i] >> j) & 1; + } + SUM += (ARRAY[n] & 1); + + pi = ((double) SUM) / N; + tau = 2.0 / sqrt (N); + + if (fabs (pi - 0.5) < tau) + { + V_N_obs = 0; + for (i = 0; i < n - 1; i++) + { + for (j = 0; j < 31; j++) + V_N_obs += (((ARRAY[i] >> j) ^ (ARRAY[i] >> (j + 1))) & 1); + V_N_obs += ((ARRAY[i] >> 31) ^ (ARRAY[i + 1])) & 1; + } + + V_N_obs++; + V_n_obs = (double) V_N_obs; + product = pi * (1.e0 - pi); + argument = + fabs (V_n_obs - + 2.e0 * N * product) / (2.e0 * sqrt (2.e0 * N) * product); + p_value = erfc (argument); + } + else + { + p_value = 0.0; + } + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value=%f\n", p_value); + } +#endif + return (fail); +} + +int +Frequency (int n, int *ARRAY) +{ + int i, j; + double f, s_obs, p_value; + double sqrt2 = 1.41421356237309504880; + int SUM; + int fail = 0; + SUM = 0; + + for (i = 0; i < n; i++) + { + for (j = 0; j < 32; j++) + SUM += (2 * ((ARRAY[i] >> j) & 1)) - 1; + } + s_obs = fabs ((double) SUM) / sqrt (32.0 * ((double) n)); + f = s_obs / sqrt2; + p_value = erfc (f); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "%d bits sequence, p_value= %f\n", 32 * n, p_value); + } +#endif + return (fail); +} + +int +BlockFrequency (int ArraySize, int m, int *ARRAY) +{ + int i, j, N, n; + double arg1, arg2, p_value; + double sum, pi, v, chi_squared; + int BlockSum; + int PT; + int pt; + int DATA; + int fail = 0; + n = ArraySize * 32; + pt = 0; + PT = 0; + DATA = ARRAY[0]; + N = (int) floor ((double) n / (double) m); + sum = 0.0; + for (i = 0; i < N; i++) + { + pi = 0.0; + BlockSum = 0; + for (j = 0; j < m; j++) + { + BlockSum += (DATA & 1); + PT++; + if (PT == 32) + { + PT = 0; + pt++; + DATA = ARRAY[pt]; + } + else + DATA = DATA >> 1; + } + + pi = (double) BlockSum / (double) m; + v = pi - 0.5; + sum += v * v; + } + chi_squared = 4.0 * m * sum; + arg1 = (double) N / 2.e0; + arg2 = chi_squared / 2.e0; + p_value = igamc (arg1, arg2); + + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, " %d bits sequence, p_value= %f\n", n, p_value); + } +#endif + return (fail); +} + + + + + + +int SizeMin[18] = + { 0, 0, 0, 0, 0, 0, 387840, 904960, 2068480, 4654080, 10342400, 22753280, + 49643520, 107560960, 231669760, 496435200, 1059061760, 0x7fffffff +}; + + +int +Universal (int n, int *ARRAY) +{ + int I, param; + int fail = 0; + if (32 * n < SizeMin[6]) + { + +#ifdef IO + { + fprintf (fileout, "Too small\n"); + } +#endif + return (fail); + } + I = 6; + while ((32 * n >= SizeMin[I]) & (I < 17)) + { + if (32 * n >= SizeMin[I + 1]) + param = SizeMin[I + 1] - 1; + else + param = 32 * n; + fail += UNIVERSAL (param, ARRAY); + I++; + } + return (fail); +} + + + + +int +UNIVERSAL (int n, int *ARRAY) +{ + int i, j, p, K, L, Q; + double arg, sqrt2, sigma, phi, sum, p_value, c; + long *T, decRep; + double expected_value[17] = { + 0, 0, 0, 0, 0, 0, 5.2177052, 6.1962507, 7.1836656, + 8.1764248, 9.1723243, 10.170032, 11.168765, + 12.168070, 13.167693, 14.167488, 15.167379 + }; + double variance[17] = { + 0, 0, 0, 0, 0, 0, 2.954, 3.125, 3.238, 3.311, 3.356, 3.384, + 3.401, 3.410, 3.416, 3.419, 3.421 + }; + int PT, DATA, pt; + int fail = 0; + double Pow[20]; + double POW; + if (n >= 387840) + L = 6; + if (n >= 904960) + L = 7; + if (n >= 2068480) + L = 8; + if (n >= 4654080) + L = 9; + if (n >= 10342400) + L = 10; + if (n >= 22753280) + L = 11; + if (n >= 49643520) + L = 12; + if (n >= 107560960) + L = 13; + if (n >= 231669760) + L = 14; + if (n >= 496435200) + L = 15; + if (n >= 1059061760) + L = 16; + PT = 0; + pt = 0; + DATA = ARRAY[pt]; + POW = pow (2, L); + for (i = 0; i <= L; i++) + Pow[i] = pow (2, i); + Q = (int) 10 *POW; + K = (int) (floor (n / L) - (double) Q); + c = + 0.7 - 0.8 / (double) L + (4 + 32 / (double) L) * pow (K, + -3 / + (double) L) / 15; + sigma = c * sqrt (variance[L] / (double) K); + sqrt2 = sqrt (2); + sum = 0.0; + p = (int) pow (2, L); + T = (long *) MYCALLOC (p, sizeof (long)); + for (i = 0; i < p; i++) + T[i] = 0; + for (i = 1; i <= Q; i++) + { + decRep = 0; + for (j = 0; j < L; j++) + { + decRep += (DATA & 1) * Pow[L - 1 - j]; + PT++; + if (PT == 32) + { + pt++; + DATA = ARRAY[pt]; + PT = 0; + } + else + DATA = DATA >> 1; + } + T[decRep] = i; + } + for (i = Q + 1; i <= Q + K; i++) + { + decRep = 0; + for (j = 0; j < L; j++) + { + decRep += (DATA & 1) * Pow[L - 1 - j]; + PT++; + if (PT == 32) + { + pt++; + DATA = ARRAY[pt]; + PT = 0; + } + else + DATA = DATA >> 1; + } + sum += log (i - T[decRep]) / log (2); + T[decRep] = i; + } + phi = (double) (sum / (double) K); + arg = fabs (phi - expected_value[L]) / (sqrt2 * sigma); + p_value = erfc (arg); + MYFREE ((char*)T); + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "L= %d\tp_value %f\texp_value= %f\tphi = %f\n", L, + p_value, expected_value[L], phi); + } +#endif + return (fail); +} + + +BitField ** +create_matrix (int M, int Q) +{ + int i; + BitField **matrix; + + if ((matrix = (BitField **) MYCALLOC (M, sizeof (BitField *))) == NULL) + { + printf + ("ERROR IN FUNCTION create_matrix: Insufficient memory available."); + printf ("\n"); + fprintf (stderr, + "CREATE_MATRIX: Insufficient memory for %dx%d matrix.\n", M, + M); + return matrix; + } + else + { + for (i = 0; i < M; i++) + { + if ((matrix[i] = (BitField *)MYCALLOC (Q, sizeof (BitField))) == NULL) + { + fprintf (stderr, + "CREATE_MATRIX: Insufficient memory for %dx%d ", M, + M); + fprintf (stderr, "matrix.\n"); + printf + ("ERROR IN FUNCTION create_matrix: Insufficient memory for "); + printf ("%dx%d matrix.\n", M, M); + return NULL; + } + } + return matrix; + } +} + + +int +Rank (int n, int *ARRAY) +{ + int N = (int) floor (n / (32)); /* NUMBER OF MATRICES */ + int r; + double p_value, product; + int i, k; + double chi_squared, arg1; + double p_32, p_31, p_30; /* PROBABILITIES */ + double R; /* RANK */ + double F_32, F_31, F_30; /* FREQUENCIES */ + BitField **matrix = create_matrix (32, 32); + int pt, PT, DATA; + int fail = 0; + pt = 0; + PT = 0; + DATA = ARRAY[0]; + r = 32; /* COMPUTE PROBABILITIES */ + product = 1; + for (i = 0; i <= r - 1; i++) + product *= + ((1.e0 - pow (2, i - 32)) * (1.e0 - pow (2, i - 32))) / (1.e0 - + pow (2, + i - r)); + p_32 = pow (2, r * (32 + 32 - r) - 32 * 32) * product; + + r = 31; + product = 1; + for (i = 0; i <= r - 1; i++) + product *= + ((1.e0 - pow (2, i - 32)) * (1.e0 - pow (2, i - 32))) / (1.e0 - + pow (2, + i - r)); + p_31 = pow (2, r * (32 + 32 - r) - 32 * 32) * product; + + p_30 = 1 - (p_32 + p_31); + + F_32 = 0; + F_31 = 0; + for (k = 0; k < N; k++) + { /* FOR EACH 32x32 MATRIX */ + def_matrix (32, 32, matrix, k, &pt, &PT, &DATA, ARRAY); + R = computeRank (32, 32, matrix); + if (R == 32) + F_32++; /* DETERMINE FREQUENCIES */ + if (R == 31) + F_31++; + } + F_30 = (double) N - (F_32 + F_31); + + chi_squared = (pow (F_32 - N * p_32, 2) / (double) (N * p_32) + + pow (F_31 - N * p_31, 2) / (double) (N * p_31) + + pow (F_30 - N * p_30, 2) / (double) (N * p_30)); + + arg1 = -chi_squared / 2.e0; + + p_value = exp (arg1); + + MYFREE ((char*)matrix); + + if (p_value < THRESHOLDFAIL) + fail++; + else + TotalTEST++; +#ifdef IO + { + fprintf (fileout, "p_value= %f\n", p_value); + } +#endif + return (fail); +} +#else +#include <stdio.h> +int +PackTestF (int *ARRAY, int ArraySize, char *C) +{ + fprintf (stderr, + "Sorry, on-line analysis is implemented using the CygWin math libraries,\nyou must recompile the application under the CygWin environment to allow online analysis\n"); +} +int +PackTestL (int *ARRAY, int ArraySize, char *C) +{ + fprintf (stderr, + "Sorry, on-line analysis is implemented using the CygWin math libraries,\nyou must recompile the application under the CygWin environment to allow online analysis\n"); +} +#endif diff --git a/nist/special-functions.c b/nist/special-functions.c new file mode 100644 index 0000000..c15b7e1 --- /dev/null +++ b/nist/special-functions.c @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <math.h> +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + S P E C I A L F U N C T I O N S + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#define LinuxorUnix +#ifdef WIN +#ifndef CYGWIN +#undef LinuxorUnix +/* same libraries are available*/ +#endif +#endif + +#ifdef LinuxorUnix +double normal(double x) +{ + double arg, result, sqrt2=1.414213562373095048801688724209698078569672; + + if (x > 0) { + arg = x/sqrt2; + result = 0.5 * ( 1 + erf(arg) ); + } + else { + arg = -x/sqrt2; + result = 0.5 * ( 1 - erf(arg) ); + } + return( result); +} + +double normal2(double a) +{ return (1.0-0.5*erfc(a/sqrt(2.0))); } +#endif diff --git a/nist/special-functions.h b/nist/special-functions.h new file mode 100644 index 0000000..61e4839 --- /dev/null +++ b/nist/special-functions.h @@ -0,0 +1,14 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + S P E C I A L F U N C T I O N P R O T O T Y P E S +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +double derf_(); /* ERROR FUNCTION */ +double derfc(); /* COMPLEMENTARY ERROR */ +double normal(double); /* NORMAL DISTRIBUTION */ +double normal2(double); /* NORMAL DISTRIBUTION */ +/* +double gser(double,double,double,double); +double gcf(double,double,double,double); +double gammln(double); LOG GAMMA FUNCTION +double gammq(double,double); INCOMPLETE GAMMA FUNCTION +*/ diff --git a/nist/template9 b/nist/template9 new file mode 100644 index 0000000..604bc53 --- /dev/null +++ b/nist/template9 @@ -0,0 +1,148 @@ +0 0 0 0 0 0 0 0 1 +0 0 0 0 0 0 0 1 1 +0 0 0 0 0 0 1 0 1 +0 0 0 0 0 0 1 1 1 +0 0 0 0 0 1 0 0 1 +0 0 0 0 0 1 0 1 1 +0 0 0 0 0 1 1 0 1 +0 0 0 0 0 1 1 1 1 +0 0 0 0 1 0 0 0 1 +0 0 0 0 1 0 0 1 1 +0 0 0 0 1 0 1 0 1 +0 0 0 0 1 0 1 1 1 +0 0 0 0 1 1 0 0 1 +0 0 0 0 1 1 0 1 1 +0 0 0 0 1 1 1 0 1 +0 0 0 0 1 1 1 1 1 +0 0 0 1 0 0 0 1 1 +0 0 0 1 0 0 1 0 1 +0 0 0 1 0 0 1 1 1 +0 0 0 1 0 1 0 0 1 +0 0 0 1 0 1 0 1 1 +0 0 0 1 0 1 1 0 1 +0 0 0 1 0 1 1 1 1 +0 0 0 1 1 0 0 1 1 +0 0 0 1 1 0 1 0 1 +0 0 0 1 1 0 1 1 1 +0 0 0 1 1 1 0 0 1 +0 0 0 1 1 1 0 1 1 +0 0 0 1 1 1 1 0 1 +0 0 0 1 1 1 1 1 1 +0 0 1 0 0 0 0 1 1 +0 0 1 0 0 0 1 0 1 +0 0 1 0 0 0 1 1 1 +0 0 1 0 0 1 0 1 1 +0 0 1 0 0 1 1 0 1 +0 0 1 0 0 1 1 1 1 +0 0 1 0 1 0 0 1 1 +0 0 1 0 1 0 1 0 1 +0 0 1 0 1 0 1 1 1 +0 0 1 0 1 1 0 1 1 +0 0 1 0 1 1 1 0 1 +0 0 1 0 1 1 1 1 1 +0 0 1 1 0 0 1 0 1 +0 0 1 1 0 0 1 1 1 +0 0 1 1 0 1 0 1 1 +0 0 1 1 0 1 1 0 1 +0 0 1 1 0 1 1 1 1 +0 0 1 1 1 0 1 0 1 +0 0 1 1 1 0 1 1 1 +0 0 1 1 1 1 0 1 1 +0 0 1 1 1 1 1 0 1 +0 0 1 1 1 1 1 1 1 +0 1 0 0 0 0 0 1 1 +0 1 0 0 0 0 1 1 1 +0 1 0 0 0 1 0 1 1 +0 1 0 0 0 1 1 1 1 +0 1 0 0 1 0 0 1 1 +0 1 0 0 1 0 1 1 1 +0 1 0 0 1 1 0 1 1 +0 1 0 0 1 1 1 1 1 +0 1 0 1 0 0 0 1 1 +0 1 0 1 0 0 1 1 1 +0 1 0 1 0 1 0 1 1 +0 1 0 1 0 1 1 1 1 +0 1 0 1 1 0 0 1 1 +0 1 0 1 1 0 1 1 1 +0 1 0 1 1 1 0 1 1 +0 1 0 1 1 1 1 1 1 +0 1 1 0 0 0 1 1 1 +0 1 1 0 0 1 1 1 1 +0 1 1 0 1 0 1 1 1 +0 1 1 0 1 1 1 1 1 +0 1 1 1 0 1 1 1 1 +0 1 1 1 1 1 1 1 1 +1 0 0 0 0 0 0 0 0 +1 0 0 0 1 0 0 0 0 +1 0 0 1 0 0 0 0 0 +1 0 0 1 0 1 0 0 0 +1 0 0 1 1 0 0 0 0 +1 0 0 1 1 1 0 0 0 +1 0 1 0 0 0 0 0 0 +1 0 1 0 0 0 1 0 0 +1 0 1 0 0 1 0 0 0 +1 0 1 0 0 1 1 0 0 +1 0 1 0 1 0 0 0 0 +1 0 1 0 1 0 1 0 0 +1 0 1 0 1 1 0 0 0 +1 0 1 0 1 1 1 0 0 +1 0 1 1 0 0 0 0 0 +1 0 1 1 0 0 1 0 0 +1 0 1 1 0 1 0 0 0 +1 0 1 1 0 1 1 0 0 +1 0 1 1 1 0 0 0 0 +1 0 1 1 1 0 1 0 0 +1 0 1 1 1 1 0 0 0 +1 0 1 1 1 1 1 0 0 +1 1 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 1 0 +1 1 0 0 0 0 1 0 0 +1 1 0 0 0 1 0 0 0 +1 1 0 0 0 1 0 1 0 +1 1 0 0 1 0 0 0 0 +1 1 0 0 1 0 0 1 0 +1 1 0 0 1 0 1 0 0 +1 1 0 0 1 1 0 0 0 +1 1 0 0 1 1 0 1 0 +1 1 0 1 0 0 0 0 0 +1 1 0 1 0 0 0 1 0 +1 1 0 1 0 0 1 0 0 +1 1 0 1 0 1 0 0 0 +1 1 0 1 0 1 0 1 0 +1 1 0 1 0 1 1 0 0 +1 1 0 1 1 0 0 0 0 +1 1 0 1 1 0 0 1 0 +1 1 0 1 1 0 1 0 0 +1 1 0 1 1 1 0 0 0 +1 1 0 1 1 1 0 1 0 +1 1 0 1 1 1 1 0 0 +1 1 1 0 0 0 0 0 0 +1 1 1 0 0 0 0 1 0 +1 1 1 0 0 0 1 0 0 +1 1 1 0 0 0 1 1 0 +1 1 1 0 0 1 0 0 0 +1 1 1 0 0 1 0 1 0 +1 1 1 0 0 1 1 0 0 +1 1 1 0 1 0 0 0 0 +1 1 1 0 1 0 0 1 0 +1 1 1 0 1 0 1 0 0 +1 1 1 0 1 0 1 1 0 +1 1 1 0 1 1 0 0 0 +1 1 1 0 1 1 0 1 0 +1 1 1 0 1 1 1 0 0 +1 1 1 1 0 0 0 0 0 +1 1 1 1 0 0 0 1 0 +1 1 1 1 0 0 1 0 0 +1 1 1 1 0 0 1 1 0 +1 1 1 1 0 1 0 0 0 +1 1 1 1 0 1 0 1 0 +1 1 1 1 0 1 1 0 0 +1 1 1 1 0 1 1 1 0 +1 1 1 1 1 0 0 0 0 +1 1 1 1 1 0 0 1 0 +1 1 1 1 1 0 1 0 0 +1 1 1 1 1 0 1 1 0 +1 1 1 1 1 1 0 0 0 +1 1 1 1 1 1 0 1 0 +1 1 1 1 1 1 1 0 0 +1 1 1 1 1 1 1 1 0 |