Merge branch 'master' into 'master'

First try of conversion to flint, plus key creation

decryption and encryption converted as well, but no idea if they work

randomisation not converted yet, needs to be revised
This commit is contained in:
Julian Ospald 2014-05-25 12:01:09 +02:00
commit 286c300890
4006 changed files with 447161 additions and 59279 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ latex/
*.la
*.a
*.o
*.d
# targets

View File

@ -380,7 +380,7 @@ EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
@ -686,7 +686,7 @@ INPUT_ENCODING = UTF-8
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl
FILE_PATTERNS =
FILE_PATTERNS = *.c *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
@ -1676,7 +1676,7 @@ HIDE_UNDOC_RELATIONS = YES
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
HAVE_DOT = YES
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) doxygen will
@ -1757,7 +1757,7 @@ INCLUDE_GRAPH = YES
# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
INCLUDED_BY_GRAPH = NO
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function

View File

@ -8,8 +8,7 @@ clean:
$(MAKE) -C src clean
clean-all: clean
$(MAKE) -C external/libtommath-0.42.0 clean
$(MAKE) -C external/libtompoly-0.04 clean
$(MAKE) -C external/flint-2.4.3 clean
doc:
doxygen

127
external/flint-2.4.3/AUTHORS vendored Normal file
View File

@ -0,0 +1,127 @@
FLINT has been developed since 2007 by a large number of people. Initially
the library was started by David Harvey and William Hart. Later maintenance
of the library was taken over solely by William Hart.
The authors of FLINT to date:
$\bullet$ William Hart -- integer and polynomial arithmetic, factorisation and
primality testing, general infrastructure (supported by EPSRC Grant
EP/G004870/1 and DFG Priority programme SPP1489)
$\bullet$ Sebastian Pancratz -- polynomial arithmetic over $\Z$, $\Z/n\Z$ and
$\Q$, $p$-adic and $q$-adic arithmetic, including polynomials and matrices
(supported by ERC Grant 204083)
$\bullet$ Andy Novocin -- LLL, polynomial factorisation over $Z$, polynomial
composition
$\bullet$ Fredrik Johansson -- matrices, polynomial and power series
arithmetic, special functions (supported by Austrian Science Fund FWF Grant
Y464-N18)
$\bullet$ Tom Bachmann -- \code{C++} expressions template wrapper,
documentation parser (Google Summer of Code 2013)
$\bullet$ Mike Hansen -- Finite fields (small and large $\F_q$),
polynomials/matrices over $\F_q$, Finite fields with Zech logarithm
representation, Fast factorisation of polynomials over $\F_q$ (supported by
Macaulay2 developers NSF Grant 1002171)
$\bullet$ Martin Lee -- Fast factorisation of polynomials over $\Z/n\Z$,
faster Brent-Kung modular composition
$\bullet$ David Harvey -- Fast Fourier Transform code, \code{zn_poly} for
polynomial arithmetic over $\Z/n\Z$, \code{mpz_poly}, profiling and
graphing code and many other parts of the FLINT library
$\bullet$ Jan Tuitman -- helped with the $p$-adic interface
$\bullet$ Jason Papadopoulos -- Block Lanczos code for quadratic sieve and
multiprecision complex root finding code for polynomials.
$\bullet$ Gonzalo Tornaria -- Theta function module, Montgomery multiplication
and significant contributions to the $\Z[x]$ modular multiplication code.
$\bullet$ Burcin Erocal -- wrote the primary FLINT wrapper in the SAGE system
(Robert Bradshaw also wrote a preliminary version of this and Martin Albrecht
and others have also contributed to it.) Burcin also contributed by writing
grant applications via his Lmonade organisation to Google. (Supported by DFG
Priority programme SPP1489.)
$\bullet$ Tom Boothby -- Improved factoring of unsigned longs, detection of
perfect powers
$\bullet$ Andres Goens -- $\F_q$ module and polynomials over $\F_q$ (supported
by DFG Priority program SPP1489)
$\bullet$ Lina Kulakova -- factorisation for polynomials over $\F_p$ for large
$p$ (Google Summer of Code 2012)
$\bullet$ Thomas DuBuisson -- logical ops for fmpz module, patches to the build
system
$\bullet$ Jean-Pierre Flori -- many build system patches and Sage integration
$\bullet$ Frithjof Schulze -- some fmpz functions and various patches
$\bullet$ Curtis Bright -- numerous patches including 32 bit support
$\bullet$ Daniel Woodhouse -- Contributed an implementation of multivariate
multiplication over $\Z/n\Z$ and used this to implement a fast ``saturation''
algorithm for Laurent polynomials. (Funded by Alessio Corti and Tom Coates
at Imperial College)
$\bullet$ Tomasz Lechowski -- Contributed some NTL and Pari polynomial
profiling code and researched algorithms for polynomials over finite fields.
(Funded by the Nuffield Foundation)
$\bullet$ Daniel Scott -- Researched lazy and relaxed algorithms of Joris van
der Hoeven. (Funded by Warwick University's Undergraduate Research Scholars
Scheme)
$\bullet$ David Howden -- Wrote code for computing Bernoulli numbers mod many
primes, including fast polynomial multiplication over $\Z/p\Z$ specifically for
the task. (Funded by Warwick University's Undergraduate Research Scholars
Scheme)
$\bullet$ Daniel Ellam -- Helped design a module for $p$-adic arithmetic for
FLINT. (Funded by Warwick University's Undergraduate Research Scholars Scheme)
$\bullet$ Richard Howell-Peak -- Wrote polynomial factorisation and
irreducibility testing code for polynomials over $\Z/p\Z$. (Funded by Warwick
University's Undergraduate Research Scholars Scheme)
$\bullet$ Peter Shrimpton -- Wrote code for a basic prime sieve,
Pocklington-Lehmer, Lucas, Fibonacci, BSPW and $n-1$ primality tests and a
Weiferich prime search. (Funded by the Nuffield Foundation)
$\bullet$ Patches and bug reports have been made by Michael Abshoff,
Didier Deshommes, Craig Citro, Timothy Abbot, Carl Witty, Gonzalo Tornaria,
Jaap Spies, Kiran Kedlaya, William Stein, Kate Minola, Didier Deshommes, Robert
Bradshaw, Serge Torres, Dan Grayson, Martin Lee, Bob Smith, Antony Vennard,
Fr\'{e}d\'{e}ric Chyzak, Julien Puydt, Dana Jacobsen, Michael Jacobson Jr.,
Mike Stillman, Jan Englehardt, Jean-Pierre Flori, Jeroen Demeyer, Shi Bai,
Qingwen Guan, Frithjof Schulze, Robert Baillie, Oleksandr Motsak, Hans
Schoenemann, Janko Boehm, Ahmed Soliman, Francois Bissey and others.
$\bullet$ In addition Michael Abshoff, William Stein and Robert Bradshaw have
contributed to the build system of FLINT.
$\bullet$ Michael Abshoff deserves special recognition for his help in
resolving a number of difficult build issues which came to light as FLINT was
incorporated into SAGE and for bringing numerous bugs to the attention of the
FLINT maintainers. Michael regularly checked FLINT for memory leaks and
corruption, which directly led to numerous issues being identified early!
He also helped with setting up various pieces of infrastructure for the FLINT
project.
$\bullet$ Numerous people have contributed to wrapping FLINT in Sage and
debugging, including Mike Hansen, Jean-Pierre Flori, Burcin Erocal, Robert
Bradshaw, Martin Albrecht, Sebastian Pancratz, Fredrik Johansson, Jeroen
Demeyer and Leif Lionhardy, amongst others.
Some code (notably \code{longlong.h} and \code{clz_tab.c}) has been used from
the GMP library, whose main author is Torbjorn Granlund.
FLINT 2 was a complete rewrite from scratch which began in about 2010.

26
external/flint-2.4.3/INSTALL vendored Normal file
View File

@ -0,0 +1,26 @@
Instructions on intalling flint 2
---------------------------------
FLINT 2 follows a standard format for installation:
./configure
make
make check
make install
However, this assumes that MPIR and MPFR are already installed on your system in
/usr/local. If the libraries are not in this location you must specify where
they are by passing their location to configure. It also assumes you wish to
install FLINT 2 at the prefix /usr/local. If not you must pass the prefix (the
directory containing lib and include subdirectories into which FLINT will be
installed) to configure:
./configure --with-mpir=/home/user1/mpir-2.1.1/ --with-mpfr=/usr --prefix=/usr
Note that the FLINT configure system can handle MPIR/MPFR as installed (in lib
and include dirs) at some location, or as source builds (built from source and
not installed).
For further configure and make options, please refer to the FLINT 2
documentation.

254
external/flint-2.4.3/Makefile vendored Normal file
View File

@ -0,0 +1,254 @@
# This file is autogenerated by ./configure -- do not edit!
SHELL=/bin/sh
FLINT_STATIC=1
FLINT_SHARED=0
FLINT_LIB=libflint.so
EXEEXT=
PREFIX=/usr
WANT_NTL=0
FLINT_CPIMPORT_DIR=/usr/share/flint
FLINT_CPIMPORT=/usr/share/flint/CPimport.txt
INCS=-I$(CURDIR) -I/usr/include -I/usr/include
LIBS=-L$(CURDIR) -L/usr/lib -L/usr/lib -lflint -lpthread -lmpfr -lgmp -lm
LIBS2=-L$(CURDIR) -L/usr/lib -L/usr/lib -lpthread -lmpfr -lgmp -lm
CC=gcc
CXX=g++
AR=ar
CFLAGS=-ansi -pedantic -Wall -O2 -funroll-loops -g -mpopcnt -DFLINT_CPIMPORT=\"/usr/share/flint/CPimport.txt\"
ABI_FLAG=
PIC_FLAG=-fPIC
EXTRA_SHARED_FLAGS=
DLPATH=LD_LIBRARY_PATH
DLPATH_ADD=$(CURDIR):/usr/lib:/usr/lib
EXTENSIONS=
EXTRA_BUILD_DIRS=
ifdef $(DLPATH)
$(DLPATH):=$($(DLPATH)):$(DLPATH_ADD)
else
$(DLPATH):=$(DLPATH_ADD)
endif
QUIET_CC = @echo ' ' CC ' ' $@;
QUIET_CXX = @echo ' ' CXX ' ' $@;
QUIET_AR = @echo ' ' AR ' ' $@;
AT=@
BUILD_DIRS = ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly \
fmpq_poly fmpz_mat mpfr_vec mpfr_mat nmod_vec nmod_poly \
nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_mat padic \
fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly \
fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve \
double_extras padic_poly padic_mat qadic \
fq fq_vec fq_mat fq_poly fq_poly_factor\
fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_poly_factor \
fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor \
$(EXTRA_BUILD_DIRS)
TEMPLATE_DIRS = fq_vec_templates fq_mat_templates fq_poly_templates \
fq_poly_factor_templates
export
SOURCES = printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c memory_manager.c version.c profiler.c thread_support.c
LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS))
HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h fmpz-conversions.h profiler.h templates.h $(patsubst %, %.h, $(TEMPLATE_DIRS))
OBJS = $(patsubst %.c, build/%.o, $(SOURCES))
LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS))
LOBJS = $(patsubst %.c, build/%.lo, $(SOURCES))
LIB_LOBJS = $(patsubst %, build/%/*.lo, $(BUILD_DIRS))
MOD_LOBJS = $(patsubst %, build/%.lo, $(BUILD_DIRS))
EXMP_SOURCES = $(wildcard examples/*.c)
EXMPS = $(patsubst %.c, %, $(EXMP_SOURCES))
TEST_SOURCES = $(wildcard test/*.c)
TESTS = $(patsubst %.c, build/%$(EXEEXT), $(TEST_SOURCES))
PROF_SOURCES = $(wildcard profile/*.c)
PROFS = $(patsubst %.c, %$(EXEEXT), $(PROF_SOURCES))
TUNE_SOURCES = $(wildcard tune/*.c)
TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES))
EXT_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/*.c)))
EXT_TEST_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/test/t-*.c)))
EXT_TUNE_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/tune/*.c)))
EXT_PROF_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/profile/p-*.c)))
EXT_OBJS = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), build/$(dir).lo))
EXT_HEADERS = $(foreach ext, $(EXTENSIONS), $(wildcard $(ext)/*.h))
all: library
quiet: library
verbose:
$(MAKE) AT= QUIET_CC= QUIET_CXX= QUIET_AR=
clean:
$(AT)$(foreach dir, $(BUILD_DIRS), BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) clean || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) clean || exit $$?;))
rm -rf test_helpers.o profiler.o
rm -f $(OBJS) $(LOBJS) $(TESTS) $(PROFS) $(EXMPS) $(FLINT_LIB) libflint.a
rm -rf build
distclean: clean
rm -f config.h fft_tuning.h fmpz-conversions.h Makefile fmpz/fmpz.c
dist:
git archive --format tar --prefix flint-2.4.2/ flint-2.4 > ../flint-2.4.2.tar; gzip ../flint-2.4.2.tar
profile: library $(PROF_SOURCES) $(EXT_PROF_SOURCES) build/profiler.o
mkdir -p build/profile
ifndef MOD
$(AT)$(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -std=c99 -O2 -g $(INCS) $(prog).c build/profiler.o -o build/$(prog) $(LIBS) || exit $$?;)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/profile; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) profile || exit $$?;))
else
$(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;)
endif
tune: library $(TUNE_SOURCES) $(EXT_TUNE_SOURCES)
mkdir -p build/tune
$(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/tune; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tune || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/tune; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tune || exit $$?;))
examples: library $(EXMP_SOURCES)
mkdir -p build/examples
$(AT)$(foreach prog, $(EXMPS), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;)
$(FLINT_LIB): $(LOBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) shared || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) shared || exit $$?;)
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/NTL-interface.lo; \
$(CXX) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) build/interfaces/NTL-interface.lo $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \
fi
$(AT)if [ "$(WANT_NTL)" -ne "1" ]; then \
$(CC) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \
fi
libflint.a: $(OBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) static || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) static || exit $$?;)
$(AT)if [ "$(FLINT_SHARED)" -eq "0" ]; then \
touch test/t-*.c; \
$(foreach dir, $(BUILD_DIRS), touch $(dir)/test/t-*.c;) \
$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), touch $(ext)/$(mod)/test/t-*.c;)) \
fi
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/NTL-interface.o; \
$(AR) rcs libflint.a build/interfaces/NTL-interface.o; \
fi
$(QUIET_AR) $(AR) rcs libflint.a $(OBJS);
$(AT)$(foreach mod, $(BUILD_DIRS), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;))
library:
$(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \
$(MAKE) shared; \
fi
$(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \
$(MAKE) static; \
fi
shared: $(FLINT_LIB)
static: libflint.a
tests: library test_helpers.o $(TESTS)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tests || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tests || exit $$?;))
mkdir -p build/interfaces/test
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/test/t-NTL-interface; \
fi
check: library test_helpers.o
ifndef MOD
$(AT)$(MAKE) $(TESTS)
$(AT)$(foreach prog, $(TESTS), $(prog) || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;)
mkdir -p build/interfaces/test
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/test/t-NTL-interface; \
build/interfaces/test/t-NTL-interface; \
fi
else
$(AT)$(foreach dir, $(MOD), test ! -d $(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; test ! -d $(dir) || $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(AT)$(foreach dir, $(MOD), MOD_DIR=$(dir); export MOD_DIR; test ! -d $(ext)/$(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; test ! -d $(ext)/$(dir) || $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;))
endif
valgrind: library
ifndef MOD
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) valgrind || exit $$?;))
else
$(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;)
endif
install: library
mkdir -p $(DESTDIR)$(PREFIX)/lib
mkdir -p $(DESTDIR)$(PREFIX)/include/flint
$(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \
cp $(FLINT_LIB) $(DESTDIR)$(PREFIX)/lib; \
fi
$(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \
cp libflint.a $(DESTDIR)$(PREFIX)/lib; \
fi
cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/flint
$(AT)if [ ! -z $(EXT_HEADERS) ]; then \
cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include/flint; \
fi
mkdir -p $(DESTDIR)$(FLINT_CPIMPORT_DIR)
cp qadic/CPimport.txt $(DESTDIR)$(FLINT_CPIMPORT_DIR)
mkdir -p $(DESTDIR)$(PREFIX)/include/flint/flintxx
cp flintxx/*.h $(DESTDIR)$(PREFIX)/include/flint/flintxx
cp *xx.h $(DESTDIR)$(PREFIX)/include/flint
build:
mkdir -p build
build/%.lo: %.c $(HEADERS) | build
$(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@;
build/%.o: %.c $(HEADERS) | build
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@;
build/test/%$(EXEEXT): test/%.c $(HEADERS) | build/test
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< -o $@ $(LIBS)
build/test:
mkdir -p build/test
build/interfaces:
mkdir -p build/interfaces
build/interfaces/NTL-interface.lo: interfaces/NTL-interface.cpp NTL-interface.h
$(QUIET_CXX) $(CXX) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@;
build/interfaces/NTL-interface.o: interfaces/NTL-interface.cpp NTL-interface.h
$(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) -c $< -o $@;
build/interfaces/test/t-NTL-interface$(EXEEXT): interfaces/test/t-NTL-interface.cpp
$(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) $< build/interfaces/NTL-interface.o -o $@ $(LIBS);
print-%:
@echo '$*=$($*)'
.PHONY: profile library shared static clean examples tune check tests distclean dist install all valgrind

221
external/flint-2.4.3/Makefile.in vendored Normal file
View File

@ -0,0 +1,221 @@
ifdef $(DLPATH)
$(DLPATH):=$($(DLPATH)):$(DLPATH_ADD)
else
$(DLPATH):=$(DLPATH_ADD)
endif
QUIET_CC = @echo ' ' CC ' ' $@;
QUIET_CXX = @echo ' ' CXX ' ' $@;
QUIET_AR = @echo ' ' AR ' ' $@;
AT=@
BUILD_DIRS = ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly \
fmpq_poly fmpz_mat mpfr_vec mpfr_mat nmod_vec nmod_poly \
nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_mat padic \
fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly \
fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve \
double_extras padic_poly padic_mat qadic \
fq fq_vec fq_mat fq_poly fq_poly_factor\
fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_poly_factor \
fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor \
$(EXTRA_BUILD_DIRS)
TEMPLATE_DIRS = fq_vec_templates fq_mat_templates fq_poly_templates \
fq_poly_factor_templates
export
SOURCES = printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c memory_manager.c version.c profiler.c thread_support.c
LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS))
HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h fmpz-conversions.h profiler.h templates.h $(patsubst %, %.h, $(TEMPLATE_DIRS))
OBJS = $(patsubst %.c, build/%.o, $(SOURCES))
LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS))
LOBJS = $(patsubst %.c, build/%.lo, $(SOURCES))
LIB_LOBJS = $(patsubst %, build/%/*.lo, $(BUILD_DIRS))
MOD_LOBJS = $(patsubst %, build/%.lo, $(BUILD_DIRS))
EXMP_SOURCES = $(wildcard examples/*.c)
EXMPS = $(patsubst %.c, %, $(EXMP_SOURCES))
TEST_SOURCES = $(wildcard test/*.c)
TESTS = $(patsubst %.c, build/%$(EXEEXT), $(TEST_SOURCES))
PROF_SOURCES = $(wildcard profile/*.c)
PROFS = $(patsubst %.c, %$(EXEEXT), $(PROF_SOURCES))
TUNE_SOURCES = $(wildcard tune/*.c)
TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES))
EXT_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/*.c)))
EXT_TEST_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/test/t-*.c)))
EXT_TUNE_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/tune/*.c)))
EXT_PROF_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/profile/p-*.c)))
EXT_OBJS = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), build/$(dir).lo))
EXT_HEADERS = $(foreach ext, $(EXTENSIONS), $(wildcard $(ext)/*.h))
all: library
quiet: library
verbose:
$(MAKE) AT= QUIET_CC= QUIET_CXX= QUIET_AR=
clean:
$(AT)$(foreach dir, $(BUILD_DIRS), BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) clean || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) clean || exit $$?;))
rm -rf test_helpers.o profiler.o
rm -f $(OBJS) $(LOBJS) $(TESTS) $(PROFS) $(EXMPS) $(FLINT_LIB) libflint.a
rm -rf build
distclean: clean
rm -f config.h fft_tuning.h fmpz-conversions.h Makefile fmpz/fmpz.c
dist:
git archive --format tar --prefix flint-2.4.2/ flint-2.4 > ../flint-2.4.2.tar; gzip ../flint-2.4.2.tar
profile: library $(PROF_SOURCES) $(EXT_PROF_SOURCES) build/profiler.o
mkdir -p build/profile
ifndef MOD
$(AT)$(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -std=c99 -O2 -g $(INCS) $(prog).c build/profiler.o -o build/$(prog) $(LIBS) || exit $$?;)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/profile; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) profile || exit $$?;))
else
$(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;)
endif
tune: library $(TUNE_SOURCES) $(EXT_TUNE_SOURCES)
mkdir -p build/tune
$(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/tune; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tune || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/tune; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tune || exit $$?;))
examples: library $(EXMP_SOURCES)
mkdir -p build/examples
$(AT)$(foreach prog, $(EXMPS), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;)
$(FLINT_LIB): $(LOBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) shared || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) shared || exit $$?;)
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/NTL-interface.lo; \
$(CXX) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) build/interfaces/NTL-interface.lo $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \
fi
$(AT)if [ "$(WANT_NTL)" -ne "1" ]; then \
$(CC) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \
fi
libflint.a: $(OBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) static || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) static || exit $$?;)
$(AT)if [ "$(FLINT_SHARED)" -eq "0" ]; then \
touch test/t-*.c; \
$(foreach dir, $(BUILD_DIRS), touch $(dir)/test/t-*.c;) \
$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), touch $(ext)/$(mod)/test/t-*.c;)) \
fi
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/NTL-interface.o; \
$(AR) rcs libflint.a build/interfaces/NTL-interface.o; \
fi
$(QUIET_AR) $(AR) rcs libflint.a $(OBJS);
$(AT)$(foreach mod, $(BUILD_DIRS), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;))
library:
$(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \
$(MAKE) shared; \
fi
$(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \
$(MAKE) static; \
fi
shared: $(FLINT_LIB)
static: libflint.a
tests: library test_helpers.o $(TESTS)
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tests || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tests || exit $$?;))
mkdir -p build/interfaces/test
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/test/t-NTL-interface; \
fi
check: library test_helpers.o
ifndef MOD
$(AT)$(MAKE) $(TESTS)
$(AT)$(foreach prog, $(TESTS), $(prog) || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;))
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;)
mkdir -p build/interfaces/test
$(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \
$(MAKE) build/interfaces/test/t-NTL-interface; \
build/interfaces/test/t-NTL-interface; \
fi
else
$(AT)$(foreach dir, $(MOD), test ! -d $(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; test ! -d $(dir) || $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(AT)$(foreach dir, $(MOD), MOD_DIR=$(dir); export MOD_DIR; test ! -d $(ext)/$(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; test ! -d $(ext)/$(dir) || $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;))
endif
valgrind: library
ifndef MOD
$(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;)
$(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) valgrind || exit $$?;))
else
$(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;)
endif
install: library
mkdir -p $(DESTDIR)$(PREFIX)/lib
mkdir -p $(DESTDIR)$(PREFIX)/include/flint
$(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \
cp $(FLINT_LIB) $(DESTDIR)$(PREFIX)/lib; \
fi
$(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \
cp libflint.a $(DESTDIR)$(PREFIX)/lib; \
fi
cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/flint
$(AT)if [ ! -z $(EXT_HEADERS) ]; then \
cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include/flint; \
fi
mkdir -p $(DESTDIR)$(FLINT_CPIMPORT_DIR)
cp qadic/CPimport.txt $(DESTDIR)$(FLINT_CPIMPORT_DIR)
mkdir -p $(DESTDIR)$(PREFIX)/include/flint/flintxx
cp flintxx/*.h $(DESTDIR)$(PREFIX)/include/flint/flintxx
cp *xx.h $(DESTDIR)$(PREFIX)/include/flint
build:
mkdir -p build
build/%.lo: %.c $(HEADERS) | build
$(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@;
build/%.o: %.c $(HEADERS) | build
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@;
build/test/%$(EXEEXT): test/%.c $(HEADERS) | build/test
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< -o $@ $(LIBS)
build/test:
mkdir -p build/test
build/interfaces:
mkdir -p build/interfaces
build/interfaces/NTL-interface.lo: interfaces/NTL-interface.cpp NTL-interface.h
$(QUIET_CXX) $(CXX) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@;
build/interfaces/NTL-interface.o: interfaces/NTL-interface.cpp NTL-interface.h
$(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) -c $< -o $@;
build/interfaces/test/t-NTL-interface$(EXEEXT): interfaces/test/t-NTL-interface.cpp
$(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) $< build/interfaces/NTL-interface.o -o $@ $(LIBS);
print-%:
@echo '$*=$($*)'
.PHONY: profile library shared static clean examples tune check tests distclean dist install all valgrind

89
external/flint-2.4.3/Makefile.subdirs vendored Normal file
View File

@ -0,0 +1,89 @@
QUIET_CC = @echo ' ' CC ' ' $@;
AT=@
SOURCES = $(wildcard *.c)
HEADERS = $(wildcard ../*.h)
TEST_HEADERS = $(wildcard *.h)
OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES))
LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES))
MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo
TEST_SOURCES = $(wildcard test/*.c)
TESTXX_SOURCES = $(wildcard test/*.cpp)
PROF_SOURCES = $(wildcard profile/*.c)
TUNE_SOURCES = $(wildcard tune/*.c)
TESTS = $(patsubst %.c, $(BUILD_DIR)/%$(EXEEXT), $(TEST_SOURCES)) \
$(patsubst %.cpp, $(BUILD_DIR)/%$(EXEEXT), $(TESTXX_SOURCES))
TESTS_RUN = $(patsubst %, %_RUN, $(TESTS))
VALGRIND_RUN = $(patsubst %, %_VALGRIND_RUN, $(TESTS))
PROFS = $(patsubst %.c, $(BUILD_DIR)/%$(EXEEXT), $(PROF_SOURCES))
TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES))
all: shared static
shared: $(MOD_LOBJ)
static: $(OBJS)
profile: $(PROFS)
-include $(patsubst %, %.d, $(PROFS))
$(BUILD_DIR)/profile/%$(EXEEXT): profile/%.c $(BUILD_DIR)/../profiler.o
$(QUIET_CC) $(CC) $(ABI_FLAG) -O2 -std=c99 -g $(INCS) $< ../build/profiler.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d"
tune: $(TUNE_SOURCES) $(HEADERS)
$(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;)
-include $(OBJS:.o=.d)
$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@ -MMD -MP -MF "$(BUILD_DIR)/$(MOD_DIR)_$*.d" -MT "$(BUILD_DIR)/$(MOD_DIR)_$*.d" -MT "$@"
$(MOD_LOBJ): $(LOBJS)
$(QUIET_CC) $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib
-include $(LOBJS:.lo=.d)
$(BUILD_DIR)/%.lo: %.c
$(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@ -MMD -MP -MF "$(BUILD_DIR)/$*.d" -MT "$(BUILD_DIR)/$*.d" -MT "$@"
clean:
rm -rf $(BUILD_DIR) $(MOD_LOBJ)
tests: $(TESTS)
check: tests $(TESTS_RUN)
valgrind: tests $(VALGRIND_RUN)
-include $(patsubst %, %.d, $(TESTS))
ifeq ($(FLINT_SHARED), 0)
$(BUILD_DIR)/test/%$(EXEEXT): $(BUILD_DIR)/../../libflint.a
endif
$(BUILD_DIR)/test/%$(EXEEXT): test/%.c $(BUILD_DIR)/../../test_helpers.o
$(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< $(BUILD_DIR)/../../test_helpers.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d"
$(BUILD_DIR)/test/%$(EXEEXT): test/%.cpp $(BUILD_DIR)/../../test_helpers.o
$(QUIET_CC) $(CXX) $(CFLAGS) $(INCS) $< $(BUILD_DIR)/../../test_helpers.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d"
%_RUN: %
@$<
%_VALGRIND_RUN: %
valgrind --track-origins=yes --leak-check=full --show-reachable=yes --log-file="$*.valgrind" $<
.PHONY: profile tune clean check tests all shared static valgrind %_RUN %_VALGRIND_RUN

1102
external/flint-2.4.3/NEWS vendored Normal file

File diff suppressed because it is too large Load Diff

172
external/flint-2.4.3/NTL-interface.h vendored Normal file
View File

@ -0,0 +1,172 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
NTL-interface.h: Header file for NTL-interface.cpp
Copyright (C) 2007 William Hart
Copyright (C) 2011 Sebastian Pancratz
Copyright (C) 2013 Mike Hansen
******************************************************************************/
#ifndef FLINT_NTL_INT_H
#define FLINT_NTL_INT_H
#include <NTL/ZZ.h>
#include <NTL/ZZX.h>
#include <NTL/ZZ_p.h>
#include <NTL/ZZ_pX.h>
#include <NTL/ZZ_pXFactoring.h>
#include <NTL/ZZ_pE.h>
#include <NTL/ZZ_pEX.h>
#include <NTL/lzz_p.h>
#include <NTL/lzz_pX.h>
#include <NTL/lzz_pXFactoring.h>
#include <NTL/lzz_pE.h>
#include <NTL/lzz_pEX.h>
#include <NTL/vec_ZZ.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_poly.h"
#include "fmpz_mod_poly.h"
#include "fq.h"
#include "fq_poly.h"
NTL_CLIENT
#ifdef __cplusplus
extern "C" {
#endif
/*
Converts an NTL ZZ to an fmpz_t.
Assumes the fmpz_t has already been allocated to have sufficient space.
*/
void fmpz_set_ZZ(fmpz_t rop, const ZZ& op);
/*
Converts an fmpz_t to an NTL ZZ. Allocation is automatically handled.
*/
void fmpz_get_ZZ(ZZ& rop, const fmpz_t op);
/*
Converts an NTL ZZ_p to an fmpz_t.
Assumes the fmpz_t has already been allocated to have sufficient space.
*/
void fmpz_set_ZZ_p(fmpz_t rop, const ZZ_p& op);
/*
Converts an fmpz_t to an NTL ZZ_p. Allocation is automatically handled.
*/
void fmpz_get_ZZ_p(ZZ_p& rop, const fmpz_t op);
/*
Converts an NTL zz_p to an fmpz_t.
*/
void fmpz_set_zz_p(fmpz_t rop, const zz_p& op);
/*
Converts an fmpz_t to an NTL zz_p.
*/
void fmpz_get_zz_p(zz_p& rop, const fmpz_t op);
/*
Converts an fmpz_poly_t to an NTL ZZX.
*/
void fmpz_poly_get_ZZX(ZZX& rop, const fmpz_poly_t op);
/*
Converts an NTL ZZX to an fmpz_poly_t.
*/
void fmpz_poly_set_ZZX(fmpz_poly_t rop, const ZZX& op);
/*
Converts an fmpz_mod_poly_t to an NTL ZZ_pX.
*/
void fmpz_mod_poly_get_ZZ_pX(ZZ_pX& rop, const fmpz_mod_poly_t op);
/*
Converts an NTL ZZ_pX to an fmpz_poly_t.
*/
void fmpz_mod_poly_set_ZZ_pX(fmpz_mod_poly_t rop, const ZZ_pX& op);
/*
Converts an fq_t to an NTL ZZ_pE.
*/
void fq_get_ZZ_pE(ZZ_pE& rop, const fq_t op, const fq_ctx_t ctx);
/*
Converts an NTL ZZ_pE to an fq_t.
*/
void fq_set_ZZ_pE(fq_t rop, const ZZ_pE& op, const fq_ctx_t ctx);
/*
Converts an fq_poly_t to an NTL ZZ_pEX.
*/
void fq_poly_get_ZZ_pEX(ZZ_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx);
/*
Converts an NTL ZZ_pEX to an fq_poly_t.
*/
void fq_poly_set_ZZ_pEX(fq_poly_t rop, const ZZ_pEX& op, const fq_ctx_t ctx);
/*
Converts an fmpz_mod_poly_t to an NTL zz_pX.
*/
void fmpz_mod_poly_get_zz_pX(zz_pX& rop, const fmpz_mod_poly_t op);
/*
Converts an NTL zz_pX to an fmpz_poly_t.
*/
void fmpz_mod_poly_set_zz_pX(fmpz_mod_poly_t rop, const zz_pX& op);
/*
Converts an fq_t to an NTL zz_pE.
*/
void fq_get_zz_pE(zz_pE& rop, const fq_t op, const fq_ctx_t ctx);
/*
Converts an NTL zz_pE to an fq_t.
*/
void fq_set_zz_pE(fq_t rop, const zz_pE& op, const fq_ctx_t ctx);
/*
Converts an fq_poly_t to an NTL zz_pEX.
*/
void fq_poly_get_zz_pEX(zz_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx);
/*
Converts an NTL zz_pEX to an fq_poly_t.
*/
void fq_poly_set_zz_pEX(fq_poly_t rop, const zz_pEX& op, const fq_ctx_t ctx);
#ifdef __cplusplus
}
#endif
#endif

15
external/flint-2.4.3/README vendored Normal file
View File

@ -0,0 +1,15 @@
FLINT 2
=======
FLINT (Fast Library for Number Theory) is a C library in support of computations
in number theory. It's also a research project into algorithms in number theory.
FLINT 2 is a complete rewrite of the FLINT library from scratch. It includes
much cleaner code and in many cases much faster algorithms and implementations.
At this stage FLINT consists mainly of fast integer and polynomial
arithmetic and linear algebra. In the future it is planned that FLINT will
contain algorithms for algebraic number theory and other number theoretic
functionality.
William Hart -- 16 Jan 2011.

242
external/flint-2.4.3/arith.h vendored Normal file
View File

@ -0,0 +1,242 @@
/*============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===============================================================================*/
/******************************************************************************
Copyright (C) 2010-2012 Fredrik Johansson
******************************************************************************/
#ifndef ARITH_H
#define ARITH_H
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpz_poly.h"
#include "fmpq_poly.h"
#include "fmpq.h"
#ifdef __cplusplus
extern "C" {
#endif
/* MPFR extras ***************************************************************/
void mpfr_zeta_inv_euler_product(mpfr_t res, ulong s, int char_4);
void mpfr_pi_chudnovsky(mpfr_t res, mpfr_rnd_t rnd);
/* Various arithmetic functions **********************************************/
void arith_primorial(fmpz_t res, slong n);
void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n);
void arith_harmonic_number(fmpq_t x, slong n);
void arith_ramanujan_tau(fmpz_t res, const fmpz_t n);
void arith_ramanujan_tau_series(fmpz_poly_t res, slong n);
void arith_divisors(fmpz_poly_t res, const fmpz_t n);
void arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k);
int arith_moebius_mu(const fmpz_t n);
void arith_euler_phi(fmpz_t res, const fmpz_t n);
/* Stirling numbers **********************************************************/
void arith_stirling_number_1u(fmpz_t s, slong n, slong k);
void arith_stirling_number_1(fmpz_t s, slong n, slong k);
void arith_stirling_number_2(fmpz_t s, slong n, slong k);
void arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen);
void arith_stirling_number_1_vec(fmpz * row, slong n, slong klen);
void arith_stirling_number_2_vec(fmpz * row, slong n, slong klen);
void arith_stirling_number_1u_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen);
void arith_stirling_number_1_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen);
void arith_stirling_number_2_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen);
void arith_stirling_matrix_1u(fmpz_mat_t mat);
void arith_stirling_matrix_1(fmpz_mat_t mat);
void arith_stirling_matrix_2(fmpz_mat_t mat);
/* Bell numbers **************************************************************/
#if FLINT64
#define BELL_NUMBER_TAB_SIZE 26
#else
#define BELL_NUMBER_TAB_SIZE 16
#endif
extern const mp_limb_t bell_number_tab[];
double arith_bell_number_size(ulong n);
void arith_bell_number(fmpz_t b, ulong n);
void arith_bell_number_bsplit(fmpz_t res, ulong n);
void arith_bell_number_multi_mod(fmpz_t res, ulong n);
void arith_bell_number_vec(fmpz * b, slong n);
void arith_bell_number_vec_recursive(fmpz * b, slong n);
void arith_bell_number_vec_multi_mod(fmpz * b, slong n);
mp_limb_t arith_bell_number_nmod(ulong n, nmod_t mod);
void arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod);
void arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod);
void arith_bell_number_nmod_vec_series(mp_ptr b, slong n, nmod_t mod);
/* Euler numbers *************************************************************/
#if FLINT64
#define SMALL_EULER_LIMIT 25
#else
#define SMALL_EULER_LIMIT 15
#endif
static const mp_limb_t euler_number_small[] = {
UWORD(1), UWORD(1), UWORD(5), UWORD(61), UWORD(1385), UWORD(50521), UWORD(2702765),
UWORD(199360981),
#if FLINT64
UWORD(19391512145), UWORD(2404879675441), UWORD(370371188237525),
UWORD(69348874393137901), UWORD(15514534163557086905)
#endif
};
double arith_euler_number_size(ulong n);
void arith_euler_number_vec(fmpz * res, slong n);
void _arith_euler_number_zeta(fmpz_t res, ulong n);
void arith_euler_number(fmpz_t res, ulong n);
void arith_euler_polynomial(fmpq_poly_t poly, ulong n);
/* Bernoulli numbers *********************************************************/
#if FLINT64
#define BERNOULLI_SMALL_NUMER_LIMIT 35
#else
#define BERNOULLI_SMALL_NUMER_LIMIT 27
#endif
static const slong _bernoulli_numer_small[] = {
WORD(1), WORD(1), WORD(-1), WORD(1), WORD(-1), WORD(5), WORD(-691), WORD(7), WORD(-3617), WORD(43867), WORD(-174611), WORD(854513),
WORD(-236364091), WORD(8553103),
#if FLINT64
WORD(-23749461029), WORD(8615841276005), WORD(-7709321041217), WORD(2577687858367)
#endif
};
void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n);
void arith_bernoulli_number(fmpq_t x, ulong n);
void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n);
void arith_bernoulli_number_vec(fmpq * num, slong n);
void arith_bernoulli_number_denom(fmpz_t den, ulong n);
double arith_bernoulli_number_size(ulong n);
void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n);
void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n);
void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n);
void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n);
void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n);
/* Cyclotomic polynomials ****************************************************/
void _arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors,
slong num_factors, ulong phi);
void arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n);
void _arith_cos_minpoly(fmpz * coeffs, slong d, ulong n);
void arith_cos_minpoly(fmpz_poly_t poly, ulong n);
/* Hypergeometric polynomials ************************************************/
void arith_legendre_polynomial(fmpq_poly_t poly, ulong n);
void arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n);
void arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n);
/* Swinnerton-Dyer polynomials ***********************************************/
void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n);
/* Landau function ***********************************************************/
void arith_landau_function_vec(fmpz * res, slong len);
/* Dedekind sums *************************************************************/
void arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k);
double arith_dedekind_sum_coprime_d(double h, double k);
void arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k);
void arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k);
void arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k);
/* Exponential sums **********************************************************/
typedef struct
{
int n;
int prefactor;
mp_limb_t sqrt_p;
mp_limb_t sqrt_q;
mp_limb_signed_t cos_p[FLINT_BITS];
mp_limb_t cos_q[FLINT_BITS];
} trig_prod_struct;
typedef trig_prod_struct trig_prod_t[1];
static __inline__
void trig_prod_init(trig_prod_t sum)
{
sum->n = 0;
sum->prefactor = 1;
sum->sqrt_p = 1;
sum->sqrt_q = 1;
}
void arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n);
/* Number of partitions ******************************************************/
void arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod);
void arith_number_of_partitions_vec(fmpz * res, slong len);
void arith_number_of_partitions_mpfr(mpfr_t x, ulong n);
void arith_number_of_partitions(fmpz_t x, ulong n);
/* Number of sums of squares representations *********************************/
void arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n);
void arith_sum_of_squares_vec(fmpz * r, ulong k, slong n);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number(fmpz_t b, ulong n)
{
if (n < BELL_NUMBER_TAB_SIZE)
fmpz_set_ui(b, bell_number_tab[n]);
else if (n < 5000)
arith_bell_number_bsplit(b, n);
else
arith_bell_number_multi_mod(b, n);
}

View File

@ -0,0 +1,124 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
static slong
_bell_series_cutoff(slong n)
{
double N, log_N, log_pow, log_fac;
N = n;
log_N = (N==0 ? 0 : log(N));
log_pow = n * log_N;
log_fac = N*log_N - N;
while (log_pow - log_fac >= -2)
{
N++;
log_N = log(N);
log_pow = n * log_N;
log_fac += log_N;
}
return N;
}
static void
_mpz_bell_bsplit(mpz_t P, mpz_t Q, slong a, slong b, slong n, slong bmax)
{
if (b - a < 20)
{
mpz_t u;
slong k;
mpz_init(u);
flint_mpz_set_ui(P, UWORD(0));
flint_mpz_set_ui(Q, UWORD(0));
flint_mpz_set_ui(Q, (b - 1 == bmax) ? UWORD(1) : b);
for (k = b - 1; k >= a; k--)
{
flint_mpz_set_ui(u, k);
flint_mpz_pow_ui(u, u, n);
mpz_addmul(P, Q, u);
if (k != a)
flint_mpz_mul_ui(Q, Q, k);
}
mpz_clear(u);
}
else
{
slong m;
mpz_t P1, Q2;
m = (a + b) / 2;
mpz_init(P1);
mpz_init(Q2);
_mpz_bell_bsplit(P1, Q, a, m, n, bmax);
_mpz_bell_bsplit(P, Q2, m, b, n, bmax);
mpz_mul(Q, Q, Q2);
mpz_addmul(P, P1, Q2);
mpz_clear(P1);
mpz_clear(Q2);
}
}
void
arith_bell_number_bsplit(fmpz_t b, ulong n)
{
slong N;
mp_bitcnt_t prec;
mpz_t P, Q;
mpfr_t Pf, Qf, E, one;
N = _bell_series_cutoff(n);
mpz_init(P);
mpz_init(Q);
_mpz_bell_bsplit(P, Q, 1, N + 1, n, N);
prec = mpz_sizeinbase(P, 2) - mpz_sizeinbase(Q, 2) + 10;
mpfr_init2(Pf, prec);
mpfr_init2(Qf, prec);
mpfr_init2(E, prec);
mpfr_init2(one, 2);
mpfr_set_z(Pf, P, GMP_RNDN);
mpfr_set_z(Qf, Q, GMP_RNDN);
mpfr_set_ui(one, 1, GMP_RNDN);
mpfr_exp(E, one, GMP_RNDN);
mpfr_mul(Qf, Qf, E, GMP_RNDN);
mpfr_div(Pf, Pf, Qf, GMP_RNDN);
mpfr_get_z(P, Pf, GMP_RNDN);
fmpz_set_mpz(b, P);
mpfr_clear(one);
mpfr_clear(Pf);
mpfr_clear(Qf);
mpfr_clear(E);
mpz_clear(P);
mpz_clear(Q);
}

View File

@ -0,0 +1,65 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_multi_mod(fmpz_t res, ulong n)
{
fmpz_comb_temp_t temp;
fmpz_comb_t comb;
nmod_t mod;
mp_ptr primes, residues;
slong k, num_primes;
mp_bitcnt_t size, prime_bits;
size = arith_bell_number_size(n);
prime_bits = FLINT_BITS - 1;
num_primes = (size + prime_bits - 1) / prime_bits;
primes = flint_malloc(num_primes * sizeof(mp_limb_t));
residues = flint_malloc(num_primes * sizeof(mp_limb_t));
primes[0] = n_nextprime(UWORD(1) << prime_bits, 0);
for (k = 1; k < num_primes; k++)
primes[k] = n_nextprime(primes[k-1], 0);
for (k = 0; k < num_primes; k++)
{
nmod_init(&mod, primes[k]);
residues[k] = arith_bell_number_nmod(n, mod);
}
fmpz_comb_init(comb, primes, num_primes);
fmpz_comb_temp_init(temp, comb);
fmpz_multi_CRT_ui(res, residues, comb, temp, 0);
fmpz_comb_clear(comb);
fmpz_comb_temp_clear(temp);
flint_free(primes);
flint_free(residues);
}

View File

@ -0,0 +1,110 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
const mp_limb_t bell_number_tab[] =
{
UWORD(1), UWORD(1), UWORD(2), UWORD(5), UWORD(15), UWORD(52), UWORD(203), UWORD(877), UWORD(4140), UWORD(21147), UWORD(115975),
UWORD(678570), UWORD(4213597), UWORD(27644437), UWORD(190899322), UWORD(1382958545),
#if FLINT64
UWORD(10480142147), UWORD(82864869804), UWORD(682076806159), UWORD(5832742205057),
UWORD(51724158235372), UWORD(474869816156751), UWORD(4506715738447323),
UWORD(44152005855084346), UWORD(445958869294805289),
UWORD(4638590332229999353),
#endif
};
static const char bell_mod_2[3] = {1, 1, 0};
static const char bell_mod_3[13] = {1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1};
mp_limb_t
arith_bell_number_nmod(ulong n, nmod_t mod)
{
mp_limb_t s, t, u;
mp_ptr facs, pows;
slong i, j;
if (n < BELL_NUMBER_TAB_SIZE)
return n_mod2_preinv(bell_number_tab[n], mod.n, mod.ninv);
if (mod.n == 2) return bell_mod_2[n % 3];
if (mod.n == 3) return bell_mod_3[n % 13];
if (mod.n <= n)
{
mp_ptr bvec = flint_malloc(sizeof(mp_limb_t) * (n + 1));
arith_bell_number_nmod_vec_recursive(bvec, n + 1, mod);
s = bvec[n];
flint_free(bvec);
return s;
}
/* Compute inverse factorials */
/* We actually compute (n! / i!) and divide out (n!)^2 at the end */
facs = flint_malloc(sizeof(mp_limb_t) * (n + 1));
facs[n] = 1;
for (i = n - 1; i >= 0; i--)
facs[i] = n_mulmod2_preinv(facs[i + 1], i + 1, mod.n, mod.ninv);
/* Compute powers */
pows = flint_calloc(n + 1, sizeof(mp_limb_t));
pows[0] = n_powmod2_ui_preinv(0, n, mod.n, mod.ninv);
pows[1] = n_powmod2_ui_preinv(1, n, mod.n, mod.ninv);
for (i = 2; i <= n; i++)
{
if (pows[i] == 0)
pows[i] = n_powmod2_ui_preinv(i, n, mod.n, mod.ninv);
for (j = 2; j <= i && i * j <= n; j++)
if (pows[i * j] == 0)
pows[i * j] = n_mulmod2_preinv(pows[i],
pows[j], mod.n, mod.ninv);
}
for (s = t = i = 0; i <= n; i++)
{
if (i % 2 == 0)
t = n_addmod(t, facs[i], mod.n);
else
t = n_submod(t, facs[i], mod.n);
u = pows[n - i];
u = n_mulmod2_preinv(u, facs[n - i], mod.n, mod.ninv);
u = n_mulmod2_preinv(u, t, mod.n, mod.ninv);
s = n_addmod(s, u, mod.n);
}
/* Remove (n!)^2 */
u = n_invmod(facs[0], mod.n);
u = n_mulmod2_preinv(u, u, mod.n, mod.ninv);
s = n_mulmod2_preinv(s, u, mod.n, mod.ninv);
flint_free(facs);
flint_free(pows);
return s;
}

View File

@ -0,0 +1,35 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod)
{
if (n < 2000 || mod.n <= n)
arith_bell_number_nmod_vec_recursive(b, n, mod);
else
arith_bell_number_nmod_vec_series(b, n, mod);
}

View File

@ -0,0 +1,56 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod)
{
slong i, k;
mp_ptr t;
if (n < BELL_NUMBER_TAB_SIZE)
{
for (i = 0; i < n; i++)
b[i] = n_mod2_preinv(bell_number_tab[i], mod.n, mod.ninv);
return;
}
n -= 1;
t = _nmod_vec_init(n);
t[0] = b[0] = b[1] = 1;
for (i = 1; i < n; i++)
{
t[i] = t[0];
for (k = i; k > 0; k--)
t[k - 1] = n_addmod(t[k - 1], t[k], mod.n);
b[i + 1] = t[0];
}
_nmod_vec_clear(t);
}

View File

@ -0,0 +1,62 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_nmod_vec_series(mp_ptr res, slong n, nmod_t mod)
{
mp_limb_t fac, c;
mp_ptr tmp;
slong k;
if (n < 1)
return;
tmp = flint_malloc(sizeof(mp_limb_t) * n);
/* Divide by factorials */
fac = n_factorial_mod2_preinv(n-1, mod.n, mod.ninv);
c = n_invmod(fac, mod.n);
for (k = n - 1; k > 0; k--)
{
tmp[k] = c;
c = n_mulmod2_preinv(c, k, mod.n, mod.ninv);
}
tmp[0] = UWORD(0);
_nmod_poly_exp_series(res, tmp, n, mod);
/* Multiply by factorials */
c = UWORD(1);
for (k = 1; k < n; k++)
{
c = n_mulmod2_preinv(c, k, mod.n, mod.ninv);
res[k] = n_mulmod2_preinv(res[k], c, mod.n, mod.ninv);
}
flint_free(tmp);
}

View File

@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "flint.h"
double
arith_bell_number_size(ulong n)
{
if (n == 0)
return 2;
return n * log(0.792 * n/log(n+1)) * 1.44269504088896 + 2;
}

View File

@ -0,0 +1,35 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_vec(fmpz * res, slong n)
{
if (n < 5000)
arith_bell_number_vec_recursive(res, n);
else
arith_bell_number_vec_multi_mod(res, n);
}

View File

@ -0,0 +1,105 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "nmod_poly.h"
#include "arith.h"
#define CRT_MAX_RESOLUTION 16
void
arith_bell_number_vec_multi_mod(fmpz * res, slong n)
{
fmpz_comb_t comb[CRT_MAX_RESOLUTION];
fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION];
mp_ptr primes, residues;
mp_ptr * polys;
nmod_t mod;
slong i, j, k, num_primes, num_primes_k, resolution;
mp_bitcnt_t size, prime_bits;
if (n < 1)
return;
resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, n / 16));
size = arith_bell_number_size(n);
prime_bits = FLINT_BITS - 1;
num_primes = (size + prime_bits - 1) / prime_bits;
primes = flint_malloc(num_primes * sizeof(mp_limb_t));
residues = flint_malloc(num_primes * sizeof(mp_limb_t));
polys = flint_malloc(num_primes * sizeof(mp_ptr));
/* Compute Bell numbers mod p */
primes[0] = n_nextprime(UWORD(1)<<prime_bits, 0);
for (k = 1; k < num_primes; k++)
primes[k] = n_nextprime(primes[k-1], 0);
for (k = 0; k < num_primes; k++)
{
/* flint_printf("prime %wd of %wd\n", k, num_primes); */
polys[k] = _nmod_vec_init(n);
nmod_init(&mod, primes[k]);
arith_bell_number_nmod_vec(polys[k], n, mod);
}
/* Init CRT comb */
for (i = 0; i < resolution; i++)
{
fmpz_comb_init(comb[i], primes, num_primes * (i + 1) / resolution);
fmpz_comb_temp_init(temp[i], comb[i]);
}
/* Reconstruction */
for (k = 0; k < n; k++)
{
size = arith_bell_number_size(k);
/* Use only as large a comb as needed */
num_primes_k = (size + prime_bits - 1) / prime_bits;
for (i = 0; i < resolution; i++)
{
if (comb[i]->num_primes >= num_primes_k)
break;
}
num_primes_k = comb[i]->num_primes;
for (j = 0; j < num_primes_k; j++)
residues[j] = polys[j][k];
fmpz_multi_CRT_ui(res + k, residues, comb[i], temp[i], 0);
}
/* Cleanup */
for (k = 0; k < num_primes; k++)
_nmod_vec_clear(polys[k]);
for (i = 0; i < resolution; i++)
{
fmpz_comb_temp_clear(temp[i]);
fmpz_comb_clear(comb[i]);
}
flint_free(primes);
flint_free(residues);
flint_free(polys);
}

View File

@ -0,0 +1,57 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_bell_number_vec_recursive(fmpz * b, slong n)
{
slong i, k;
fmpz * t;
if (n < BELL_NUMBER_TAB_SIZE)
{
for (i = 0; i < n; i++)
fmpz_set_ui(b + i, bell_number_tab[i]);
return;
}
n -= 1;
t = _fmpz_vec_init(n);
fmpz_one(t);
fmpz_one(b);
fmpz_one(b + 1);
for (i = 1; i < n; i++)
{
fmpz_set(t + i, t);
for (k = i; k > 0; k--)
fmpz_add(t + k - 1, t + k - 1, t + k);
fmpz_set(b + i + 1, t);
}
_fmpz_vec_clear(t, n);
}

View File

@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n)
{
_arith_bernoulli_number_zeta(num, den, n);
}
void arith_bernoulli_number(fmpq_t x, ulong n)
{
_arith_bernoulli_number(fmpq_numref(x), fmpq_denref(x), n);
}

View File

@ -0,0 +1,80 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
#define BERNOULLI_DENOM_MAX_SMALL 178
#if FLINT64
#define __u32 unsigned int
#else
#define __u32 mp_limb_t
#endif
static const __u32 __bernoulli_denom_small[] =
{
UWORD(1), UWORD(6), UWORD(30), UWORD(42), UWORD(30), UWORD(66), UWORD(2730), UWORD(6), UWORD(510), UWORD(798), UWORD(330),
UWORD(138), UWORD(2730), UWORD(6), UWORD(870), UWORD(14322), UWORD(510), UWORD(6), UWORD(1919190), UWORD(6), UWORD(13530),
UWORD(1806), UWORD(690), UWORD(282), UWORD(46410), UWORD(66), UWORD(1590), UWORD(798), UWORD(870), UWORD(354),
UWORD(56786730), UWORD(6), UWORD(510), UWORD(64722), UWORD(30), UWORD(4686), UWORD(140100870), UWORD(6), UWORD(30),
UWORD(3318), UWORD(230010), UWORD(498), UWORD(3404310), UWORD(6), UWORD(61410), UWORD(272118), UWORD(1410), UWORD(6),
UWORD(4501770), UWORD(6), UWORD(33330), UWORD(4326), UWORD(1590), UWORD(642), UWORD(209191710), UWORD(1518),
UWORD(1671270), UWORD(42), UWORD(1770), UWORD(6), UWORD(2328255930), UWORD(6), UWORD(30), UWORD(4357878), UWORD(510),
UWORD(8646), UWORD(4206930), UWORD(6), UWORD(4110), UWORD(274386), UWORD(679470), UWORD(6), UWORD(2381714790),
UWORD(6), UWORD(4470), UWORD(2162622), UWORD(30), UWORD(138), UWORD(1794590070), UWORD(6), UWORD(230010),
UWORD(130074), UWORD(2490), UWORD(1002), UWORD(3404310), UWORD(66), UWORD(5190), UWORD(2478), UWORD(1043970),
UWORD(1074),
};
void arith_bernoulli_number_denom(fmpz_t den, ulong n)
{
slong i;
mp_limb_t p;
const mp_limb_t * primes;
if (n % 2 == 1)
{
fmpz_set_ui(den, 1 + (n == 1));
}
else if (n <= BERNOULLI_DENOM_MAX_SMALL)
{
fmpz_set_ui(den, __bernoulli_denom_small[n / 2]);
}
else
{
n_prime_pi_bounds(&p, &p, n);
primes = n_primes_arr_readonly(p + 1);
fmpz_set_ui(den, UWORD(6));
for (i = 2; i < n; i++)
{
p = primes[i];
if (p - 1 > n)
break;
if (n % (p - 1) == 0)
fmpz_mul_ui(den, den, p);
}
}
}

View File

@ -0,0 +1,41 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
double arith_bernoulli_number_size(ulong n)
{
double x;
/* |B_n| < 2 */
if (n <= 14)
return 1.0;
x = 2 + (n + 1) * log(n + 1) * 1.44269504088897; /* 1/log(2) */
x -= n * 4.0941911703612822; /* log2(2*pi*e) */
return x + 2;
}

View File

@ -0,0 +1,59 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n)
{
if (n < 700)
_arith_bernoulli_number_vec_recursive(num, den, n);
else if (n < 3900)
_arith_bernoulli_number_vec_zeta(num, den, n);
else
_arith_bernoulli_number_vec_multi_mod(num, den, n);
}
void arith_bernoulli_number_vec(fmpq * x, slong n)
{
fmpz * num, * den;
slong i;
if (n <= 0)
return;
num = _fmpz_vec_init(n * 2);
den = num + n;
_arith_bernoulli_number_vec(num, den, n);
for (i = 0; i < n; i++)
{
fmpz_swap(num + i, fmpq_numref(x + i));
fmpz_swap(den + i, fmpq_denref(x + i));
}
_fmpz_vec_clear(num, n * 2);
}

View File

@ -0,0 +1,150 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
static void
__bernoulli_number_vec_mod_p(mp_ptr res, mp_ptr tmp, const fmpz * den,
slong m, nmod_t mod)
{
mp_limb_t fac, c, t;
slong k;
/* x^2/(cosh(x)-1) = \sum_{k=0}^{\infty} 2(1-2k)/(2k)! B_2k x^(2k) */
/* Divide by factorials */
fac = n_factorial_mod2_preinv(2*m, mod.n, mod.ninv);
c = n_invmod(fac, mod.n);
for (k = m - 1; k >= 0; k--)
{
tmp[k] = c;
c = n_mulmod2_preinv(c, (2*k+1)*(2*k+2), mod.n, mod.ninv);
}
_nmod_poly_inv_series(res, tmp, m, mod);
res[0] = UWORD(1);
/* N_(2k) = -1 * D_(2k) * (2k)! / (2k-1) */
c = n_negmod(UWORD(1), mod.n);
for (k = 1; k < m; k++)
{
t = fmpz_fdiv_ui(den + 2*k, mod.n);
t = n_mulmod2_preinv(c, t, mod.n, mod.ninv);
res[k] = n_mulmod2_preinv(res[k], t, mod.n, mod.ninv);
c = n_mulmod2_preinv(c, 2*(k+1)*(2*k-1), mod.n, mod.ninv);
}
}
#define CRT_MAX_RESOLUTION 16
void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n)
{
fmpz_comb_t comb[CRT_MAX_RESOLUTION];
fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION];
mp_limb_t * primes;
mp_limb_t * residues;
mp_ptr * polys;
mp_ptr temppoly;
nmod_t mod;
slong i, j, k, m, num_primes, num_primes_k, resolution;
mp_bitcnt_t size, prime_bits;
if (n < 1)
return;
for (i = 0; i < n; i++)
arith_bernoulli_number_denom(den + i, i);
/* Number of nonzero entries (apart from B_1) */
m = (n + 1) / 2;
resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, m / 16));
/* Note that the denominators must be accounted for */
size = arith_bernoulli_number_size(n) + _fmpz_vec_max_bits(den, n) + 2;
prime_bits = FLINT_BITS - 1;
num_primes = (size + prime_bits - 1) / prime_bits;
primes = flint_malloc(num_primes * sizeof(mp_limb_t));
residues = flint_malloc(num_primes * sizeof(mp_limb_t));
polys = flint_malloc(num_primes * sizeof(mp_ptr));
/* Compute Bernoulli numbers mod p */
primes[0] = n_nextprime(UWORD(1)<<prime_bits, 0);
for (k = 1; k < num_primes; k++)
primes[k] = n_nextprime(primes[k-1], 0);
temppoly = _nmod_vec_init(m);
for (k = 0; k < num_primes; k++)
{
polys[k] = _nmod_vec_init(m);
nmod_init(&mod, primes[k]);
__bernoulli_number_vec_mod_p(polys[k], temppoly, den, m, mod);
}
/* Init CRT comb */
for (i = 0; i < resolution; i++)
{
fmpz_comb_init(comb[i], primes, num_primes * (i + 1) / resolution);
fmpz_comb_temp_init(temp[i], comb[i]);
}
/* Trivial entries */
if (n > 1)
fmpz_set_si(num + 1, WORD(-1));
for (k = 3; k < n; k += 2)
fmpz_zero(num + k);
/* Reconstruction */
for (k = 0; k < n; k += 2)
{
size = arith_bernoulli_number_size(k) + fmpz_bits(den + k) + 2;
/* Use only as large a comb as needed */
num_primes_k = (size + prime_bits - 1) / prime_bits;
for (i = 0; i < resolution; i++)
{
if (comb[i]->num_primes >= num_primes_k)
break;
}
num_primes_k = comb[i]->num_primes;
for (j = 0; j < num_primes_k; j++)
residues[j] = polys[j][k / 2];
fmpz_multi_CRT_ui(num + k, residues, comb[i], temp[i], 1);
}
/* Cleanup */
for (k = 0; k < num_primes; k++)
_nmod_vec_clear(polys[k]);
_nmod_vec_clear(temppoly);
for (i = 0; i < resolution; i++)
{
fmpz_comb_temp_clear(temp[i]);
fmpz_comb_clear(comb[i]);
}
flint_free(primes);
flint_free(residues);
flint_free(polys);
}

View File

@ -0,0 +1,165 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static void
__ramanujan_even_common_denom(fmpz * num, fmpz * den, slong start, slong n)
{
fmpz_t t, c, d, cden;
slong j, k, m, mcase;
int prodsize;
if (start >= n)
return;
fmpz_init(t);
fmpz_init(c);
fmpz_init(d);
fmpz_init(cden);
/* Common denominator */
arith_primorial(cden, n + 1);
start += start % 2;
/* Convert initial values to common denominator */
for (k = 0; k < start; k += 2)
{
fmpz_divexact(t, cden, den + k);
fmpz_mul(num + k, num + k, t);
}
/* Ramanujan's recursive formula */
for (m = start; m < n; m += 2)
{
mcase = m % 6;
fmpz_mul_ui(num + m, cden, m + UWORD(3));
fmpz_divexact_ui(num + m, num + m, UWORD(3));
if (mcase == 4)
{
fmpz_neg(num + m, num + m);
fmpz_divexact_ui(num + m, num + m, UWORD(2));
}
/* All factors are strictly smaller than m + 4; choose prodsize such
that (m + 4)^prodsize fits in an slong. */
{
#if FLINT64
if (m < WORD(1444)) prodsize = 6;
else if (m < WORD(2097148)) prodsize = 3;
else if (m < WORD(3037000495)) prodsize = 2; /* not very likely... */
else abort();
#else
if (m < WORD(32)) prodsize = 6;
else if (m < WORD(1286)) prodsize = 3;
else if (m < WORD(46336)) prodsize = 2;
else abort();
#endif
}
/* c = t = binomial(m+3, m) */
fmpz_set_ui(t, m + UWORD(1));
fmpz_mul_ui(t, t, m + UWORD(2));
fmpz_mul_ui(t, t, m + UWORD(3));
fmpz_divexact_ui(t, t, UWORD(6));
fmpz_set(c, t);
for (j = 6; j <= m; j += 6)
{
slong r = m - j;
/* c = binomial(m+3, m-j); */
switch (prodsize)
{
case 2:
fmpz_mul_ui(c, c, (r+6)*(r+5));
fmpz_mul_ui(c, c, (r+4)*(r+3));
fmpz_mul_ui(c, c, (r+2)*(r+1));
fmpz_set_ui(d, (j+0)*(j+3));
fmpz_mul_ui(d, d, (j-2)*(j+2));
fmpz_mul_ui(d, d, (j-1)*(j+1));
fmpz_divexact(c, c, d);
break;
case 3:
fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4));
fmpz_mul_ui(c, c, (r+3)*(r+2)*(r+1));
fmpz_set_ui(d, (j+0)*(j+3)*(j-2));
fmpz_mul_ui(d, d, (j+2)*(j-1)*(j+1));
fmpz_divexact(c, c, d);
break;
case 6:
fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4)*(r+3)*(r+2)*(r+1));
fmpz_divexact_ui(c, c, (j+0)*(j+3)*(j-2)*(j+2)*(j-1)*(j+1));
break;
}
fmpz_submul(num + m, c, num + (m - j));
}
fmpz_divexact(num + m, num + m, t);
}
/* Convert to separate denominators */
for (k = 0; k < n; k += 2)
{
arith_bernoulli_number_denom(den + k, k);
fmpz_divexact(t, cden, den + k);
fmpz_divexact(num + k, num + k, t);
}
fmpz_clear(t);
fmpz_clear(c);
fmpz_clear(d);
fmpz_clear(cden);
}
void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n)
{
slong i, start;
fmpz_t t;
fmpz_t d;
fmpz_init(t);
fmpz_init(d);
start = FLINT_MIN(BERNOULLI_SMALL_NUMER_LIMIT, n);
/* Initial values */
for (i = 0; i < start; i += 2)
_arith_bernoulli_number(num + i, den + i, i);
__ramanujan_even_common_denom(num, den, start, n);
/* Odd values */
for (i = 1; i < n; i += 2)
_arith_bernoulli_number(num + i, den + i, i);
fmpz_clear(d);
fmpz_clear(t);
}

View File

@ -0,0 +1,35 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n)
{
slong i;
/* Go backwards to exploit MPFR cache for pi */
for (i = n - 1; i >= 0; i--)
_arith_bernoulli_number_zeta(num + i, den + i, i);
}

View File

@ -0,0 +1,87 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n)
{
mpz_t r;
mpfr_t t, u, z, pi;
mp_bitcnt_t prec, pi_prec;
arith_bernoulli_number_denom(den, n);
if (n % 2)
{
fmpz_set_si(num, -(n == 1));
return;
}
if (n < BERNOULLI_SMALL_NUMER_LIMIT)
{
fmpz_set_si(num, _bernoulli_numer_small[n / 2]);
return;
}
prec = arith_bernoulli_number_size(n) + fmpz_bits(den);
prec += 10 + 2*FLINT_BIT_COUNT(n);
pi_prec = prec;
mpz_init(r);
mpfr_init2(t, prec);
mpfr_init2(u, prec);
mpfr_init2(z, prec);
mpfr_init2(pi, pi_prec);
/* t = 2 * n! / (2*pi)^n */
flint_mpz_fac_ui(r, n);
mpfr_set_z(t, r, GMP_RNDN);
mpfr_mul_2exp(t, t, 1, GMP_RNDN);
mpfr_const_pi(pi, GMP_RNDN);
mpfr_mul_2exp(pi, pi, 1, GMP_RNDN);
mpfr_pow_ui(pi, pi, n, GMP_RNDN);
mpfr_div(t, t, pi, GMP_RNDN);
/* t = t / zeta(n) */
mpfr_zeta_inv_euler_product(z, n, 0);
mpfr_div(t, t, z, GMP_RNDN);
/* round numerator */
fmpz_get_mpz(r, den);
mpfr_mul_z(t, t, r, GMP_RNDN);
mpfr_round(t, t);
mpfr_get_z(r, t, GMP_RNDN);
fmpz_set_mpz(num, r);
if (n % 4 == 0)
fmpz_neg(num, num);
mpz_clear(r);
mpfr_clear(t);
mpfr_clear(u);
mpfr_clear(z);
mpfr_clear(pi);
}

View File

@ -0,0 +1,73 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n)
{
fmpz_t t;
fmpz * den;
slong k;
if (n == 0)
{
fmpq_poly_set_ui(poly, UWORD(1));
return;
}
fmpq_poly_fit_length(poly, n + 1);
fmpz_init(t);
den = _fmpz_vec_init(n + 1);
_arith_bernoulli_number_vec(poly->coeffs, den, n + 1);
/* Multiply the odd term by binomial(n,1) = n */
fmpz_mul_ui(poly->coeffs + 1, poly->coeffs + 1, n);
/* Multiply even terms by binomial coefficients */
fmpz_one(t);
for (k = 2; k <= n; k += 2)
{
fmpz_mul2_uiui(t, t, n-k+1, n-k+2);
fmpz_divexact2_uiui(t, t, k, k-1);
fmpz_mul(poly->coeffs + k, poly->coeffs + k, t);
}
/* Convert to common denominator */
arith_primorial(poly->den, n + 2);
for (k = 0; k <= n; k++)
{
fmpz_mul(poly->coeffs + k, poly->coeffs+k, poly->den);
fmpz_divexact(poly->coeffs + k, poly->coeffs + k, den + k);
}
_fmpz_poly_reverse(poly->coeffs, poly->coeffs, n + 1, n + 1);
_fmpq_poly_set_length(poly, n + 1);
fmpq_poly_canonicalise(poly);
_fmpz_vec_clear(den, n + 1);
fmpz_clear(t);
}

View File

@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
_arith_chebyshev_t_polynomial(fmpz * coeffs, ulong n)
{
slong k, i, d, m;
d = n % 2;
fmpz_zero(coeffs);
fmpz_set_ui(coeffs + d, d ? n : 1);
if (n % 4 >= 2)
fmpz_neg(coeffs + d, coeffs + d);
m = n / 2;
for (k = 1; k <= m; k++)
{
i = 2 * k + d;
fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, 4*(m-k+1), n+k-m-1);
fmpz_divexact2_uiui(coeffs + i, coeffs + i, n+2*k-2*m-1, n+2*k-2*m);
fmpz_neg(coeffs + i, coeffs + i);
fmpz_zero(coeffs + i - 1);
}
}
void
arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n)
{
if (n == 0)
{
fmpz_poly_set_ui(poly, UWORD(1));
return;
}
fmpz_poly_fit_length(poly, n + 1);
if (n == 1)
{
fmpz_zero(poly->coeffs);
fmpz_one(poly->coeffs + 1);
}
else
_arith_chebyshev_t_polynomial(poly->coeffs, n);
_fmpz_poly_set_length(poly, n + 1);
}

View File

@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
_arith_chebyshev_u_polynomial(fmpz * coeffs, ulong n)
{
slong k, i, d, m;
d = n % 2;
fmpz_zero(coeffs);
fmpz_set_ui(coeffs + d, d ? n + 1 : 1);
if (n % 4 >= 2)
fmpz_neg(coeffs + d, coeffs + d);
m = n / 2;
for (k = 1; k <= m; k++)
{
i = 2 * k + d;
fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, 4*(m-k+1), n+k-m);
fmpz_divexact2_uiui(coeffs + i, coeffs + i, n+2*k-2*m-1, n+2*k-2*m);
fmpz_neg(coeffs + i, coeffs + i);
fmpz_zero(coeffs + i - 1);
}
}
void
arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n)
{
if (n == 0)
{
fmpz_poly_set_ui(poly, UWORD(1));
return;
}
fmpz_poly_fit_length(poly, n + 1);
if (n == 1)
{
fmpz_zero(poly->coeffs);
fmpz_set_ui(poly->coeffs + 1, UWORD(2));
}
else
_arith_chebyshev_u_polynomial(poly->coeffs, n);
_fmpz_poly_set_length(poly, n + 1);
}

View File

@ -0,0 +1,268 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
#define MAX_32BIT 58
static const int lookup_table[MAX_32BIT][28] =
{
{-1, 1}, {1, 1}, {1, 2}, {0, 1}, {-1, 2, 4}, {-1, 2},
{-1, -4, 4, 8}, {-1, 0, 2}, {1, -6, 0, 8}, {-1, -2, 4},
{1, 6, -12, -32, 16, 32}, {-3, 0, 4}, {-1, 6, 24, -32, -80, 32, 64},
{1, -4, -4, 8}, {1, 8, -16, -8, 16}, {1, 0, -8, 0, 8},
{1, -8, -40, 80, 240, -192, -448, 128, 256}, {-1, -6, 0, 8},
{1, 10, -40, -160, 240, 672, -448, -1024, 256, 512}, {5, 0, -20, 0, 16},
{1, -16, 32, 48, -96, -32, 64}, {-1, 6, 12, -32, -16, 32},
{-1, -12, 60, 280, -560, -1792, 1792, 4608, -2304, -5120, 1024, 2048},
{1, 0, -16, 0, 16}, {-1, 10, 100, -40, -800, 32, 2240, 0, -2560, 0,
1024}, {-1, -6, 24, 32, -80, -32, 64},
{1, 18, 0, -240, 0, 864, 0, -1152, 0, 512}, {-7, 0, 56, 0, -112, 0, 64},
{-1, 14, 112, -448, -2016, 4032, 13440, -15360, -42240, 28160, 67584,
-24576, -53248, 8192, 16384}, {1, -8, -16, 8, 16},
{-1, -16, 112, 672, -2016, -8064, 13440, 42240, -42240, -112640, 67584,
159744, -53248, -114688, 16384, 32768},
{1, 0, -32, 0, 160, 0, -256, 0, 128},
{1, -24, 48, 344, -688, -1088, 2176, 1280, -2560, -512, 1024},
{1, 8, -40, -80, 240, 192, -448, -128, 256},
{1, 16, -160, -368, 1760, 2272, -7232, -5504, 13824, 5632, -12288,
-2048, 4096}, {-3, 0, 36, 0, -96, 0, 64},
{-1, 18, 180, -960, -5280, 14784, 59136, -101376, -329472, 366080,
1025024, -745472, -1863680, 860160, 1966080, -524288, -1114112, 131072,
262144}, {-1, 10, 40, -160, -240, 672, 448, -1024, -256, 512},
{1, 24, -48, -632, 1264, 3296, -6592, -6784, 13568, 6144, -12288, -2048,
4096}, {1, 0, -48, 0, 304, 0, -512, 0, 256},
{1, -20, -220, 1320, 7920, -25344, -109824, 219648, 768768, -1025024,
-3075072, 2795520, 7454720, -4587520, -11141120, 4456448, 10027008,
-2359296, -4980736, 524288, 1048576}, {1, 16, 32, -48, -96, 32, 64},
{1, 22, -220, -1760, 7920, 41184, -109824, -439296, 768768, 2562560,
-3075072, -8945664, 7454720, 19496960, -11141120, -26738688, 10027008,
22413312, -4980736, -10485760, 1048576, 2097152},
{-11, 0, 220, 0, -1232, 0, 2816, 0, -2816, 0, 1024},
{1, -24, -144, 248, 1680, -864, -7168, 1152, 13824, -512, -12288, 0,
4096}, {1, -12, -60, 280, 560, -1792, -1792, 4608, 2304, -5120, -1024,
2048}, {-1, -24, 264, 2288, -11440, -64064, 192192, 823680, -1647360,
-5857280, 8200192, 25346048, -25346048, -70189056, 50135040, 127008768,
-63504384, -149422080, 49807360, 110100480, -22020096, -46137344,
4194304, 8388608}, {1, 0, -64, 0, 320, 0, -512, 0, 256},
{-1, 28, 196, -2968, -3136, 66304, 18816, -658816, -53760, 3587584,
78848, -11741184, -57344, 24084480, 16384, -31195136, 0, 24772608, 0,
-11010048, 0, 2097152}, {-1, -10, 100, 40, -800, -32, 2240, 0, -2560,
0, 1024}, {1, 32, -64, -1504, 3008, 16832, -33664, -76288, 152576,
173568, -347136, -210944, 421888, 131072, -262144, -32768, 65536},
{13, 0, -364, 0, 2912, 0, -9984, 0, 16640, 0, -13312, 0, 4096},
{-1, 26, 364, -2912, -21840, 96096, 512512, -1464320, -6223360,
12446720, 44808192, -65175552, -206389248, 222265344, 635043840,
-508035072, -1333592064, 784465920, 1917583360, -807403520,
-1857028096, 530579456, 1157627904, -201326592, -419430400, 33554432,
67108864}, {-1, 18, 0, -240, 0, 864, 0, -1152, 0, 512},
{1, 24, -432, -1208, 15216, 28064, -185024, -263424, 1149184, 1250304,
-4177920, -3356672, 9375744, 5324800, -13123584, -4947968, 11141120,
2490368, -5242880, -524288, 1048576},
{1, 0, -96, 0, 1376, 0, -6656, 0, 13568, 0, -12288, 0, 4096},
{1, -40, 80, 2120, -4240, -31648, 63296, 194432, -388864, -613376,
1226752, 1087488, -2174976, -1097728, 2195456, 589824, -1179648,
-131072, 262144}, {-1, -14, 112, 448, -2016, -4032, 13440, 15360,
-42240, -28160, 67584, 24576, -53248, -8192, 16384}
};
/* The coefficients in 2^d * \prod_{i=1}^d (x - cos(a_i)) are
easily bounded using the binomial theorem. */
static slong
magnitude_bound(slong d)
{
slong res;
fmpz_t t;
fmpz_init(t);
fmpz_bin_uiui(t, d, d / 2);
res = fmpz_bits(t);
fmpz_clear(t);
return FLINT_ABS(res) + d;
}
static void
fmpz_mul_or_div_2exp(fmpz_t x, fmpz_t y, slong s)
{
if (s >= 0)
fmpz_mul_2exp(x, y, s);
else
fmpz_fdiv_q_2exp(x, y, -s);
}
/* Balanced product of linear factors (x+alpha_i) using
fixed-point arithmetic with prec bits */
static void
balanced_product(fmpz * c, fmpz * alpha, slong len, slong prec)
{
if (len == 1)
{
fmpz_one(c + 1);
fmpz_mul_2exp(c + 1, c + 1, prec);
fmpz_set(c, alpha);
}
else if (len == 2)
{
fmpz_mul(c, alpha, alpha + 1);
fmpz_fdiv_q_2exp(c, c, prec);
fmpz_add(c + 1, alpha, alpha + 1);
fmpz_one(c + 2);
fmpz_mul_2exp(c + 2, c + 2, prec);
}
else
{
fmpz *L, *R;
slong i, m;
m = len / 2;
L = _fmpz_vec_init(len + 2);
R = L + m + 1;
balanced_product(L, alpha, m, prec);
balanced_product(R, alpha + m, len - m, prec);
_fmpz_poly_mul(c, R, len - m + 1, L, m + 1);
for (i = 0; i < len + 1; i++)
fmpz_fdiv_q_2exp(c + i, c + i, prec);
_fmpz_vec_clear(L, len + 2);
}
}
void
_arith_cos_minpoly(fmpz * coeffs, slong d, ulong n)
{
slong i, j;
fmpz * alpha;
fmpz_t half;
mpfr_t t, u;
mp_bitcnt_t prec;
slong exp;
if (n <= MAX_32BIT)
{
for (i = 0; i <= d; i++)
fmpz_set_si(coeffs + i, lookup_table[n - 1][i]);
return;
}
/* Direct formula for odd primes > 3 */
if (n_is_prime(n))
{
slong s = (n - 1) / 2;
switch (s % 4)
{
case 0:
fmpz_set_si(coeffs, WORD(1));
fmpz_set_si(coeffs + 1, -s);
break;
case 1:
fmpz_set_si(coeffs, WORD(1));
fmpz_set_si(coeffs + 1, s + 1);
break;
case 2:
fmpz_set_si(coeffs, WORD(-1));
fmpz_set_si(coeffs + 1, s);
break;
case 3:
fmpz_set_si(coeffs, WORD(-1));
fmpz_set_si(coeffs + 1, -s - 1);
break;
}
for (i = 2; i <= s; i++)
{
slong b = (s - i) % 2;
fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, s+i-b, s+2-b-i);
fmpz_divexact2_uiui(coeffs + i, coeffs + i, i, i-1);
fmpz_neg(coeffs + i, coeffs + i);
}
return;
}
prec = magnitude_bound(d) + 5 + FLINT_BIT_COUNT(d);
alpha = _fmpz_vec_init(d);
fmpz_init(half);
mpfr_init2(t, prec);
mpfr_init2(u, prec);
fmpz_one(half);
fmpz_mul_2exp(half, half, prec - 1);
mpfr_const_pi(t, prec);
mpfr_div_ui(t, t, n, MPFR_RNDN);
for (i = j = 0; j < d; i++)
{
if (n_gcd(n, i) == 1)
{
mpfr_mul_ui(u, t, 2 * i, MPFR_RNDN);
mpfr_cos(u, u, MPFR_RNDN);
mpfr_neg(u, u, MPFR_RNDN);
exp = mpfr_get_z_2exp(_fmpz_promote(alpha + j), u);
_fmpz_demote_val(alpha + j);
fmpz_mul_or_div_2exp(alpha + j, alpha + j, exp + prec);
j++;
}
}
balanced_product(coeffs, alpha, d, prec);
/* Scale and round */
for (i = 0; i < d + 1; i++)
{
slong r = d;
if ((n & (n - 1)) == 0)
r--;
fmpz_mul_2exp(coeffs + i, coeffs + i, r);
fmpz_add(coeffs + i, coeffs + i, half);
fmpz_fdiv_q_2exp(coeffs + i, coeffs + i, prec);
}
fmpz_clear(half);
mpfr_clear(t);
mpfr_clear(u);
_fmpz_vec_clear(alpha, d);
}
void
arith_cos_minpoly(fmpz_poly_t poly, ulong n)
{
if (n == 0)
{
fmpz_poly_set_ui(poly, UWORD(1));
}
else
{
slong d = (n <= 2) ? 1 : n_euler_phi(n) / 2;
fmpz_poly_fit_length(poly, d + 1);
_arith_cos_minpoly(poly->coeffs, d, n);
_fmpz_poly_set_length(poly, d + 1);
}
}

View File

@ -0,0 +1,160 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
_arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors,
slong num_factors, ulong phi)
{
slong i, k;
int small;
ulong D;
D = phi / 2;
/* Phi_p(x) = 1 + x + x^2 + ... + x^{p-1} */
if (num_factors == 1)
{
for (i = 0; i <= D; i++)
fmpz_one(a + i);
return;
}
/* Phi_{2n}(x) = Phi_n(-x)*/
if (factors[0] == UWORD(2))
{
_arith_cyclotomic_polynomial(a, n / 2, factors + 1,
num_factors - 1, phi);
for (i = 1; i <= D; i += 2)
fmpz_neg(a + i, a + i);
return;
}
fmpz_one(a);
for (i = 1; i <= D; i++)
fmpz_zero(a + i);
/* Coefficients are guaranteed not to overflow an fmpz */
small = (num_factors == 2) || /* Always +1/0/-1*/
(n < WORD(10163195)) || /* At most 27 bits */
(FLINT_BITS == 64 && n < WORD(169828113)); /* At most 60 bits */
/* Iterate over all divisors of n */
for (k = 0; k < (WORD(1) << num_factors); k++)
{
int mu;
ulong d;
mu = (num_factors & 1) ? -1 : 1;
d = WORD(1);
for (i = 0; i < num_factors; i++)
{
if ((k >> i) & 1)
{
d *= factors[i];
mu = -mu;
}
}
/* Multiply by (x^d - 1)^{\mu(n/d)} */
if (small)
{
if (mu == 1)
for (i = D; i >= d; i--) a[i] -= a[i - d];
else
for (i = d; i <= D; i++) a[i] += a[i - d];
}
else
{
if (mu == 1)
for (i = D; i >= d; i--) fmpz_sub(a + i, a + i, a + i - d);
else
for (i = d; i <= D; i++) fmpz_add(a + i, a + i, a + i - d);
}
}
}
void
arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n)
{
n_factor_t factors;
slong i, j;
ulong s, phi;
if (n <= 2)
{
if (n == 0)
{
fmpz_poly_set_ui(poly, UWORD(1));
}
else
{
fmpz_poly_fit_length(poly, 2);
fmpz_set_si(poly->coeffs, (n == 1) ? WORD(-1) : WORD(1));
fmpz_set_si(poly->coeffs + 1, WORD(1));
_fmpz_poly_set_length(poly, 2);
}
return;
}
/* Write n = q * s where q is squarefree, compute the factors of q,
and compute phi(s) which determines the degree of the polynomial. */
n_factor_init(&factors);
n_factor(&factors, n, 1);
s = phi = UWORD(1);
for (i = 0; i < factors.num; i++)
{
phi *= factors.p[i] - 1;
while (factors.exp[i] > 1)
{
s *= factors.p[i];
factors.exp[i]--;
}
}
fmpz_poly_fit_length(poly, phi * s + 1);
/* Evaluate lower half of Phi_s(x) */
_arith_cyclotomic_polynomial(poly->coeffs, n / s,
factors.p, factors.num, phi);
/* Palindromic extension */
for (i = 0; i < (phi + 1) / 2; i++)
fmpz_set(poly->coeffs + phi - i, poly->coeffs + i);
/* Stretch */
if (s != 1)
{
for (i = phi; i > 0; i--)
{
fmpz_set(poly->coeffs + i*s, poly->coeffs + i);
for (j = 1; j < s; j++)
fmpz_zero(poly->coeffs + i*s - j);
}
}
_fmpz_poly_set_length(poly, phi * s + 1);
}

View File

@ -0,0 +1,307 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static const int mod4_tab[8] = { 2, 1, 3, 0, 0, 3, 1, 2 };
static const int gcd24_tab[24] = {
24, 1, 2, 3, 4, 1, 6, 1, 8, 3, 2, 1,
12, 1, 2, 3, 8, 1, 6, 1, 4, 3, 2, 1
};
static mp_limb_t
n_sqrtmod_2exp(mp_limb_t a, int k)
{
mp_limb_t x;
int i;
if (a == 0 || k == 0)
return 0;
if (k == 1)
return 1;
if (k == 2)
{
if (a == 1)
return 1;
return 0;
}
x = 1;
for (i = 3; i < k; i++)
x += (a - x * x) / 2;
if (k < FLINT_BITS)
x &= ((UWORD(1) << k) - 1);
return x;
}
static mp_limb_t
n_sqrtmod_ppow(mp_limb_t a, mp_limb_t p, int k, mp_limb_t pk, mp_limb_t pkinv)
{
mp_limb_t r, t;
int i;
r = n_sqrtmod(a, p);
if (r == 0)
return r;
i = 1;
while (i < k)
{
t = n_mulmod2_preinv(r, r, pk, pkinv);
t = n_submod(t, a, pk);
t = n_mulmod2_preinv(t, n_invmod(n_addmod(r, r, pk), pk), pk, pkinv);
r = n_submod(r, t, pk);
i *= 2;
}
return r;
}
void
trigprod_mul_prime_power(trig_prod_t prod, mp_limb_t k, mp_limb_t n,
mp_limb_t p, int exp)
{
mp_limb_t m, mod, inv;
if (k <= 3)
{
if (k == 0)
{
prod->prefactor = 0;
}
else if (k == 2 && (n % 2 == 1))
{
prod->prefactor *= -1;
}
else if (k == 3)
{
switch (n % 3)
{
case 0:
prod->prefactor *= 2;
prod->cos_p[prod->n] = 1;
prod->cos_q[prod->n] = 18;
break;
case 1:
prod->prefactor *= -2;
prod->cos_p[prod->n] = 7;
prod->cos_q[prod->n] = 18;
break;
case 2:
prod->prefactor *= -2;
prod->cos_p[prod->n] = 5;
prod->cos_q[prod->n] = 18;
break;
}
prod->n++;
}
return;
}
/* Power of 2 */
if (p == 2)
{
mod = 8 * k;
inv = n_preinvert_limb(mod);
m = n_submod(1, n_mod2_preinv(24 * n, mod, inv), mod);
m = n_sqrtmod_2exp(m, exp + 3);
m = n_mulmod2_preinv(m, n_invmod(3, mod), mod, inv);
prod->prefactor *= n_jacobi(-1, m);
if (exp % 2 == 1)
prod->prefactor *= -1;
prod->sqrt_p *= k;
prod->cos_p[prod->n] = (mp_limb_signed_t)(k - m);
prod->cos_q[prod->n] = 2 * k;
prod->n++;
return;
}
/* Power of 3 */
if (p == 3)
{
mod = 3 * k;
inv = n_preinvert_limb(mod);
m = n_submod(1, n_mod2_preinv(24 * n, mod, inv), mod);
m = n_sqrtmod_ppow(m, p, exp + 1, mod, inv);
m = n_mulmod2_preinv(m, n_invmod(8, mod), mod, inv);
prod->prefactor *= (2 * n_jacobi_unsigned(m, 3));
if (exp % 2 == 0)
prod->prefactor *= -1;
prod->sqrt_p *= k;
prod->sqrt_q *= 3;
prod->cos_p[prod->n] = (mp_limb_signed_t)(3 * k - 8 * m);
prod->cos_q[prod->n] = 6 * k;
prod->n++;
return;
}
/* Power of prime greater than 3 */
inv = n_preinvert_limb(k);
m = n_submod(1, n_mod2_preinv(24 * n, k, inv), k);
if (m % p == 0)
{
if (exp == 1)
{
prod->prefactor *= n_jacobi(3, k);
prod->sqrt_p *= k;
}
else
prod->prefactor = 0;
return;
}
m = n_sqrtmod_ppow(m, p, exp, k, inv);
if (m == 0)
{
prod->prefactor = 0;
return;
}
prod->prefactor *= 2;
prod->prefactor *= n_jacobi(3, k);
prod->sqrt_p *= k;
prod->cos_p[prod->n] = 4 * n_mulmod2_preinv(m, n_invmod(24, k), k, inv);
prod->cos_q[prod->n] = k;
prod->n++;
}
/*
Solve (k2^2 * d2 * e) * n1 = (d2 * e * n + (k2^2 - 1) / d1) mod k2
TODO: test this on 32 bit
*/
static mp_limb_t
solve_n1(mp_limb_t n, mp_limb_t k1, mp_limb_t k2,
mp_limb_t d1, mp_limb_t d2, mp_limb_t e)
{
mp_limb_t inv, n1, u, t[2];
inv = n_preinvert_limb(k1);
umul_ppmm(t[1], t[0], k2, k2);
sub_ddmmss(t[1], t[0], t[1], t[0], UWORD(0), UWORD(1));
mpn_divrem_1(t, 0, t, 2, d1);
n1 = n_ll_mod_preinv(t[1], t[0], k1, inv);
n1 = n_mod2_preinv(n1 + d2*e*n, k1, inv);
u = n_mulmod2_preinv(k2, k2, k1, inv);
u = n_invmod(u * d2 * e, k1);
n1 = n_mulmod2_preinv(n1, u, k1, inv);
return n1;
}
void
arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n)
{
n_factor_t fac;
int i;
if (k <= 1)
{
prod->prefactor = k;
return;
}
n_factor_init(&fac);
n_factor(&fac, k, 0);
/* Repeatedly factor A_k(n) into A_k1(n1)*A_k2(n2) with k1, k2 coprime */
for (i = 0; i + 1 < fac.num && prod->prefactor != 0; i++)
{
mp_limb_t p, k1, k2, inv, n1, n2;
p = fac.p[i];
/* k = 2 * k1 with k1 odd */
if (p == UWORD(2) && fac.exp[i] == 1)
{
k2 = k / 2;
inv = n_preinvert_limb(k2);
n2 = n_invmod(32, k2);
n2 = n_mulmod2_preinv(n2,
n_mod2_preinv(8*n + 1, k2, inv), k2, inv);
n1 = ((k2 % 8 == 3) || (k2 % 8 == 5)) ^ (n & 1);
trigprod_mul_prime_power(prod, 2, n1, 2, 1);
k = k2;
n = n2;
}
/* k = 4 * k1 with k1 odd */
else if (p == UWORD(2) && fac.exp[i] == 2)
{
k2 = k / 4;
inv = n_preinvert_limb(k2);
n2 = n_invmod(128, k2);
n2 = n_mulmod2_preinv(n2,
n_mod2_preinv(8*n + 5, k2, inv), k2, inv);
n1 = (n + mod4_tab[(k2 / 2) % 8]) % 4;
trigprod_mul_prime_power(prod, 4, n1, 2, 2);
prod->prefactor *= -1;
k = k2;
n = n2;
}
/* k = k1 * k2 with k1 odd or divisible by 8 */
else
{
mp_limb_t d1, d2, e;
k1 = n_pow(fac.p[i], fac.exp[i]);
k2 = k / k1;
d1 = gcd24_tab[k1 % 24];
d2 = gcd24_tab[k2 % 24];
e = 24 / (d1 * d2);
n1 = solve_n1(n, k1, k2, d1, d2, e);
n2 = solve_n1(n, k2, k1, d2, d1, e);
trigprod_mul_prime_power(prod, k1, n1, fac.p[i], fac.exp[i]);
k = k2;
n = n2;
}
}
if (fac.num != 0 && prod->prefactor != 0)
trigprod_mul_prime_power(prod, k, n,
fac.p[fac.num - 1], fac.exp[fac.num - 1]);
}

View File

@ -0,0 +1,84 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k)
{
if (fmpz_cmp_ui(k, UWORD(2)) <= 0 || fmpz_is_zero(h) || fmpz_equal(h, k))
{
fmpq_zero(s);
}
else if (fmpz_sgn(h) < 0)
{
fmpz_t t;
fmpz_init(t);
fmpz_neg(t, h);
arith_dedekind_sum(s, t, k);
fmpq_neg(s, s);
fmpz_clear(t);
}
else
{
fmpz_t t, u, q;
fmpz_init(t);
fmpz_init(u);
fmpz_init(q);
fmpz_gcd(q, h, k);
fmpz_divexact(t, h, q);
fmpz_divexact(u, k, q);
if (fmpz_cmp(t, u) > 0)
{
fmpq_t r;
fmpq_init(r);
/* r = (1 + h(h-3k) + k^2) / (12hk) */
fmpz_mul_ui(fmpq_numref(r), u, UWORD(3));
fmpz_sub(fmpq_numref(r), t, fmpq_numref(r));
fmpz_mul(fmpq_numref(r), fmpq_numref(r), t);
fmpz_addmul(fmpq_numref(r), u, u);
fmpz_add_ui(fmpq_numref(r), fmpq_numref(r), UWORD(1));
fmpz_mul(fmpq_denref(r), t, u);
fmpz_mul_ui(fmpq_denref(r), fmpq_denref(r), UWORD(12));
fmpq_canonicalise(r);
arith_dedekind_sum_coprime(s, u, t);
fmpq_sub(s, r, s);
fmpq_clear(r);
}
else
{
arith_dedekind_sum_coprime(s, t, u);
}
fmpz_clear(t);
fmpz_clear(u);
fmpz_clear(q);
}
}

View File

@ -0,0 +1,54 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
/* Small enough that a numerical computation is safe */
#define DOUBLE_CUTOFF (UWORD(1) << 21)
void
arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k)
{
if (fmpz_cmp_ui(k, DOUBLE_CUTOFF) < 0)
{
double t;
t = arith_dedekind_sum_coprime_d(*h, *k) * (6 * (*k));
/* Round to nearest after truncation */
if (t > 0)
t += 0.5;
else
t -= 0.5;
fmpz_set_d(fmpq_numref(s), t);
fmpz_set_ui(fmpq_denref(s), UWORD(6) * (*k));
fmpq_canonicalise(s);
}
else
{
arith_dedekind_sum_coprime_large(s, h, k);
}
}

View File

@ -0,0 +1,57 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
double
arith_dedekind_sum_coprime_d(double h, double k)
{
double a, b, t, s, sign;
if (k <= 2)
return 0.0;
a = k;
b = h;
s = 0.0;
sign = 1.0;
while (b > 0)
{
s += sign * (1.0 + a*a + b*b) / (a * b);
t = fmod(a, b);
a = b;
b = t;
sign = -sign;
}
s *= (1./12);
if (sign < 0)
s -= 0.25;
return s;
}

View File

@ -0,0 +1,96 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k)
{
fmpz_t sigma, p, pp, hh, kk, a, t;
int sign;
if (fmpz_cmp_ui(k, UWORD(2)) <= 0)
{
fmpq_zero(s);
return;
}
sign = 1;
fmpz_init(sigma);
fmpz_init(hh);
fmpz_init(kk);
fmpz_init(p);
fmpz_init(pp);
fmpz_init(a);
fmpz_init(t);
fmpz_set_ui(p, UWORD(1));
fmpz_set(hh, h);
fmpz_set(kk, k);
while (!fmpz_is_zero(hh))
{
fmpz_fdiv_qr(a, t, kk, hh);
if (sign == 1)
fmpz_add(sigma, sigma, a);
else
fmpz_sub(sigma, sigma, a);
sign = -sign;
/* kk, hh = hh, kk mod hh */
fmpz_swap(kk, hh);
fmpz_swap(hh, t);
/* p, pp = a*p + pp, p */
fmpz_addmul(pp, a, p);
fmpz_swap(p, pp);
}
if (sign < 0)
fmpz_sub_ui(sigma, sigma, UWORD(3));
/* s = (sigma + (h - p*s) / p) / 12 */
if (sign < 0)
fmpz_add(fmpq_numref(s), h, pp);
else
fmpz_sub(fmpq_numref(s), h, pp);
fmpz_addmul(fmpq_numref(s), sigma, p);
fmpz_mul_ui(fmpq_denref(s), p, UWORD(12));
_fmpq_canonicalise(fmpq_numref(s), fmpq_denref(s));
fmpz_clear(sigma);
fmpz_clear(hh);
fmpz_clear(kk);
fmpz_clear(p);
fmpz_clear(pp);
fmpz_clear(a);
fmpz_clear(t);
}

View File

@ -0,0 +1,82 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k)
{
fmpz_t i, j, q1, r1, q2, r2;
if (fmpz_is_zero(k))
{
fmpq_zero(s);
return;
}
fmpz_init(i);
fmpz_init(j);
fmpz_init(q1);
fmpz_init(r1);
fmpz_init(q2);
fmpz_init(r2);
fmpz_zero(fmpq_numref(s));
for (fmpz_one(i); fmpz_cmp(i, k) < 0; fmpz_add_ui(i, i, 1))
{
fmpz_fdiv_qr(q1, r1, i, k);
if (fmpz_is_zero(r1))
continue;
fmpz_mul(j, h, i);
fmpz_fdiv_qr(q2, r2, j, k);
if (fmpz_is_zero(r2))
continue;
fmpz_mul(q1, q1, k);
fmpz_sub(q1, i, q1);
fmpz_mul_ui(q1, q1, 2);
fmpz_sub(q1, q1, k);
fmpz_mul(q2, q2, k);
fmpz_sub(q2, j, q2);
fmpz_mul_ui(q2, q2, 2);
fmpz_sub(q2, q2, k);
fmpz_addmul(fmpq_numref(s), q1, q2);
}
fmpz_mul(fmpq_denref(s), k, k);
fmpz_mul_ui(fmpq_denref(s), fmpq_denref(s), 4);
fmpq_canonicalise(s);
fmpz_clear(i);
fmpz_clear(j);
fmpz_clear(q1);
fmpz_clear(r1);
fmpz_clear(q2);
fmpz_clear(r2);
}

View File

@ -0,0 +1,87 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "arith.h"
#include "fmpz.h"
/* note: destroys factors! */
void
_arith_divisor_sigma(fmpz_t res, const fmpz_factor_t factors, ulong k)
{
slong i;
fmpz * p;
fmpz_t r;
fmpz_one(res);
if (factors->num == 0)
return;
fmpz_init(r);
if (k == 0)
{
for (i = 0; i < factors->num; i++)
{
fmpz_set_ui(r, factors->exp[i] + UWORD(1));
fmpz_mul(res, res, r);
}
return;
}
else
{
for (i = 0; i < factors->num; i++)
{
p = factors->p + i;
fmpz_set(p, factors->p + i);
fmpz_pow_ui(p, p, k);
fmpz_pow_ui(r, p, factors->exp[i] + UWORD(1));
fmpz_sub_ui(r, r, UWORD(1));
fmpz_sub_ui(p, p, UWORD(1));
fmpz_divexact(p, r, p);
}
_fmpz_vec_prod(res, factors->p, factors->num);
}
fmpz_clear(r);
}
void
arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k)
{
fmpz_factor_t factors;
if (fmpz_is_zero(n))
{
fmpz_zero(res);
return;
}
fmpz_factor_init(factors);
fmpz_factor(factors, n);
_arith_divisor_sigma(res, factors, k);
fmpz_factor_clear(factors);
}

165
external/flint-2.4.3/arith/divisors.c vendored Normal file
View File

@ -0,0 +1,165 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "arith.h"
#include "fmpz.h"
#define FLINT_NUM_TINY_DIVISORS FLINT_BITS
const int FLINT_TINY_DIVISORS_SIZE[FLINT_NUM_TINY_DIVISORS] = {
0,1,2,2,3,2,4,2,4,3,4,2,6,2,4,4,5,2,6,2,6,4,4,2,8,3,4,4,6,2,8,2,
#if FLINT64
6,4,4,4,9,2,4,4,8,2,8,2,6,6,4,2,10,3,6,4,6,2,8,4,8,4,4,2,12,2,4,6
#endif
};
const ulong FLINT_TINY_DIVISORS_LOOKUP[FLINT_NUM_TINY_DIVISORS] = {
UWORD(0x0),UWORD(0x2),UWORD(0x6),0xaUL,UWORD(0x16),UWORD(0x22),0x4eUL,UWORD(0x82),UWORD(0x116),0x20aUL,
UWORD(0x426),UWORD(0x802),0x105eUL,UWORD(0x2002),UWORD(0x4086),0x802aUL,UWORD(0x10116),UWORD(0x20002),
0x4024eUL,UWORD(0x80002),UWORD(0x100436),0x20008aUL,UWORD(0x400806),UWORD(0x800002),
0x100115eUL,UWORD(0x2000022),UWORD(0x4002006),0x800020aUL,UWORD(0x10004096),UWORD(0x20000002),
0x4000846eUL,UWORD(0x80000002),
#if FLINT64
UWORD(0x100010116),0x20000080aUL,UWORD(0x400020006),UWORD(0x8000000a2),0x100004125eUL,
UWORD(0x2000000002),UWORD(0x4000080006),0x800000200aUL,UWORD(0x10000100536),
UWORD(0x20000000002),0x400002040ceUL,UWORD(0x80000000002),UWORD(0x100000400816),
0x20000000822aUL,UWORD(0x400000800006),UWORD(0x800000000002),0x100000101115eUL,
UWORD(0x2000000000082),UWORD(0x4000002000426),0x800000002000aUL,UWORD(0x10000004002016),
UWORD(0x20000000000002),0x4000000804024eUL,UWORD(0x80000000000822),
UWORD(0x100000010004196),0x20000000008000aUL,UWORD(0x400000020000006),
UWORD(0x800000000000002),0x100000004010947eUL,UWORD(0x2000000000000002),
UWORD(0x4000000080000006),0x800000000020028aUL
#endif
};
void
_arith_divisors(fmpz *res, slong size, fmpz_factor_t factors)
{
slong i;
slong *exp = flint_malloc(sizeof(slong) * factors->num);
slong *exp_max = flint_malloc(sizeof(slong) * factors->num);
fmpz *powers = _fmpz_vec_init(factors->num);
fmpz_t d;
for (i = 0; i < factors->num; i++)
{
exp[i] = 0;
fmpz_set(powers + i, factors->p + i);
exp_max[i] = factors->exp[i];
fmpz_pow_ui(powers + i, powers + i, exp_max[i]);
}
fmpz_init(d);
fmpz_one(res);
fmpz_one(d);
res++;
i = 0;
while (1)
{
while (1)
{
if (i == factors->num)
goto all_done;
if (exp[i] < exp_max[i])
{
exp[i]++;
fmpz_mul(d, d, factors->p + i);
i = 0;
break;
}
else
{
exp[i] = 0;
fmpz_divexact(d, d, powers+i);
i += 1;
}
}
fmpz_set(res, d);
res++;
}
all_done:
fmpz_clear(d);
flint_free(exp);
flint_free(exp_max);
_fmpz_vec_clear(powers, factors->num);
}
void
_arith_divisors_tiny(fmpz_poly_t res, slong n)
{
slong size;
slong i, k;
size = FLINT_TINY_DIVISORS_SIZE[n];
fmpz_poly_fit_length(res, size);
i = 0;
for (k = 1; k <= n; k++)
{
if (FLINT_TINY_DIVISORS_LOOKUP[n] & (UWORD(1) << k))
{
fmpz_poly_set_coeff_si(res, i, k);
i++;
}
}
_fmpz_poly_set_length(res, size);
return;
}
void
arith_divisors(fmpz_poly_t res, const fmpz_t n)
{
slong i, size, m;
fmpz_factor_t factors;
if (!COEFF_IS_MPZ(*n))
{
m = fmpz_get_si(n);
if (-FLINT_NUM_TINY_DIVISORS < m && m < FLINT_NUM_TINY_DIVISORS)
{
_arith_divisors_tiny(res, FLINT_ABS(m));
return;
}
}
fmpz_factor_init(factors);
fmpz_factor(factors, n);
/* TODO: check for overflow for huge n */
size = 1;
for (i = 0; i < factors->num; i++)
size *= factors->exp[i] + 1;
fmpz_poly_fit_length(res, size);
_arith_divisors(res->coeffs, size, factors);
_fmpz_poly_set_length(res, size);
_fmpz_vec_sort(res->coeffs, size);
fmpz_factor_clear(factors);
}

876
external/flint-2.4.3/arith/doc/arith.txt vendored Normal file
View File

@ -0,0 +1,876 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010, 2011 Fredrik Johansson
******************************************************************************/
*******************************************************************************
Primorials
*******************************************************************************
void arith_primorial(fmpz_t res, slong n)
Sets \code{res} to ``$n$ primorial'' or $n \#$, the product of all prime
numbers less than or equal to $n$.
*******************************************************************************
Harmonic numbers
*******************************************************************************
void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n)
Sets \code{(num, den)} to the reduced numerator and denominator of
the $n$-th harmonic number $H_n = 1 + 1/2 + 1/3 + \dotsb + 1/n$. The
result is zero if $n \leq 0$.
Table lookup is used for $H_n$ whose numerator and denominator
fit in single limb. For larger $n$, the function
\code{flint_mpn_harmonic_odd_balanced()} is used.
void arith_harmonic_number(fmpq_t x, slong n)
Sets \code{x} to the $n$-th harmonic number. This function is
equivalent to \code{_arith_harmonic_number} apart from the output
being a single \code{fmpq_t} variable.
*******************************************************************************
Stirling numbers
*******************************************************************************
void arith_stirling_number_1u(fmpz_t s, slong n, slong k)
void arith_stirling_number_1(fmpz_t s, slong n, slong k)
void arith_stirling_number_2(fmpz_t s, slong n, slong k)
Sets $s$ to $S(n,k)$ where $S(n,k)$ denotes an unsigned Stirling
number of the first kind $|S_1(n, k)|$, a signed Stirling number
of the first kind $S_1(n, k)$, or a Stirling number of the second
kind $S_2(n, k)$. The Stirling numbers are defined using the
generating functions
\begin{align*}
x_{(n)} & = \sum_{k=0}^n S_1(n,k) x^k \\
x^{(n)} & = \sum_{k=0}^n |S_1(n,k)| x^k \\
x^n & = \sum_{k=0}^n S_2(n,k) x_{(k)}
\end{align*}
where $x_{(n)} = x(x-1)(x-2) \dotsm (x-n+1)$ is a falling factorial
and $x^{(n)} = x(x+1)(x+2) \dotsm (x+n-1)$ is a rising factorial.
$S(n,k)$ is taken to be zero if $n < 0$ or $k < 0$.
These three functions are useful for computing isolated Stirling
numbers efficiently. To compute a range of numbers, the vector or
matrix versions should generally be used.
void arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen)
void arith_stirling_number_1_vec(fmpz * row, slong n, slong klen)
void arith_stirling_number_2_vec(fmpz * row, slong n, slong klen)
Computes the row of Stirling numbers
\code{S(n,0), S(n,1), S(n,2), ..., S(n,klen-1)}.
To compute a full row, this function can be called with
\code{klen = n+1}. It is assumed that \code{klen} is at most $n + 1$.
void arith_stirling_number_1u_vec_next(fmpz * row, fmpz * prev, slong n,
slong klen)
void arith_stirling_number_1_vec_next(fmpz * row, fmpz * prev, slong n,
slong klen)
void arith_stirling_number_2_vec_next(fmpz * row, fmpz * prev, slong n,
slong klen)
Given the vector \code{prev} containing a row of Stirling numbers
\code{S(n-1,0), S(n-1,1), S(n-1,2), ..., S(n-1,klen-1)}, computes
and stores in the row argument
\code{S(n,0), S(n,1), S(n,2), ..., S(n,klen-1)}.
If \code{klen} is greater than \code{n}, the output ends with
\code{S(n,n) = 1} followed by \code{S(n,n+1) = S(n,n+2) = ... = 0}.
In this case, the input only needs to have length \code{n-1};
only the input entries up to \code{S(n-1,n-2)} are read.
The \code{row} and \code{prev} arguments are permitted to be the
same, meaning that the row will be updated in-place.
void arith_stirling_matrix_1u(fmpz_mat_t mat)
void arith_stirling_matrix_1(fmpz_mat_t mat)
void arith_stirling_matrix_2(fmpz_mat_t mat)
For an arbitrary $m$-by-$n$ matrix, writes the truncation of the
infinite Stirling number matrix
\begin{lstlisting}
row 0 : S(0,0)
row 1 : S(1,0), S(1,1)
row 2 : S(2,0), S(2,1), S(2,2)
row 3 : S(3,0), S(3,1), S(3,2), S(3,3)
\end{lstlisting}
up to row $m-1$ and column $n-1$ inclusive. The upper triangular
part of the matrix is zeroed.
For any $n$, the $S_1$ and $S_2$ matrices thus obtained are
inverses of each other.
*******************************************************************************
Bell numbers
*******************************************************************************
void arith_bell_number(fmpz_t b, ulong n)
Sets $b$ to the Bell number $B_n$, defined as the
number of partitions of a set with $n$ members. Equivalently,
$B_n = \sum_{k=0}^n S_2(n,k)$ where $S_2(n,k)$ denotes a Stirling number
of the second kind.
This function automatically selects between table lookup, binary
splitting, and the multimodular algorithm.
void arith_bell_number_bsplit(fmpz_t res, ulong n)
Computes the Bell number $B_n$ by evaluating a precise truncation of
the series $B_n = e^{-1} \sum_{k=0}^{\infty} \frac{k^n}{k!}$ using
binary splitting.
void arith_bell_number_multi_mod(fmpz_t res, ulong n)
Computes the Bell number $B_n$ using a multimodular algorithm.
This function evaluates the Bell number modulo several limb-size
primes using\\ \code{arith_bell_number_nmod} and reconstructs the integer
value using the fast Chinese remainder algorithm.
A bound for the number of needed primes is computed using
\code{arith_bell_number_size}.
void arith_bell_number_vec(fmpz * b, slong n)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive. Automatically switches between the \code{recursive}
and \code{multi_mod} algorithms depending on the size of $n$.
void arith_bell_number_vec_recursive(fmpz * b, slong n)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive. This function uses table lookup if $B_{n-1}$ fits in a
single word, and a standard triangular recurrence otherwise.
void arith_bell_number_vec_multi_mod(fmpz * b, slong n)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive.
This function evaluates the Bell numbers modulo several limb-size
primes using\\ \code{arith_bell_number_nmod_vec} and reconstructs the
integer values using the fast Chinese remainder algorithm.
A bound for the number of needed primes is computed using
\code{arith_bell_number_size}.
mp_limb_t bell_number_nmod(ulong n, nmod_t mod)
Computes the Bell number $B_n$ modulo a prime $p$ given by \code{mod}
After handling special cases, we use the formula
$$B_n = \sum_{k=0}^n \frac{(n-k)^n}{(n-k)!}
\sum_{j=0}^k \frac{(-1)^j}{j!}.$$
We arrange the operations in such a way that we only have to
multiply (and not divide) in the main loop. As a further optimisation,
we use sieving to reduce the number of powers that need to be
evaluated. This results in $O(n)$ memory usage.
The divisions by factorials require $n > p$, so we fall back to
calling\\ \code{bell_number_nmod_vec_recursive} and reading off the
last entry when $p \le n$.
void arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive modulo a prime $p$ given by \code{mod}. Automatically
switches between the \code{recursive} and \code{series} algorithms
depending on the size of $n$ and whether $p$ is large enough for the
series algorithm to work.
void arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive modulo a prime $p$ given by \code{mod}. This function uses
table lookup if $B_{n-1}$ fits in a single word, and a standard
triangular recurrence otherwise.
void arith_bell_number_nmod_vec_series(mp_ptr b, slong n, nmod_t mod)
Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$
inclusive modulo a prime $p$ given by \code{mod}. This function
expands the exponential generating function
$$\sum_{k=0}^{\infty} \frac{B_n}{n!} x^n = \exp(e^x-1).$$
We require that $p \ge n$.
double arith_bell_number_size(ulong n)
Returns $b$ such that $B_n < 2^{\lfloor b \rfloor}$, using the inequality
$$B_n < \left(\frac{0.792n}{\log(n+1)}\right)^n$$
which is given in \cite{BerTas2010}.
*******************************************************************************
Bernoulli numbers and polynomials
*******************************************************************************
void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n)
Sets \code{(num, den)} to the reduced numerator and denominator
of the $n$-th Bernoulli number. As presently implemented,
this function simply calls\\ \code{_arith_bernoulli_number_zeta}.
void arith_bernoulli_number(fmpq_t x, ulong n)
Sets \code{x} to the $n$-th Bernoulli number. This function is
equivalent to\\ \code{_arith_bernoulli_number} apart from the output
being a single \code{fmpq_t} variable.
void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n)
Sets the elements of \code{num} and \code{den} to the reduced
numerators and denominators of the Bernoulli numbers
$B_0, B_1, B_2, \ldots, B_{n-1}$ inclusive. This function automatically
chooses between the \code{recursive}, \code{zeta} and \code{multi_mod}
algorithms according to the size of $n$.
void arith_bernoulli_number_vec(fmpq * x, slong n)
Sets the \code{x} to the vector of Bernoulli numbers
$B_0, B_1, B_2, \ldots, B_{n-1}$ inclusive. This function is
equivalent to \code{_arith_bernoulli_number_vec} apart
from the output being a single \code{fmpq} vector.
void arith_bernoulli_number_denom(fmpz_t den, ulong n)
Sets \code{den} to the reduced denominator of the $n$-th
Bernoulli number $B_n$. For even $n$, the denominator is computed
as the product of all primes $p$ for which $p - 1$ divides $n$;
this property is a consequence of the von Staudt-Clausen theorem.
For odd $n$, the denominator is trivial (\code{den} is set to 1 whenever
$B_n = 0$). The initial sequence of values smaller than $2^{32}$ are
looked up directly from a table.
double arith_bernoulli_number_size(ulong n)
Returns $b$ such that $|B_n| < 2^{\lfloor b \rfloor}$, using the inequality
$$|B_n| < \frac{4 n!}{(2\pi)^n}$$ and $n! \le (n+1)^{n+1} e^{-n}$.
No special treatment is given to odd $n$. Accuracy is not guaranteed
if $n > 10^{14}$.
void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n)
Sets \code{poly} to the Bernoulli polynomial of degree $n$,
$B_n(x) = \sum_{k=0}^n \binom{n}{k} B_k x^{n-k}$ where $B_k$
is a Bernoulli number. This function basically calls
\code{arith_bernoulli_number_vec} and then rescales the coefficients
efficiently.
void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n)
Sets \code{(num, den)} to the reduced numerator and denominator
of the $n$-th Bernoulli number.
This function first computes the exact denominator and a bound
for the size of the numerator. It then computes an approximation
of $|B_n| = 2n! \zeta(n) / (2 \pi)^n$ as a floating-point number
and multiplies by the denominator to to obtain a real number
that rounds to the exact numerator. For tiny $n$, the numerator
is looked up from a table to avoid unnecessary overhead.
void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n)
Sets the elements of \code{num} and \code{den} to the reduced
numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$
inclusive.
The first few entries are computed using \code{arith_bernoulli_number},
and then Ramanujan's recursive formula expressing $B_m$ as a sum over
$B_k$ for $k$ congruent to $m$ modulo 6 is applied repeatedly.
To avoid costly GCDs, the numerators are transformed internally
to a common denominator and all operations are performed using
integer arithmetic. This makes the algorithm fast for small $n$,
say $n < 1000$. The common denominator is calculated directly
as the primorial of $n + 1$.
%[1] http://en.wikipedia.org/w/index.php?
% title=Bernoulli_number&oldid=405938876
void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n)
Sets the elements of \code{num} and \code{den} to the reduced
numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$
inclusive. Uses repeated direct calls to\\
\code{_arith_bernoulli_number_zeta}.
void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n)
Sets the elements of \code{num} and \code{den} to the reduced
numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$
inclusive. Uses the generating function
$$\frac{x^2}{\cosh(x)-1} = \sum_{k=0}^{\infty}
\frac{(2-4k) B_{2k}}{(2k)!} x^{2k}$$
which is evaluated modulo several limb-size primes using \code{nmod_poly}
arithmetic to yield the numerators of the Bernoulli numbers after
multiplication by the denominators and CRT reconstruction. This formula,
given (incorrectly) in \citep{BuhlerCrandallSompolski1992}, saves about
half of the time compared to the usual generating function $x/(e^x-1)$
since the odd terms vanish.
*******************************************************************************
Euler numbers and polynomials
Euler numbers are the integers $E_n$ defined by
$$\frac{1}{\cosh(t)} = \sum_{n=0}^{\infty} \frac{E_n}{n!} t^n.$$
With this convention, the odd-indexed numbers are zero and the even
ones alternate signs, viz.
$E_0, E_1, E_2, \ldots = 1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, \ldots$.
The corresponding Euler polynomials are defined by
$$\frac{2e^{xt}}{e^t+1} = \sum_{n=0}^{\infty} \frac{E_n(x)}{n!} t^n.$$
*******************************************************************************
void arith_euler_number(fmpz_t res, ulong n)
Sets \code{res} to the Euler number $E_n$. Currently calls
\code{_arith_euler_number_zeta}.
void arith_euler_number_vec(fmpz * res, slong n)
Computes the Euler numbers $E_0, E_1, \dotsc, E_{n-1}$ for $n \geq 0$
and stores the result in \code{res}, which must be an initialised
\code{fmpz} vector of sufficient size.
This function evaluates the even-index $E_k$ modulo several limb-size
primes using the generating function and \code{nmod_poly} arithmetic.
A tight bound for the number of needed primes is computed using
\code{arith_euler_number_size}, and the final integer values are recovered
using balanced CRT reconstruction.
double arith_euler_number_size(ulong n)
Returns $b$ such that $|E_n| < 2^{\lfloor b \rfloor}$, using the inequality
$$|E_n| < \frac{2^{n+2} n!}{\pi^{n+1}}$$ and $n! \le (n+1)^{n+1} e^{-n}$.
No special treatment is given to odd $n$.
Accuracy is not guaranteed if $n > 10^{14}$.
void euler_polynomial(fmpq_poly_t poly, ulong n)
Sets \code{poly} to the Euler polynomial $E_n(x)$. Uses the formula
$$E_n(x) = \frac{2}{n+1}\left(B_{n+1}(x) -
2^{n+1}B_{n+1}\left(\frac{x}{2}\right)\right),$$
with the Bernoulli polynomial $B_{n+1}(x)$ evaluated once
using \code{bernoulli_polynomial} and then rescaled.
void _arith_euler_number_zeta(fmpz_t res, ulong n)
Sets \code{res} to the Euler number $E_n$. For even $n$, this function
uses the relation $$|E_n| = \frac{2^{n+2} n!}{\pi^{n+1}} L(n+1)$$
where $L(n+1)$ denotes the Dirichlet $L$-function with character
$\chi = \{ 0, 1, 0, -1 \}$.
*******************************************************************************
Legendre polynomials
*******************************************************************************
void arith_legendre_polynomial(fmpq_poly_t poly, ulong n)
Sets \code{poly} to the $n$-th Legendre polynomial
$$P_n(x) = \frac{1}{2^n n!} \frac{d^n}{dx^n} \left[
\left(x^2-1\right)^n \right].$$
The coefficients are calculated using a hypergeometric recurrence.
To improve performance, the common denominator is computed in one step
and the coefficients are evaluated using integer arithmetic. The
denominator is given by
$\gcd(n!,2^n) = 2^{\lfloor n/2 \rfloor + \lfloor n/4 \rfloor + \ldots}.$
void arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n)
Sets \code{poly} to the Chebyshev polynomial of the first kind $T_n(x)$,
defined formally by $T_n(x) = \cos(n \cos^{-1}(x))$. The coefficients are
calculated using a hypergeometric recurrence.
void arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n)
Sets \code{poly} to the Chebyshev polynomial of the first kind $U_n(x)$,
which satisfies $(n+1) U_n(x) = T'_{n+1}(x)$.
The coefficients are calculated using a hypergeometric recurrence.
*******************************************************************************
Multiplicative functions
*******************************************************************************
void arith_euler_phi(fmpz_t res, const fmpz_t n)
Sets \code{res} to the Euler totient function $\phi(n)$, counting the
number of positive integers less than or equal to $n$ that are coprime
to $n$.
int arith_moebius_mu(const fmpz_t n)
Computes the Moebius function $\mu(n)$, which is defined as $\mu(n) = 0$
if $n$ has a prime factor of multiplicity greater than $1$, $\mu(n) = -1$
if $n$ has an odd number of distinct prime factors, and $\mu(n) = 1$ if
$n$ has an even number of distinct prime factors. By convention,
$\mu(0) = 0$.
void arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k)
Sets \code{res} to $\sigma_k(n)$, the sum of $k$th powers of all
divisors of $n$.
void arith_divisors(fmpz_poly_t res, const fmpz_t n)
Set the coefficients of the polynomial \code{res} to the divisors of $n$,
including $1$ and $n$ itself, in ascending order.
void arith_ramanujan_tau(fmpz_t res, const fmpz_t n)
Sets \code{res} to the Ramanujan tau function $\tau(n)$ which is the
coefficient of $q^n$ in the series expansion of
$f(q) = q \prod_{k \geq 1} \bigl(1 - q^k\bigr)^{24}$.
We factor $n$ and use the identity $\tau(pq) = \tau(p) \tau(q)$
along with the recursion
$\tau(p^{r+1}) = \tau(p) \tau(p^r) - p^{11} \tau(p^{r-1})$
for prime powers.
The base values $\tau(p)$ are obtained using the function
\code{arith_ramanujan_tau_series()}. Thus the speed of
\code{arith_ramanujan_tau()} depends on the largest prime factor of $n$.
Future improvement: optimise this function for small $n$, which
could be accomplished using a lookup table or by calling
\code{arith_ramanujan_tau_series()} directly.
void arith_ramanujan_tau_series(fmpz_poly_t res, slong n)
Sets \code{res} to the polynomial with coefficients
$\tau(0),\tau(1), \dotsc, \tau(n-1)$, giving the initial $n$ terms
in the series expansion of
$f(q) = q \prod_{k \geq 1} \bigl(1-q^k\bigr)^{24}$.
We use the theta function identity
\begin{equation*}
f(q) = q \Biggl( \sum_{k \geq 0} (-1)^k (2k+1) q^{k(k+1)/2} \Biggr)^8
\end{equation*}
which is evaluated using three squarings. The first squaring is done
directly since the polynomial is very sparse at this point.
*******************************************************************************
Cyclotomic polynomials
*******************************************************************************
void _arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors,
slong num_factors, ulong phi)
Sets \code{a} to the lower half of the cyclotomic polynomial $\Phi_n(x)$,
given $n \ge 3$ which must be squarefree.
A precomputed array containing the prime factors of $n$ must be provided,
as well as the value of the Euler totient function $\phi(n)$ as \code{phi}.
If $n$ is even, 2 must be the first factor in the list.
The degree of $\Phi_n(x)$ is exactly $\phi(n)$. Only the low
$(\phi(n) + 1) / 2$ coefficients are written; the high coefficients
can be obtained afterwards by copying the low coefficients
in reverse order, since $\Phi_n(x)$ is a palindrome for $n \ne 1$.
We use the sparse power series algorithm described as Algorithm 4
\cite{ArnoldMonagan2011}. The algorithm is based on the identity
$$\Phi_n(x) = \prod_{d|n} (x^d - 1)^{\mu(n/d)}.$$
Treating the polynomial as a power series, the multiplications and
divisions can be done very cheaply using repeated additions and
subtractions. The complexity is $O(2^k \phi(n))$ where $k$ is the
number of prime factors in $n$.
To improve efficiency for small $n$, we treat the \code{fmpz}
coefficients as machine integers when there is no risk of overflow.
The following bounds are given in Table 6 of \cite{ArnoldMonagan2011}:
For $n < 10163195$, the largest coefficient in any $\Phi_n(x)$
has 27 bits, so machine arithmetic is safe on 32 bits.
For $n < 169828113$, the largest coefficient in any $\Phi_n(x)$
has 60 bits, so machine arithmetic is safe on 64 bits.
Further, the coefficients are always $\pm 1$ or 0 if there are
exactly two prime factors, so in this case machine arithmetic can be
used as well.
Finally, we handle two special cases: if there is exactly one prime
factor $n = p$, then $\Phi_n(x) = 1 + x + x^2 + \ldots + x^{n-1}$,
and if $n = 2m$, we use $\Phi_n(x) = \Phi_m(-x)$ to fall back
to the case when $n$ is odd.
void arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n)
Sets \code{poly} to the $n$th cyclotomic polynomial, defined as
$$\Phi_n(x) = \prod_{\omega} (x-\omega)$$
where $\omega$ runs over all the $n$th primitive roots of unity.
We factor $n$ into $n = qs$ where $q$ is squarefree,
and compute $\Phi_q(x)$. Then $\Phi_n(x) = \Phi_q(x^s)$.
void _arith_cos_minpoly(fmpz * coeffs, slong d, ulong n)
For $n \ge 1$, sets \code{(coeffs, d+1)} to the minimal polynomial
$\Psi_n(x)$ of $\cos(2 \pi / n)$, scaled to have integer coefficients
by multiplying by $2^d$ ($2^{d-1}$ when $n$ is a power of two).
The polynomial $\Psi_n(x)$ is described in \cite{WaktinsZeitlin1993}.
As proved in that paper, the roots of $\Psi_n(x)$ for $n \ge 3$ are
$\cos(2 \pi k / n)$ where $0 \le k < d$ and where $\gcd(k, n) = 1$.
To calculate $\Psi_n(x)$, we compute the roots numerically with MPFR
and use a balanced product tree to form a polynomial with fixed-point
coefficients, i.e. an approximation of $2^p 2^d \Psi_n(x)$.
To determine the precision $p$, we note that the coefficients
in $\prod_{i=1}^d (x - \alpha)$ can be bounded by the central
coefficient in the binomial expansion of $(x+1)^d$.
When $n$ is an odd prime, we use a direct formula for the coefficients
(\url{http://mathworld.wolfram.com/TrigonometryAngles.html}).
void arith_cos_minpoly(fmpz_poly_t poly, ulong n)
Sets \code{poly} to the minimal polynomial $\Psi_n(x)$ of
$\cos(2 \pi / n)$, scaled to have integer coefficients. This
polynomial has degree 1 if $n = 1$ or $n = 2$, and
degree $\phi(n) / 2$ otherwise.
We allow $n = 0$ and define $\Psi_0 = 1$.
*******************************************************************************
Swinnerton-Dyer polynomials
*******************************************************************************
void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n)
Sets \code{poly} to the Swinnerton-Dyer polynomial $S_n$, defined as
the integer polynomial
$$S_n = \prod (x \pm \sqrt{2} \pm \sqrt{3}
\pm \sqrt{5} \pm \ldots \pm \sqrt{p_n})$$
where $p_n$ denotes the $n$-th prime number and all combinations
of signs are taken. This polynomial has degree $2^n$ and is
irreducible over the integers.
*******************************************************************************
Landau's function
*******************************************************************************
void arith_landau_function_vec(fmpz * res, slong len)
Computes the first \code{len} values of Landau's function $g(n)$
starting with $g(0)$. Landau's function gives the largest order
of an element of the symmetric group $S_n$.
Implements the ``basic algorithm'' given in
\cite{DelegliseNicolasZimmermann2009}. The running time is
$O(n^{3/2} / \sqrt{\log n})$.
*******************************************************************************
Dedekind sums
Most of the definitions and relations used in the following section
are given by Apostol \cite{Apostol1997}. The Dedekind sum $s(h,k)$ is
defined for all integers $h$ and $k$ as
$$s(h,k) = \sum_{i=1}^{k-1} \left(\left(\frac{i}{k}\right)\right)
\left(\left(\frac{hi}{k}\right)\right)$$
where
$$((x))=\begin{cases}
x-\lfloor x\rfloor-1/2 &\mbox{if }
x\in\mathbb{Q}\setminus\mathbb{Z}\\
0 &\mbox{if }x\in\mathbb{Z}.
\end{cases}$$
If $0 < h < k$ and $(h,k) = 1$, this reduces to
$$s(h,k) = \sum_{i=1}^{k-1} \frac{i}{k}
\left(\frac{hi}{k}-\left\lfloor\frac{hi}{k}\right\rfloor
-\frac{1}{2}\right).$$
The main formula for evaluating the series above is the following.
Letting $r_0 = k$, $r_1 = h$, $r_2, r_3, \ldots, r_n, r_{n+1} = 1$
be the remainder sequence in the Euclidean algorithm for
computing GCD of $h$ and $k$,
$$s(h,k) = \frac{1-(-1)^n}{8} - \frac{1}{12} \sum_{i=1}^{n+1}
(-1)^i \left(\frac{1+r_i^2+r_{i-1}^2}{r_i r_{i-1}}\right).$$
Writing $s(h,k) = p/q$, some useful properties employed are
$|s| < k / 12$, $q | 6k$ and $2|p| < k^2$.
*******************************************************************************
void arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k)
Computes $s(h,k)$ for arbitrary $h$ and $k$ using a straightforward
implementation of the defining sum using \code{fmpz} arithmetic.
This function is slow except for very small $k$ and is mainly
intended to be used for testing purposes.
double arith_dedekind_sum_coprime_d(double h, double k)
Returns an approximation of $s(h,k)$ computed by evaluating the
remainder sequence sum using double-precision arithmetic.
Assumes that $0 < h < k$ and $(h,k) = 1$, and that $h$, $k$ and
their remainders can be represented exactly as doubles, e.g.
$k < 2^{53}$.
We give a rough error analysis with IEEE double precision arithmetic,
assuming $2 k^2 < 2^{53}$. By assumption, the terms in the sum evaluate
exactly apart from the division. Thus each term is bounded in magnitude
by $2k$ and its absolute error is bounded by $k 2^{-52}$.
By worst-case analysis of the Euclidean algorithm, we also know that
no more than 40 terms will be added.
It follows that the absolute error is at most $C k 2^{-53}$ for
some constant $C$. If we multiply the output by $6 k$ in order
to obtain an integer numerator, the order of magnitude of the error
is around $6 C k^2 2^{-53}$, so rounding to the nearest integer gives
a correct numerator whenever $k < 2^{26-d}$ for some small number of
guard bits $d$. A computation has shown that $d = 5$ is sufficient,
i.e. this function can be used for exact computation when
$k < 2^{21} \approx 2 \times 10^6$. This bound can likely be improved.
void arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k)
Computes $s(h,k)$ for $h$ and $k$ satisfying $0 \le h \le k$ and
$(h,k) = 1$. This function effectively evaluates the remainder
sequence sum using \code{fmpz} arithmetic, without optimising for
any special cases. To avoid rational arithmetic, we use
the integer algorithm of Knuth \cite{Knuth1977}.
void arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k)
Computes $s(h,k)$ for $h$ and $k$ satisfying $0 \le h \le k$
and $(h,k) = 1$.
This function calls \code{arith_dedekind_sum_coprime_d} if $k$ is small
enough for a double-precision estimate of the sum to yield a correct
numerator upon multiplication by $6k$ and rounding to the nearest integer.
Otherwise, it calls \code{arith_dedekind_sum_coprime_large}.
void arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k)
Computes $s(h,k)$ for arbitrary $h$ and $k$. If the caller
can guarantee $0 < h < k$ and $(h,k) = 1$ ahead of time, it is always
cheaper to call \code{arith_dedekind_sum_coprime}.
This function uses the following identities to reduce the general
case to the situation where $0 < h < k$ and $(h,k) = 1$:
If $k \le 2$ or $h = 0$, $s(h,k) = 0$.
If $h < 0$, $s(h,k) = -s(-h,k)$.
For any $q > 0$, $s(qh,qk) = s(h,k)$.
If $0 < k < h$ and $(h,k) = 1$,
$s(h,k) = (1+h(h-3k)+k^2) / (12hk) - t(k,h).$
*******************************************************************************
Number of partitions
*******************************************************************************
void arith_number_of_partitions_vec(fmpz * res, slong len)
Computes first \code{len} values of the partition function $p(n)$
starting with $p(0)$. Uses inversion of Euler's pentagonal series.
void arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod)
Computes first \code{len} values of the partition function $p(n)$
starting with $p(0)$, modulo the modulus defined by \code{mod}.
Uses inversion of Euler's pentagonal series.
void arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n)
Symbolically evaluates the exponential sum
$$A_k(n) = \sum_{h=0}^{k-1}
\exp\left(\pi i \left[ s(h,k) - \frac{2hn}{k}\right]\right)$$
appearing in the Hardy-Ramanujan-Rademacher formula, where $s(h,k)$ is a
Dedekind sum.
Rather than evaluating the sum naively, we factor $A_k(n)$ into a
product of cosines based on the prime factorisation of $k$. This
process is based on the identities given in \cite{Whiteman1956}.
The special \code{trig_prod_t} structure \code{prod} represents a
product of cosines of rational arguments, multiplied by an algebraic
prefactor. It must be pre-initialised with \code{trig_prod_init}.
This function assumes that $24k$ and $24n$ do not overflow a single limb.
If $n$ is larger, it can be pre-reduced modulo $k$, since $A_k(n)$
only depends on the value of $n \bmod k$.
void arith_number_of_partitions_mpfr(mpfr_t x, ulong n)
Sets the pre-initialised MPFR variable $x$ to the exact value of $p(n)$.
The value is computed using the Hardy-Ramanujan-Rademacher formula.
The precision of $x$ will be changed to allow $p(n)$ to be represented
exactly. The interface of this function may be updated in the future
to allow computing an approximation of $p(n)$ to smaller precision.
The Hardy-Ramanujan-Rademacher formula is given with error bounds
in \cite{Rademacher1937}. We evaluate it in the form
$$p(n) = \sum_{k=1}^N B_k(n) U(C/k) + R(n,N)$$
where
$$U(x) = \cosh(x) + \frac{\sinh(x)}{x},
\quad C = \frac{\pi}{6} \sqrt{24n-1}$$
$$B_k(n) = \sqrt{\frac{3}{k}} \frac{4}{24n-1} A_k(n)$$
and where $A_k(n)$ is a certain exponential sum. The remainder satisfies
$$|R(n,N)| < \frac{44 \pi^2}{225 \sqrt{3}} N^{-1/2} +
\frac{\pi \sqrt{2}}{75} \left(\frac{N}{n-1}\right)^{1/2}
\sinh\left(\pi \sqrt{\frac{2}{3}} \frac{\sqrt{n}}{N} \right).$$
We choose $N$ such that $|R(n,N)| < 0.25$, and a working precision
at term $k$ such that the absolute error of the term is expected to be
less than $0.25 / N$. We also use a summation variable with increased
precision, essentially making additions exact. Thus the sum of errors
adds up to less than 0.5, giving the correct value of $p(n)$ when
rounding to the nearest integer.
The remainder estimate at step $k$ provides an upper bound for the size
of the $k$-th term. We add $\log_2 N$ bits to get low bits in the terms
below $0.25 / N$ in magnitude.
Using \code{arith_hrr_expsum_factored}, each $B_k(n)$ evaluation
is broken down to a product of cosines of exact rational multiples
of $\pi$. We transform all angles to $(0, \pi/4)$ for optimal accuracy.
Since the evaluation of each term involves only $O(\log k)$ multiplications
and evaluations of trigonometric functions of small angles, the
relative rounding error is at most a few bits. We therefore just add
an additional $\log_2 (C/k)$ bits for the $U(x)$ when $x$ is large.
The cancellation of terms in $U(x)$ is of no concern, since Rademacher's
bound allows us to terminate before $x$ becomes small.
This analysis should be performed in more detail to give a rigorous
error bound, but the precision currently implemented is almost
certainly sufficient, not least considering that Rademacher's
remainder bound significantly overshoots the actual values.
To improve performance, we switch to doubles when the working precision
becomes small enough. We also use a separate accumulator variable
which gets added to the main sum periodically, in order to avoid
costly updates of the full-precision result when $n$ is large.
void arith_number_of_partitions(fmpz_t x, ulong n)
Sets $x$ to $p(n)$, the number of ways that $n$ can be written
as a sum of positive integers without regard to order.
This function uses a lookup table for $n < 128$ (where $p(n) < 2^{32}$),
and otherwise calls \code{arith_number_of_partitions_mpfr}.
*******************************************************************************
Sums of squares
*******************************************************************************
void arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n)
Sets $r$ to the number of ways $r_k(n)$ in which $n$ can be represented
as a sum of $k$ squares.
If $k = 2$ or $k = 4$, we write $r_k(n)$ as a divisor sum.
Otherwise, we either recurse on $k$ or compute the theta function
expansion up to $O(x^{n+1})$ and read off the last coefficient.
This is generally optimal.
void arith_sum_of_squares_vec(fmpz * r, ulong k, slong n)
For $i = 0, 1, \ldots, n-1$, sets $r_i$ to the number of
representations of $i$ a sum of $k$ squares, $r_k(i)$.
This effectively computes the $q$-expansion of $\vartheta_3(q)$
raised to the $k$th power, i.e.
$$\vartheta_3^k(q) = \left( \sum_{i=-\infty}^{\infty} q^{i^2} \right)^k.$$
*******************************************************************************
MPFR extras
*******************************************************************************
void mpfr_pi_chudnovsky(mpfr_t x, mpfr_rnd_t rnd)
Sets \code{x} to $\pi$, rounded in the direction \code{rnd}.
Uses the Chudnovsky algorithm, which typically is about four times
faster than the MPFR default function. As currently implemented, the
value is not cached for repeated use.

View File

@ -0,0 +1,31 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void arith_euler_number(fmpz_t res, ulong n)
{
_arith_euler_number_zeta(res, n);
}

View File

@ -0,0 +1,38 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
double arith_euler_number_size(ulong n)
{
double x;
x = n + 2;
x += ((n + 1) * log(n + 1) - n) * 1.44269504088897; /* 1/log(2) */
x -= 1.6514961294723*(n+1); /* log2(pi) */
return x + 2;
}

View File

@ -0,0 +1,147 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
/* Computes length-m vector containing |E_{2k}| */
static void
__euler_number_vec_mod_p(mp_ptr res, mp_ptr tmp, slong m, nmod_t mod)
{
mp_limb_t fac, c;
slong k;
/* Divide by factorials */
fac = n_factorial_mod2_preinv(2*(m-1), mod.n, mod.ninv);
c = n_invmod(fac, mod.n);
for (k = m - 1; k >= 0; k--)
{
tmp[k] = c;
c = n_mulmod2_preinv(c, (2*k)*(2*k-1), mod.n, mod.ninv);
}
_nmod_poly_inv_series(res, tmp, m, mod);
/* Multiply by factorials */
c = UWORD(1);
for (k = 0; k < m; k++)
{
res[k] = n_mulmod2_preinv(res[k], c, mod.n, mod.ninv);
c = n_mulmod2_preinv(c, (2*k+1)*(2*k+2), mod.n, mod.ninv);
c = n_negmod(c, mod.n);
}
}
#define CRT_MAX_RESOLUTION 16
void __euler_number_vec_multi_mod(fmpz * res, slong n)
{
fmpz_comb_t comb[CRT_MAX_RESOLUTION];
fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION];
mp_limb_t * primes;
mp_limb_t * residues;
mp_ptr * polys;
mp_ptr temppoly;
nmod_t mod;
slong i, j, k, m, num_primes, num_primes_k, resolution;
mp_bitcnt_t size, prime_bits;
if (n < 1)
return;
/* Number of nonzero entries */
m = (n + 1) / 2;
resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, m / 16));
size = arith_euler_number_size(n);
prime_bits = FLINT_BITS - 1;
num_primes = (size + prime_bits - 1) / prime_bits;
primes = flint_malloc(num_primes * sizeof(mp_limb_t));
residues = flint_malloc(num_primes * sizeof(mp_limb_t));
polys = flint_malloc(num_primes * sizeof(mp_ptr));
/* Compute Euler numbers mod p */
primes[0] = n_nextprime(UWORD(1)<<prime_bits, 0);
for (k = 1; k < num_primes; k++)
primes[k] = n_nextprime(primes[k-1], 0);
temppoly = _nmod_vec_init(m);
for (k = 0; k < num_primes; k++)
{
polys[k] = _nmod_vec_init(m);
nmod_init(&mod, primes[k]);
__euler_number_vec_mod_p(polys[k], temppoly, m, mod);
}
/* Init CRT comb */
for (i = 0; i < resolution; i++)
{
fmpz_comb_init(comb[i], primes, num_primes * (i + 1) / resolution);
fmpz_comb_temp_init(temp[i], comb[i]);
}
/* Trivial entries */
for (k = 1; k < n; k += 2)
fmpz_zero(res + k);
/* Reconstruction */
for (k = 0; k < n; k += 2)
{
size = arith_euler_number_size(k);
/* Use only as large a comb as needed */
num_primes_k = (size + prime_bits - 1) / prime_bits;
for (i = 0; i < resolution; i++)
{
if (comb[i]->num_primes >= num_primes_k)
break;
}
num_primes_k = comb[i]->num_primes;
for (j = 0; j < num_primes_k; j++)
residues[j] = polys[j][k / 2];
fmpz_multi_CRT_ui(res + k, residues, comb[i], temp[i], 0);
if (k % 4)
fmpz_neg(res + k, res + k);
}
/* Cleanup */
for (k = 0; k < num_primes; k++)
_nmod_vec_clear(polys[k]);
_nmod_vec_clear(temppoly);
for (i = 0; i < resolution; i++)
{
fmpz_comb_temp_clear(temp[i]);
fmpz_comb_clear(comb[i]);
}
flint_free(primes);
flint_free(residues);
flint_free(polys);
}
void arith_euler_number_vec(fmpz * res, slong n)
{
__euler_number_vec_multi_mod(res, n);
}

View File

@ -0,0 +1,80 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void _arith_euler_number_zeta(fmpz_t res, ulong n)
{
mpz_t r;
mpfr_t t, z, pi;
mp_bitcnt_t prec, pi_prec;
if (n % 2)
{
fmpz_zero(res);
return;
}
if (n < SMALL_EULER_LIMIT)
{
fmpz_set_ui(res, euler_number_small[n / 2]);
if (n % 4 == 2)
fmpz_neg(res, res);
return;
}
prec = arith_euler_number_size(n) + 10;
pi_prec = prec + FLINT_BIT_COUNT(n);
mpz_init(r);
mpfr_init2(t, prec);
mpfr_init2(z, prec);
mpfr_init2(pi, pi_prec);
flint_mpz_fac_ui(r, n);
mpfr_set_z(t, r, GMP_RNDN);
mpfr_mul_2exp(t, t, n + 2, GMP_RNDN);
/* pi^(n + 1) * L(n+1) */
mpfr_zeta_inv_euler_product(z, n + 1, 1);
mpfr_const_pi(pi, GMP_RNDN);
mpfr_pow_ui(pi, pi, n + 1, GMP_RNDN);
mpfr_mul(z, z, pi, GMP_RNDN);
mpfr_div(t, t, z, GMP_RNDN);
/* round */
mpfr_round(t, t);
mpfr_get_z(r, t, GMP_RNDN);
fmpz_set_mpz(res, r);
if (n % 4 == 2)
fmpz_neg(res, res);
mpz_clear(r);
mpfr_clear(t);
mpfr_clear(z);
mpfr_clear(pi);
}

67
external/flint-2.4.3/arith/euler_phi.c vendored Normal file
View File

@ -0,0 +1,67 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz.h"
#include "arith.h"
void arith_euler_phi(fmpz_t res, const fmpz_t n)
{
fmpz_factor_t factors;
fmpz_t t;
ulong exp;
slong i;
if (fmpz_sgn(n) <= 0)
{
fmpz_zero(res);
return;
}
if (fmpz_abs_fits_ui(n))
{
fmpz_set_ui(res, n_euler_phi(fmpz_get_ui(n)));
return;
}
fmpz_factor_init(factors);
fmpz_factor(factors, n);
fmpz_one(res);
fmpz_init(t);
for (i = 0; i < factors->num; i++)
{
fmpz_sub_ui(t, factors->p + i, UWORD(1));
fmpz_mul(res, res, t);
exp = factors->exp[i];
if (exp != 1)
{
fmpz_pow_ui(t, factors->p + i, exp - UWORD(1));
fmpz_mul(res, res, t);
}
}
fmpz_clear(t);
fmpz_factor_clear(factors);
}

View File

@ -0,0 +1,53 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void arith_euler_polynomial(fmpq_poly_t poly, ulong n)
{
fmpz_t t;
slong k;
if (n == 0)
{
fmpq_poly_set_ui(poly, UWORD(1));
return;
}
arith_bernoulli_polynomial(poly, n + 1);
fmpz_init(t);
fmpz_set_si(t, WORD(-2));
for (k = n; k >= 0; k--)
{
fmpz_mul(poly->coeffs + k, poly->coeffs + k, t);
fmpz_mul_ui(t, t, UWORD(2));
fmpz_sub_ui(t, t, UWORD(2));
}
fmpz_zero(poly->coeffs + n + 1);
fmpz_mul_ui(poly->den, poly->den, n + 1);
fmpq_poly_canonicalise(poly);
fmpz_clear(t);
}

View File

@ -0,0 +1,124 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "mpn_extras.h"
#include "arith.h"
#if FLINT64
#define FLINT_HARMONIC_MAX_TINY 46
#else
#define FLINT_HARMONIC_MAX_TINY 24
#endif
const mp_limb_t FLINT_HARMONIC_TINY_P[] =
{
UWORD(0), UWORD(1), UWORD(3), UWORD(11), UWORD(25), UWORD(137), UWORD(49), UWORD(363), UWORD(761), UWORD(7129), UWORD(7381),
UWORD(83711), UWORD(86021), UWORD(1145993), UWORD(1171733), UWORD(1195757), UWORD(2436559), UWORD(42142223),
UWORD(14274301), UWORD(275295799), UWORD(55835135), UWORD(18858053), UWORD(19093197), UWORD(444316699),
UWORD(1347822955),
#if FLINT64
UWORD(34052522467), UWORD(34395742267), UWORD(312536252003), UWORD(315404588903),
UWORD(9227046511387), UWORD(9304682830147), UWORD(290774257297357), UWORD(586061125622639),
UWORD(53676090078349), UWORD(54062195834749), UWORD(54437269998109), UWORD(54801925434709),
UWORD(2040798836801833), UWORD(2053580969474233), UWORD(2066035355155033),
UWORD(2078178381193813), UWORD(85691034670497533), UWORD(12309312989335019),
UWORD(532145396070491417), UWORD(5884182435213075787), UWORD(5914085889685464427),
UWORD(5943339269060627227),
#endif
};
const mp_limb_t FLINT_HARMONIC_TINY_Q[] =
{
UWORD(1), UWORD(1), UWORD(2), UWORD(6), UWORD(12), UWORD(60), UWORD(20), UWORD(140), UWORD(280), UWORD(2520), UWORD(2520),
UWORD(27720), UWORD(27720), UWORD(360360), UWORD(360360), UWORD(360360), UWORD(720720), UWORD(12252240),
UWORD(4084080), UWORD(77597520), UWORD(15519504), UWORD(5173168), UWORD(5173168), UWORD(118982864),
UWORD(356948592),
#if FLINT64
UWORD(8923714800), UWORD(8923714800), UWORD(80313433200), UWORD(80313433200), UWORD(2329089562800),
UWORD(2329089562800), UWORD(72201776446800), UWORD(144403552893600), UWORD(13127595717600),
UWORD(13127595717600), UWORD(13127595717600), UWORD(13127595717600), UWORD(485721041551200),
UWORD(485721041551200), UWORD(485721041551200), UWORD(485721041551200),
UWORD(19914562703599200), UWORD(2844937529085600), UWORD(122332313750680800),
UWORD(1345655451257488800), UWORD(1345655451257488800), UWORD(1345655451257488800),
#endif
};
static void
_mpq_harmonic_odd_balanced(fmpz_t num, fmpz_t den, slong n)
{
mpz_t p, q;
mp_ptr t, v;
mp_size_t ts, vs;
slong size;
if (n <= 0)
{
fmpz_zero(num);
fmpz_one(den);
return;
}
/* TODO: we could avoid the copying/allocation overhead when there
is guaranteed to be sufficient space in res already */
size = FLINT_BIT_COUNT(n) * (n+2) + 2*FLINT_BITS;
mpz_init2(p, size);
mpz_init2(q, size);
t = p->_mp_d;
v = q->_mp_d;
flint_mpn_harmonic_odd_balanced(t, &ts, v, &vs, 1, n+1, n, 1);
p->_mp_size = ts;
q->_mp_size = vs;
fmpz_set_mpz(num, p);
fmpz_set_mpz(den, q);
mpz_clear(p);
mpz_clear(q);
_fmpq_canonicalise(num, den);
}
void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n)
{
n = FLINT_MAX(n, 0);
if (n <= FLINT_HARMONIC_MAX_TINY)
{
fmpz_set_ui(num, FLINT_HARMONIC_TINY_P[n]);
fmpz_set_ui(den, FLINT_HARMONIC_TINY_Q[n]);
}
else
{
_mpq_harmonic_odd_balanced(num, den, n);
}
}
void arith_harmonic_number(fmpq_t x, slong n)
{
_arith_harmonic_number(fmpq_numref(x), fmpq_denref(x), n);
}

View File

@ -0,0 +1,68 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
void arith_landau_function_vec(fmpz * res, slong len)
{
mp_limb_t p, pmax;
mp_limb_t pk, pkhi;
fmpz_t a;
ulong k, n;
if (len < 1)
return;
for (k = 0; k < len; k++)
fmpz_one(res + k);
pmax = 1.328 * sqrt(len*log(len) + 1);
fmpz_init(a);
for (p = UWORD(2); p <= pmax; p = n_nextprime(p, 0))
{
for (n = len - 1; n >= p; n--)
{
pk = p;
pkhi = UWORD(0);
for (k = 1; k <= len; k++)
{
if (pk > n || pkhi)
break;
fmpz_mul_ui(a, res + n - pk, pk);
if (fmpz_cmp(res + n, a) < 0)
fmpz_set(res + n, a);
umul_ppmm(pkhi, pk, pk, p);
}
}
}
fmpz_clear(a);
}

View File

@ -0,0 +1,97 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static __inline__ void __legendre_denom(fmpz_t den, ulong n)
{
ulong d, k;
d = k = n >> 1;
while (k)
{
k >>= 1;
d += k;
}
fmpz_one(den);
fmpz_mul_2exp(den, den, d);
}
void _arith_legendre_polynomial(fmpz * coeffs, fmpz_t den, ulong n)
{
fmpz * r;
int odd;
slong k;
ulong L;
L = n / 2;
odd = n % 2;
r = coeffs + odd;
__legendre_denom(den, n);
fmpz_bin_uiui(r, n, L);
fmpz_mul(r, r, den);
if (odd)
fmpz_mul_ui(r, r, L + 1);
fmpz_fdiv_q_2exp(r, r, 2*L);
if (L % 2)
fmpz_neg(r, r);
for (k = 1; k <= L; k++)
{
fmpz_mul2_uiui(r + 2, r, L + 1 - k, 2*k + 2*L - 1 + 2*odd);
fmpz_divexact2_uiui(r + 2, r + 2, k, 2*k - 1 + 2*odd);
fmpz_neg(r + 2, r + 2);
r += 2;
}
for (k = 1 - odd; k < n; k += 2)
fmpz_zero(coeffs + k);
}
void arith_legendre_polynomial(fmpq_poly_t poly, ulong n)
{
if (n == 0)
{
fmpq_poly_set_ui(poly, UWORD(1));
return;
}
fmpq_poly_fit_length(poly, n + 1);
if (n == 1)
{
fmpz_zero(poly->coeffs);
fmpz_one(poly->coeffs + 1);
fmpz_one(poly->den);
}
else
_arith_legendre_polynomial(poly->coeffs, poly->den, n);
_fmpq_poly_set_length(poly, n + 1);
}

56
external/flint-2.4.3/arith/moebius_mu.c vendored Normal file
View File

@ -0,0 +1,56 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz.h"
#include "arith.h"
int arith_moebius_mu(const fmpz_t n)
{
fmpz_factor_t factors;
slong i;
int mu;
if (fmpz_abs_fits_ui(n))
return n_moebius_mu(fmpz_get_ui(n));
fmpz_factor_init(factors);
fmpz_factor(factors, n);
mu = 1;
for (i = 0; i < factors->num; i++)
{
if (factors->exp[i] != UWORD(1))
{
mu = 0;
break;
}
}
if (factors->num % 2)
mu = -mu;
fmpz_factor_clear(factors);
return mu;
}

View File

@ -0,0 +1,70 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <math.h>
#include "arith.h"
/* This nice round number precisely fits on 32 bits */
#define NUMBER_OF_SMALL_PARTITIONS 128
const unsigned int
partitions_lookup[NUMBER_OF_SMALL_PARTITIONS] =
{
UWORD(1),UWORD(1),UWORD(2),UWORD(3),UWORD(5),UWORD(7),UWORD(11),UWORD(15),UWORD(22),UWORD(30),UWORD(42),UWORD(56),UWORD(77),UWORD(101),UWORD(135),
UWORD(176),UWORD(231),UWORD(297),UWORD(385),UWORD(490),UWORD(627),UWORD(792),UWORD(1002),UWORD(1255),UWORD(1575),UWORD(1958),
UWORD(2436),UWORD(3010),UWORD(3718),UWORD(4565),UWORD(5604),UWORD(6842),UWORD(8349),UWORD(10143),UWORD(12310),UWORD(14883),
UWORD(17977),UWORD(21637),UWORD(26015),UWORD(31185),UWORD(37338),UWORD(44583),UWORD(53174),UWORD(63261),UWORD(75175),
UWORD(89134),UWORD(105558),UWORD(124754),UWORD(147273),UWORD(173525),UWORD(204226),UWORD(239943),UWORD(281589),
UWORD(329931),UWORD(386155),UWORD(451276),UWORD(526823),UWORD(614154),UWORD(715220),UWORD(831820),UWORD(966467),
UWORD(1121505),UWORD(1300156),UWORD(1505499),UWORD(1741630),UWORD(2012558),UWORD(2323520),UWORD(2679689),
UWORD(3087735),UWORD(3554345),UWORD(4087968),UWORD(4697205),UWORD(5392783),UWORD(6185689),UWORD(7089500),
UWORD(8118264),UWORD(9289091),UWORD(10619863),UWORD(12132164),UWORD(13848650),UWORD(15796476),UWORD(18004327),
UWORD(20506255),UWORD(23338469),UWORD(26543660),UWORD(30167357),UWORD(34262962),UWORD(38887673),
UWORD(44108109),UWORD(49995925),UWORD(56634173),UWORD(64112359),UWORD(72533807),UWORD(82010177),
UWORD(92669720),UWORD(104651419),UWORD(118114304),UWORD(133230930),UWORD(150198136),UWORD(169229875),
UWORD(190569292),UWORD(214481126),UWORD(241265379),UWORD(271248950),UWORD(304801365),UWORD(342325709),
UWORD(384276336),UWORD(431149389),UWORD(483502844),UWORD(541946240),UWORD(607163746),UWORD(679903203),
UWORD(761002156),UWORD(851376628),UWORD(952050665),UWORD(1064144451),UWORD(1188908248),UWORD(1327710076),
UWORD(1482074143),UWORD(1653668665),UWORD(1844349560),UWORD(2056148051),UWORD(2291320912),
UWORD(2552338241),UWORD(2841940500),UWORD(3163127352),UWORD(3519222692),UWORD(3913864295)
};
void
arith_number_of_partitions(fmpz_t x, ulong n)
{
if (n < NUMBER_OF_SMALL_PARTITIONS)
{
fmpz_set_ui(x, partitions_lookup[n]);
}
else
{
mpfr_t t;
mpfr_init(t);
arith_number_of_partitions_mpfr(t, n);
mpfr_get_z(_fmpz_promote(x), t, MPFR_RNDN);
_fmpz_demote_val(x);
mpfr_clear(t);
}
}

View File

@ -0,0 +1,539 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
Inspired by code written for Sage by Jonathan Bober.
******************************************************************************/
#include <math.h>
#include "arith.h"
#define DOUBLE_PREC 53
#define PI 3.141592653589793238462643
#define INV_LOG2 (1.44269504088896340735992468 + 1e-12)
#define HRR_A (1.1143183348516376904 + 1e-12) /* 44*pi^2/(225*sqrt(3)) */
#define HRR_B (0.0592384391754448833 + 1e-12) /* pi*sqrt(2)/75 */
#define HRR_C (2.5650996603237281911 + 1e-12) /* pi*sqrt(2/3) */
#define HRR_D (1.2424533248940001551 + 1e-12) /* log(2) + log(3)/2 */
#define PI_USE_CHUDNOVSKY 1
#define PI_CHUDNOVSKY_CUTOFF 1000000
#define VERBOSE 0
static double
partitions_remainder_bound(double n, double terms)
{
return HRR_A/sqrt(terms)
+ HRR_B*sqrt(terms/(n-1)) * sinh(HRR_C * sqrt(n)/terms);
}
/* Crude upper bound, sufficient to estimate the precision */
static double
log_sinh(double x)
{
if (x > 4)
return x;
else
return log(x) + x*x*(1/6.);
}
static double
partitions_remainder_bound_log2(double n, double N)
{
double t1, t2;
t1 = log(HRR_A) - 0.5*log(N);
t2 = log(HRR_B) + 0.5*(log(N) - log(n-1)) + log_sinh(HRR_C * sqrt(n)/N);
return (FLINT_MAX(t1, t2) + 1) * INV_LOG2;
}
slong
partitions_needed_terms(ulong n)
{
slong N;
for (N = 1; partitions_remainder_bound_log2(n, N) > 10; N++);
for ( ; partitions_remainder_bound(n, N) > (n > 1500 ? 0.25 : 1); N++);
return N;
}
static double
partitions_term_bound(double n, double k)
{
return ((PI*sqrt(24*n-1) / (6.0*k)) + HRR_D - log(24.0*n-1) + 0.5*log(k)) * INV_LOG2;
}
/* Bound number of prime factors in k */
static mp_limb_t primorial_tab[] = {
1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870,
#if FLINT64
UWORD(6469693230), UWORD(200560490130), UWORD(7420738134810), UWORD(304250263527210),
UWORD(13082761331670030), UWORD(614889782588491410)
#endif
};
static __inline__ int
bound_primes(ulong k)
{
int i;
for (i = 0; i < sizeof(primorial_tab) / sizeof(mp_limb_t); i++)
if (k <= primorial_tab[i])
return i;
return i;
}
static __inline__ slong
log2_ceil(double x)
{
/* ceil(log2(n)) = bitcount(n-1);
this is too large if x is a power of two */
return FLINT_BIT_COUNT((slong) x);
}
static slong
partitions_prec_bound(ulong n, slong k, slong N)
{
slong prec;
prec = partitions_term_bound(n, k);
prec += log2_ceil(8 * N * (26 * (sqrt(n) / k) + 7 * bound_primes(k) + 22));
return prec;
}
double
cos_pi_pq(mp_limb_signed_t p, mp_limb_signed_t q)
{
/* Force 0 <= p < q */
p = FLINT_ABS(p);
p %= (2 * q);
if (p >= q)
p = 2 * q - p;
if (4 * p <= q)
return cos(p * PI / q);
else if (4 * p < 3 * q)
return sin((q - 2*p) * PI / (2 * q));
else
return -cos((q - p) * PI / q);
}
void
mpfr_sqrt_z(mpfr_t x, mpz_t z, mpfr_rnd_t rnd)
{
if (mpz_fits_ulong_p(z))
mpfr_sqrt_ui(x, flint_mpz_get_ui(z), rnd);
else
{
mpfr_set_z(x, z, rnd);
mpfr_sqrt(x, x, rnd);
}
}
void
mpfr_set_fmpz(mpfr_t c, const fmpz_t b)
{
if (COEFF_IS_MPZ(*b))
mpfr_set_z(c, COEFF_TO_PTR(*b), MPFR_RNDN);
else
mpfr_set_si(c, *b, MPFR_RNDN);
}
void
mpfr_mul_fmpz(mpfr_t c, mpfr_srcptr a, const fmpz_t b)
{
if (COEFF_IS_MPZ(*b))
mpfr_mul_z(c, a, COEFF_TO_PTR(*b), MPFR_RNDN);
else
mpfr_mul_si(c, a, *b, MPFR_RNDN);
}
void
mpfr_add_fmpz(mpfr_t c, mpfr_srcptr a, const fmpz_t b)
{
if (COEFF_IS_MPZ(*b))
mpfr_add_z(c, a, COEFF_TO_PTR(*b), MPFR_RNDN);
else
mpfr_add_si(c, a, *b, MPFR_RNDN);
}
void
_fmpz_poly_evaluate_mpfr(mpfr_t res, const fmpz * f, slong len,
const mpfr_t a)
{
if (len == 0)
mpfr_set_ui(res, 0, MPFR_RNDN);
else if (len == 1)
mpfr_set_fmpz(res, f);
else
{
slong i = len - 1;
mpfr_t t;
mpfr_init2(t, mpfr_get_prec(res));
mpfr_set_fmpz(res, f + i);
for (i = len - 2; i >= 0; i--)
{
mpfr_mul(t, res, a, MPFR_RNDN);
mpfr_add_fmpz(res, t, f + i);
}
mpfr_clear(t);
}
}
void
fmpz_poly_evaluate_mpfr(mpfr_t res, const fmpz_poly_t f, const mpfr_t a)
{
if (res == a)
{
mpfr_t t;
mpfr_init2(t, mpfr_get_prec(res));
_fmpz_poly_evaluate_mpfr(t, f->coeffs, f->length, a);
mpfr_swap(res, t);
mpfr_clear(t);
}
else
{
_fmpz_poly_evaluate_mpfr(res, f->coeffs, f->length, a);
}
}
void
findroot(mpfr_t x, fmpz_poly_t poly, double x0)
{
slong i;
slong prec, initial_prec, target_prec, guard_bits;
slong precs[FLINT_BITS];
fmpz_poly_t poly2;
mpfr_t t, u, xn;
initial_prec = 48;
target_prec = mpfr_get_prec(x) + 32;
mpfr_init2(t, 53);
mpfr_init2(u, 53);
mpfr_init2(xn, 53);
mpfr_set_d(xn, x0, MPFR_RNDN);
fmpz_poly_init(poly2);
fmpz_poly_derivative(poly2, poly);
guard_bits = fmpz_poly_max_bits(poly2);
guard_bits = FLINT_ABS(guard_bits);
for (i = 0, prec = target_prec; prec >= initial_prec; i++)
{
precs[i] = prec;
prec = prec / 2 + 8;
}
for (i--; i >= 0; i--)
{
mpfr_set_prec(t, precs[i] + guard_bits);
mpfr_set_prec(u, precs[i] + guard_bits);
mpfr_prec_round(xn, precs[i], MPFR_RNDN);
fmpz_poly_evaluate_mpfr(t, poly, xn);
fmpz_poly_evaluate_mpfr(u, poly2, xn);
mpfr_div(t, t, u, MPFR_RNDN);
mpfr_sub(xn, xn, t, MPFR_RNDN);
}
mpfr_set(x, xn, MPFR_RNDN);
fmpz_poly_clear(poly2);
mpfr_clear(t);
mpfr_clear(u);
mpfr_clear(xn);
}
void cos_minpoly(fmpz_poly_t poly, slong p, slong q)
{
if (p % 2 == 0)
arith_cos_minpoly(poly, q);
else
arith_cos_minpoly(poly, 2 * q);
}
int use_newton(slong prec, slong q)
{
if (q < 250 && prec > 400 + 4*q*q)
return 1;
return 0;
}
void mpfr_cos_pi_pq(mpfr_t t, mp_limb_signed_t p, mp_limb_signed_t q)
{
/* Force 0 <= p < q */
p = FLINT_ABS(p);
p %= (2 * q);
if (p >= q)
p = 2 * q - p;
if (use_newton(mpfr_get_prec(t), q))
{
fmpz_poly_t poly;
slong d;
fmpz_poly_init(poly);
d = n_gcd(q, p);
q /= d;
p /= d;
cos_minpoly(poly, p, q);
findroot(t, poly, cos(3.1415926535897932385 * p / q));
fmpz_poly_clear(poly);
}
else
{
mpfr_const_pi(t, MPFR_RNDN);
if (4 * p <= q)
{
mpfr_mul_si(t, t, p, MPFR_RNDN);
mpfr_div_ui(t, t, q, MPFR_RNDN);
mpfr_cos(t, t, MPFR_RNDN);
}
else if (4 * p < 3 * q)
{
mpfr_mul_si(t, t, q - 2*p, MPFR_RNDN);
mpfr_div_ui(t, t, 2 * q, MPFR_RNDN);
mpfr_sin(t, t, MPFR_RNDN);
}
else
{
mpfr_mul_si(t, t, q - p, MPFR_RNDN);
mpfr_div_ui(t, t, q, MPFR_RNDN);
mpfr_cos(t, t, MPFR_RNDN);
mpfr_neg(t, t, MPFR_RNDN);
}
}
}
void
eval_trig_prod(mpfr_t sum, trig_prod_t prod)
{
int i;
if (prod->prefactor == 0)
{
mpfr_set_ui(sum, UWORD(0), MPFR_RNDN);
return;
}
if (mpfr_get_prec(sum) <= DOUBLE_PREC)
{
double s;
s = prod->prefactor * sqrt((double)prod->sqrt_p/(double)prod->sqrt_q);
for (i = 0; i < prod->n; i++)
s *= cos_pi_pq(prod->cos_p[i], prod->cos_q[i]);
mpfr_set_d(sum, s, MPFR_RNDN);
}
else
{
mp_limb_t v;
mpfr_t t;
mpfr_init2(t, mpfr_get_prec(sum));
mpfr_set_si(sum, prod->prefactor, MPFR_RNDN);
v = n_gcd_full(prod->sqrt_p, prod->sqrt_q);
prod->sqrt_p /= v;
prod->sqrt_q /= v;
if (prod->sqrt_p != 1)
{
mpfr_sqrt_ui(t, prod->sqrt_p, MPFR_RNDN);
mpfr_mul(sum, sum, t, MPFR_RNDN);
}
if (prod->sqrt_q != 1)
{
mpfr_sqrt_ui(t, prod->sqrt_q, MPFR_RNDN);
mpfr_div(sum, sum, t, MPFR_RNDN);
}
for (i = 0; i < prod->n; i++)
{
mpfr_cos_pi_pq(t, prod->cos_p[i], prod->cos_q[i]);
mpfr_mul(sum, sum, t, MPFR_RNDN);
}
mpfr_clear(t);
}
}
void
sinh_cosh_divk_precomp(mpfr_t sh, mpfr_t ch, mpfr_t ex, slong k)
{
mpfr_t t;
mpfr_root(ch, ex, k, MPFR_RNDN);
/* The second term doesn't need full precision,
but this doesn't affect performance that much... */
mpfr_init2(t, mpfr_get_prec(ch));
mpfr_ui_div(t, 1, ch, MPFR_RNDN);
mpfr_sub(sh, ch, t, MPFR_RNDN);
mpfr_add(ch, ch, t, MPFR_RNDN);
mpfr_div_2exp(ch, ch, 1, MPFR_RNDN);
mpfr_div_2exp(sh, sh, 1, MPFR_RNDN);
mpfr_clear(t);
}
void
_arith_number_of_partitions_mpfr(mpfr_t x, ulong n, slong N0, slong N)
{
trig_prod_t prod;
mpfr_t acc, C, t1, t2, t3, t4, exp1;
mpz_t n24;
double Cd;
slong k;
slong prec, guard_bits;
#if VERBOSE
timeit_t t0;
#endif
if (n <= 2)
{
mpfr_set_ui(x, FLINT_MAX(1, n), MPFR_RNDN);
return;
}
/* Compute initial precision */
guard_bits = 2 * FLINT_BIT_COUNT(N) + 32;
prec = partitions_remainder_bound_log2(n, N0) + guard_bits;
prec = FLINT_MAX(prec, DOUBLE_PREC);
mpfr_set_prec(x, prec);
mpfr_init2(acc, prec);
mpfr_init2(C, prec);
mpfr_init2(t1, prec);
mpfr_init2(t2, prec);
mpfr_init2(t3, prec);
mpfr_init2(t4, prec);
mpfr_set_ui(x, 0, MPFR_RNDN);
mpfr_set_ui(acc, 0, MPFR_RNDN);
mpz_init(n24);
flint_mpz_set_ui(n24, n);
flint_mpz_mul_ui(n24, n24, 24);
flint_mpz_sub_ui(n24, n24, 1);
#if VERBOSE
timeit_start(t0);
#endif
/* C = (pi/6)*sqrt(24*n-1) */
if (PI_USE_CHUDNOVSKY && prec > PI_CHUDNOVSKY_CUTOFF)
mpfr_pi_chudnovsky(t1, MPFR_RNDN);
else
mpfr_const_pi(t1, MPFR_RNDN);
mpfr_sqrt_z(t2, n24, MPFR_RNDN);
mpfr_mul(t1, t1, t2, MPFR_RNDN);
mpfr_div_ui(C, t1, 6, MPFR_RNDN);
Cd = mpfr_get_d(C, MPFR_RNDN);
mpfr_init2(exp1, prec);
mpfr_exp(exp1, C, prec);
#if VERBOSE
timeit_stop(t0);
flint_printf("TERM 1: %wd ms\n", t0->cpu);
#endif
for (k = N0; k <= N; k++)
{
trig_prod_init(prod);
arith_hrr_expsum_factored(prod, k, n % k);
if (prod->prefactor != 0)
{
if (prec > DOUBLE_PREC)
{
prec = partitions_prec_bound(n, k, N);
mpfr_set_prec(t1, prec);
mpfr_set_prec(t2, prec);
mpfr_set_prec(t3, prec);
mpfr_set_prec(t4, prec);
}
/* Compute A_k(n) * sqrt(3/k) * 4 / (24*n-1) */
prod->prefactor *= 4;
prod->sqrt_p *= 3;
prod->sqrt_q *= k;
eval_trig_prod(t1, prod);
mpfr_div_z(t1, t1, n24, MPFR_RNDN);
/* Multiply by (cosh(z) - sinh(z)/z) where z = C / k */
if (prec <= DOUBLE_PREC)
{
double z = Cd / k;
mpfr_mul_d(t1, t1, cosh(z) - sinh(z)/z, MPFR_RNDN);
}
else
{
mpfr_div_ui(t2, C, k, MPFR_RNDN);
if (k < 35)
sinh_cosh_divk_precomp(t3, t4, exp1, k);
else
mpfr_sinh_cosh(t3, t4, t2, MPFR_RNDN);
mpfr_div(t3, t3, t2, MPFR_RNDN);
mpfr_sub(t2, t4, t3, MPFR_RNDN);
mpfr_mul(t1, t1, t2, MPFR_RNDN);
}
/* Add to accumulator */
mpfr_add(acc, acc, t1, MPFR_RNDN);
if (mpfr_get_prec(acc) > 2 * prec + 32)
{
mpfr_add(x, x, acc, MPFR_RNDN);
mpfr_set_prec(acc, prec + 32);
mpfr_set_ui(acc, 0, MPFR_RNDN);
}
}
}
mpfr_add(x, x, acc, MPFR_RNDN);
mpz_clear(n24);
mpfr_clear(acc);
mpfr_clear(exp1);
mpfr_clear(C);
mpfr_clear(t1);
mpfr_clear(t2);
mpfr_clear(t3);
mpfr_clear(t4);
}
void
arith_number_of_partitions_mpfr(mpfr_t x, ulong n)
{
_arith_number_of_partitions_mpfr(x, n, 1, partitions_needed_terms(n));
}

View File

@ -0,0 +1,61 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod)
{
mp_ptr tmp;
mp_limb_t r;
slong k, n;
r = mod.n - UWORD(1);
if (len < 1)
return;
tmp = _nmod_vec_init(len);
_nmod_vec_zero(tmp, len);
tmp[0] = UWORD(1);
for (n = k = 1; n + 4*k + 2 < len; k += 2)
{
tmp[n] = r;
tmp[n + k] = r;
tmp[n + 3*k + 1] = UWORD(1);
tmp[n + 4*k + 2] = UWORD(1);
n += 6*k + 5;
}
if (n < len) tmp[n] = r;
if (n + k < len) tmp[n + k] = r;
if (n + 3*k + 1 < len) tmp[n + 3*k + 1] = WORD(1);
_nmod_poly_inv_series(res, tmp, len, mod);
_nmod_vec_clear(tmp);
}

View File

@ -0,0 +1,57 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void
arith_number_of_partitions_vec(fmpz * res, slong len)
{
fmpz * tmp;
slong k, n;
if (len < 1)
return;
tmp = _fmpz_vec_init(len);
tmp[0] = WORD(1);
for (n = k = 1; n + 4*k + 2 < len; k += 2)
{
tmp[n] = WORD(-1);
tmp[n + k] = WORD(-1);
tmp[n + 3*k + 1] = WORD(1);
tmp[n + 4*k + 2] = WORD(1);
n += 6*k + 5;
}
if (n < len) tmp[n] = WORD(-1);
if (n + k < len) tmp[n + k] = WORD(-1);
if (n + 3*k + 1 < len) tmp[n + 3*k + 1] = WORD(1);
_fmpz_poly_inv_series(res, tmp, len);
_fmpz_vec_clear(tmp, len);
}

View File

@ -0,0 +1,653 @@
/* Pi computation using Chudnovsky's algortithm.
* Copyright 2002, 2005 Hanhong Xue (macroxue at yahoo dot com)
* Modified 2005 by Torbjorn Granlund (tege at swox dot com) to allow more than
2G digits to be computed. Modified 2009 by Torbjorn Granlund for GMPbench.
* Modified 2011 by Fredrik Johansson to make reentrant and adapt for
use in FLINT.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>
#include <mpfr.h>
#include "arith.h"
#define A 13591409
#define B 545140134
#define C 640320
#define D 12
#define BITS_PER_DIGIT 3.32192809488736234787
#define DIGITS_PER_ITER 14.1816474627254776555
#define DOUBLE_PREC 53
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
typedef struct {
ulong max_facs;
ulong num_facs;
ulong *fac;
ulong *pow;
} fac_t[1];
typedef struct {
slong fac;
slong pow;
slong nxt;
} sieve_t;
typedef struct
{
sieve_t *sieve;
slong sieve_size;
fac_t ftmp, fmul;
mpz_t gcd;
mpz_t *pstack, *qstack, *gstack;
fac_t *fpstack, *fgstack;
slong top;
}
pi_state_struct;
typedef pi_state_struct pi_state[1];
#define INIT_FACS 32
#define p1 (state->pstack[state->top])
#define q1 (state->qstack[state->top])
#define g1 (state->gstack[state->top])
#define fp1 (state->fpstack[state->top])
#define fg1 (state->fgstack[state->top])
#define p2 (state->pstack[state->top+1])
#define q2 (state->qstack[state->top+1])
#define g2 (state->gstack[state->top+1])
#define fp2 (state->fpstack[state->top+1])
#define fg2 (state->fgstack[state->top+1])
/* r = sqrt(x) */
void
my_sqrt_ui(pi_state state, mpf_t t1, mpf_t t2, mpf_t r, ulong x)
{
ulong prec, bits, prec0;
prec0 = mpf_get_prec(r);
if (prec0 <= DOUBLE_PREC)
{
mpf_set_d(r, sqrt(x));
return;
}
bits = 0;
for (prec = prec0; prec > DOUBLE_PREC; )
{
int bit = prec&1;
prec = (prec+bit)/2;
bits = bits*2+bit;
}
mpf_set_prec_raw(t1, DOUBLE_PREC);
mpf_set_d(t1, 1/sqrt(x));
while (prec < prec0)
{
prec *=2;
if (prec < prec0)
{
/* t1 = t1+t1*(1-x*t1*t1)/2; */
mpf_set_prec_raw(t2, prec);
mpf_mul(t2, t1, t1); /* half x half -> full */
mpf_mul_ui(t2, t2, x);
mpf_ui_sub(t2, 1, t2);
mpf_set_prec_raw(t2, prec/2);
mpf_div_2exp(t2, t2, 1);
mpf_mul(t2, t2, t1); /* half x half -> half */
mpf_set_prec_raw(t1, prec);
mpf_add(t1, t1, t2);
}
else
{
break;
}
prec -= (bits&1);
bits /=2;
}
/* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */
mpf_set_prec_raw(t2, prec0/2);
mpf_mul_ui(t2, t1, x);
mpf_mul(r, t2, t2); /* half x half -> full */
mpf_ui_sub(r, x, r);
mpf_mul(t1, t1, r); /* half x half -> half */
mpf_div_2exp(t1, t1, 1);
mpf_add(r, t1, t2);
}
/* r = y/x WARNING: r cannot be the same as y. */
void
my_div(pi_state state, mpf_t t1, mpf_t t2, mpf_t r, mpf_t y, mpf_t x)
{
ulong prec, bits, prec0;
prec0 = mpf_get_prec(r);
if (prec0 <= DOUBLE_PREC)
{
mpf_set_d(r, mpf_get_d(y) / mpf_get_d(x));
return;
}
bits = 0;
for (prec = prec0; prec > DOUBLE_PREC; )
{
int bit = prec & 1;
prec = (prec + bit) / 2;
bits = bits*2 + bit;
}
mpf_set_prec_raw(t1, DOUBLE_PREC);
mpf_ui_div(t1, 1, x);
while (prec < prec0)
{
prec *= 2;
if (prec < prec0)
{
/* t1 = t1+t1*(1-x*t1); */
mpf_set_prec_raw(t2, prec);
mpf_mul(t2, x, t1); /* full x half -> full */
mpf_ui_sub(t2, 1, t2);
mpf_set_prec_raw(t2, prec/2);
mpf_mul(t2, t2, t1); /* half x half -> half */
mpf_set_prec_raw(t1, prec);
mpf_add(t1, t1, t2);
}
else
{
prec = prec0;
/* t2=y*t1, t1 = t2+t1*(y-x*t2); */
mpf_set_prec_raw(t2, prec / 2);
mpf_mul(t2, t1, y); /* half x half -> half */
mpf_mul(r, x, t2); /* full x half -> full */
mpf_sub(r, y, r);
mpf_mul(t1, t1, r); /* half x half -> half */
mpf_add(r, t1, t2);
break;
}
prec -= (bits & 1);
bits /= 2;
}
}
/*///////////////////////////////////////////////////////////////////////////*/
static __inline__ void
fac_reset(fac_t f)
{
f[0].num_facs = 0;
}
static __inline__ void
fac_init_size(fac_t f, slong s)
{
if (s < INIT_FACS)
s = INIT_FACS;
f[0].fac = flint_malloc(s*sizeof(ulong)*2);
f[0].pow = f[0].fac + s;
f[0].max_facs = s;
fac_reset(f);
}
static __inline__ void
fac_init(fac_t f)
{
fac_init_size(f, INIT_FACS);
}
static __inline__ void
fac_clear(fac_t f)
{
flint_free(f[0].fac);
}
static __inline__ void
fac_resize(fac_t f, slong s)
{
if (f[0].max_facs < s)
{
fac_clear(f);
fac_init_size(f, s);
}
}
/* f = base^pow */
static __inline__ void
fac_set_bp(pi_state state, fac_t f, ulong base, slong pow)
{
slong i;
assert(base<state->sieve_size);
for (i=0, base/=2; base>0; i++, base = state->sieve[base].nxt)
{
f[0].fac[i] = state->sieve[base].fac;
f[0].pow[i] = state->sieve[base].pow*pow;
}
f[0].num_facs = i;
assert(i<=f[0].max_facs);
}
/* r = f*g */
static __inline__ void
fac_mul2(pi_state state, fac_t r, fac_t f, fac_t g)
{
slong i, j, k;
for (i=j=k=0; i<f[0].num_facs && j<g[0].num_facs; k++)
{
if (f[0].fac[i] == g[0].fac[j])
{
r[0].fac[k] = f[0].fac[i];
r[0].pow[k] = f[0].pow[i] + g[0].pow[j];
i++; j++;
}
else if (f[0].fac[i] < g[0].fac[j])
{
r[0].fac[k] = f[0].fac[i];
r[0].pow[k] = f[0].pow[i];
i++;
}
else
{
r[0].fac[k] = g[0].fac[j];
r[0].pow[k] = g[0].pow[j];
j++;
}
}
for (; i<f[0].num_facs; i++, k++)
{
r[0].fac[k] = f[0].fac[i];
r[0].pow[k] = f[0].pow[i];
}
for (; j<g[0].num_facs; j++, k++)
{
r[0].fac[k] = g[0].fac[j];
r[0].pow[k] = g[0].pow[j];
}
r[0].num_facs = k;
assert(k<=r[0].max_facs);
}
/* f *= g */
static __inline__ void
fac_mul(pi_state state, fac_t f, fac_t g)
{
fac_t tmp;
fac_resize(state->fmul, f[0].num_facs + g[0].num_facs);
fac_mul2(state, state->fmul, f, g);
tmp[0] = f[0];
f[0] = state->fmul[0];
state->fmul[0] = tmp[0];
}
/* f *= base^pow */
static __inline__ void
fac_mul_bp(pi_state state, fac_t f, ulong base, ulong pow)
{
fac_set_bp(state, state->ftmp, base, pow);
fac_mul(state, f, state->ftmp);
}
/* remove factors of power 0 */
static __inline__ void
fac_compact(fac_t f)
{
slong i, j;
for (i=0, j=0; i<f[0].num_facs; i++)
{
if (f[0].pow[i]>0)
{
if (j < i)
{
f[0].fac[j] = f[0].fac[i];
f[0].pow[j] = f[0].pow[i];
}
j++;
}
}
f[0].num_facs = j;
}
/* convert factorized form to number */
void
bs_mul(pi_state state, mpz_t r, slong a, slong b)
{
slong i, j;
if (b-a<=32)
{
flint_mpz_set_ui(r, 1);
for (i=a; i<b; i++)
for (j=0; j<state->fmul[0].pow[i]; j++)
flint_mpz_mul_ui(r, r, state->fmul[0].fac[i]);
}
else
{
mpz_t r2;
mpz_init(r2);
bs_mul(state, r2, a, (a+b)/2);
bs_mul(state, r, (a+b)/2, b);
mpz_mul(r, r, r2);
mpz_clear(r2);
}
}
/* f /= gcd(f,g), g /= gcd(f,g) */
void
fac_remove_gcd(pi_state state, mpz_t p, fac_t fp, mpz_t g, fac_t fg)
{
slong i, j, k, c;
fac_resize(state->fmul, min(fp->num_facs, fg->num_facs));
for (i=j=k=0; i < fp->num_facs && j < fg->num_facs; )
{
if (fp->fac[i] == fg->fac[j])
{
c = min(fp->pow[i], fg->pow[j]);
fp->pow[i] -= c;
fg->pow[j] -= c;
state->fmul->fac[k] = fp->fac[i];
state->fmul->pow[k] = c;
i++; j++; k++;
}
else if (fp->fac[i] < fg->fac[j])
{
i++;
}
else
{
j++;
}
}
state->fmul->num_facs = k;
assert(k <= state->fmul->max_facs);
if (state->fmul->num_facs)
{
bs_mul(state, state->gcd, 0, state->fmul->num_facs);
mpz_divexact(p, p, state->gcd);
mpz_divexact(g, g, state->gcd);
fac_compact(fp);
fac_compact(fg);
}
}
/*///////////////////////////////////////////////////////////////////////////*/
/* binary splitting */
void
bs(pi_state state, ulong a, ulong b,
unsigned gflag, slong level)
{
ulong i, mid;
if (b - a == 1)
{
/*
g(b-1,b) = (6b-5)(2b-1)(6b-1)
p(b-1,b) = b^3 * C^3 / 24
q(b-1,b) = (-1)^b*g(b-1,b)*(A+Bb).
*/
flint_mpz_set_ui(p1, b);
flint_mpz_mul_ui(p1, p1, b);
flint_mpz_mul_ui(p1, p1, b);
flint_mpz_mul_ui(p1, p1, (C/24)*(C/24));
flint_mpz_mul_ui(p1, p1, C*24);
flint_mpz_set_ui(g1, 2*b-1);
flint_mpz_mul_ui(g1, g1, 6*b-1);
flint_mpz_mul_ui(g1, g1, 6*b-5);
flint_mpz_set_ui(q1, b);
flint_mpz_mul_ui(q1, q1, B);
flint_mpz_add_ui(q1, q1, A);
mpz_mul (q1, q1, g1);
if (b%2)
mpz_neg(q1, q1);
i=b;
while ((i&1)==0) i>>=1;
fac_set_bp(state, fp1, i, 3); /* b^3 */
fac_mul_bp(state, fp1, 3*5*23*29, 3);
fp1[0].pow[0]--;
fac_set_bp(state, fg1, 2*b-1, 1); /* 2b-1 */
fac_mul_bp(state, fg1, 6*b-1, 1); /* 6b-1 */
fac_mul_bp(state, fg1, 6*b-5, 1); /* 6b-5 */
}
else
{
/*
p(a,b) = p(a,m) * p(m,b)
g(a,b) = g(a,m) * g(m,b)
q(a,b) = q(a,m) * p(m,b) + q(m,b) * g(a,m)
*/
mid = a+(b-a)*0.5224; /* tuning parameter */
bs(state, a, mid, 1, level+1);
state->top++;
bs(state, mid, b, gflag, level+1);
state->top--;
if (level>=4) { /* tuning parameter */
fac_remove_gcd(state, p2, fp2, g1, fg1);
}
mpz_mul(p1, p1, p2);
mpz_mul(q1, q1, p2);
mpz_mul(q2, q2, g1);
mpz_add(q1, q1, q2);
fac_mul(state, fp1, fp2);
if (gflag)
{
mpz_mul(g1, g1, g2);
fac_mul(state, fg1, fg2);
}
}
}
void
build_sieve(pi_state state, slong n, sieve_t *s)
{
slong m, i, j, k;
state->sieve_size = n;
m = (slong)sqrt(n);
memset(s, 0, sizeof(sieve_t)*n/2);
s[1/2].fac = 1;
s[1/2].pow = 1;
for (i=3; i<=n; i+=2)
{
if (s[i/2].fac == 0)
{
s[i/2].fac = i;
s[i/2].pow = 1;
if (i <= m)
{
for (j=i*i, k=i/2; j<=n; j+=i+i, k++)
{
if (s[j/2].fac==0)
{
s[j/2].fac = i;
if (s[k].fac == i)
{
s[j/2].pow = s[k].pow + 1;
s[j/2].nxt = s[k].nxt;
}
else
{
s[j/2].pow = 1;
s[j/2].nxt = k;
}
}
}
}
}
}
}
void
mpfr_pi_chudnovsky(mpfr_t res, mpfr_rnd_t rnd)
{
mpf_t pi, qi, t1, t2;
mpfr_prec_t prec;
slong i, depth=1, terms;
pi_state state;
prec = mpfr_get_prec(res) + 64;
terms = prec / (BITS_PER_DIGIT * DIGITS_PER_ITER);
while ((WORD(1)<<depth)<terms)
depth++;
depth++;
state->top = 0;
state->sieve_size = max(3*5*23*29+1, terms*6);
state->sieve = (sieve_t *)flint_malloc(sizeof(sieve_t)*(state->sieve_size)/2);
build_sieve(state, state->sieve_size, state->sieve);
/* allocate stacks */
state->pstack = flint_malloc(sizeof(mpz_t)*depth);
state->qstack = flint_malloc(sizeof(mpz_t)*depth);
state->gstack = flint_malloc(sizeof(mpz_t)*depth);
state->fpstack = flint_malloc(sizeof(fac_t)*depth);
state->fgstack = flint_malloc(sizeof(fac_t)*depth);
for (i=0; i<depth; i++)
{
mpz_init(state->pstack[i]);
mpz_init(state->qstack[i]);
mpz_init(state->gstack[i]);
fac_init(state->fpstack[i]);
fac_init(state->fgstack[i]);
}
mpz_init(state->gcd);
fac_init(state->ftmp);
fac_init(state->fmul);
/* begin binary splitting process */
if (terms<=0)
{
flint_mpz_set_ui(p2,1);
flint_mpz_set_ui(q2,0);
flint_mpz_set_ui(g2,1);
}
else
{
bs(state, 0,terms,0,0);
}
/* free some resources */
flint_free(state->sieve);
mpz_clear(state->gcd);
fac_clear(state->ftmp);
fac_clear(state->fmul);
for (i=1; i<depth; i++)
{
mpz_clear(state->pstack[i]);
mpz_clear(state->qstack[i]);
mpz_clear(state->gstack[i]);
fac_clear(state->fpstack[i]);
fac_clear(state->fgstack[i]);
}
mpz_clear(state->gstack[0]);
fac_clear(state->fpstack[0]);
fac_clear(state->fgstack[0]);
flint_free(state->gstack);
flint_free(state->fpstack);
flint_free(state->fgstack);
/*
p*(C/D)*sqrt(C)
pi = -----------------
(q+A*p)
*/
flint_mpz_addmul_ui(q1, p1, A);
flint_mpz_mul_ui(p1, p1, C/D);
mpf_init2(pi, prec);
mpf_set_z(pi, p1);
mpz_clear(p1);
mpf_init2(qi, prec);
mpf_set_z(qi, q1);
mpz_clear(q1);
flint_free(state->pstack);
flint_free(state->qstack);
/* initialize temp float variables for sqrt & div */
mpf_init2(t1, prec);
mpf_init2(t2, prec);
/* final step */
my_div(state, t1, t2, qi, pi, qi);
my_sqrt_ui(state, t1, t2, pi, C);
mpf_mul(qi, qi, pi);
mpfr_set_f(res, qi, rnd);
/* free float resources */
mpf_clear(pi);
mpf_clear(qi);
mpf_clear(t1);
mpf_clear(t2);
}

151
external/flint-2.4.3/arith/primorial.c vendored Normal file
View File

@ -0,0 +1,151 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
Copyright (C) 2010 William Hart
******************************************************************************/
#include "arith.h"
#if FLINT64
#define LARGEST_ULONG_PRIMORIAL 52
#else
#define LARGEST_ULONG_PRIMORIAL 28
#endif
/* Only those with odd index */
const ulong ULONG_PRIMORIALS[] =
{
UWORD(6),UWORD(30),UWORD(210),UWORD(210),UWORD(2310),UWORD(30030),UWORD(30030),UWORD(510510),UWORD(9699690),UWORD(9699690),
UWORD(223092870),UWORD(223092870),UWORD(223092870)
#if FLINT64
,UWORD(6469693230),UWORD(200560490130),UWORD(200560490130),UWORD(200560490130),UWORD(7420738134810),
UWORD(7420738134810),UWORD(304250263527210),UWORD(13082761331670030),UWORD(13082761331670030),
UWORD(614889782588491410), UWORD(614889782588491410), UWORD(614889782588491410)
#endif
};
#define PROD_LIMBS_DIRECT_CUTOFF 50
mp_size_t mpn_prod_limbs_direct(mp_limb_t * result, const mp_limb_t * factors,
mp_size_t n)
{
mp_size_t k, len;
mp_limb_t top;
if (n < 1)
{
result[0] = UWORD(1);
return 1;
}
result[0] = factors[0];
len = 1;
for (k=1; k<n; k++)
{
top = mpn_mul_1(result, result, len, factors[k]);
if (top)
{
result[len] = top;
len++;
}
}
return len;
}
mp_size_t mpn_prod_limbs_balanced(mp_limb_t * result, mp_limb_t * scratch,
const mp_limb_t * factors, mp_size_t n, ulong bits)
{
mp_size_t an, bn, alen, blen, len;
mp_limb_t top;
if (n < PROD_LIMBS_DIRECT_CUTOFF)
return mpn_prod_limbs_direct(result, factors, n);
an = n/2;
bn = n - an;
alen = mpn_prod_limbs_balanced(scratch, result, factors, an, bits);
blen = mpn_prod_limbs_balanced(scratch + alen, result, factors + an, bn, bits);
len = alen + blen;
if (alen <= blen)
top = mpn_mul(result, scratch + alen, blen, scratch, alen);
else
top = mpn_mul(result, scratch, alen, scratch + alen, blen);
if (!top)
len--;
return len;
}
/*
Set result to the product of the given factors, return the
length of the result. It is assumed that no factors are zero.
bits must be set to some bound on the bit size of the entries
in factors. If no bound is known, simply use FLINT_BITS.
*/
mp_size_t mpn_prod_limbs(mp_limb_t * result, const mp_limb_t * factors,
mp_size_t n, ulong bits)
{
mp_size_t len, limbs;
mp_limb_t * scratch;
if (n < PROD_LIMBS_DIRECT_CUTOFF)
return mpn_prod_limbs_direct(result, factors, n);
limbs = (n * bits - 1)/FLINT_BITS + 2;
scratch = flint_malloc(sizeof(mp_limb_t) * limbs);
len = mpn_prod_limbs_balanced(result, scratch, factors, n, bits);
flint_free(scratch);
return len;
}
void arith_primorial(fmpz_t res, slong n)
{
mp_size_t len, pi;
ulong bits;
__mpz_struct * mpz_ptr;
const mp_limb_t * primes;
if (n <= LARGEST_ULONG_PRIMORIAL)
{
if (n <= 2)
fmpz_set_ui(res, 1 + (n==2));
else
fmpz_set_ui(res, ULONG_PRIMORIALS[(n-1)/2-1]);
return;
}
pi = n_prime_pi(n);
primes = n_primes_arr_readonly(pi);
bits = FLINT_BIT_COUNT(primes[pi - 1]);
mpz_ptr = _fmpz_promote(res);
mpz_realloc2(mpz_ptr, pi*bits);
len = mpn_prod_limbs(mpz_ptr->_mp_d, primes, pi, bits);
mpz_ptr->_mp_size = len;
}

View File

@ -0,0 +1,120 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright 2009 William Hart
Copyright 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <mpfr.h>
#include "profiler.h"
#include "flint.h"
#include "fmpz_mat.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "arith.h"
typedef struct
{
ulong n;
int algorithm;
} bernoulli_vec_t;
void sample(void * arg, ulong count)
{
fmpz * num;
fmpz * den;
bernoulli_vec_t * params = (bernoulli_vec_t *) arg;
ulong n = params->n;
slong i;
int algorithm = params->algorithm;
num = _fmpz_vec_init(n);
den = _fmpz_vec_init(n);
prof_start();
for (i = 0; i < count; i++)
{
if (algorithm == 0)
{
_arith_bernoulli_number_vec_recursive(num, den, n);
}
else if (algorithm == 1)
{
_arith_bernoulli_number_vec_multi_mod(num, den, n);
}
else if (algorithm == 2)
{
_arith_bernoulli_number_vec_zeta(num, den, n);
mpfr_free_cache();
}
}
prof_stop();
_fmpz_vec_clear(num, n);
_fmpz_vec_clear(den, n);
}
int main(void)
{
double min_recursive, min_multi_mod, min_zeta, max;
bernoulli_vec_t params;
slong n;
flint_printf("n / recursive / multi_mod / zeta / best [times in us]\n");
for (n = 2; n <= 10000; n = (slong) ((double) n * 1.2) + 1)
{
params.n = n;
if (n < 1500)
{
params.algorithm = 0;
prof_repeat(&min_recursive, &max, sample, &params);
}
else
min_recursive = 0.0;
params.algorithm = 1;
prof_repeat(&min_multi_mod, &max, sample, &params);
params.algorithm = 2;
prof_repeat(&min_zeta, &max, sample, &params);
flint_printf("%wd %.2f %.2f %.2f ",
n, min_recursive, min_multi_mod, min_zeta);
if (min_recursive && min_recursive < min_multi_mod && \
min_recursive < min_zeta)
flint_printf("(recursive)\n");
else if (min_multi_mod < min_zeta)
flint_printf("(multi_mod)\n");
else
flint_printf("(zeta)\n");
}
return 0;
}

View File

@ -0,0 +1,120 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz.h"
#include "arith.h"
void arith_ramanujan_tau_series(fmpz_poly_t res, slong n)
{
slong j, k, jv, kv;
fmpz_t tmp;
fmpz_poly_fit_length(res, n);
_fmpz_vec_zero(res->coeffs, n);
_fmpz_poly_set_length(res, n);
fmpz_init(tmp);
for (j = jv = 0; jv < n; jv += ++j)
{
fmpz_set_ui(tmp, 2*j+1);
for (k = kv = 0; jv + kv < n; kv += ++k)
{
if ((j+k) & 1)
fmpz_submul_ui(res->coeffs + jv+kv, tmp, 2*k+1);
else
fmpz_addmul_ui(res->coeffs + jv+kv, tmp, 2*k+1);
}
}
fmpz_poly_sqrlow(res, res, n-1);
fmpz_poly_sqrlow(res, res, n-1);
fmpz_poly_shift_left(res, res, 1);
fmpz_clear(tmp);
}
void _arith_ramanujan_tau(fmpz_t res, fmpz_factor_t factors)
{
fmpz_poly_t poly;
fmpz_t tau_p, p_11, next, this, prev;
slong k, r;
ulong max_prime;
max_prime = UWORD(1);
for (k = 0; k < factors->num; k++)
{
/* TODO: handle overflow properly */
max_prime = FLINT_MAX(max_prime, fmpz_get_ui(factors->p + k));
}
fmpz_poly_init(poly);
arith_ramanujan_tau_series(poly, max_prime + 1);
fmpz_one(res);
fmpz_init(tau_p);
fmpz_init(p_11);
fmpz_init(next);
fmpz_init(this);
fmpz_init(prev);
for (k = 0; k < factors->num; k++)
{
ulong p = fmpz_get_ui(factors->p + k);
fmpz_set(tau_p, poly->coeffs + p);
fmpz_set_ui(p_11, p);
fmpz_pow_ui(p_11, p_11, 11);
fmpz_one(prev);
fmpz_set(this, tau_p);
for (r = 1; r < factors->exp[k]; r++)
{
fmpz_mul(next, tau_p, this);
fmpz_submul(next, p_11, prev);
fmpz_set(prev, this);
fmpz_set(this, next);
}
fmpz_mul(res, res, this);
}
fmpz_clear(tau_p);
fmpz_clear(p_11);
fmpz_clear(next);
fmpz_clear(this);
fmpz_clear(prev);
fmpz_poly_clear(poly);
}
void arith_ramanujan_tau(fmpz_t res, const fmpz_t n)
{
fmpz_factor_t factors;
if (fmpz_sgn(n) <= 0)
{
fmpz_zero(res);
return;
}
fmpz_factor_init(factors);
fmpz_factor(factors, n);
_arith_ramanujan_tau(res, factors);
fmpz_factor_clear(factors);
}

138
external/flint-2.4.3/arith/stirling1.c vendored Normal file
View File

@ -0,0 +1,138 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static void
_rising_factorial(fmpz * res, slong a, slong b, slong trunc)
{
const slong span = b - a;
switch (span)
{
case 0:
fmpz_one(res);
break;
case 1:
fmpz_set_ui(res, a);
if (trunc > 1) fmpz_one(res+1);
break;
case 2:
fmpz_set_ui(res, a);
fmpz_mul_ui(res, res, a + UWORD(1));
if (trunc > 1)
{
fmpz_set_ui(res+1, 2*a + UWORD(1));
if (trunc > 2) fmpz_one(res+2);
}
break;
case 3:
fmpz_set_ui(res, a);
fmpz_mul_ui(res, res, a + UWORD(1));
fmpz_mul_ui(res, res, a + UWORD(2));
if (trunc > 1)
{
fmpz_set_ui(res+1, 3*a);
fmpz_mul_ui(res+1, res+1, a + UWORD(2));
fmpz_add_ui(res+1, res+1, 2);
if (trunc > 2)
{
fmpz_set_ui(res+2, 3*(a+1));
if (trunc > 3)
fmpz_one(res+3);
}
}
break;
default:
{
const slong mid = (a + b) / 2;
const int chk = (b - a + 1 < trunc); /* i.e. nprod < trunc */
const slong nleft = chk ? mid - a + 1 : trunc;
const slong nright = chk ? b - mid + 1 : trunc;
fmpz *left = _fmpz_vec_init(nleft);
fmpz *right = _fmpz_vec_init(nright);
_rising_factorial(left, a, mid, trunc);
_rising_factorial(right, mid, b, trunc);
if (chk)
_fmpz_poly_mul(res, right, nright, left, nleft);
else
_fmpz_poly_mullow(res, left, nleft, right, nright, trunc);
_fmpz_vec_clear(left, nleft);
_fmpz_vec_clear(right, nright);
}
}
}
void
arith_stirling_number_1u(fmpz_t s, slong n, slong k)
{
/* Various special cases
TODO: factorials, binomial coefficients, harmonic numbers ... */
if (k < 1)
{
fmpz_set_ui(s, (n == 0) & (k == 0));
}
if (k >= n)
{
fmpz_set_ui(s, n == k);
}
else
{
fmpz *tmp = _fmpz_vec_init(k+1);
_rising_factorial(tmp, 0, n, k+1);
fmpz_set(s, tmp+k);
_fmpz_vec_clear(tmp, k+1);
}
}
void
arith_stirling_number_1(fmpz_t s, slong n, slong k)
{
arith_stirling_number_1u(s, n, k);
if ((n + k) % 2)
fmpz_neg(s, s);
}
void
arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen)
{
if (klen > 0)
_rising_factorial(row, 0, n, klen);
}
void
arith_stirling_number_1_vec(fmpz * row, slong n, slong klen)
{
slong k;
arith_stirling_number_1u_vec(row, n, klen);
for (k = (n + 1) % 2; k < klen; k += 2)
fmpz_neg(row + k, row + k);
}

134
external/flint-2.4.3/arith/stirling2.c vendored Normal file
View File

@ -0,0 +1,134 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static __inline__ void
_fmpz_addmul_alt(fmpz_t s, fmpz_t t, fmpz_t u, int parity)
{
if (parity % 2)
fmpz_submul(s, t, u);
else
fmpz_addmul(s, t, u);
}
static void
_fmpz_stirling2_powsum(fmpz_t s, slong n, slong k)
{
fmpz_t t, u;
fmpz * bc;
slong j, m, max_bc;
fmpz_init(t);
fmpz_init(u);
max_bc = (k+1) / 2;
bc = _fmpz_vec_init(max_bc + 1);
fmpz_one(bc);
for (j = 1; j <= max_bc; j++)
{
fmpz_set(bc+j, bc+j-1);
fmpz_mul_ui(bc+j, bc+j, k+1-j);
fmpz_divexact_ui(bc+j, bc+j, j);
}
fmpz_zero(s);
for (j = 1; j <= k; j += 2)
{
fmpz_set_ui(u, j);
fmpz_pow_ui(u, u, n);
m = j;
/* Process each m = 2^p * j */
while (1)
{
if (m > max_bc)
_fmpz_addmul_alt(s, bc+k-m, u, k + m);
else
_fmpz_addmul_alt(s, bc+m, u, k + m);
m *= 2;
if (m > k)
break;
fmpz_mul_2exp(u, u, n);
}
}
_fmpz_vec_clear(bc, max_bc + 1);
fmpz_fac_ui(t, k);
fmpz_divexact(s, s, t);
fmpz_clear(t);
fmpz_clear(u);
}
void
arith_stirling_number_2(fmpz_t s, slong n, slong k)
{
if (n < 0 || k < 0 || k > n)
{
fmpz_zero(s);
return;
}
/* Topmost diagonals */
if (k >= n - 1)
{
if (k == n)
fmpz_one(s);
else /* k == n - 1 */
{
/* S(n,n-1) = binomial(n,2) */
fmpz_set_ui(s, n);
fmpz_mul_ui(s, s, n-1);
fmpz_divexact_ui(s, s, UWORD(2));
}
return;
}
/* Leftmost columns */
if (k <= 2)
{
if (k < 2)
fmpz_set_ui(s, k);
else
{
/* S(n,2) = 2^(n-1)-1 */
fmpz_one(s);
fmpz_mul_2exp(s, s, n-1);
fmpz_sub_ui(s, s, UWORD(1));
}
return;
}
_fmpz_stirling2_powsum(s, n, k);
}
void
arith_stirling_number_2_vec(fmpz * row, slong n, slong klen)
{
slong m;
for (m = 0; m <= n; m++)
arith_stirling_number_2_vec_next(row, row, m, klen);
}

119
external/flint-2.4.3/arith/stirlingmat.c vendored Normal file
View File

@ -0,0 +1,119 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010, 2013 Fredrik Johansson
******************************************************************************/
#include "arith.h"
void arith_stirling_number_1u_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen)
{
slong k;
if (klen > n) fmpz_one(row + n);
if (n != 0 && klen != 0) fmpz_zero(row);
for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--)
{
fmpz_mul_ui(row + k, prev + k, n - UWORD(1));
fmpz_add(row + k, prev + k - 1, row + k);
}
for (k = n + 1; k < klen; k++)
fmpz_zero(row + k);
}
void arith_stirling_number_1_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen)
{
slong k;
if (klen > n) fmpz_one(row + n);
if (n != 0 && klen != 0) fmpz_zero(row);
for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--)
{
fmpz_mul_ui(row + k, prev + k, n - UWORD(1));
fmpz_sub(row + k, prev + k - 1, row + k);
}
for (k = n + 1; k < klen; k++)
fmpz_zero(row + k);
}
void arith_stirling_number_2_vec_next(fmpz * row,
const fmpz * prev, slong n, slong klen)
{
slong k;
if (klen > n) fmpz_one(row + n);
if (n != 0 && klen != 0) fmpz_zero(row);
for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--)
{
fmpz_mul_ui(row + k, prev + k, k);
fmpz_add(row + k, prev + k - 1, row + k);
}
for (k = n + 1; k < klen; k++)
fmpz_zero(row + k);
}
void
arith_stirling_matrix_1u(fmpz_mat_t mat)
{
slong n;
if (fmpz_mat_is_empty(mat))
return;
for (n = 0; n < mat->r; n++)
arith_stirling_number_1u_vec_next(mat->rows[n],
mat->rows[n - (n != 0)], n, mat->c);
}
void
arith_stirling_matrix_1(fmpz_mat_t mat)
{
slong n;
if (fmpz_mat_is_empty(mat))
return;
for (n = 0; n < mat->r; n++)
arith_stirling_number_1_vec_next(mat->rows[n],
mat->rows[n - (n != 0)], n, mat->c);
}
void
arith_stirling_matrix_2(fmpz_mat_t mat)
{
slong n;
if (fmpz_mat_is_empty(mat))
return;
for (n = 0; n < mat->r; n++)
arith_stirling_number_2_vec_next(mat->rows[n],
mat->rows[n - (n != 0)], n, mat->c);
}

View File

@ -0,0 +1,137 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz.h"
#include "arith.h"
static void
sum_of_two_squares(fmpz_t r, const fmpz_t n)
{
fmpz_factor_t fac;
slong i;
fmpz_factor_init(fac);
fmpz_factor(fac, n);
fmpz_one(r);
for (i = 0; i < fac->num; i++)
{
const int res = fmpz_fdiv_ui(fac->p + i, 4);
if (res == 1)
{
fac->exp[i]++;
fmpz_mul_ui(r, r, fac->exp[i]);
}
else if (res == 3)
{
if (fac->exp[i] % 2)
{
fmpz_zero(r);
break;
}
}
}
fmpz_mul_ui(r, r, 4);
fmpz_factor_clear(fac);
}
static void
sum_of_four_squares(fmpz_t r, const fmpz_t n)
{
const mp_bitcnt_t v = fmpz_val2(n);
if (v == 0)
{
arith_divisor_sigma(r, n, 1);
fmpz_mul_ui(r, r, 8);
}
else
{
fmpz_tdiv_q_2exp(r, n, v);
arith_divisor_sigma(r, r, 1);
fmpz_mul_ui(r, r, 24);
}
}
static void
sum_of_squares_recursive(fmpz_t r, slong k, ulong n)
{
fmpz_t t, u;
slong i, j;
fmpz_init(t);
fmpz_init(u);
fmpz_zero(r);
for (i = j = 0; j <= n; i++)
{
fmpz_set_ui(u, n - j);
arith_sum_of_squares(t, k - 1, u);
if (j > 0)
fmpz_mul_ui(t, t, 2);
fmpz_add(r, r, t);
j += 2 * i + 1;
}
fmpz_clear(t);
fmpz_clear(u);
}
static void
sum_of_squares_series(fmpz_t r, ulong k, slong n)
{
fmpz * t;
t = _fmpz_vec_init(n + 1);
arith_sum_of_squares_vec(t, k, n + 1);
fmpz_set(r, t + n);
_fmpz_vec_clear(t, n + 1);
}
void
arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n)
{
if (fmpz_sgn(n) <= 0 || k == 0)
fmpz_set_ui(r, fmpz_is_zero(n) != 0);
else if (k == 1)
fmpz_set_ui(r, 2 * (fmpz_is_square(n) != 0));
else if (k == 2)
sum_of_two_squares(r, n);
else if (k == 4)
sum_of_four_squares(r, n);
else if (k == 3 || k == 5)
sum_of_squares_recursive(r, k, fmpz_get_ui(n));
else if (fmpz_fits_si(n))
sum_of_squares_series(r, k, fmpz_get_ui(n));
else
{
flint_printf("Exception (arith_sum_of_squares). n is too large.\n");
abort();
}
}

View File

@ -0,0 +1,108 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "arith.h"
static void
theta3_qexp(fmpz * r, slong n)
{
slong i, j;
_fmpz_vec_zero(r, n);
for (i = j = 0; j < n; i++)
{
fmpz_set_ui(r + j, i == 0 ? 1 : 2);
j += 1 + 2*i;
}
}
static void
theta3_qexp_squared(fmpz * r, slong n)
{
slong i, j, x, y;
_fmpz_vec_zero(r, n);
for (x = i = 0; x < n; i++)
{
for (y = j = 0; x + y < n; j++)
{
fmpz_add_ui(r + x + y, r + x + y, (x ? 2 : 1) * (y ? 2 : 1));
y += 2 * j + 1;
}
x += 2 * i + 1;
}
}
void
arith_sum_of_squares_vec(fmpz * r, ulong k, slong n)
{
if (k == 0 || n <= 1)
{
_fmpz_vec_zero(r, n);
if (n > 0)
fmpz_set_ui(r, 1);
}
else if (k == 1)
{
theta3_qexp(r, n);
}
else if (k == 2)
{
theta3_qexp_squared(r, n);
}
else if (k % 2 == 0)
{
fmpz * t = _fmpz_vec_init(n);
theta3_qexp_squared(t, n);
_fmpz_poly_pow_trunc(r, t, k / 2, n);
_fmpz_vec_clear(t, n);
}
else
{
fmpz *t, *u;
t = _fmpz_vec_init(n);
u = _fmpz_vec_init(n);
theta3_qexp_squared(t, n);
if (k == 3)
{
theta3_qexp(u, n);
_fmpz_poly_mullow(r, t, n, u, n, n);
}
else
{
_fmpz_poly_pow_trunc(u, t, (k - 1) / 2, n);
theta3_qexp(t, n);
_fmpz_poly_mullow(r, t, n, u, n, n);
}
_fmpz_vec_clear(t, n);
_fmpz_vec_clear(u, n);
}
}

View File

@ -0,0 +1,138 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
Inspired by a Sage implementation written by William Stein.
******************************************************************************/
#include <math.h>
#include "arith.h"
/* Bound coefficients using (x + u)^(2^n) and the binomial
coefficients. TODO: this is about 2x too large... */
static slong __bound_prec(ulong n)
{
slong i;
double u, N;
N = UWORD(1) << n;
/* u = (sum of square roots)^(2^n) */
u = 0;
for (i = 0; i < n; i++)
u += sqrt(n_nth_prime(1 + i));
u = N * log(u) * 1.44269504088897;
/* Central binomial coefficient C(N,N/2) < 2^N / sqrt(3*N/2) */
u += N - 0.5*(n-1) - 0.792481250360578; /* log(sqrt(3)) */
return u;
}
void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n)
{
fmpz *square_roots, *T, *tmp1, *tmp2, *tmp3;
fmpz_t one;
slong i, j, k, N;
slong prec;
if (n == 0)
{
fmpz_poly_zero(poly);
fmpz_poly_set_coeff_ui(poly, 1, UWORD(1));
return;
}
N = WORD(1) << n;
prec = __bound_prec(n);
/* flint_printf("prec: %wd\n", prec); */
fmpz_poly_fit_length(poly, N + 1);
T = poly->coeffs;
fmpz_init(one);
fmpz_one(one);
fmpz_mul_2exp(one, one, prec);
square_roots = _fmpz_vec_init(n);
tmp1 = flint_malloc((N/2 + 1) * sizeof(fmpz));
tmp2 = flint_malloc((N/2 + 1) * sizeof(fmpz));
tmp3 = _fmpz_vec_init(N);
for (i = 0; i < n; i++)
{
fmpz_set_ui(square_roots + i, n_nth_prime(i + 1));
fmpz_mul_2exp(square_roots + i, square_roots + i, 2 * prec);
fmpz_sqrt(square_roots + i, square_roots + i);
}
/* Build linear factors */
for (i = 0; i < N; i++)
{
fmpz_zero(T + i);
for (j = 0; j < n; j++)
{
if ((i >> j) & 1)
fmpz_add(T + i, T + i, square_roots + j);
else
fmpz_sub(T + i, T + i, square_roots + j);
}
}
/* For each level... */
for (i = 0; i < n; i++)
{
slong stride = UWORD(1) << i;
for (j = 0; j < N; j += 2*stride)
{
for (k = 0; k < stride; k++)
{
tmp1[k] = T[j + k];
tmp2[k] = T[j + stride + k];
}
tmp1[stride] = *one;
tmp2[stride] = *one;
_fmpz_poly_mullow(tmp3, tmp1, stride + 1, tmp2, stride + 1, 2*stride);
_fmpz_vec_scalar_fdiv_q_2exp(T + j, tmp3, 2*stride, prec);
}
}
/* Round */
fmpz_fdiv_q_2exp(one, one, 1);
for (i = 0; i < N; i++)
fmpz_add(T + i, T + i, one);
_fmpz_vec_scalar_fdiv_q_2exp(T, T, N, prec);
fmpz_one(T + (UWORD(1) << n));
_fmpz_poly_set_length(poly, N + 1);
_fmpz_vec_clear(square_roots, n);
flint_free(tmp1);
flint_free(tmp2);
_fmpz_vec_clear(tmp3, UWORD(1) << n);
fmpz_clear(one);
}

View File

@ -0,0 +1,120 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
int main(void)
{
fmpz * b1;
fmpz * b2;
slong n, k;
const slong maxn = 400;
FLINT_TEST_INIT(state);
flint_printf("bell_number....");
fflush(stdout);
b1 = _fmpz_vec_init(maxn);
/* Consistency test */
for (n = 0; n < maxn; n++)
arith_bell_number(b1 + n, n);
for (n = 0; n < maxn; n++)
{
b2 = _fmpz_vec_init(n);
arith_bell_number_vec(b2, n);
if (!_fmpz_vec_equal(b1, b2, n))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
abort();
}
_fmpz_vec_clear(b2, n);
}
/* Compare with B_n = sum of Stirling numbers of 2nd kind */
for (n = 0; n < 1000; n += (n < 50) ? + 1 : n/4)
{
b2 = _fmpz_vec_init(n+1);
arith_stirling_number_2_vec(b2, n, n+1);
for (k = 1; k <= n; k++)
fmpz_add(b2, b2, b2 + k);
arith_bell_number(b1, n);
if (!fmpz_equal(b1, b2))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
fmpz_print(b1);
flint_printf("\n");
fmpz_print(b2);
flint_printf("\n");
abort();
}
/* Also check nmod value */
{
nmod_t mod;
mp_limb_t bb;
nmod_init(&mod, n_randtest_prime(state, 0));
bb = arith_bell_number_nmod(n, mod);
if (fmpz_fdiv_ui(b1, mod.n) != bb)
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
fmpz_print(b1);
flint_printf("\n");
flint_printf("should be %wu mod %wu\n", bb, mod.n);
abort();
}
}
_fmpz_vec_clear(b2, n+1);
}
_fmpz_vec_clear(b1, maxn);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
int main(void)
{
slong i;
FLINT_TEST_INIT(state);
flint_printf("bell_number_multi_mod....");
fflush(stdout);
for (i = 0; i < 100; i++)
{
slong n;
fmpz_t b1, b2;
fmpz_init(b1);
fmpz_init(b2);
n = n_randint(state, 500);
arith_bell_number_bsplit(b1, n);
arith_bell_number_multi_mod(b2, n);
if (!fmpz_equal(b1, b2))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
abort();
}
fmpz_clear(b1);
fmpz_clear(b2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,77 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
int main(void)
{
slong i, j;
FLINT_TEST_INIT(state);
flint_printf("bell_number_nmod....");
fflush(stdout);
for (i = 0; i < 10; i++)
{
mp_ptr b;
slong n;
nmod_t mod;
mp_limb_t p;
n = n_randint(state, 1000);
p = n_randtest_prime(state, 0);
nmod_init(&mod, p);
b = _nmod_vec_init(n + 1);
arith_bell_number_nmod_vec(b, n + 1, mod);
for (j = 0; j <= n; j++)
{
mp_limb_t u = arith_bell_number_nmod(j, mod);
if (u != b[j])
{
flint_printf("FAIL: p = %wu, i = %wd\n", p, j);
abort();
}
}
_nmod_vec_clear(b);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,78 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "nmod_vec.h"
#include "ulong_extras.h"
int main(void)
{
mp_ptr b1, b2;
slong n;
const slong maxn = 3000;
FLINT_TEST_INIT(state);
flint_printf("bell_number_nmod_vec....");
fflush(stdout);
b1 = _nmod_vec_init(maxn);
b2 = _nmod_vec_init(maxn);
for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4)
{
nmod_t mod;
mp_limb_t p;
do {
p = n_randtest_prime(state, 0);
} while (p < n);
nmod_init(&mod, p);
arith_bell_number_nmod_vec_recursive(b1, n, mod);
arith_bell_number_nmod_vec_series(b2, n, mod);
if (!_nmod_vec_equal(b1, b2, n))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
abort();
}
}
_nmod_vec_clear(b1);
_nmod_vec_clear(b2);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,69 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
int main(void)
{
fmpz * b1;
fmpz * b2;
slong n;
const slong maxn = 1000;
FLINT_TEST_INIT(state);
flint_printf("bell_number_vec....");
fflush(stdout);
b1 = _fmpz_vec_init(maxn);
b2 = _fmpz_vec_init(maxn);
for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4)
{
arith_bell_number_vec_recursive(b1, n);
arith_bell_number_vec_multi_mod(b2, n);
if (!_fmpz_vec_equal(b1, b2, n))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
abort();
}
}
_fmpz_vec_clear(b1, maxn);
_fmpz_vec_clear(b2, maxn);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,120 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
#include "fmpq.h"
int main()
{
fmpz * num1;
fmpz * den1;
fmpz_t num2;
fmpz_t den2;
slong n, N;
FLINT_TEST_INIT(state);
flint_printf("bernoulli_number....");
fflush(stdout);
N = 4000;
num1 = _fmpz_vec_init(N);
den1 = _fmpz_vec_init(N);
fmpz_init(num2);
fmpz_init(den2);
_arith_bernoulli_number_vec_multi_mod(num1, den1, N);
for (n = 0; n < N; n++)
{
_arith_bernoulli_number(num2, den2, n);
if (!fmpz_equal(num1 + n, num2))
{
flint_printf("FAIL: n = %wd, numerator\n", n);
flint_printf("vec: "); fmpz_print(num1 + n); flint_printf("\n");
flint_printf("single: "); fmpz_print(num2); flint_printf("\n");
abort();
}
if (!fmpz_equal(den1 + n, den2))
{
flint_printf("FAIL: n = %wd, denominator\n", n);
flint_printf("vec: "); fmpz_print(den1 + n); flint_printf("\n");
flint_printf("single: "); fmpz_print(den2); flint_printf("\n");
abort();
}
}
/* Check non underscore versions */
do
{
slong N = 100;
fmpq * x;
fmpq_t t;
fmpq_init(t);
x = flint_malloc(sizeof(fmpq) * N);
for (n = 0; n < N; n++)
fmpq_init(x + n);
arith_bernoulli_number_vec(x, N);
for (n = 0; n < N; n++)
{
arith_bernoulli_number(t, n);
if (!fmpq_equal(x + n, t))
{
flint_printf("FAIL!: n = %wd\n", n);
abort();
}
}
for (n = 0; n < N; n++)
fmpq_clear(x + n);
flint_free(x);
fmpq_clear(t);
} while (0);
_fmpz_vec_clear(num1, N);
_fmpz_vec_clear(den1, N);
fmpz_clear(num2);
fmpz_clear(den2);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,67 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "ulong_extras.h"
int main()
{
fmpz_t s, t;
slong n;
FLINT_TEST_INIT(state);
flint_printf("bernoulli_number_denom....");
fflush(stdout);
fmpz_init(s);
fmpz_init(t);
for (n = 0; n < 1000; n++)
{
arith_bernoulli_number_denom(t, n);
fmpz_addmul_ui(s, t, n_nth_prime(n+1));
}
fmpz_set_str(t, "34549631155954474103407159", 10);
if (!fmpz_equal(s, t))
{
flint_printf("FAIL: Hash disagrees with known value\n");
abort();
}
fmpz_clear(s);
fmpz_clear(t);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,102 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
int main()
{
fmpz * num1;
fmpz * num2;
fmpz * num3;
fmpz * den1;
fmpz * den2;
fmpz * den3;
slong i, n, N;
FLINT_TEST_INIT(state);
flint_printf("bernoulli_number_vec....");
fflush(stdout);
N = 2000;
num1 = _fmpz_vec_init(N);
num2 = _fmpz_vec_init(N);
num3 = _fmpz_vec_init(N);
den1 = _fmpz_vec_init(N);
den2 = _fmpz_vec_init(N);
den3 = _fmpz_vec_init(N);
for (n = 0; n < N; n += (n<100) ? 1 : n/3)
{
_arith_bernoulli_number_vec_recursive(num1, den1, n);
_arith_bernoulli_number_vec_multi_mod(num2, den2, n);
_arith_bernoulli_number_vec_zeta(num3, den3, n);
for (i = 0; i < n; i++)
{
if (!fmpz_equal(num1 + i, num2 + i) ||
!fmpz_equal(num1 + i, num3 + i))
{
flint_printf("FAIL: n = %wd, numerator of B_%wd\n", n, i);
flint_printf("recursive: "); fmpz_print(num1 + i); flint_printf("\n");
flint_printf("multi_mod: "); fmpz_print(num2 + i); flint_printf("\n");
flint_printf("zeta: "); fmpz_print(num3 + i); flint_printf("\n");
abort();
}
if (!fmpz_equal(den1 + i, den2 + i) ||
!fmpz_equal(den1 + i, den3 + i))
{
flint_printf("FAIL: n = %wd, denominator of B_%wd\n", n, i);
flint_printf("recursive: "); fmpz_print(den1 + i); flint_printf("\n");
flint_printf("multi_mod: "); fmpz_print(den2 + i); flint_printf("\n");
flint_printf("zeta: "); fmpz_print(den3 + i); flint_printf("\n");
abort();
}
}
}
_fmpz_vec_clear(num1, N);
_fmpz_vec_clear(num2, N);
_fmpz_vec_clear(num3, N);
_fmpz_vec_clear(den1, N);
_fmpz_vec_clear(den2, N);
_fmpz_vec_clear(den3, N);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,89 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
int main()
{
fmpq_poly_t P, Q;
mpz_t t;
slong k, n;
FLINT_TEST_INIT(state);
flint_printf("bernoulli_polynomial....");
fflush(stdout);
for (n = 0; n <= 100; n++)
{
fmpq_poly_init(P);
fmpq_poly_init(Q);
mpz_init(t);
for (k = 0; k <= n; k++)
{
arith_bernoulli_polynomial(P, k);
flint_mpz_bin_uiui(t, n+1, k);
fmpq_poly_scalar_mul_mpz(P, P, t);
fmpq_poly_add(Q, Q, P);
}
fmpq_poly_scalar_div_ui(Q, Q, n+1);
mpz_clear(t);
fmpq_poly_zero(P);
fmpq_poly_set_coeff_ui(P, n, UWORD(1));
if (!fmpq_poly_equal(P, Q))
{
flint_printf("ERROR: sum up to n = %wd did not add to x^n\n", n);
flint_printf("Sum: ");
fmpq_poly_print_pretty(Q, "x");
flint_printf("\nExpected: ");
fmpq_poly_print_pretty(P, "x");
flint_printf("\n");
abort();
}
fmpq_poly_clear(P);
fmpq_poly_clear(Q);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,82 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "fmpz_poly.h"
int main()
{
fmpz_poly_t T0, T1, T2, t;
slong n;
FLINT_TEST_INIT(state);
flint_printf("chebyshev_t_polynomial....");
fflush(stdout);
fmpz_poly_init(T0);
fmpz_poly_init(T1);
fmpz_poly_init(T2);
fmpz_poly_init(t);
arith_chebyshev_t_polynomial(T0, 0);
arith_chebyshev_t_polynomial(T1, 1);
for (n = 2; n <= 500; n++)
{
arith_chebyshev_t_polynomial(T2, n);
/* Verify T_{n+1} = 2 x T_n - T_{n-1} */
fmpz_poly_scalar_mul_ui(t, T1, UWORD(2));
fmpz_poly_shift_left(t, t, 1);
fmpz_poly_sub(t, t, T0);
if (!fmpz_poly_equal(t, T2))
{
flint_printf("FAIL: n = %wd\n", n);
flint_printf("t: "); fmpz_poly_print_pretty(t, "x"); flint_printf("\n");
flint_printf("T2: "); fmpz_poly_print_pretty(T2, "x"); flint_printf("\n");
abort();
}
fmpz_poly_swap(T0, T1);
fmpz_poly_swap(T1, T2);
}
fmpz_poly_clear(T0);
fmpz_poly_clear(T1);
fmpz_poly_clear(T2);
fmpz_poly_clear(t);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "fmpz_poly.h"
int main()
{
fmpz_poly_t T, U;
slong n;
FLINT_TEST_INIT(state);
flint_printf("chebyshev_u_polynomial....");
fflush(stdout);
fmpz_poly_init(T);
fmpz_poly_init(U);
for (n = 0; n <= 500; n++)
{
arith_chebyshev_u_polynomial(U, n);
arith_chebyshev_t_polynomial(T, n + 1);
fmpz_poly_derivative(T, T);
fmpz_poly_scalar_divexact_ui(T, T, n + 1);
if (!fmpz_poly_equal(T, U))
{
flint_printf("FAIL: n = %wd\n", n);
flint_printf("T: "); fmpz_poly_print_pretty(T, "x"); flint_printf("\n");
flint_printf("U: "); fmpz_poly_print_pretty(U, "x"); flint_printf("\n");
abort();
}
}
fmpz_poly_clear(T);
fmpz_poly_clear(U);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,129 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "fmpz_poly.h"
/*
Generated with Mathematica:
Table[Mod[MinimalPolynomial[Cos[2 Pi/n]][1337], 31337], {n,1,500}]
*/
static const short testdata[] = {
1,
1336, 1338, 2675, 1337, 8113, 2673, 6283, 2719, 29508, 2765, 6949,
5437, 2788, 26742, 25554, 26194, 29376, 29506, 30945, 15614, 8957,
16643, 9263, 21050, 30556, 10533, 1570, 11562, 3988, 16546, 26642, 4041,
3581, 109, 9839, 27175, 11691, 1460, 28287, 18369, 16503, 3184, 13336,
23083, 12495, 3246, 14160, 8081, 5301, 8652, 28989, 24149, 17733, 1568,
4800, 28863, 29280, 13741, 30919, 29819, 28584, 8913, 550, 6207, 13930,
23373, 12644, 15265, 27975, 30386, 1603, 15894, 22276, 3138, 11610,
2208, 515, 30817, 23050, 4333, 25031, 13615, 5116, 18609, 25490, 14555,
22663, 8425, 21751, 19293, 3, 10688, 26829, 14467, 1426, 12413, 5305,
25377, 27164, 3711,
9613, 22340, 7457, 3704, 1795, 22877, 31060, 17472, 11317, 22274,
11036, 7796, 27242, 22174, 3663, 10507, 16599, 18192, 15208, 7257, 7022,
10810, 27891, 18495, 7032, 11383, 20768, 27351, 31089, 27723, 10486,
2075, 25298, 20531, 28548, 25342, 6510, 20657, 15608, 5534, 22145,
30150, 25222, 12128, 389, 21860, 9631, 4536, 4704, 3677, 27282, 26668,
20784, 15684, 12847, 1307, 10586, 24355, 27553, 10952, 8886, 25029,
29278, 29964, 17943, 1006, 5895, 11466, 16679, 17500, 5414, 3420, 17644,
5165, 6255, 2807, 30577, 26277, 14032, 2425, 13945, 27988, 17437, 28204,
11853, 12265, 8097, 24919, 10703, 18081, 19121, 23364, 14035, 2382,
1722, 21617, 11863, 27682, 8538, 26401,
1487, 14570, 14213, 18315, 30244, 14611, 25421, 13954, 29802,
29118, 5788, 7547, 9710, 21645, 17858, 20672, 2295, 21286, 7217, 30405,
5090, 22674, 5747, 5809, 13789, 16385, 23732, 12258, 10944, 14669, 2043,
1453, 13510, 12422, 24073, 3025, 28094, 2770, 9198, 27411, 24736, 28958,
23508, 27897, 17838, 10690, 5375, 29469, 22458, 9466, 28541, 16308,
20491, 10320, 9836, 673, 26630, 20819, 25687, 19263, 16620, 28683,
30268, 1113, 26632, 18450, 17555, 20121, 18083, 12796, 26659, 9788,
10448, 2828, 29753, 26653, 13636, 6270, 10398, 16224, 1481, 1153, 26387,
17835, 19289, 2683, 1937, 16760, 14372, 12632, 15716, 12423, 24202,
14543, 10763, 27059, 437, 18647, 17133, 27774,
2039, 3931, 7737, 20470, 11068, 26238, 28463, 22610, 28349, 23819,
22780, 4101, 13218, 12878, 25048, 25163, 11032, 10129, 2571, 9319,
11708, 6704, 19105, 11593, 24863, 26090, 15235, 18038, 22056, 19624,
12066, 9798, 16508, 22376, 15776, 10595, 28391, 18898, 11645, 16655,
19391, 11364, 28198, 4348, 6653, 11962, 22652, 18750, 22125, 21504,
23718, 25662, 6768, 24234, 29605, 8280, 5246, 23064, 1360, 21538, 4374,
8186, 7540, 24091, 3017, 23007, 12000, 11289, 8698, 22118, 5505, 18535,
29647, 15878, 4416, 8598, 13062, 8878, 9674, 5066, 17770, 24888, 20643,
1345, 22570, 1363, 3710, 18429, 11731, 14885, 12983, 18600, 26334,
27101, 17858, 22221, 2471, 911, 12033, 2824,
6354, 984, 28507, 3521, 17963, 6558, 11166, 24004, 24367, 8572,
19198, 6937, 15220, 13122, 3540, 589, 17503, 14073, 14954, 26020, 12974,
20684, 19844, 17852, 1097, 10831, 23848, 7013, 15683, 15954, 22290,
30257, 15807, 22775, 13607, 9428, 30055, 11607, 30426, 2579, 340, 29747,
25213, 28551, 5705, 15704, 10625, 16932, 3215, 16716, 6698, 21470,
29839, 511, 23506, 4338, 30506, 18038, 20430, 20586, 18225, 7721, 15812,
3140, 22149, 4949, 8125, 9897, 6323, 20612, 2012, 23744, 9414, 16497,
5557, 5225, 8518, 30549, 21805, 5692, 25222, 16326, 22995, 27432, 16385,
23506, 9911, 23131, 3880, 30647, 13222, 10416, 5619, 2078, 9411, 12398,
22772, 7328, 17932, 19965,
-1
};
int main()
{
fmpz_poly_t p;
slong n;
FLINT_TEST_INIT(state);
flint_printf("cyclotomic_cos_polynomial....");
fflush(stdout);
fmpz_poly_init(p);
for (n = 0; testdata[n] != -1; n++)
{
mp_limb_t y;
arith_cos_minpoly(p, n);
y = fmpz_poly_evaluate_mod(p, 1337, 31337);
if (y != testdata[n])
{
flint_printf("FAIL: n = %wd\n", n);
flint_printf("y = %wu\n", y);
flint_printf("\n");
abort();
}
}
fmpz_poly_clear(p);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,145 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "fmpz_poly.h"
#include "ulong_extras.h"
void cyclotomic_naive(fmpz_poly_t poly, ulong n)
{
fmpz_poly_t t;
slong d;
fmpz_poly_init(t);
fmpz_poly_set_ui(poly, UWORD(1));
for (d = 1; d <= n; d++)
{
if (n % d == 0)
{
if (n_moebius_mu(n / d) == 1)
{
fmpz_poly_zero(t);
fmpz_poly_set_coeff_si(t, d, 1);
fmpz_poly_set_coeff_si(t, 0, -1);
fmpz_poly_mul(poly, poly, t);
}
}
}
for (d = 1; d <= n; d++)
{
if (n % d == 0)
{
if (n_moebius_mu(n / d) == -1)
{
fmpz_poly_zero(t);
fmpz_poly_set_coeff_si(t, d, 1);
fmpz_poly_set_coeff_si(t, 0, -1);
fmpz_poly_div(poly, poly, t);
}
}
}
fmpz_poly_clear(t);
}
int main()
{
fmpz_poly_t A, B;
slong n;
FLINT_TEST_INIT(state);
flint_printf("cyclotomic_polynomial....");
fflush(stdout);
for (n = 0; n <= 1000; n++)
{
fmpz_poly_init(A);
fmpz_poly_init(B);
arith_cyclotomic_polynomial(A, n);
cyclotomic_naive(B, n);
if (!fmpz_poly_equal(A, B))
{
flint_printf("FAIL: wrong value of Phi_%wd(x)\n", n);
flint_printf("Computed:\n");
fmpz_poly_print_pretty(A, "x");
flint_printf("\n\nExpected:\n");
fmpz_poly_print_pretty(B, "x");
flint_printf("\n\n");
abort();
}
fmpz_poly_clear(A);
fmpz_poly_clear(B);
}
/* We verify the first value that does not fit on 32 bits.
This exercises the slow path at least on a 32 bit system.
Testing the 64 bit value is a bit too much to do by default
as it requires ~2 GB of memory and takes a few minutes. */
{
fmpz_t h, ref;
const ulong nn = UWORD(10163195);
/* const ulong nn = UWORD(169828113); 64-bit case */
fmpz_init(h);
fmpz_init(ref);
fmpz_set_str(ref, "1376877780831", 10);
/* fmpz_set_str(ref, "31484567640915734941", 10); 64-bit case */
fmpz_poly_init(A);
arith_cyclotomic_polynomial(A, UWORD(10163195));
fmpz_poly_height(h, A);
if (!fmpz_equal(h, ref))
{
flint_printf("Bad computation of Phi_%wd(x)\n", nn);
flint_printf("Computed height:\n");
fmpz_print(h);
flint_printf("\nExpected height:\n");
fmpz_print(ref);
flint_printf("\n\n");
abort();
}
fmpz_poly_clear(A);
fmpz_clear(h);
fmpz_clear(ref);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,192 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpq.h"
#include "arith.h"
#include "ulong_extras.h"
#include "math.h"
/*
The results in the following random test cases were computed with the
naive implementation. Doing a live comparison with large values against
the naive implementation would take too much time.
*/
static const slong testdata[][4] =
{
/* h, k, p/q */
{WORD(20816815), WORD(29229), WORD(-10669), WORD(87687)},
{WORD(-481962612), WORD(709105), WORD(-910639), WORD(141821)},
{WORD(-70965), WORD(3384), WORD(1785), WORD(752)},
{WORD(1899905), WORD(6657), WORD(-43795), WORD(5706)},
{WORD(-1893), WORD(511167), WORD(-3411568), WORD(170389)},
{WORD(1417295), WORD(10180), WORD(3543), WORD(4072)},
{WORD(-1149), WORD(9350), WORD(6971), WORD(9350)},
{WORD(-15520), WORD(22977640), WORD(-70331425), WORD(574441)},
{WORD(3339), WORD(9873153), WORD(270746882), WORD(1097017)},
{WORD(470645896), WORD(71754), WORD(-21713), WORD(107631)},
{WORD(1153), WORD(1332403), WORD(258755243), WORD(2664806)},
{WORD(-501576), WORD(292801), WORD(269095), WORD(292801)},
{WORD(1861), WORD(34440), WORD(-723059), WORD(206640)},
{WORD(-4278761), WORD(239321), WORD(791947), WORD(239321)},
{WORD(9414763), WORD(30776409), WORD(-93285463), WORD(92329227)},
{WORD(4872687), WORD(2199), WORD(146), WORD(733)},
{WORD(-22349505), WORD(60581653), WORD(27694241), WORD(60581653)},
{WORD(85739724), WORD(9289), WORD(961), WORD(2654)},
{WORD(-5616), WORD(124023), WORD(-31447), WORD(41341)},
{WORD(99382204), WORD(1378843), WORD(-2537405), WORD(2757686)},
{WORD(1903), WORD(15842), WORD(102), WORD(89)},
{WORD(-907226), WORD(5818), WORD(5608), WORD(2909)},
{WORD(-948920), WORD(4768), WORD(-4815), WORD(1192)},
{WORD(-352220914), WORD(15390287), WORD(-171358081), WORD(30780574)},
{WORD(-159206), WORD(3028284), WORD(12921745), WORD(4542426)},
{WORD(61951448), WORD(1624), WORD(-341), WORD(406)},
{WORD(-49167), WORD(2092), WORD(-32915), WORD(4184)},
{WORD(-20878222), WORD(586303210), WORD(-530581301), WORD(293151605)},
{WORD(-1435637), WORD(3483), WORD(-4787), WORD(20898)},
{WORD(-1129797), WORD(171620), WORD(238211), WORD(68648)},
{WORD(-177095), WORD(2914), WORD(1132), WORD(1457)},
{WORD(-343227551), WORD(1509), WORD(-3289), WORD(4527)},
{WORD(57497376), WORD(1351), WORD(373), WORD(2702)},
{WORD(3350543), WORD(5771893), WORD(-51196457), WORD(5771893)},
{WORD(-44408), WORD(1670), WORD(367), WORD(1670)},
{WORD(-4139), WORD(59959), WORD(-286689), WORD(119918)},
{WORD(7397588), WORD(16695), WORD(-41627), WORD(20034)},
{WORD(-78900791), WORD(10792), WORD(-30905), WORD(21584)},
{WORD(-1204294), WORD(10134), WORD(-8945), WORD(30402)},
{WORD(27649424), WORD(57014291), WORD(731583513), WORD(114028582)},
{WORD(3275043), WORD(436410815), WORD(2018428417), WORD(174564326)},
#if FLINT64 /* skip on 32 bit only because of the literals */
{WORD(61247), WORD(81381215), WORD(3622491319), WORD(32552486)},
{WORD(-52118), WORD(125095621), WORD(-24931204413), WORD(125095621)},
{WORD(201446493), WORD(951783261), WORD(2467429915), WORD(634522174)},
{WORD(176112), WORD(72187934), WORD(2692844825), WORD(72187934)},
{WORD(1272), WORD(8722219), WORD(9972821075), WORD(17444438)},
#endif
{0, 0, 0, 0}
};
int main(void)
{
fmpz_t hh, kk;
fmpq_t s1, s2;
slong i, h, k;
FLINT_TEST_INIT(state);
flint_printf("dedekind_sum....");
fflush(stdout);
fmpz_init(hh);
fmpz_init(kk);
fmpq_init(s1);
fmpq_init(s2);
for (k = -200; k < 200; k++)
{
for (h = -200; h < 200; h++)
{
fmpz_set_si(hh, h);
fmpz_set_si(kk, k);
arith_dedekind_sum(s1, hh, kk);
arith_dedekind_sum_naive(s2, hh, kk);
if (!fmpq_equal(s1, s2))
{
flint_printf("FAIL:\n");
flint_printf("s(%wd,%wd)\n", h, k);
flint_printf("s1: "); fmpq_print(s1); flint_printf("\n");
flint_printf("s2: "); fmpq_print(s2); flint_printf("\n");
abort();
}
}
}
/* Test large values, 10-30 bits */
for (i = 0; testdata[i][0] != 0; i++)
{
h = testdata[i][0];
k = testdata[i][1];
fmpz_set_si(hh, h);
fmpz_set_si(kk, k);
arith_dedekind_sum(s1, hh, kk);
fmpz_set_si(fmpq_numref(s2), testdata[i][2]);
fmpz_set_si(fmpq_denref(s2), testdata[i][3]);
if (!fmpq_equal(s1, s2))
{
flint_printf("FAIL:\n");
flint_printf("s(%wd,%wd)\n", h, k);
flint_printf("s1: "); fmpq_print(s1); flint_printf("\n");
flint_printf("s2: "); fmpq_print(s2); flint_printf("\n");
abort();
}
}
/* Check a large value computed with Pari */
fmpz_set_ui(hh, 1);
fmpz_mul_2exp(hh, hh, 1000);
fmpz_add_ui(hh, hh, 1);
fmpz_set_ui(kk, 1);
fmpz_mul_2exp(kk, kk, 1001);
fmpz_add_ui(kk, kk, 1);
arith_dedekind_sum(s1, hh, kk);
if ((fmpz_fdiv_ui(fmpq_numref(s1), 1000000000) != 906445312) ||
(fmpz_fdiv_ui(fmpq_denref(s1), 1000000000) != 8416259))
{
flint_printf("Wrong large value:\n");
fmpq_print(s1);
flint_printf("\n");
abort();
}
/* Just check that nothing crashes with bignums */
for (i = 0; i < 1000; i++)
{
fmpz_randtest(hh, state, 300);
fmpz_randtest(kk, state, 300);
arith_dedekind_sum(s1, hh, kk);
}
fmpz_clear(hh);
fmpz_clear(kk);
fmpq_clear(s1);
fmpq_clear(s2);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,86 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpq.h"
#include "arith.h"
#include "ulong_extras.h"
#include "math.h"
int main(void)
{
double s1, s2f;
fmpz_t hh, kk;
fmpq_t s2;
slong h, k;
FLINT_TEST_INIT(state);
flint_printf("dedekind_sum_coprime_d....");
fflush(stdout);
fmpz_init(hh);
fmpz_init(kk);
fmpq_init(s2);
for (k = 0; k < 300; k++)
{
for (h = 0; h <= k; h++)
{
if (n_gcd(k, h) == 1)
{
fmpz_set_si(hh, h);
fmpz_set_si(kk, k);
s1 = arith_dedekind_sum_coprime_d(h, k);
arith_dedekind_sum_naive(s2, hh, kk);
s2f = ((double)fmpz_get_si(fmpq_numref(s2))) /
fmpz_get_si(fmpq_denref(s2));
if (fabs(s1 - s2f) > 1e-10)
{
flint_printf("FAIL:\n");
flint_printf("s(%wd,%wd)\n", h, k);
flint_printf("s1: %.20f\n", s1);
flint_printf("s2: %.20f\n", s2f);
flint_printf("Exact: "); fmpq_print(s2); flint_printf("\n");
abort();
}
}
}
}
fmpz_clear(hh);
fmpz_clear(kk);
fmpq_clear(s2);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,83 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpq.h"
#include "arith.h"
#include "ulong_extras.h"
#include "math.h"
int main(void)
{
fmpz_t hh, kk;
fmpq_t s1, s2;
slong h, k;
FLINT_TEST_INIT(state);
flint_printf("dedekind_sum_coprime_large....");
fflush(stdout);
fmpz_init(hh);
fmpz_init(kk);
fmpq_init(s1);
fmpq_init(s2);
for (k = 0; k < 300; k++)
{
for (h = 0; h <= k; h++)
{
if (n_gcd(k, h) == 1)
{
fmpz_set_si(hh, h);
fmpz_set_si(kk, k);
arith_dedekind_sum_coprime_large(s1, hh, kk);
arith_dedekind_sum_naive(s2, hh, kk);
if (!fmpq_equal(s1, s2))
{
flint_printf("FAIL:\n");
flint_printf("s(%wd,%wd)\n", h, k);
flint_printf("s1: "); fmpq_print(s1); flint_printf("\n");
flint_printf("s2: "); fmpq_print(s2); flint_printf("\n");
abort();
}
}
}
}
fmpz_clear(hh);
fmpz_clear(kk);
fmpq_clear(s1);
fmpq_clear(s2);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,94 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "fmpz_poly.h"
#include "fmpz.h"
#include "arith.h"
#include "ulong_extras.h"
void fmpz_sigma_naive(fmpz_t x, ulong n, ulong k)
{
slong i = 0;
fmpz_t t;
fmpz_poly_t p;
fmpz_init(t);
fmpz_poly_init(p);
fmpz_set_ui(t, n);
arith_divisors(p, t);
fmpz_zero(x);
for (i = 0; i < p->length; i++)
{
fmpz_poly_get_coeff_fmpz(t, p, i);
fmpz_pow_ui(t, t, k);
fmpz_add(x, x, t);
}
fmpz_clear(t);
fmpz_poly_clear(p);
}
int main(void)
{
fmpz_t m, a, b;
slong n, k;
FLINT_TEST_INIT(state);
flint_printf("divisor_sigma....");
fflush(stdout);
fmpz_init(a);
fmpz_init(b);
fmpz_init(m);
for (n = 0; n < 5000; n++)
{
for (k = 0; k < 10; k++)
{
fmpz_set_ui(m, n);
arith_divisor_sigma(a, m, k);
fmpz_sigma_naive(b, n, k);
if (!fmpz_equal(a, b))
{
flint_printf("FAIL:\n");
flint_printf("wrong value for n=%wd, k=%wd\n", n, k);
abort();
}
}
}
fmpz_clear(a);
fmpz_clear(b);
fmpz_clear(m);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,86 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "fmpz_poly.h"
#include "arith.h"
#include "ulong_extras.h"
void arith_divisors_naive(fmpz_poly_t p, slong n)
{
slong k;
slong i = 0;
n = FLINT_ABS(n);
fmpz_poly_zero(p);
for (k = 1; k <= n; k++)
{
if (n % k == 0)
{
fmpz_poly_set_coeff_si(p, i, k);
i++;
}
}
}
int main(void)
{
fmpz_t t;
fmpz_poly_t a, b;
slong n;
FLINT_TEST_INIT(state);
flint_printf("divisors....");
fflush(stdout);
fmpz_init(t);
fmpz_poly_init(a);
fmpz_poly_init(b);
for (n = -1000; n < 1000; n++)
{
fmpz_set_si(t, n);
arith_divisors(a, t);
arith_divisors_naive(b, n);
if (!fmpz_poly_equal(a, b))
{
flint_printf("FAIL:\n");
flint_printf("wrong value for n=%wd\n", n);
abort();
}
}
fmpz_clear(t);
fmpz_poly_clear(a);
fmpz_poly_clear(b);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,81 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_vec.h"
int main()
{
fmpz * r;
fmpz_t s, t;
slong k, n;
FLINT_TEST_INIT(state);
flint_printf("euler_number_vec....");
fflush(stdout);
for (n = 2; n <= 3000; n += (n<100) ? 2 : n/3)
{
n += n % 2;
r = _fmpz_vec_init(n + 1);
fmpz_init(s);
fmpz_init(t);
arith_euler_number_vec(r, n + 1);
/* sum binomial(n,k) E_k = 0 */
fmpz_set_ui(t, UWORD(1));
for (k = 0; k <= n; k++)
{
fmpz_addmul(s, r + k, t);
fmpz_mul_ui(t, t, n - k);
fmpz_divexact_ui(t, t, k + 1);
}
if (!fmpz_is_zero(s))
{
flint_printf("ERROR: sum over 0,...,n = %wd\n", n);
_fmpz_vec_print(r, n + 1);
abort();
}
fmpz_clear(s);
fmpz_clear(t);
_fmpz_vec_clear(r, n + 1);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,74 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
int main()
{
fmpz * ress;
fmpz_t res;
slong n, N;
FLINT_TEST_INIT(state);
flint_printf("euler_number_zeta....");
fflush(stdout);
N = 3000;
ress = _fmpz_vec_init(N);
arith_euler_number_vec(ress, N);
for (n = 0; n < N; n++)
{
fmpz_init(res);
arith_euler_number(res, n);
if (!fmpz_equal(res, ress + n))
{
flint_printf("FAIL: n = %wd\n", n);
flint_printf("Value: "); fmpz_print(res); flint_printf("\n");
abort();
}
fmpz_clear(res);
}
_fmpz_vec_clear(ress, N);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,118 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "ulong_extras.h"
#include "profiler.h"
int main(void)
{
slong i;
ulong n;
fmpz_t x, y, z;
FLINT_TEST_INIT(state);
flint_printf("euler_phi....");
fflush(stdout);
fmpz_init(x);
fmpz_init(y);
fmpz_init(z);
for (i = 0; i < 100; i++)
{
fmpz_set_ui(x, i);
arith_euler_phi(y, x);
arith_euler_phi(x, x);
fmpz_set_ui(z, n_euler_phi(i));
if (!fmpz_equal(x, y) || !fmpz_equal(x, z))
{
flint_printf("FAIL: %wd\n", i);
abort();
}
}
/* Aliasing test */
for (i = 0; i < 1000; i++)
{
fmpz_randtest(x, state, FLINT_BITS);
fmpz_randtest(y, state, 5);
fmpz_pow_ui(y, y, n_randtest(state) % 100);
fmpz_mul(x, x, y);
fmpz_set(z, x);
arith_euler_phi(y, x);
arith_euler_phi(x, x);
if (!fmpz_equal(x, y))
{
flint_printf("FAIL: ");
fmpz_print(z);
flint_printf("\n");
abort();
}
}
/* Power of a single prime, phi(p^n) = (p-1) * p^(n-1) */
for (i = 0; i < 100; i++)
{
n = (n_randtest(state) % 100) + 1;
fmpz_set_ui(x, n_nth_prime(i+1));
fmpz_pow_ui(x, x, n);
arith_euler_phi(x, x);
fmpz_set_ui(y, n_nth_prime(i+1));
fmpz_pow_ui(y, y, n-1);
fmpz_mul_ui(y, y, n_nth_prime(i+1)-1);
if (!fmpz_equal(x, y))
{
flint_printf("FAIL: %wu ^ %wu\n", n_nth_prime(i+1), n);
}
}
/* Something nontrivial */
fmpz_set_str(x, "10426024348053113487152988625265848110501553295256578345594388516660144", 10);
fmpz_set_str(y, "2265085829098571747262267425315881590169106756213617459200000000000000", 10);
arith_euler_phi(x, x);
if (!fmpz_equal(x, y))
{
flint_printf("FAIL: special test value\n");
abort();
}
fmpz_clear(x);
fmpz_clear(y);
fmpz_clear(z);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,93 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
int main()
{
fmpq_poly_t P, Q;
mpz_t t;
slong k, n;
FLINT_TEST_INIT(state);
flint_printf("euler_polynomial....");
fflush(stdout);
for (n = 0; n <= 100; n++)
{
fmpq_poly_init(P);
fmpq_poly_init(Q);
mpz_init(t);
for (k = 0; k < n; k++)
{
arith_euler_polynomial(P, k);
flint_mpz_bin_uiui(t, n, k);
fmpq_poly_scalar_mul_mpz(P, P, t);
fmpq_poly_add(Q, Q, P);
}
fmpq_poly_scalar_div_ui(Q, Q, 2);
arith_euler_polynomial(P, n);
fmpq_poly_add(Q, Q, P);
mpz_clear(t);
fmpq_poly_zero(P);
fmpq_poly_set_coeff_ui(P, n, UWORD(1));
if (!fmpq_poly_equal(P, Q))
{
flint_printf("ERROR: sum up to n = %wd did not add to x^n\n", n);
flint_printf("Sum: ");
fmpq_poly_print_pretty(Q, "x");
flint_printf("\nExpected: ");
fmpq_poly_print_pretty(P, "x");
flint_printf("\n");
abort();
}
fmpq_poly_clear(P);
fmpq_poly_clear(Q);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,154 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz.h"
#include "fmpq.h"
#include "ulong_extras.h"
#include "profiler.h"
void numerical_test(fmpq_t res, slong n, double ans)
{
const double tol = 1e-13;
double err;
mpq_t tmp;
mpq_init(tmp);
arith_harmonic_number(res, n);
fmpq_get_mpq(tmp, res);
err = mpq_get_d(tmp) - ans;
err = FLINT_ABS(err);
if (err > tol)
{
flint_printf("FAIL: %wd %.16f %.16f\n", n, mpq_get_d(tmp), ans);
abort();
}
mpq_clear(tmp);
}
void
mpq_harmonic_balanced(mpq_t res, slong a, slong b)
{
slong k;
mpq_t t;
mpq_init(t);
if (b - a < 50)
{
flint_mpq_set_ui(res, 0, UWORD(1));
for (k = a; k <= b; k++)
{
flint_mpq_set_ui(t, UWORD(1), k);
mpq_add(res, res, t);
}
}
else
{
mpq_harmonic_balanced(res, a, (a+b)/2);
mpq_harmonic_balanced(t, (a+b)/2+1, b);
mpq_add(res, res, t);
}
mpq_clear(t);
}
int main(void)
{
slong i;
mpq_t x, y;
fmpq_t t;
FLINT_TEST_INIT(state);
flint_printf("harmonic_number....");
fflush(stdout);
fmpq_init(t);
mpq_init(x);
mpq_init(y);
for (i = -2; i < 1000; i++)
{
mpq_harmonic_balanced(x, 1, i);
arith_harmonic_number(t, i);
fmpq_get_mpq(y, t);
if (!mpq_equal(x, y))
{
flint_printf("FAIL: %wd\n", i);
abort();
}
}
numerical_test(t, 1000, 7.4854708605503449127);
numerical_test(t, 1001, 7.4864698615493459117);
numerical_test(t, 1002, 7.4874678655413618797);
numerical_test(t, 1003, 7.4884648745144426375);
numerical_test(t, 10000, 9.7876060360443822642);
numerical_test(t, 10001, 9.7877060260453821642);
numerical_test(t, 10002, 9.7878060060493813643);
numerical_test(t, 10003, 9.7879059760583786652);
numerical_test(t, 10004, 9.7880059360743722677);
numerical_test(t, 20000, 10.480728217229327573);
numerical_test(t, 30000, 10.886184992119899362);
numerical_test(t, 40000, 11.173862897945522882);
numerical_test(t, 50000, 11.397003949278482638);
numerical_test(t, 60000, 11.579323839415955783);
numerical_test(t, 70000, 11.733473328773164956);
numerical_test(t, 80000, 11.867003828544530692);
numerical_test(t, 90000, 11.984786169759202469);
numerical_test(t, 100000, 12.090146129863427947);
numerical_test(t, 100001, 12.090156129763428947);
numerical_test(t, 100002, 12.090166129563432947);
numerical_test(t, 100003, 12.090176129263441947);
numerical_test(t, 100004, 12.090186128863457946);
numerical_test(t, 300000, 13.188755085205611713);
numerical_test(t, 500000, 13.699580042305528322);
numerical_test(t, 700000, 14.036051993212618803);
numerical_test(t, 900000, 14.287366262763433338);
mpq_clear(x);
mpq_clear(y);
fmpq_clear(t);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,70 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
static const mp_limb_t known[] = {
1, 1, 2, 3, 4, 6, 6, 12, 15, 20, 30, 30, 60, 60, 84, 105, 140, 210,
210, 420, 420, 420, 420, 840, 840, 1260, 1260, 1540, 2310, 2520,
4620, 4620, 5460, 5460, 9240, 9240, 13860, 13860, 16380, 16380,
27720, 30030, 32760, 60060, 60060, 60060, 60060, 120120
};
int main(void)
{
fmpz * res;
slong k, n;
FLINT_TEST_INIT(state);
flint_printf("landau_function_vec....");
fflush(stdout);
n = 45;
res = _fmpz_vec_init(n);
arith_landau_function_vec(res, n);
for (k = 0; k < n; k++)
{
if (fmpz_cmp_ui(res + k, known[k]))
{
flint_printf("FAIL:\n");
flint_printf("k = %wd, res[k] = %wd, expected: %wd\n",
k, fmpz_get_si(res + k), known[k]);
abort();
}
}
_fmpz_vec_clear(res, n);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,86 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "profiler.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpq_poly.h"
int main()
{
fmpq_poly_t Pn, Pn1, Pn2, R;
slong n;
FLINT_TEST_INIT(state);
flint_printf("legendre_polynomial....");
fflush(stdout);
fmpq_poly_init(Pn);
fmpq_poly_init(Pn1);
fmpq_poly_init(Pn2);
fmpq_poly_init(R);
fmpq_poly_set_ui(Pn, UWORD(1));
fmpq_poly_set_coeff_ui(Pn1, 1, UWORD(1));
for (n = 0; n <= 500; n++)
{
arith_legendre_polynomial(R, n);
if (!fmpq_poly_equal(Pn, R))
{
flint_printf("FAIL: n = %wd\n", n);
flint_printf("Direct: "); fmpq_poly_print_pretty(R, "x"); flint_printf("\n");
flint_printf("Recur.: "); fmpq_poly_print_pretty(Pn, "x"); flint_printf("\n");
abort();
}
fmpq_poly_shift_left(Pn2, Pn1, 1);
fmpq_poly_scalar_mul_ui(Pn2, Pn2, 2*n + 3);
fmpq_poly_scalar_mul_si(Pn, Pn, -(n+1));
fmpq_poly_add(Pn2, Pn2, Pn);
fmpq_poly_scalar_div_ui(Pn2, Pn2, n+2);
fmpq_poly_swap(Pn, Pn1);
fmpq_poly_swap(Pn1, Pn2);
}
fmpq_poly_clear(Pn);
fmpq_poly_clear(Pn1);
fmpq_poly_clear(Pn2);
fmpq_poly_clear(R);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,98 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "ulong_extras.h"
#include "profiler.h"
void check(fmpz_t n, int expected)
{
int mu;
mu = arith_moebius_mu(n);
if (mu != expected)
{
flint_printf("FAIL:");
fmpz_print(n);
flint_printf("\n");
}
}
int main(void)
{
fmpz_t x;
ulong p;
slong i, j, k, l;
FLINT_TEST_INIT(state);
flint_printf("moebius_mu....");
fflush(stdout);
fmpz_init(x);
for (i = -1000; i < 1000; i++)
{
fmpz_set_si(x, i);
check(x, n_moebius_mu(FLINT_ABS(i)));
}
for (i = 0; i < 1000; i++)
{
fmpz_set_ui(x, 1);
/* Product of some primes */
k = n_randtest(state) % 10;
l = n_randtest(state) % 10;
for (j = 0; j < k; j++)
{
l += (n_randtest(state) % 10) + 1;
fmpz_mul_ui(x, x, n_nth_prime(l+1));
}
check(x, (k % 2 ? -1 : 1));
fmpz_neg(x, x);
check(x, (k % 2 ? -1 : 1));
fmpz_abs(x, x);
/* No longer square-free */
p = n_nth_prime(n_randtest(state) % 100 + 1);
fmpz_mul_ui(x, x, p*p);
check(x, 0);
}
fmpz_clear(x);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,160 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <mpfr.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "arith.h"
#include "ulong_extras.h"
/* Values mod 10^9 generated with Sage */
static const ulong testdata[][2] =
{
{100000, 421098519},
{100001, 33940350},
{100002, 579731933},
{100003, 625213730},
{100004, 539454200},
{100005, 69672418},
{100006, 865684292},
{100007, 641916724},
{100008, 36737908},
{100009, 293498270},
{100010, 177812057},
{100011, 756857293},
{100012, 950821113},
{100013, 824882014},
{100014, 533894560},
{100015, 660734788},
{100016, 835912257},
{100017, 302982816},
{100018, 468609888},
{100019, 221646940},
{1000000, 104673818},
{1000001, 980212296},
{1000002, 709795681},
{1000003, 530913758},
{1000004, 955452980},
{1000005, 384388683},
{1000006, 138665072},
{1000007, 144832602},
{1000008, 182646067},
{1000009, 659145045},
{1000010, 17911162},
{1000011, 606326324},
{1000012, 99495156},
{1000013, 314860251},
{1000014, 497563335},
{1000015, 726842109},
{1000016, 301469541},
{1000017, 227491620},
{1000018, 704160927},
{1000019, 995311980},
{10000000, 677288980},
{10000001, 433805210},
{10000002, 365406948},
{10000003, 120899894},
{10000004, 272822040},
{10000005, 71938624},
{10000006, 637670808},
{10000007, 766947591},
{10000008, 980210244},
{10000009, 965734705},
{10000010, 187411691},
{10000011, 485652153},
{10000012, 825498761},
{10000013, 895802660},
{10000014, 152775845},
{10000015, 791493402},
{10000016, 299640598},
{10000017, 383615481},
{10000018, 378922331},
{10000019, 37059200},
{100000000, 836637702},
{100000001, 66421565},
{100000002, 747849093},
{100000003, 465329748},
{100000004, 166747980},
{0, 0},
};
int main(void)
{
fmpz_t p;
fmpz * v;
slong i;
FLINT_TEST_INIT(state);
flint_printf("number_of_partitions....");
fflush(stdout);
fmpz_init(p);
v = _fmpz_vec_init(3000);
arith_number_of_partitions_vec(v, 3000);
for (i = 0; i < 3000; i++)
{
arith_number_of_partitions(p, i);
if (!fmpz_equal(p, v + i))
{
flint_printf("FAIL:\n");
flint_printf("p(%wd) does not agree with power series\n", i);
flint_printf("Computed p(%wd): ", i); fmpz_print(p); flint_printf("\n");
flint_printf("Expected: "); fmpz_print(v + i); flint_printf("\n");
abort();
}
}
_fmpz_vec_clear(v, 3000);
for (i = 0; testdata[i][0] != 0; i++)
{
arith_number_of_partitions(p, testdata[i][0]);
if (fmpz_fdiv_ui(p, 1000000000) != testdata[i][1])
{
flint_printf("FAIL:\n");
flint_printf("p(%wd) does not agree with known value mod 10^9\n",
testdata[i][0]);
flint_printf("Computed: %wu\n", fmpz_fdiv_ui(p, 1000000000));
flint_printf("Expected: %wu\n", testdata[i][1]);
abort();
}
}
fmpz_clear(p);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,120 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <gmp.h>
#include "flint.h"
#include "arith.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
#include "profiler.h"
#include "nmod_vec.h"
int main(void)
{
fmpz * p;
mp_ptr pmod;
slong k, n;
const slong maxn = 1000;
FLINT_TEST_INIT(state);
flint_printf("number_of_partitions_vec....");
fflush(stdout);
p = _fmpz_vec_init(maxn);
pmod = _nmod_vec_init(maxn);
for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4)
{
fmpz_t s, t;
nmod_t mod;
nmod_init(&mod, n_randtest_prime(state, 0));
arith_number_of_partitions_vec(p, n);
arith_number_of_partitions_nmod_vec(pmod, n, mod);
for (k = 0; k < n; k++)
{
if (fmpz_fdiv_ui(p + k, mod.n) != pmod[k])
{
flint_printf("FAIL:\n");
flint_printf("n = %wd, k = %wd\n", n, k);
abort();
}
}
if (n > 1)
{
fmpz_init(s);
fmpz_init(t);
for (k = 1; k < n; k++)
{
slong j;
j = n - 1 - k*(3*k - 1)/2;
if (j >= 0)
fmpz_set(t, p + j);
else
fmpz_zero(t);
j = n - 1 - k*(3*k + 1)/2;
if (j >= 0)
fmpz_add(t, t, p + j);
if (k % 2)
fmpz_add(s, s, t);
else
fmpz_sub(s, s, t);
}
if (!fmpz_equal(s, p + n - 1))
{
flint_printf("FAIL:\n");
flint_printf("n = %wd\n", n);
fmpz_print(s);
flint_printf("\n");
fmpz_print(p + n - 1);
flint_printf("\n");
abort();
}
fmpz_clear(s);
fmpz_clear(t);
}
}
_fmpz_vec_clear(p, maxn);
_nmod_vec_clear(pmod);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,66 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "arith.h"
#include "ulong_extras.h"
int main(void)
{
slong k;
FLINT_TEST_INIT(state);
flint_printf("pi_chudnovsky....");
fflush(stdout);
for (k = 2; k < 20; k++)
{
mpfr_t x, y;
mpfr_init2(x, WORD(1) << k);
mpfr_init2(y, WORD(1) << k);
mpfr_const_pi(x, MPFR_RNDN);
mpfr_pi_chudnovsky(y, MPFR_RNDN);
if (!mpfr_equal_p(x, y))
{
flint_printf("FAIL:\n");
flint_printf("Wrong value at prec = %wd\n", WORD(1) << k);
abort();
}
mpfr_clear(x);
mpfr_clear(y);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,69 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "arith.h"
#include "ulong_extras.h"
int main(void)
{
ulong k;
fmpz_t x;
fmpz_t y;
FLINT_TEST_INIT(state);
flint_printf("primorial....");
fflush(stdout);
fmpz_init(x);
fmpz_init(y);
fmpz_set_ui(y, 1);
for (k = 0; k < 10000; k++)
{
arith_primorial(x, k);
if (n_is_prime(k))
fmpz_mul_ui(y, y, k);
if (!fmpz_equal(x, y))
{
flint_printf("FAIL:\n");
flint_printf("primorial of %wu disagrees with direct product\n", k);
fmpz_print(x);
flint_printf("\n");
abort();
}
}
fmpz_clear(x);
fmpz_clear(y);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@ -0,0 +1,172 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "flint.h"
#include "arith.h"
#include "ulong_extras.h"
void check_value(slong n, char *ans)
{
fmpz_t x, y;
fmpz_init(x);
fmpz_init(y);
fmpz_set_si(y, n);
arith_ramanujan_tau(x, y);
fmpz_set_str(y, ans, 10);
if (!fmpz_equal(x,y))
{
flint_printf("FAIL:\n");
flint_printf("tau(%wd) gave ", n);
fmpz_print(x);
flint_printf(", expected %s\n", ans);
abort();
}
fmpz_clear(x);
fmpz_clear(y);
}
void consistency_check(slong n)
{
fmpz_poly_t p;
fmpz_t x, y;
slong k;
fmpz_poly_init(p);
fmpz_init(x);
fmpz_init(y);
arith_ramanujan_tau_series(p, n);
if (p->length != n && !(n == 1 && p->length == 0))
{
flint_printf("FAIL:\n");
flint_printf("wrong length of polynomial %wd\n", n);
abort();
}
for (k=0; k<n; k++)
{
fmpz_set_si(y, k);
arith_ramanujan_tau(x, y);
fmpz_poly_get_coeff_fmpz(y, p, k);
if (!fmpz_equal(x,y))
{
flint_printf("FAIL:\n");
flint_printf("different tau n=%wd, k=%wd\n", n, k);
fmpz_print(x);
flint_printf("\n");
fmpz_print(y);
flint_printf("\n");
abort();
}
}
fmpz_clear(x);
fmpz_clear(y);
fmpz_poly_clear(p);
}
int main(void)
{
FLINT_TEST_INIT(state);
flint_printf("ramanujan_tau....");
fflush(stdout);
check_value(0, "0");
check_value(1, "1");
check_value(2, "-24");
check_value(3, "252");
check_value(4, "-1472");
check_value(5, "4830");
check_value(6, "-6048");
check_value(7, "-16744");
check_value(8, "84480");
check_value(9, "-113643");
check_value(10, "-115920");
check_value(11, "534612");
check_value(12, "-370944");
check_value(13, "-577738");
check_value(14, "401856");
check_value(15, "1217160");
check_value(16, "987136");
check_value(17, "-6905934");
check_value(18, "2727432");
check_value(19, "10661420");
check_value(20, "-7109760");
check_value(21, "-4219488");
check_value(22, "-12830688");
check_value(23, "18643272");
check_value(24, "21288960");
check_value(25, "-25499225");
check_value(26, "13865712");
check_value(27, "-73279080");
check_value(28, "24647168");
check_value(29, "128406630");
check_value(30, "-29211840");
check_value(31, "-52843168");
check_value(32, "-196706304");
check_value(33, "134722224");
check_value(34, "165742416");
check_value(35, "-80873520");
check_value(36, "167282496");
check_value(37, "-182213314");
check_value(38, "-255874080");
check_value(39, "-145589976");
check_value(40, "408038400");
check_value(41, "308120442");
check_value(42, "101267712");
check_value(43, "-17125708");
check_value(44, "-786948864");
check_value(45, "-548895690");
check_value(46, "-447438528");
check_value(47, "2687348496");
check_value(48, "248758272");
check_value(49, "-1696965207");
check_value(1000, "-30328412970240000");
check_value(10000, "-482606811957501440000");
check_value(100000, "-2983637890141033828147200000");
check_value(5040, "9072480147209256960");
check_value(25401600, "-982963272212951631424865761586105548800");
check_value(100003, "1194906306375914517502892252");
check_value(15251, "-67392761749743476612496");
check_value(16777216, "5141538908507386166920374725609506471936");
check_value(43046721, "447670851294004737003138291024309833342241");
check_value(462594208,
"-313042078739616847874899392539635327193629261824");
consistency_check(0);
consistency_check(1);
consistency_check(2);
consistency_check(3);
consistency_check(10);
consistency_check(11);
consistency_check(100);
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

Some files were not shown because too many files have changed in this diff Show More